diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d7126a6224f7009ac511df9e95fbbb32ae0d7365 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# vim swp +*.swp + +# log and exec file +log/ +lte_build_oai/ +targets/bin/ +cmake_targets/nas_sim_tools/build/ diff --git a/README.txt b/README.txt index aec938c0d341e147599279c7c3a315d1aee63fd3..37f6a865712344caf06f56529945a9021301c272 100644 --- a/README.txt +++ b/README.txt @@ -17,7 +17,7 @@ openairinterface5g ├── maketags : Script to generate emacs tags ├── nfapi : Contains the NFAPI code. A local Readme file provides more details. ├── openair1 : 3GPP LTE Rel-10/12 PHY layer + PHY RF simulation. A local Readme file provides more details. -├── openair2 : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP implementation. +├── openair2 : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP implementation. ├── COMMON ├── DOCS ├── ENB_APP @@ -61,3 +61,5 @@ v1.0.0 -> January 2019. This version first implements the architectural split de S1-flex has been introduced. New tools: config library, telnet server, ... A lot of bugfixes and a proper automated Continuous Integration process validates contributions. +v1.0.1 -> February 2019: Bug fix for the UE L1 simulator. +v1.0.2 -> February 2019: Full OAI support for 3.13.1 UHD diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index fc0290fc44c2a03ed428511fb067b86c16ace0aa..56624d32300372d6f6326e5d873c9c66fc2a4395 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -33,15 +33,18 @@ def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { def doRedHatBuild = false def doFlexranCtrlTest = false +// Location of the executor node +def nodeExecutor = params.nodeExecutor + pipeline { agent { - label 'bellatrix' + label nodeExecutor } options { disableConcurrentBuilds() timestamps() gitLabConnection('OAI GitLab') - gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-FDD-Band7", "Test-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40"]) + gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13"]) ansiColor('xterm') } @@ -85,6 +88,9 @@ pipeline { echo "GitLab Act is ${env.gitlabActionType}" script { if ("MERGE".equals(env.gitlabActionType)) { + // since a bit, in push events, gitlabUserEmail is not populated + gitCommitAuthorEmailAddr = env.gitlabUserEmail + echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}" // GitLab-Jenkins plugin integration is lacking to perform the merge by itself // Doing it manually --> it may have merge conflicts sh "./ci-scripts/doGitLabMerge.sh --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}" @@ -104,6 +110,11 @@ pipeline { } else { echo "Git Branch is ${GIT_BRANCH}" echo "Git Commit is ${GIT_COMMIT}" + // since a bit, in push events, gitlabUserEmail is not populated + gitCommitAuthorEmailAddr = sh returnStdout: true, script: 'git log -n1 --pretty=format:%ae ${GIT_COMMIT}' + gitCommitAuthorEmailAddr = gitCommitAuthorEmailAddr.trim() + echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}" + sh "git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG" sh "zip -r -qq localZip.zip ." // Running astyle options on all C/H files in the repository @@ -129,6 +140,7 @@ pipeline { script { def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Merge Conflicts -- Cannot perform CI" addGitLabMRComment comment: message + currentBuild.result = 'FAILURE' } } } @@ -166,14 +178,6 @@ pipeline { } } - stage ("Start VM -- L2-Sim") { - steps { - timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" - } - } - } - stage ("Start VM -- phy-sim") { steps { timeout (time: 5, unit: 'MINUTES') { @@ -223,7 +227,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build eNb-ethernet") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } @@ -232,20 +236,11 @@ pipeline { steps { gitlabCommitStatus(name: "Build UE-ethernet") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } } - stage ("Build L2-Simulator-eNB") { - steps { - //gitlabCommitStatus(name: "Build UE-ethernet") { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" - } - //} - } - } stage ("Build physical simulators") { steps { gitlabCommitStatus(name: "Build phy-sim") { @@ -260,7 +255,7 @@ pipeline { expression {doRedHatBuild} } steps { - gitlabCommitStatus(name: "Build eNb-USRP-CentOS") { + gitlabCommitStatus(name: "Build eNb-USRP-RHE") { script { try { withCredentials([ @@ -271,7 +266,7 @@ pipeline { } } } catch (Exception e) { - echo "Red Hat build failed not an error now" + echo "Red Hat build failed but we could keep running pipeline if all ubuntu-based build passed" } } } @@ -279,6 +274,11 @@ pipeline { } } post { + failure { + script { + currentBuild.result = 'FAILURE' + } + } always { script { dir ('archives') { @@ -289,6 +289,17 @@ pipeline { } if ("MERGE".equals(env.gitlabActionType)) { sh "./ci-scripts/oai-ci-vm-tool report-build --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}" + // If the merge request has introduced more CPPCHECK errors or warnings, notifications in GitLab + if (fileExists('oai_cppcheck_added_errors.txt')) { + def ret=readFile('./oai_cppcheck_added_errors.txt').trim(); + if ("0".equals(ret)) { + echo "No added cppcheck warnings/errors in this merge request" + } else { + def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Some modified files in Merge Request MAY have INTRODUCED up to " + ret + " CPPCHECK errors/warnings" + addGitLabMRComment comment: message + } + } + // If the merge request has introduced compilation warnings, notifications in GitLab sh "./ci-scripts/checkAddedWarnings.sh --src-branch ${env.gitlabSourceBranch} --target-branch ${env.gitlabTargetBranch}" def res=readFile('./oai_warning_files.txt').trim(); if ("0".equals(res)) { @@ -312,219 +323,239 @@ pipeline { stage ("Variant Tests") { parallel { - stage ("Test physical simulators") { - steps { - gitlabCommitStatus(name: "Test phy-sim") { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + stage ("VM-based tests") { + stages { + stage ("Test physical simulators") { + steps { + script { + timeout (time: 20, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test phy-sim") { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + } + } + stage ("Build Flexran Controller") { + when { + expression {doFlexranCtrlTest} + } + steps { + script { + timeout (time: 20, unit: 'MINUTES') { + try { + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + } + } + stage ("Test basic simulator") { + steps { + script { + timeout (time: 30, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test basic-sim") { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + } + } + stage ("Test L1 simulator") { + steps { + script { + timeout (time: 30, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test L1-sim") { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l1-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + } + } + stage ("Test RF simulator") { + steps { + script { + timeout (time: 30, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test RF-sim") { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + } + } + stage ("Test L2 simulator") { + steps { + script { + timeout (time: 30, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test L2-sim") { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + } + } + stage ("Destroy all Virtual Machines") { + steps { + sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } } - stage ("Test basic simulator") { + stage ("Test MONOLITHIC - FDD - Band 7 - B210") { steps { - gitlabCommitStatus(name: "Test basic-sim") { - timeout (time: 30, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + script { + triggerSlaveJob ('eNB-CI-FDD-Band7-B210', 'Test-Mono-FDD-Band7') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-CI-FDD-Band7-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' } } } } - stage ("Test L2 simulator") { + stage ("Test MONOLITHIC - TDD - Band 40 - B210") { steps { - gitlabCommitStatus(name: "Test L2-sim") { - timeout (time: 30, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + script { + triggerSlaveJob ('eNB-CI-TDD-Band40-B210', 'Test-Mono-TDD-Band40') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-CI-TDD-Band40-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' } } } } - stage ("Build Flexran Controller") { - when { - expression {doFlexranCtrlTest} - } + stage ("Test IF4p5 - FDD - Band 7 - B210") { steps { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + script { + sh "sleep 60" + triggerSlaveJob ('eNB-CI-IF4p5-FDD-Band7-B210', 'Test-IF4p5-FDD-Band7') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-CI-IF4p5-FDD-Band7-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } } } } - stage ("Test FDD - Band 7 - B210") { + stage ("Test IF4p5 - TDD - Band 40 - B210") { steps { script { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-FDD-Band7") { - build job: 'eNB-CI-FDD-Band7-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) - ] - } - } else { - gitlabCommitStatus(name: "Test-FDD-Band7") { - build job: 'eNB-CI-FDD-Band7-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] - } - } + sh "sleep 60" + triggerSlaveJob ('eNB-CI-IF4p5-TDD-Band40-B210', 'Test-IF4p5-TDD-Band40') } } post { - // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build always { script { - if (!fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-FDD-Band7-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-FDD-Band7-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-FDD-Band7-B210.html' - } - } + finalizeSlaveJob('eNB-CI-IF4p5-TDD-Band40-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' } } } } - stage ("Test TDD - Band 40 - B210") { + stage ("Test MONOLITHIC - FDD - Band 13 - B210") { steps { script { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-TDD-Band40") { - build job: 'eNB-CI-TDD-Band40-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) - ] - } - } else { - gitlabCommitStatus(name: "Test-TDD-Band40") { - build job: 'eNB-CI-TDD-Band40-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] - } - } + triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-B210', 'Test-Mono-FDD-Band13') } } post { - // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build always { script { - if (!fileExists('test_results-eNB-CI-TDD-Band40-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-TDD-Band40-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-TDD-Band40-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-TDD-Band40-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-TDD-Band40-B210.html' - } - } + finalizeSlaveJob('eNB-CI-MONO-FDD-Band13-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' } } } } - stage ("Test IF4p5 - FDD - Band 7 - B210") { + stage ("Test OAI UE - FDD - Band 20 - B200") { steps { script { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-IF4p5-FDD-Band7") { - build job: 'eNB-CI-IF4p5-FDD-Band7-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) - ] - } - } else { - gitlabCommitStatus(name: "Test-IF4p5-FDD-Band7") { - build job: 'eNB-CI-IF4p5-FDD-Band7-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] - } - } + triggerSlaveJobNoGitLab ('UE-CI-FDD-Band20-B200') } } post { - // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build always { script { - if (!fileExists('test_results-eNB-CI-IF4p5-FDD-Band7-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-IF4p5-FDD-Band7-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-IF4p5-FDD-Band7-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-IF4p5-FDD-Band7-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-IF4p5-FDD-Band7-B210.html' - } - } + finalizeSlaveJob('UE-CI-FDD-Band20-B200') + } + } + failure { + script { + currentBuild.result = 'FAILURE' } } } } - stage ("Test IF4p5 - TDD - Band 40 - B210") { + stage ("Test OAI UE - OAI eNB - FDD - Band 7 - B200") { steps { script { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-IF4p5-TDD-Band40") { - build job: 'eNB-CI-IF4p5-TDD-Band40-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) - ] - } - } else { - gitlabCommitStatus(name: "Test-IF4p5-TDD-Band40") { - build job: 'eNB-CI-IF4p5-TDD-Band40-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] - } - } + // Delayed trigger on slave job, so it is always the last one to run + sh "sleep 240" + triggerSlaveJob ('eNB-UE-CI-MONO-FDD-Band7-B200', 'Test-eNB-OAI-UE-FDD-Band7') } } post { - // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build always { script { - if (!fileExists('test_results-eNB-CI-IF4p5-TDD-Band40-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-IF4p5-TDD-Band40-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-IF4p5-TDD-Band40-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-IF4p5-TDD-Band40-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-IF4p5-TDD-Band40-B210.html' - } - } + finalizeSlaveJob('eNB-UE-CI-MONO-FDD-Band7-B200') + } + } + failure { + script { + currentBuild.result = 'FAILURE' } } } @@ -552,11 +583,6 @@ pipeline { } } } - stage ("Destroy all Virtual Machines") { - steps { - sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } } post { always { @@ -565,13 +591,18 @@ pipeline { sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}" emailext attachmentsPattern: '*results*.html', body: '''Hi, + Here are attached HTML report files for $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS! Regards, OAI CI Team''', replyTo: 'no-reply@openairinterface.org', subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!', - to: env.gitlabUserEmail + to: gitCommitAuthorEmailAddr + + if (fileExists('.git/CI_COMMIT_MSG')) { + sh "rm -f .git/CI_COMMIT_MSG" + } } } success { @@ -602,3 +633,66 @@ OAI CI Team''', } } } + +// ---- Slave Job functions + +def triggerSlaveJob (jobName, gitlabStatusName) { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: gitlabStatusName) { + build job: jobName, + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: true), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) + ] + } + } else { + gitlabCommitStatus(name: gitlabStatusName) { + build job: jobName, + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), + string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), + booleanParam(name: 'eNB_mergeRequest', value: false) + ] + } + } +} + +def triggerSlaveJobNoGitLab (jobName) { + if ("MERGE".equals(env.gitlabActionType)) { + build job: jobName, + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: true), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) + ] + } else { + build job: jobName, + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), + string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), + booleanParam(name: 'eNB_mergeRequest', value: false) + ] + } +} + +def finalizeSlaveJob(jobName) { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. The only drop-back is that we may retrieve the HTML report of a previous build + fileName = "test_results-${jobName}.html" + if (!fileExists(fileName)) { + copyArtifacts(projectName: jobName, + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists(fileName)) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' ${fileName}" + archiveArtifacts artifacts: fileName + } + } +} diff --git a/ci-scripts/Jenkinsfile-tmp-full-ran b/ci-scripts/Jenkinsfile-tmp-full-ran new file mode 100644 index 0000000000000000000000000000000000000000..3e0777b6a7247f1ad83ca817e509be50bcb361f2 --- /dev/null +++ b/ci-scripts/Jenkinsfile-tmp-full-ran @@ -0,0 +1,430 @@ +#!/bin/groovy +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +// Template Jenkins Declarative Pipeline script to run Test w/ RF HW + +// Location of the python executor node shall be in the same subnet as the others servers +def pythonExecutor = params.pythonExecutor + +// Location of the test XML file to be run +def testXMLFile = params.pythonTestXmlFile +def mainPythonAllXmlFiles = "" +def buildStageStatus = true + +// Name of the test stage +def testStageName = params.pipelineTestStageName + +// Name of the phone resource +def ciSmartPhoneResource = params.smartphonesResource + +// Name of the phone resource +def oaiUEResource = params.oaiUEResource + +// Terminate Status +def termENB = 0 +def termOAIUE = 1 +def termStatusArray = new Boolean[termOAIUE + 1] +termStatusArray[termENB] = false +termStatusArray[termOAIUE] = 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 + +pipeline { + agent { + label pythonExecutor + } + options { + disableConcurrentBuilds() + ansiColor('xterm') + lock(extra: [[resource: ciSmartPhoneResource]], resource: ciSmartPhoneResource) + } + + stages { + 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.smartphonesResource == null) { + allParametersPresent = false + } + if (params.oaiUEResource == null) { + allParametersPresent = false + } + if (params.eNB_IPAddress == null) { + allParametersPresent = false + } + if (params.eNB_SourceCodePath == null) { + allParametersPresent = false + } + if (params.eNB_Credentials == null) { + allParametersPresent = false + } + if (params.UE_IPAddress == null) { + allParametersPresent = false + } + if (params.UE_SourceCodePath == null) { + allParametersPresent = false + } + if (params.UE_Credentials == null) { + allParametersPresent = false + } + // the following 4 parameters should be pushed by the master trigger + // if not present, take the job GIT variables (used for developing) + if (params.eNB_Repository == null) { + eNB_Repository = env.GIT_URL + } else { + eNB_Repository = params.eNB_Repository + } + echo "eNB_Repository : ${eNB_Repository}" + if (params.eNB_Branch == null) { + eNB_Branch = env.GIT_BRANCH + } else { + eNB_Branch = params.eNB_Branch + } + echo "eNB_Branch : ${eNB_Branch}" + if (params.eNB_CommitID == null) { + eNB_CommitID = env.GIT_COMMIT + } else { + eNB_CommitID = params.eNB_CommitID + } + echo "eNB_CommitID : ${eNB_CommitID}" + if (params.eNB_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.EPC_IPAddress == null) { + allParametersPresent = false + } + if (params.EPC_Type == null) { + allParametersPresent = false + } + if (params.EPC_SourceCodePath == null) { + allParametersPresent = false + } + if (params.EPC_Credentials == null) { + allParametersPresent = false + } + + if (params.ADB_IPAddress == null) { + allParametersPresent = false + } + if (params.ADB_Credentials == null) { + allParametersPresent = false + } + + if (allParametersPresent) { + echo "All parameters are present" + if (eNB_AllowMergeRequestProcess) { + sh "git fetch" + sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" + } else { + sh "git fetch" + sh "git checkout -f ${eNB_CommitID}" + } + } else { + echo "Some parameters are missing" + sh "./ci-scripts/fail.sh" + } + } + } + } + stage ("Build and Test") { + steps { + script { + dir ('ci-scripts') { + echo "\u2705 \u001B[32m${testStageName}\u001B[0m" + // If not present picking a default XML file + if (params.pythonTestXmlFile == null) { + // picking default + testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' + echo "Test XML file(default): ${testXMLFile}" + mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " + } else { + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { + mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " + echo "Test XML file : ${xmlFile}" + } + } + } + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] + ]) { + sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { + try { + sh "python3 main.py --mode=TesteNB --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + } catch (Exception e) { + currentBuild.result = 'FAILURE' + buildStageStatus = false + } + } + } + sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password}" + } + } + } + } + } + stage ("Terminate") { + parallel { + stage('Terminate eNB') { + steps { + echo '\u2705 \u001B[32mTerminate eNB\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" + } + } + post { + success { + script { + termStatusArray[termENB] = true + } + } + } + } + stage('Terminate OAI-UE') { + steps { + echo '\u2705 \u001B[32mTerminate OAI-UE\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateOAIUE --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password}" + } + } + post { + success { + script { + termStatusArray[termOAIUE] = true + } + } + } + } + } + } + stage('Log Collection') { + parallel { + stage('Log Collection (eNB - Run)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m' + sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("enb.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "enb.log.${env.BUILD_ID}.zip" + } + if(fileExists("ci-scripts/test_results.html")) { + sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html" + sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" + archiveArtifacts "test_results-${JOB_NAME}.html" + } + } + } + } + stage('Log Collection (OAI UE - Run)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (OAI UE - Run)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectOAIUE --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (OAI UE - Run)\u001B[0m' + sh "sshpass -p \'${UE_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${UE_Username}@${params.UE_IPAddress}:${UE_SourceCodePath}/cmake_targets/ue.log.zip ./ue.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("ue.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "ue.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (Ping)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (Ping)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectPing --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (Ping)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/ping.log.zip ./ping.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("ping.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "ping.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (Iperf)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (Iperf)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectIperf --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (Iperf)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/iperf.log.zip ./iperf.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("iperf.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "iperf.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (SPGW)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (SPGW)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (SPGW)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/spgw.log.zip ./spgw.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("spgw.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "spgw.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (MME)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (MME)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (MME)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/mme.log.zip ./mme.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("mme.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "mme.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (HSS)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (HSS)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectHSS --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (HSS)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/hss.log.zip ./hss.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("hss.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "hss.log.${env.BUILD_ID}.zip" + } + } + } + } + } + } + } + + 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]) { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" + } + } + if (!termStatusArray[termOAIUE]) { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateOAIUE --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password}" + } + } + } + } + } +} diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index 39347b35584884dde6e0f33003bd188add6d6cf0..5ffaefa89ff261cd5b54c1f3510b0337ef57a06d 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -106,19 +106,6 @@ pipeline { if (params.pythonExecutor != null) { echo "eNB CI executor node : ${pythonExecutor}" } - // 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) { - mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " - echo "Test XML file : ${xmlFile}" - } - } // If not present picking a default Stage Name if (params.pipelineTestStageName == null) { // picking default @@ -191,6 +178,13 @@ pipeline { 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" @@ -203,6 +197,21 @@ pipeline { script { dir ('ci-scripts') { echo "\u2705 \u001B[32m${testStageName}\u001B[0m" + // If not present picking a default XML file + if (params.pythonTestXmlFile == null) { + // picking default + testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' + echo "Test XML file(default): ${testXMLFile}" + mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " + } else { + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { + mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " + echo "Test XML file : ${xmlFile}" + } + } + } withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'], [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], @@ -211,6 +220,7 @@ pipeline { sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { try { sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" } catch (Exception e) { @@ -218,6 +228,7 @@ pipeline { buildStageStatus = false } } + } sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" } } diff --git a/ci-scripts/Jenkinsfile-tmp-ue b/ci-scripts/Jenkinsfile-tmp-ue new file mode 100644 index 0000000000000000000000000000000000000000..c2db977bcb8ff4faf068ae68355bccbc810bce79 --- /dev/null +++ b/ci-scripts/Jenkinsfile-tmp-ue @@ -0,0 +1,271 @@ +#!/bin/groovy +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +// Template Jenkins Declarative Pipeline script to run Test w/ RF HW + +// Location of the python executor node shall be in the same subnet as the others servers +def pythonExecutor = params.pythonExecutor + +// Location of the test XML file to be run +def testXMLFile = params.pythonTestXmlFile +def mainPythonAllXmlFiles = "" +def buildStageStatus = true + +// Name of the test stage +def testStageName = params.pipelineTestStageName + +// Name of the phone resource +def ciSmartPhoneResource = params.smartphonesResource + +// 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 + +pipeline { + agent { + label pythonExecutor + } + options { + disableConcurrentBuilds() + ansiColor('xterm') + lock (ciSmartPhoneResource) + } + stages { + 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.smartphonesResource == null) { + allParametersPresent = false + } + if (params.UE_IPAddress == null) { + allParametersPresent = false + } + if (params.UE_SourceCodePath == null) { + allParametersPresent = false + } + if (params.UE_Credentials == null) { + allParametersPresent = false + } + // the following 4 parameters should be pushed by the master trigger + // if not present, take the job GIT variables (used for developing) + if (params.eNB_Repository == null) { + eNB_Repository = env.GIT_URL + } else { + eNB_Repository = params.eNB_Repository + } + echo "eNB_Repository : ${eNB_Repository}" + if (params.eNB_Branch == null) { + eNB_Branch = env.GIT_BRANCH + } else { + eNB_Branch = params.eNB_Branch + } + echo "eNB_Branch : ${eNB_Branch}" + if (params.eNB_CommitID == null) { + eNB_CommitID = env.GIT_COMMIT + } else { + eNB_CommitID = params.eNB_CommitID + } + echo "eNB_CommitID : ${eNB_CommitID}" + if (params.eNB_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.EPC_IPAddress == null) { + allParametersPresent = false + } + if (params.EPC_Type == null) { + allParametersPresent = false + } + if (params.EPC_SourceCodePath == null) { + allParametersPresent = false + } + if (params.EPC_Credentials == null) { + allParametersPresent = false + } +*/ + if (params.ADB_IPAddress == null) { + allParametersPresent = false + } + if (params.ADB_Credentials == null) { + allParametersPresent = false + } + + if (allParametersPresent) { + echo "All parameters are present" + if (eNB_AllowMergeRequestProcess) { + sh "git fetch" + sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" + } else { + sh "git fetch" + sh "git checkout -f ${eNB_CommitID}" + } + } else { + echo "Some parameters are missing" + sh "./ci-scripts/fail.sh" + } + } + } + } + stage ("Build and Test") { + steps { + script { + dir ('ci-scripts') { + echo "\u2705 \u001B[32m${testStageName}\u001B[0m" + // If not present picking a default XML file + if (params.pythonTestXmlFile == null) { + // picking default + testXMLFile = 'xml_files/ue_band20_build.xml' + echo "Test XML file(default): ${testXMLFile}" + mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " + } else { + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { + mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " + echo "Test XML file : ${xmlFile}" + } + } + } + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] + ]) { + sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { + try { + sh "python3 main.py --mode=TestUE --UEIPAddress=${params.UE_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + } catch (Exception e) { + currentBuild.result = 'FAILURE' + buildStageStatus = false + } + } + } + sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password}" + } + } + } + } + } + stage('Log Collection') { + parallel { + stage('Log Collection (OAI UE - Build)') { + steps { + echo '\u2705 \u001B[32mLog Collection (OAI UE - Build)\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=LogCollectBuild --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (UE - Build)\u001B[0m' + sh "sshpass -p \'${UE_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${UE_Username}@${params.UE_IPAddress}:${UE_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("build.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "build.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (OAI UE - Run)') { + steps { + echo '\u2705 \u001B[32mLog Collection (OAI UE - Run)\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=LogCollectOAIUE --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (UE - Run)\u001B[0m' + sh "sshpass -p \'${UE_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${UE_Username}@${params.UE_IPAddress}:${UE_SourceCodePath}/cmake_targets/ue.log.zip ./ue.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("ue.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "ue.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: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -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/add_user_to_conf_file.awk b/ci-scripts/add_user_to_conf_file.awk new file mode 100644 index 0000000000000000000000000000000000000000..b338d5e7ac073cc7cc31b5d7b50a36d682feb88c --- /dev/null +++ b/ci-scripts/add_user_to_conf_file.awk @@ -0,0 +1,33 @@ +BEGIN{lineIdx=0;captureUEDesc=0} +{ + if ($0 ~/UE0/) { + captureUEDesc = 1 + } + if (captureUEDesc == 1) { + captureLine[lineIdx] = $0 + lineIdx = lineIdx + 1 + } + print $0 +} +END { + for (ueIdx = 1; ueIdx < num_ues; ueIdx++) { + print "" + for (k = 0; k < lineIdx; k++) { + if (captureLine[k] ~/UE0/) { + mLine = captureLine[k] + gsub("UE0", "UE"ueIdx, mLine) + print mLine + } else { + if (captureLine[k] ~/MSIN=/) { + mLine = captureLine[k] + MSIN=sprintf("%08d", 1111+int(ueIdx)) + gsub("00001111", MSIN, mLine) + print mLine + } else { + print captureLine[k] + } + } + + } + } +} diff --git a/ci-scripts/add_user_to_subscriber_list.awk b/ci-scripts/add_user_to_subscriber_list.awk new file mode 100644 index 0000000000000000000000000000000000000000..1e25990f59ff1c37d1094fc80041cc65824b147b --- /dev/null +++ b/ci-scripts/add_user_to_subscriber_list.awk @@ -0,0 +1,27 @@ +BEGIN{lineIdx=0} +{ + captureLine[lineIdx] = $0 + lineIdx = lineIdx + 1 + print $0 +} +END{ + for (ueIdx = 1; ueIdx < num_ues; ueIdx++) { + for (k = 0; k < lineIdx; k++) { + if (captureLine[k] ~/UserName=/) { + mLine = captureLine[k] + MSIN=sprintf("%08d", 1111+int(ueIdx)) + gsub("00001111", MSIN, mLine) + print mLine + } else { + if (captureLine[k] ~/SubscriptionIndex/) { + mLine = captureLine[k] + MSIN=sprintf("%d", 111+int(ueIdx)) + gsub("111", MSIN, mLine) + print mLine + } else { + print captureLine[k] + } + } + } + } +} diff --git a/ci-scripts/buildOnRH.sh b/ci-scripts/buildOnRH.sh index bb57cde165ed82b63e74cd774bbcf20a84e37223..076f34f8d22a61967ce3af91b893ea0f5ebb2efe 100755 --- a/ci-scripts/buildOnRH.sh +++ b/ci-scripts/buildOnRH.sh @@ -180,7 +180,7 @@ echo "Checking build status" echo "############################################################" LOG_PATTERN=.Rel14.txt -NB_PATTERN_FILES=4 +NB_PATTERN_FILES=7 LOG_FILES=`ls $ARCHIVES_LOC/*.txt` STATUS=0 @@ -204,12 +204,13 @@ then STATUS=-1 fi +echo "COMMAND: build_oai -I -w USRP --eNB" > $ARCHIVES_LOC/build_final_status.log if [ $STATUS -eq 0 ] then - echo "BUILD_OK" > $ARCHIVES_LOC/build_final_status.log + echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log echo "STATUS seems OK" else - echo "BUILD_KO" > $ARCHIVES_LOC/build_final_status.log + echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log echo "STATUS failed?" fi exit $STATUS diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index f9fb3b776f2ed3cba130c1a27203c9d68888bd17..ee5fc56c5f9711cce9c8477b9270041cf75799e1 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -94,17 +94,24 @@ function build_on_vm { echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" + acquire_vm_create_lock uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml - fi + echo "Waiting for VM to be started" + uvt-kvm wait $VM_NAME --insecure - echo "Waiting for VM to be started" - uvt-kvm wait $VM_NAME --insecure + VM_IP_ADDR=`uvt-kvm ip $VM_NAME` + echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + release_vm_create_lock + else + echo "Waiting for VM to be started" + uvt-kvm wait $VM_NAME --insecure - VM_IP_ADDR=`uvt-kvm ip $VM_NAME` - echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + VM_IP_ADDR=`uvt-kvm ip $VM_NAME` + echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + fi echo "############################################################" - echo "Copying GIT repo into VM ($VM_NAME)" + echo "Copying GIT repo into VM ($VM_NAME)" echo "############################################################" if [[ "$VM_NAME" == *"-flexran-rtc"* ]] then @@ -206,6 +213,6 @@ function build_on_vm { echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS fi fi - ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS + ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS rm -f $VM_CMDS } diff --git a/ci-scripts/checkAddedWarnings.sh b/ci-scripts/checkAddedWarnings.sh index 609261becff992d566369526508374543a5ce528..0ffaee9500b8ab8859aad2234bf218e049c1ff50 100755 --- a/ci-scripts/checkAddedWarnings.sh +++ b/ci-scripts/checkAddedWarnings.sh @@ -95,7 +95,7 @@ fi # Merge request scenario -MERGE_COMMMIT=`git log -n1 | grep commit | sed -e "s@commit @@"` +MERGE_COMMMIT=`git log -n1 --pretty=format:%H` TARGET_INIT_COMMIT=`cat .git/refs/remotes/origin/$TARGET_BRANCH` echo " ---- Checking the modified files by the merge request ----" diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh index 61cbf1256016054c62276550bb7986b4ebcdf17c..6ac43ca19fefd240bcaf64e13c2aeac48889a4eb 100755 --- a/ci-scripts/checkCodingFormattingRules.sh +++ b/ci-scripts/checkCodingFormattingRules.sh @@ -111,7 +111,7 @@ fi # Merge request scenario -MERGE_COMMMIT=`git log -n1 | grep commit | sed -e "s@commit @@"` +MERGE_COMMMIT=`git log -n1 --pretty=format:%H` TARGET_INIT_COMMIT=`cat .git/refs/remotes/origin/$TARGET_BRANCH` echo " ---- Checking the modified files by the merge request ----" diff --git a/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf new file mode 100644 index 0000000000000000000000000000000000000000..becd484c56021cc1e81005a8c82f0fcc9def3dcb --- /dev/null +++ b/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf @@ -0,0 +1,221 @@ +Active_eNBs = ( "eNB-CU-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = ( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-CU-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + tr_s_preference = "f1" + + local_s_if_name = "lo"; + remote_s_address = "127.0.0.3"; + local_s_address = "127.0.0.4"; + local_s_portc = 501; + remote_s_portc = 500; + local_s_portd = 601; + remote_s_portd = 600; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNodeB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 100; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnable = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* + srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =; + */ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff= 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + /* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; + */ + + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( + { + ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +log_config = { + global_log_level = "info"; + global_log_verbosity = "medium"; + pdcp_log_level = "info"; + pdcp_log_verbosity = "high"; + rrc_log_level = "info"; + rrc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; + gtp_log_level = "info"; + gtp_log_verbosity = "medium"; +}; + +NETWORK_CONTROLLER : { + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; diff --git a/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf new file mode 100644 index 0000000000000000000000000000000000000000..7e4dfc6de623cc66a1f368dbc385d1ef41616ada --- /dev/null +++ b/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf @@ -0,0 +1,221 @@ +Active_eNBs = ( "eNB-CU-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = ( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-CU-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + tr_s_preference = "f1" + + local_s_if_name = "lo"; + remote_s_address = "127.0.0.3"; + local_s_address = "127.0.0.4"; + local_s_portc = 501; + remote_s_portc = 500; + local_s_portd = 601; + remote_s_portd = 600; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNodeB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -25; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnable = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* + srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =; + */ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff= 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + /* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; + */ + + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( + { + ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +log_config = { + global_log_level = "info"; + global_log_verbosity = "medium"; + pdcp_log_level = "info"; + pdcp_log_verbosity = "high"; + rrc_log_level = "info"; + rrc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; + gtp_log_level = "info"; + gtp_log_verbosity = "medium"; +}; + +NETWORK_CONTROLLER : { + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; diff --git a/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf new file mode 100644 index 0000000000000000000000000000000000000000..b1c4774aba8eee211deb18e90f6fd8f5d6d8ab1d --- /dev/null +++ b/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf @@ -0,0 +1,221 @@ +Active_eNBs = ( "eNB-CU-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = ( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-CU-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + tr_s_preference = "f1" + + local_s_if_name = "lo"; + remote_s_address = "127.0.0.3"; + local_s_address = "127.0.0.4"; + local_s_portc = 501; + remote_s_portc = 500; + local_s_portd = 601; + remote_s_portd = 600; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNodeB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnable = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* + srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =; + */ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff= 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + /* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; + */ + + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( + { + ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +log_config = { + global_log_level = "info"; + global_log_verbosity = "medium"; + pdcp_log_level = "info"; + pdcp_log_verbosity = "high"; + rrc_log_level = "info"; + rrc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; + gtp_log_level = "info"; + gtp_log_verbosity = "medium"; +}; + +NETWORK_CONTROLLER : { + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; diff --git a/ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..fe994ef88975745b3c16b60372d16a551f3ee16c --- /dev/null +++ b/ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf @@ -0,0 +1,119 @@ +Active_eNBs = ( "eNB-Eurecom-DU"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_CU_ID = 0xe00; + + eNB_name = "eNB-Eurecom-DU"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 115; + + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + } + ); + + + # ------- 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_if_name = "lo"; + remote_n_address = "127.0.0.4"; + local_n_address = "127.0.0.3"; + local_n_portc = 500; + remote_n_portc = 501; + local_n_portd = 600; + remote_n_portd = 601; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 10; + att_rx = 10; + bands = [7]; + max_pdschReferenceSignalPower = -29; + max_rxgain = 115; + eNB_instances = [0]; + } +); + +log_config = { + global_log_level = "info"; + global_log_verbosity = "medium"; + hw_log_level = "info"; + hw_log_verbosity = "medium"; + phy_log_level = "info"; + phy_log_verbosity = "medium"; + mac_log_level = "info"; + mac_log_verbosity = "high"; + rlc_log_level = "info"; + rlc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; +}; + +NETWORK_CONTROLLER : { + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; diff --git a/ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..85407e3f350391fadfb44a427c5ab49084be4ffc --- /dev/null +++ b/ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf @@ -0,0 +1,119 @@ +Active_eNBs = ( "eNB-Eurecom-DU"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_CU_ID = 0xe00; + + eNB_name = "eNB-Eurecom-DU"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + } + ); + + + # ------- 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_if_name = "lo"; + remote_n_address = "127.0.0.4"; + local_n_address = "127.0.0.3"; + local_n_portc = 500; + remote_n_portc = 501; + local_n_portd = 600; + remote_n_portd = 601; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 10; + att_rx = 10; + bands = [7]; + max_pdschReferenceSignalPower = -25; + max_rxgain = 125; + eNB_instances = [0]; + } +); + +log_config = { + global_log_level = "info"; + global_log_verbosity = "medium"; + hw_log_level = "info"; + hw_log_verbosity = "medium"; + phy_log_level = "info"; + phy_log_verbosity = "medium"; + mac_log_level = "info"; + mac_log_verbosity = "high"; + rlc_log_level = "info"; + rlc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; +}; + +NETWORK_CONTROLLER : { + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; diff --git a/ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..3e97f58068f7ca0695ed24e6615d5cf98a8bfc0f --- /dev/null +++ b/ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf @@ -0,0 +1,119 @@ +Active_eNBs = ( "eNB-Eurecom-DU"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_CU_ID = 0xe00; + + eNB_name = "eNB-Eurecom-DU"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 120; + + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + } + ); + + + # ------- 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_if_name = "lo"; + remote_n_address = "127.0.0.4"; + local_n_address = "127.0.0.3"; + local_n_portc = 500; + remote_n_portc = 501; + local_n_portd = 600; + remote_n_portd = 601; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 10; + att_rx = 10; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 120; + eNB_instances = [0]; + } +); + +log_config = { + global_log_level = "info"; + global_log_verbosity = "medium"; + hw_log_level = "info"; + hw_log_verbosity = "medium"; + phy_log_level = "info"; + phy_log_verbosity = "medium"; + mac_log_level = "info"; + mac_log_verbosity = "high"; + rlc_log_level = "info"; + rlc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; +}; + +NETWORK_CONTROLLER : { + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; diff --git a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf index e3d3402c1c64bd95503f5ad712f91c1772457da7..ea8a56e38571e452792402c54b193598e3509b18 100644 --- a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf +++ b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf @@ -13,9 +13,9 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; - plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2;} ); + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2;} ); tr_s_preference = "local_mac" @@ -48,23 +48,23 @@ eNBs = prach_zero_correlation = 1; prach_freq_offset = 1; pucch_delta_shift = 1; - pucch_nRB_CQI = 1; - pucch_nCS_AN = 0; - pucch_n1_AN = 32; - pdsch_referenceSignalPower = -27; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -24; pdsch_p_b = 0; pusch_n_SB = 1; pusch_enable64QAM = "DISABLE"; pusch_hoppingMode = "interSubFrame"; - pusch_hoppingOffset = 0; + pusch_hoppingOffset = 0; pusch_groupHoppingEnabled = "ENABLE"; pusch_groupAssignment = 0; pusch_sequenceHoppingEnabled = "DISABLE"; pusch_nDMRS1 = 1; phich_duration = "NORMAL"; phich_resource = "ONESIXTH"; - srs_enable = "DISABLE"; - /* srs_BandwidthConfig =; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; srs_SubframeConfig =; srs_ackNackST =; srs_MaxUpPts =;*/ @@ -73,14 +73,14 @@ eNBs = pusch_alpha = "AL1"; pucch_p0_Nominal = -104; msg3_delta_Preamble = 6; - pucch_deltaF_Format1 = "deltaF2"; - pucch_deltaF_Format1b = "deltaF3"; - pucch_deltaF_Format2 = "deltaF0"; - pucch_deltaF_Format2a = "deltaF0"; - pucch_deltaF_Format2b = "deltaF0"; - - rach_numberOfRA_Preambles = "n64"; #64 - rach_preamblesGroupAConfig = "DISABLE"; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = "n64"; #64 + rach_preamblesGroupAConfig = "DISABLE"; /* rach_sizeOfRA_PreamblesGroupA = ; rach_messageSizeGroupA = ; @@ -105,7 +105,7 @@ eNBs = ue_TransmissionMode = "tm1"; # eMTC Parameters - emtc_parameters : + emtc_parameters : { eMTC_configured = 1; #hyperSFN_r13 = 0; @@ -115,7 +115,7 @@ eNBs = #SIB1 schedulingInfoSIB1_BR_r13 = 4; - #system_info_value_tag_SI = + #system_info_value_tag_SI = #( # { # systemInfoValueTagSi_r13 = 0; @@ -124,7 +124,7 @@ eNBs = cellSelectionInfoCE_r13 = "ENABLE"; q_RxLevMinCE_r13 = -70; - bandwidthReducedAccessRelatedInfo_r13 = "ENABLE" + bandwidthReducedAccessRelatedInfo_r13 = "ENABLE" si_WindowLength_BR_r13 = "ms20"; #0 si_RepetitionPattern_r13 = "everyRF"; #0 @@ -136,7 +136,7 @@ eNBs = } ); - fdd_DownlinkOrTddSubframeBitmapBR_r13 = "subframePattern40-r13"; + fdd_DownlinkOrTddSubframeBitmapBR_r13 = "subframePattern40-r13"; fdd_DownlinkOrTddSubframeBitmapBR_val_r13 = 0xFFFFFFFFFF; startSymbolBR_r13 = 2; si_HoppingConfigCommon_r13 = "off"; #1; # Note: 1==OFF ! @@ -157,14 +157,14 @@ eNBs = rach_numberOfRA_Preambles = 60; #14 rach_powerRampingStep = 4; - rach_preambleInitialReceivedTargetPower = -110; + rach_preambleInitialReceivedTargetPower = -110; rach_preambleTransMax = 10; rach_raResponseWindowSize = 10; rach_macContentionResolutionTimer = 64; rach_maxHARQ_Msg3Tx = 4; # max size for this array is 4 - rach_CE_LevelInfoList_r13 = + rach_CE_LevelInfoList_r13 = ( { firstPreamble_r13 = 60; @@ -175,7 +175,7 @@ eNBs = } ); - # BCCH CONFIG + # BCCH CONFIG bcch_modificationPeriodCoeff = 2; #PCCH Config @@ -189,8 +189,8 @@ eNBs = prach_zero_correlation = 1; prach_freq_offset = 1; - #PDSCH Config Common - pdsch_referenceSignalPower = -27 + #PDSCH Config Common + pdsch_referenceSignalPower = -24 pdsch_p_b = 0; @@ -208,27 +208,27 @@ eNBs = pucch_delta_shift = 1; pucch_nRB_CQI = 0; pucch_nCS_AN = 0; - pucch_n1_AN = 32; + pucch_n1_AN = 0; pusch_p0_Nominal = -96; pusch_alpha = "AL1"; pucch_p0_Nominal = -104; - pucch_deltaF_Format1 = "deltaF0"; - pucch_deltaF_Format1b = "deltaF3"; - pucch_deltaF_Format2 = "deltaF0"; - pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format1 = "deltaF0"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; pucch_deltaF_Format2b = "deltaF0"; msg3_delta_Preamble = 6; prach_ConfigCommon_v1310 = "ENABLE"; - + mpdcch_startSF_CSS_RA_r13 = "fdd-r13"; mpdcch_startSF_CSS_RA_r13_val = "v1"; #0 prach_HoppingOffset_r13 = 0; - + pdsch_maxNumRepetitionCEmodeA_r13 = "r16"; #0 #pdsch_maxNumRepetitionCEmodeB_r13 = "r384"; # NULL - 2 @@ -245,7 +245,7 @@ eNBs = ); # max size for this array is 4 - prach_parameters_ce_r13 = + prach_parameters_ce_r13 = ( { prach_config_index_br = 3; @@ -255,17 +255,17 @@ eNBs = numRepetitionPerPreambleAttempt_r13 = 1; #0 mpdcch_NumRepetition_RA_r13 = 1; #0 prach_HoppingConfig_r13 = 0; #1 - max_available_narrow_band = [3]; + max_available_narrow_band = [3]; } ); - n1PUCCH_AN_InfoList_r13 = + n1PUCCH_AN_InfoList_r13 = ( { - pucch_info_value = 0; + pucch_info_value = 33; } ); - + ue_TimersAndConstants_t300 = "ms1000"; ue_TimersAndConstants_t301 = "ms400"; @@ -283,21 +283,21 @@ eNBs = } - pucch_NumRepetitionCE_Msg4_Level0_r13 = "n1"; #0 + pucch_NumRepetitionCE_Msg4_Level0_r13 = "n1"; #0 #pucch_NumRepetitionCE_Msg4_Level1_r13 = "n2"; #1 #pucch_NumRepetitionCE_Msg4_Level2_r13 = "n16"; #2 #pucch_NumRepetitionCE_Msg4_Level3_r13 = "n32"; #3 - sib2_freq_hoppingParameters_r13 : + sib2_freq_hoppingParameters_r13 : { #sib2_mpdcch_pdsch_hoppingNB_r13 = "nb2"; #0 #sib2_interval_DLHoppingConfigCommonModeA_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) - #sib2_interval_DLHoppingConfigCommonModeA_r13_val = "int1"; + #sib2_interval_DLHoppingConfigCommonModeA_r13_val = "int1"; #sib2_interval_DLHoppingConfigCommonModeB_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) - #sib2_interval_DLHoppingConfigCommonModeB_r13_val = "int2"; + #sib2_interval_DLHoppingConfigCommonModeB_r13_val = "int2"; sib2_interval_ULHoppingConfigCommonModeA_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) - sib2_interval_ULHoppingConfigCommonModeA_r13_val = "int4"; #2 + sib2_interval_ULHoppingConfigCommonModeA_r13_val = "int4"; #2 # sib2_interval_ULHoppingConfigCommonModeB_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) # sib2_interval_ULHoppingConfigCommonModeB_r13_val = "int2"; #0 @@ -305,11 +305,11 @@ eNBs = } rach_preamblesGroupAConfig = "DISABLE"; - + phich_duration = "NORMAL"; phich_resource = "ONESIXTH"; srs_enable = "DISABLE"; - + } @@ -360,6 +360,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -392,36 +397,56 @@ eNBs = ); MACRLCs = ( - { + { num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; phy_test_mode = 0; puSch10xSnr = 200; puCch10xSnr = 200; - } + } ); L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - } + prach_dtx_threshold = 200; + } ); RUs = ( - { + { local_rf = "yes" nb_tx = 1 nb_rx = 1 att_tx = 0 att_rx = 0; bands = [13]; - max_pdschReferenceSignalPower = -27; - max_rxgain = 125; + max_pdschReferenceSignalPower = -24; + max_rxgain = 110; eNB_instances = [0]; } -); +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; log_config : { @@ -440,4 +465,3 @@ log_config : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf index b6028a81524f3a745485680a9660c5632d09278e..370697660e62474d4410d818e47721964d83c62b 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -37,7 +37,7 @@ eNBs = nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 125; + rx_gain = 115; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -178,8 +183,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; scheduler_mode = "fairRR"; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 150; + puCch10xSnr = 150; } ); diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 10cbd04e9a0fbe7b3bb0202de805734ea499dcb3..fbbc2f1154f6cd82f8708c38749b679d7fb605e9 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -178,8 +183,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; scheduler_mode = "fairRR"; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 150; + puCch10xSnr = 150; } ); @@ -199,7 +204,7 @@ RUs = ( att_rx = 0; bands = [38]; max_pdschReferenceSignalPower = -27; - max_rxgain = 115; + max_rxgain = 125; eNB_instances = [0]; } diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf index c79dbf1ac04921d47f955a79725053cc026c6030..f49d860a51f263284140c2458536b7211dc0e2cb 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -37,7 +37,7 @@ eNBs = nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 125; + rx_gain = 120; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -178,8 +183,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; scheduler_mode = "fairRR"; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 150; + puCch10xSnr = 150; } ); @@ -199,7 +204,7 @@ RUs = ( att_rx = 0; bands = [38]; max_pdschReferenceSignalPower = -27; - max_rxgain = 115; + max_rxgain = 120; eNB_instances = [0]; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf index 2c2ca635a6d7035261f1b65a1ce30add15caae08..c119e2f1c039f7d5cf4d755dd4bee195f9735e71 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf @@ -178,6 +178,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf index 4dd8c1ee22d9dd88003bf5b74dfd859f606a2a7e..a0d3ba6d06190d5392e211a0c3c7ef2380223ec3 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf @@ -178,6 +178,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index cae47b152c2129a67b5f090fc1c352035b7e0048..92a6e6f0bc49ae787a1ebbcde7077adae5a1f988 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -94,6 +94,14 @@ eNBs = pcch_default_PagingCycle = 128; pcch_nB = "oneT"; + drx_Config_present = "prSetup"; //"prSetup" "prRelease" + drx_onDurationTimer = "psf1"; // "psfX": X=1,2,3,4,5,6,8,10,20,30,40,50,60,80,100 + drx_InactivityTimer = "psf1"; // "psfX": X=1,2,3,4,5,6,8,10,20,30,40,50,60,80,100,200,300,500,750,1280,1920,2560 + drx_RetransmissionTimer = "psf1"; // "psfX": X=1,2,4,6,8,16,24,33 + drx_longDrx_CycleStartOffset_present = "prSf128"; // "psfX": X=10,20,32,40,64,80,128,160,256,320,512,640,1024,1280,2048,2560 + drx_longDrx_CycleStartOffset = 0; // X >= 0 && X < drx_longDrx_CycleStartOffset_present + drx_shortDrx_Cycle = "sf16"; // "sfX": X=2,5,8,10,16,20,32,40,64,80,128,160,256,320,512,640 + drx_shortDrx_ShortCycleTimer = 3; // 1..16 integer. Total duration in short cycle = drx_shortDrx_Cycle*drx_shortDrx_ShortCycleTimer [subframe] bcch_modificationPeriodCoeff = 2; ue_TimersAndConstants_t300 = 1000; ue_TimersAndConstants_t301 = 1000; @@ -178,6 +186,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf index 4e5510b0d429b94e3c1645c3fce137be2e600210..b006e04e91beb7356d5ca300d3a7ed40cfb3d7d1 100644 --- a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf @@ -181,6 +181,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -202,18 +207,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 200; puCch10xSnr = 200; - } + } ); L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_rf = "yes" nb_tx = 2 nb_rx = 2 @@ -224,7 +229,7 @@ RUs = ( max_rxgain = 115; eNB_instances = [0]; } -); +); THREAD_STRUCT = ( { @@ -262,4 +267,3 @@ log_config : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf index 594e3299db2a7862d60e778833a810cb0ec6924b..cabbed871a49bd74bdc7d3a649675a44c10e207a 100644 --- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf @@ -178,6 +178,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { @@ -200,18 +205,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 200; puCch10xSnr = 200; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_rf = "yes" nb_tx = 1 nb_rx = 1 @@ -223,7 +228,7 @@ RUs = ( eNB_instances = [0]; } -); +); THREAD_STRUCT = ( { @@ -261,4 +266,3 @@ NETWORK_CONTROLLER : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/lte-tdd-basic-sim.conf b/ci-scripts/conf_files/lte-tdd-basic-sim.conf index da330d2379576389ea3dede669c12a8486a6e89b..a376f45453a94f2cdcbd283ed1f6b88f24d49c84 100644 --- a/ci-scripts/conf_files/lte-tdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-tdd-basic-sim.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 285b7eaf9f54a4f3f0f6b636936b5eaaa7efb48b..d39f1e062064742373b0886fb071fb370246220d 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -144,6 +144,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 62e7fb48a445d0b508bf1cdcc7ff78caf0afad3d..0ae17356de40bd59002d4c66af947e24ed16bc3d 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -144,6 +144,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf index f99b701b8e1aa4770aed9ace72ad23b103a408a7..c58f05c82f5ca41c25adf6811d838a7c321b49b6 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -144,6 +144,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf index 6c80a4f7cf0d14817d3e911192e395993ab8d69c..6f6aa987881ffb9905f68bca0d0a64a1ac0b6cb6 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf @@ -7,7 +7,7 @@ eNBs = { # real_time choice in {hard, rt-preempt, no} real_time = "no"; - + ////////// Identification parameters: eNB_ID = 0xe00; @@ -181,6 +181,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -202,18 +207,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 160; puCch10xSnr = 160; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_if_name = "lo"; remote_address = "127.0.0.2"; local_address = "127.0.0.1"; @@ -229,7 +234,7 @@ RUs = ( att_rx = 0; eNB_instances = [0]; } -); +); THREAD_STRUCT = ( { @@ -267,4 +272,3 @@ NETWORK_CONTROLLER : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf index f4be50810c431a608f7b5732c3337201d2140f70..ec7fce3dbf9d3f69361903df61ea688b0fd84734 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf @@ -7,7 +7,7 @@ eNBs = { # real_time choice in {hard, rt-preempt, no} real_time = "no"; - + ////////// Identification parameters: eNB_ID = 0xe00; @@ -181,6 +181,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -202,18 +207,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 160; puCch10xSnr = 160; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_if_name = "lo"; remote_address = "127.0.0.2"; local_address = "127.0.0.1"; @@ -229,7 +234,7 @@ RUs = ( att_rx = 0; eNB_instances = [0]; } -); +); THREAD_STRUCT = ( { @@ -267,4 +272,3 @@ NETWORK_CONTROLLER : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf index 48c8370b4b25399b465d6be0e787e6c669d00eaf..4ebbff4bdab963f049e6737772cca618eae409f4 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf @@ -7,7 +7,7 @@ eNBs = { # real_time choice in {hard, rt-preempt, no} real_time = "no"; - + ////////// Identification parameters: eNB_ID = 0xe00; @@ -181,6 +181,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -202,18 +207,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 160; puCch10xSnr = 160; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_if_name = "lo"; remote_address = "127.0.0.2"; local_address = "127.0.0.1"; @@ -229,7 +234,7 @@ RUs = ( att_rx = 0; eNB_instances = [0]; } -); +); THREAD_STRUCT = ( { @@ -267,4 +272,3 @@ NETWORK_CONTROLLER : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf index c2a86f079e983672a2fcf8949e211d6862d00b94..52c0593d1b3006072da5684d9eaf4248fc13a6d9 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf @@ -179,6 +179,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "ens3"; @@ -196,13 +201,13 @@ eNBs = MACRLCs = ( { num_cc = 1; - local_s_if_name = "lo:"; - remote_s_address = "127.0.0.1"; - local_s_address = "127.0.0.2"; - local_s_portc = 50001; - remote_s_portc = 50000; - local_s_portd = 50011; - remote_s_portd = 50010; + local_s_if_name = "ens3"; + remote_s_address = "CI_UE_IP_ADDR"; + local_s_address = "CI_ENB_IP_ADDR"; + local_s_portc = 50001; + remote_s_portc = 50000; + local_s_portd = 50011; + remote_s_portd = 50010; tr_s_preference = "nfapi"; tr_n_preference = "local_RRC"; } @@ -211,7 +216,7 @@ MACRLCs = ( THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } diff --git a/ci-scripts/conf_files/rru.fdd.band7.conf b/ci-scripts/conf_files/rru.fdd.band7.conf index dab69e1f1ed4c5833f843ef3d9cdd90e4f6b740b..ea923ae3718a6a61ed08481d16e1f91df8f1db5b 100644 --- a/ci-scripts/conf_files/rru.fdd.band7.conf +++ b/ci-scripts/conf_files/rru.fdd.band7.conf @@ -42,4 +42,3 @@ log_config = { rrc_log_level ="error"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/rru.tdd.band40.conf b/ci-scripts/conf_files/rru.tdd.band40.conf index 775a2fbc67076b6999f02a84e1e1afd7365ede10..fb2b9399e23551a3281915a8ca7a551fb05f30b0 100644 --- a/ci-scripts/conf_files/rru.tdd.band40.conf +++ b/ci-scripts/conf_files/rru.tdd.band40.conf @@ -42,4 +42,3 @@ log_config = { rrc_log_level ="error"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/ue.nfapi.conf b/ci-scripts/conf_files/ue.nfapi.conf index ea0236cab4e97b640b0c8ac17601ccb184c22c25..2b602cbcf292902e6702f134aeabfaa012956185 100644 --- a/ci-scripts/conf_files/ue.nfapi.conf +++ b/ci-scripts/conf_files/ue.nfapi.conf @@ -17,21 +17,21 @@ log_config = { L1s = ( - { + { num_cc = 1; tr_n_preference = "nfapi"; - local_n_if_name = "lo"; - remote_n_address = "127.0.0.2"; - local_n_address = "127.0.0.1"; - local_n_portc = 50000; - remote_n_portc = 50001; - local_n_portd = 50010; - remote_n_portd = 50011; + local_n_if_name = "ens3"; + remote_n_address = "CI_ENB_IP_ADDR"; + local_n_address = "CI_UE_IP_ADDR"; + local_n_portc = 50000; + remote_n_portc = 50001; + local_n_portd = 50010; + remote_n_portd = 50011; } ); RUs = ( - { + { local_rf = "yes" nb_tx = 1 nb_rx = 1 @@ -40,5 +40,5 @@ RUs = ( bands = [7,38,42,43]; max_pdschReferenceSignalPower = -27; max_rxgain = 125; - } + } ); diff --git a/ci-scripts/cppcheck_suppressions.list b/ci-scripts/cppcheck_suppressions.list new file mode 100644 index 0000000000000000000000000000000000000000..4536f5731561dcca5ba7a39fef6f56e14689e91d --- /dev/null +++ b/ci-scripts/cppcheck_suppressions.list @@ -0,0 +1,101 @@ +// *INDENT-OFF* cppcheck doesn't like "astyling" this file!!!! +// /* +// * 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 +// */ +//***************************************************************************** +//***************************************************************************** +// section for "valid" memory leaks: the related functions are allocators and +// the caller is responsible of freeing the memory. cppcheck has a mechanism +// to check more accuretaly this, by defining callers responsible of freeing +// but tools like valgring might be more suitable +// +//----------------------------------------------------------------------------- +// suppress error about keysP memory leak, free must be done by calling func +memleak:common/utils/hashtable/obj_hashtable.c +//----------------------------------------------------------------------------- +// suppress error about keys memory leak, free must be done by calling func +memleak:openair2/UTIL/OMG/omg_hashtable.c +//----------------------------------------------------------------------------- +// suppress error about data memory leak. This is the buffer where +// _emm_as_encode function creates the encoded buffer +// +memleak:openair3/NAS/UE/EMM/SAP/emm_as.c +//----------------------------------------------------------------------------- +//***************************************************************************** +// section for files not used in oai exec's included in CI. +// Possibly candidates for removal otherwise should be documented and updated +// for project rules enforcement +// ---------------------------------------------------------------------------- +// likely sources for test programs, maintained? +invalidPrintfArgType_sint:openair1/PHY/CODING/TESTBENCH/ltetest.c +memleak:openair1/PHY/CODING/TESTBENCH/ltetest.c +invalidPrintfArgType_sint:openair1/PHY/CODING/TESTBENCH/pdcch_test.c +// +//----------------------------------------------------------------------------- +// oaisim deprecated, remove? +doubleFree:openair3/TEST/oaisim_mme_list_benchmark.c +// +//----------------------------------------------------------------------------- +// is itti analyzer deprecated +nullPointer:common/utils/itti_analyzer/itti_analyzer.c +nullPointerRedundantCheck:common/utils/itti_analyzer/libbuffers/buffers.c +doubleFree:common/utils/itti_analyzer/libbuffers/socket.c +memleak:common/utils/itti_analyzer/libbuffers/socket.c +memleak:common/utils/itti_analyzer/libparser/array_type.c +memleak:common/utils/itti_analyzer/libui/ui_callbacks.c +//----------------------------------------------------------------------------- +// obviously never even compiled!!! +syntaxError:openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +//----------------------------------------------------------------------------- +// omg, otg commented out in cmakelist to be cleaned up definitely? +arrayIndexOutOfBounds:openair2/UTIL/OMG/omg.c +uninitvar:openair2/UTIL/OTG/otg_rx_socket.c +//----------------------------------------------------------------------------- +// cppcheck is not able to understand that buf is initialized at the first +// iteration of the loop. +nullPointer:common/utils/T/local_tracer.c:243 +//----------------------------------------------------------------------------- +// once again cppcheck does not understand that fds is initialized in the +// first iteration of the loop +nullPointer:common/utils/T/tracer/multi.c:264 +nullPointer:common/utils/T/tracer/multi.c:265 +// +//***************************************************************************** +// +// True problems we don't know how to fix, Suppression is commented out, +// as these kind of problem need either to be fixed or can be suppressed +// when fully uderstood +//----------------------------------------------------------------------------- +// the function [nv]fapi_pnf_p7_config_create should return +// _this. _this points to a structure and a dynamically allocated field is +// returned. cppcheck suspects _this will never be released, so do i +// memleak:nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c +// memleak:nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +//----------------------------------------------------------------------------- +// may be security_data->kenb.value is released from calling functions. But even +// when, for test, freeing it before returning from emm_proc_security_mode_command +// which does the allocation, cppcheck complains. So something might be wrong... +// memleak:openair3/NAS/UE/EMM/SecurityModeControl.c +//----------------------------------------------------------------------------- +// when used, nobody but the original developer can guess if sn_data_cnf is set or not +// cppcheck found that in some cases it is not, code needs cleanup before fixing that... +// uninitvar:openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +//***************************************************************************** +// *INDENT-ON* diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh index 192008d86723d357f7a6dcb1d75674f3cf657377..e693b07b913eadbf5b17cca0754545c025b89e9d 100755 --- a/ci-scripts/createVM.sh +++ b/ci-scripts/createVM.sh @@ -49,6 +49,35 @@ function create_usage { echo "" } +function acquire_vm_create_lock { + local FlockFile="/tmp/vmclone.lck" + local unlocked="0" + touch ${FlockFile} 2>/dev/null + if [[ $? -ne 0 ]] + then + echo "Cannot access lock file ${FlockFile}" + exit 2 + fi + while [ $unlocked -eq 0 ] + do + exec 5>${FlockFile} + flock -nx 5 + if [[ $? -ne 0 ]] + then + echo "Another instance of VM creation is running" + sleep 10 + else + unlocked="1" + fi + done + chmod 666 ${FlockFile} 2>/dev/null +} + +function release_vm_create_lock { + local FlockFile="/tmp/vmclone.lck" + rm -Rf ${FlockFile} +} + function create_vm { echo "############################################################" echo "OAI CI VM script" @@ -60,10 +89,12 @@ function create_vm { echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" + acquire_vm_create_lock uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure VM_IP_ADDR=`uvt-kvm ip $VM_NAME` echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + release_vm_create_lock } diff --git a/ci-scripts/doGitLabMerge.sh b/ci-scripts/doGitLabMerge.sh index 852b6407eabf34ab822aa67d6f99780f68e61475..dd93ff41b7443ac4f145ef02902a63b3e9a5ad86 100755 --- a/ci-scripts/doGitLabMerge.sh +++ b/ci-scripts/doGitLabMerge.sh @@ -103,6 +103,11 @@ esac done +if [[ $TARGET_COMMIT_ID == "latest" ]] +then + TARGET_COMMIT_ID=`git log -n1 --pretty=format:%H origin/$TARGET_BRANCH` +fi + echo "Source Branch is : $SOURCE_BRANCH" echo "Source Commit ID is : $SOURCE_COMMIT_ID" echo "Target Branch is : $TARGET_BRANCH" @@ -121,6 +126,7 @@ git config user.email "jenkins@openairinterface.org" git config user.name "OAI Jenkins" git checkout -f $SOURCE_COMMIT_ID +git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG git merge --ff $TARGET_COMMIT_ID -m "Temporary merge for CI" diff --git a/ci-scripts/doc/ci_dev_home.md b/ci-scripts/doc/ci_dev_home.md new file mode 100644 index 0000000000000000000000000000000000000000..3bfc36d3f45b468b884cada014fac1110f48dd42 --- /dev/null +++ b/ci-scripts/doc/ci_dev_home.md @@ -0,0 +1,31 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI CI Dev documentation</font></b> + </td> + </tr> +</table> + +VM-based RF-Less Environment: + +* [How to setup your test env](./vm_based_simulator_env.md) +* [How to deal with OAI source files](./vm_based_simulator_sources.md) +* [The main script](./vm_based_simulator_main_scripts.md) +* [How to create one or several VM instances](./vm_based_simulator_create.md) +* [How to build an OAI variant](./vm_based_simulator_build.md) +* [How the build is checked](./vm_based_simulator_check_build.md) +* [How to test an OAI variant](./vm_based_simulator_test.md) +* [How to destroy all VM instances](./vm_based_simulator_destroy.md) + +Currently missing documentation: +* How to generate a build report +* How to generate a test report + +--- + diff --git a/ci-scripts/doc/vm_based_simulator_build.md b/ci-scripts/doc/vm_based_simulator_build.md new file mode 100644 index 0000000000000000000000000000000000000000..ca3ab356ea70a5f3a7abbc74850efbc7eeff3527 --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_build.md @@ -0,0 +1,262 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI CI Virtual-Machine-based Test Environment: build an OAI variant</font></b> + </td> + </tr> +</table> + +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Detailed Description](#2-detailed-description) +3. [Typical Usage](#3-typical-usage) + +# 1. Introduction # + +```bash +$ cd /tmp/CI-raphael +$ ls *.zip +localZip.zip +$ ./ci-scripts/oai-ci-vm-tool build --help +OAI CI VM script + Original Author: Raphael Defosseux + Requirements: + -- uvtool uvtool-libvirt apt-cacher + -- xenial image already synced + Default: + -- eNB with USRP + +Usage: +------ + oai-ci-vm-tool build [OPTIONS] + +Mandatory Options: +-------- + --job-name #### OR -jn #### + Specify the name of the Jenkins job. + + --build-id #### OR -id #### + Specify the build ID of the Jenkins job. + + --workspace #### OR -ws #### + Specify the workspace. + +Options: +-------- + # OpenAirInterface Build Variants + --variant enb-usrp OR -v1 + --variant basic-sim OR -v2 + --variant phy-sim OR -v3 + --variant cppcheck OR -v4 + --variant enb-ethernet OR -v7 + --variant ue-ethernet OR -v8 + # non-OSA Build Variants + --variant flexran-rtc OR -v10 + # OpenAirInterface Test Variants + --variant l1-sim OR -v20 + --variant rf-sim OR -v21 + --variant l2-sim OR -v22 + Specify the variant to build. + + --keep-vm-alive OR -k + Keep the VM alive after the build. + + --daemon OR -D + Run as daemon + + --help OR -h + Print this help message. +``` + +# 2. Detailed Description # + +Source file concerned: `ci-scripts/buildOnVM.sh` + +## 2.1. build_on_vm function ## + +* First check if the ZIP file is available and if the apt-cacher proxy configuration file is present. If not, it will stop. +* Check if the VM instance is alive. If not, create it. +* Once the VM is alive, retrieve the IP address with VM_IP_ADDR=`uvt-kvm ip $VM_NAME` +* We copy the ZIP file to the VM : `scp localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu` +* apt-cacher proxy file: `scp etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu` + +Then we open a SSH session on the VM : `ssh ubuntu@$VM_IP_ADDR` + +* We copy the apt-cacher proxy file to its destination space: `sudo cp 01proxy /etc/apt/apt.conf.d/` +* We create an hush login file to eliminate the ssh opening session messages. +* We unzip the ZIP file into `/home/ubuntu/tmp/` folder +* and we work from there. + +# 3. Typical Usage # + +## 3.1. Build in the foreground, check the results and destroy the VM at the end ## + +```bash +$ cd /tmp/CI-raphael +$ ls *.zip +localZip.zip +$ ./ci-scripts/oai-ci-vm-tool build --workspace /tmp/CI-raphael --job-name RAN-CI-develop --build-id 47 --variant enb-usrp +############################################################ +OAI CI VM script +############################################################ +VM_NAME = RAN-CI-develop-b47-enb-usrp +VM_CMD_FILE = RAN-CI-develop-b47-enb-usrp_cmds.txt +JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/enb_usrp +BUILD_OPTIONS = --eNB -w USRP --mu +VM_MEMORY = 2048 MBytes +VM_CPU = 4 +############################################################ +Creating VM (RAN-CI-develop-b47-enb-usrp) on Ubuntu Cloud Image base +############################################################ +Waiting for VM to be started +Warning: Permanently added '192.168.122.2' (ECDSA) to the list of known hosts. +RAN-CI-develop-b47-enb-usrp has for IP addr = 192.168.122.2 +############################################################ +Copying GIT repo into VM (RAN-CI-develop-b47-enb-usrp) +############################################################ +Warning: Permanently added '192.168.122.2' (ECDSA) to the list of known hosts. +############################################################ +Running install and build script on VM (RAN-CI-develop-b47-enb-usrp) +############################################################ +Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-145-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + Get cloud support with Ubuntu Advantage Cloud Guest: + http://www.ubuntu.com/business/services/cloud + +0 packages can be updated. +0 updates are security updates. + +New release '18.04.2 LTS' available. +Run 'do-release-upgrade' to upgrade to it. + + +sudo apt-get --yes --quiet install zip subversion libboost-dev +unzip -qq -DD ../localZip.zip +cd /home/ubuntu/tmp +source oaienv +cd cmake_targets +./build_oai -I --eNB -w USRP --mu + +# Here wait for a few minutes 8 to 12 minutes # + +############################################################ +Creating a tmp folder to store results and artifacts +############################################################ +############################################################ +Destroying VM +############################################################ +# Host 192.168.122.2 found: line 19 +/home/eurecom/.ssh/known_hosts updated. +Original contents retained as /home/eurecom/.ssh/known_hosts.old +############################################################ +Checking build status +############################################################ +STATUS seems OK +``` + +If you are adding the `-k` or `--keep-vm-alive` option, the VM instance will not be destroyed and you explore what happenned. + +## 3.2. Build in the background ## + +This is how it is done in the CI master job pipeline. + +```bash +$ cd /tmp/CI-raphael +$ ls *.zip +localZip.zip +$ ./ci-scripts/oai-ci-vm-tool build --workspace /tmp/CI-raphael --job-name RAN-CI-develop --build-id 47 --variant phy-sim --daemon +12:44:24 ############################################################ +12:44:24 OAI CI VM script +12:44:24 ############################################################ +12:44:24 VM_NAME = RAN-CI-develop-b47-phy-sim +12:44:24 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt +12:44:24 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +12:44:24 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim +12:44:24 BUILD_OPTIONS = --phy_simulators +12:44:24 VM_MEMORY = 2048 MBytes +12:44:24 VM_CPU = 4 +12:44:24 ############################################################ +12:44:24 Creating VM (RAN-CI-develop-b47-phy-sim) on Ubuntu Cloud Image base +12:44:24 ############################################################ +12:44:27 Waiting for VM to be started +12:46:34 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts. +12:46:34 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220 +12:46:34 ############################################################ +12:46:34 Copying GIT repo into VM (RAN-CI-develop-b47-phy-sim) +12:46:34 ############################################################ +12:46:34 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts. +12:46:34 ############################################################ +12:46:34 Running install and build script on VM (RAN-CI-develop-b47-phy-sim) +12:46:34 ############################################################ +12:46:34 Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-145-generic x86_64) +12:46:34 +12:46:34 * Documentation: https://help.ubuntu.com +12:46:34 * Management: https://landscape.canonical.com +12:46:34 * Support: https://ubuntu.com/advantage +12:46:34 +12:46:34 Get cloud support with Ubuntu Advantage Cloud Guest: +12:46:34 http://www.ubuntu.com/business/services/cloud +12:46:34 +12:46:34 0 packages can be updated. +12:46:34 0 updates are security updates. +12:46:34 +12:46:34 New release '18.04.2 LTS' available. +12:46:34 Run 'do-release-upgrade' to upgrade to it. +12:46:34 +12:46:34 +12:46:34 sudo apt-get --yes --quiet install zip daemon subversion libboost-dev +12:46:46 unzip -qq -DD ../localZip.zip +12:46:48 source oaienv +12:46:48 sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh +12:46:48 STATUS seems OK +``` + +So here is 2.5 minutes, a VM was created, source files copied and the build process is started in the background. + +```bash +$ cd /tmp/raphael +$ ./ci-scripts/oai-ci-vm-tool wait --workspace /var/jenkins/workspace/RAN-CI-develop --variant phy-sim --job-name RAN-CI-develop --build-id 47 --keep-vm-alive +12:49:14 ############################################################ +12:49:14 OAI CI VM script +12:49:14 ############################################################ +12:49:14 VM_NAME = RAN-CI-develop-b47-phy-sim +12:49:14 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt +12:49:14 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +12:49:14 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim +12:49:14 BUILD_OPTIONS = --phy_simulators +12:49:15 Waiting for VM to be started +12:49:15 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts. +12:49:16 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220 +12:49:16 ############################################################ +12:49:16 Waiting build process to end on VM (RAN-CI-develop-b47-phy-sim) +12:49:16 ############################################################ +12:49:16 ps -aux | grep build +12:54:23 ############################################################ +12:54:23 Creating a tmp folder to store results and artifacts +12:54:23 ############################################################ +12:54:23 ############################################################ +12:54:23 Checking build status +12:54:23 ############################################################ +12:54:23 STATUS seems OK +``` + +Here the `--keep-vm-alive` option is used to keep the VM alive and performs some testing. + +--- + +Next step: [how the build is checked](./vm_based_simulator_check_build.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_check_build.md b/ci-scripts/doc/vm_based_simulator_check_build.md new file mode 100644 index 0000000000000000000000000000000000000000..d66b8ff2a01928c9976667936438655a4f88d6bc --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_check_build.md @@ -0,0 +1,44 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI CI Virtual-Machine-based Test Environment: checking the build result</font></b> + </td> + </tr> +</table> + +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Detailed Description](#2-detailed-description) + +# 1. Introduction # + +Function is called: + +- when building in foreground +- when waiting for the background build process is finished + +# 2. Detailed Description # + +Source file concerned: `ci-scripts/waitBuildOnVM.sh` + +## 2.1. check_on_vm_build function ## + +* Retrieve the build log files from the VM instance `ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt` +* and copy them locally in the workspace at $ARCHIVES_LOC +* List all log files that match the pattern. Each should have + * the `Built target` pattern (the library/executable SHALL link) +* The number of patterned log files SHALL match $NB_PATTERN_FILES defined in `ci-scripts/oai-ci-vm-tool` script for the variant + +--- + +Next step: [how to test a function](./vm_based_simulator_test.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_create.md b/ci-scripts/doc/vm_based_simulator_create.md new file mode 100644 index 0000000000000000000000000000000000000000..c54d69ca144eab6abb00c8df68cd81c3d405f589 --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_create.md @@ -0,0 +1,111 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI CI Virtual-Machine-based Test Environment: create a VM instance</font></b> + </td> + </tr> +</table> + +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Detailed Description](#2-detailed-description) +3. [Typical Usage](#3-typical-usage) + +# 1. Introduction # + +```bash +$ cd /tmp/CI-raphael +$ ./ci-scripts/oai-ci-vm-tool create --help +OAI CI VM script + Original Author: Raphael Defosseux + Requirements: + -- uvtool uvtool-libvirt apt-cacher + -- xenial image already synced + Default: + -- eNB with USRP + +Usage: +------ + oai-ci-vm-tool create [OPTIONS] + +Mandatory Options: +-------- + --job-name #### OR -jn #### + Specify the name of the Jenkins job. + + --build-id #### OR -id #### + Specify the build ID of the Jenkins job. + + # OpenAirInterface Build Variants + --variant enb-usrp OR -v1 + --variant basic-sim OR -v2 + --variant phy-sim OR -v3 + --variant cppcheck OR -v4 + --variant enb-ethernet OR -v7 + --variant ue-ethernet OR -v8 + # non-OSA Build Variants + --variant flexran-rtc OR -v10 + # OpenAirInterface Test Variants + --variant l1-sim OR -v20 + --variant rf-sim OR -v21 + --variant l2-sim OR -v22 + Specify the variant to build. + + --help OR -h + Print this help message. +``` + +# 2. Detailed Description # + +Source file concerned: `ci-scripts/createVM.sh` + +## 2.1. create_vm function ## + +This is the function that is being called from the main oai-vm-tool script. + +The main purpose is to start a VM instance: + +```bash +uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml +``` + +Variables are set in the main script based on the options. + +`--unsafe-caching` option is used because our VM instances are throw-away's. + +`--template ci-scripts/template-host.xml` is used to duplicate the CPU properties to the VM instance. **VERY IMPORTANT to build OAI** + +## 2.2. Lock / Unlock functions ## + +There are `acquire_vm_create_lock` and `release_vm_create_lock` functions. + +Creating Virtual Machines instances in parallel **creates a lot of stress** on the host server HW. If you launch creations in parallel (Jenkins pipeline could do it) or you are several people working on the same host server, this mechanism atomizes the creation process and wait until the previous VM creation is finished. + +# 3. Typical Usage # + +```bash +$ cd /tmp/CI-raphael +$ ./ci-scripts/oai-ci-vm-tool create --job-name raphael --build-id 1 --variant phy-sim +# or a more **unique approach** +$ ./ci-scripts/oai-ci-vm-tool create -jn toto -id 1 -v2 +``` + +The Jenkins pipeline uses the master job name as `job-name` option and the job-build ID. + +Try to be unique if you are several developers working on the same host server. + +Finally, typically I never use the `create` command. I use directly the build command that checks if VM is created and if not, will create it. See next step. + +--- + +Next step: [how to build an OAI variant](./vm_based_simulator_build.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_destroy.md b/ci-scripts/doc/vm_based_simulator_destroy.md new file mode 100644 index 0000000000000000000000000000000000000000..d69e82a005d0e3bba62484e10eacb08c218f9ad5 --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_destroy.md @@ -0,0 +1,71 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI CI Virtual-Machine-based Test Environment: Properly Destroy all VM instances</font></b> + </td> + </tr> +</table> + +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Detailed Description](#2-detailed-description) +3. [Typical Usage](#3-typical-usage) + +# 1. Introduction # + +```bash +$ cd /tmp/CI-raphael +$ ./ci-scripts/oai-ci-vm-tool destroy --help +OAI CI VM script + Original Author: Raphael Defosseux + Requirements: + -- uvtool uvtool-libvirt apt-cacher + +Usage: +------ + oai-ci-vm-tool destroy [OPTIONS] + +Mandatory Options: +-------- + --job-name #### OR -jn #### + Specify the name of the Jenkins job. + + --build-id #### OR -id #### + Specify the build ID of the Jenkins job. + +Options: +-------- + --help OR -h + Print this help message. +``` + +# 2. Detailed Description # + +Source file concerned: `ci-scripts/destroyAllRunningVM.sh` + +## 2.1. destroy_vm function ## + +This is the function that is being called from the main oai-vm-tool script. + +The main purpose is to destroy all VM instances whose name matches a pattern. + +It also cleans up the `.ssh/known_hosts` file. + +# 3. Typical Usage # + +```bash +$ cd /tmp/CI-raphael +$ ./ci-scripts/oai-ci-vm-tool destroy --job-name raphael --build-id 1 +``` + +--- + +You can go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_env.md b/ci-scripts/doc/vm_based_simulator_env.md new file mode 100644 index 0000000000000000000000000000000000000000..5dbcfbd93118db7f224691741cbd96592936dbd6 --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_env.md @@ -0,0 +1,123 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI CI Virtual-Machine-based Simulator Test Environment</font></b> + </td> + </tr> +</table> + +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Prerequisites](#2-prerequisites) + 1. [uvtool installation](#21-uvtool-installation) + 2. [apt-cacher-server installation](#22-apt-cacher-server-installation) + +# 1. Introduction # + +This document explains how the master pipeline works and how any developer could contribute to add testing. + +It is an extension to the wiki [page](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-master-job). + +The purpose of this master pipeline is to: + +* Validate that a Merge Request is mergeable +* Validate that a Merge Request is following coding guidelines +* Validate that a Merge Request is not breaking any typical build variant +* Validate that a Merge Request is not breaking any legacy simulator-based test + +We will mainly focused on the 2 last items. + +Last point, this documentation is valid for all CI-supported branches: + +* `master` +* `develop` +* `develop-nr` + +But the feature set may not be aligned. **The principles still apply.** + +# 2. Prerequisites # + +Some details are available on this wiki [section](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-ci-architecture#22-pipeline-executor). + +Currently we have a host server (`bellatrix`) with the current parameters: + +* 40 x Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.40GHz +* 64 Gbytes RAM +* Ubuntu 16.04.3 LTS (xenial) + +For you to replicate this environment, you need a strong server: + +* At least 16 cores +* Ubuntu 16 (xenial) or higher (such as bionic, not tested) + +Also we are using a Virtual Machine (VM for the rest of document) based strategy for the moment. + +So you need to install 2 tools: + +* uvt-kvm +* apt-cacher + +We are planning to also add: + +* A Red Hat Linux Entreprise 7.6 host environment +* A Container-based strategy (such as Docket and Kubernetes) + +## 2.1. uvtool installation ## + +```bash +$ sudo apt-get install uvtool +# if you don't have already, create an ssh key +$ ssh-keygen -b 2048 +# retrieve an image +$ sudo uvt-simplestreams-libvirt sync arch=amd64 release=xenial +# we might soon switch to an Ubuntu 18.04 version +$ sudo uvt-simplestreams-libvirt sync arch=amd64 release=bionic +$ uvt-simplestreams-libvirt query +release=bionic arch=amd64 label=release (20190402) +release=xenial arch=amd64 label=release (20190406) +``` + +On our server, I don't update (sync) that often (every 2-4 months). + +For more details: + +* uvtool syntax is [here](http://manpages.ubuntu.com/manpages/trusty/man1/uvt-kvm.1.html) +* more readable tutorial is [here](https://help.ubuntu.com/lts/serverguide/cloud-images-and-uvtool.html) + +## 2.2. apt-cacher-server installation ## + +I recommend to follow to the letter this [tutorial](https://help.ubuntu.com/community/Apt-Cacher-Server). + +The reason: we are creating/using/destroying a lot of VM instances and we are always installing the same packages. +This service allows to cache on the host and, doing so, **decreases the pressure on your internet bandwith usage**. +It also optimizes time at build stage. + +```bash +$ sudo apt-get install apt-cacher apache2 +$ sudo vi /etc/default/apt-cache +$ sudo service apache2 restart + +# Server configuration +$ sudo vi /etc/apt-cacher/apt-cacher.conf + --> allowed_hosts = * + --> fix the installer_files_regexp +$ sudo vi /etc/apt/apt.conf.d/01proxy +--> add `Acquire::http::Proxy "http://<IP address or hostname of the apt-cacher server>:3142";` +$ sudo service apt-cacher restart +``` + +This last file (/etc/apt/apt.conf.d/01proxy) is very important since it is tested in any CI script. + +--- + +We can now switch to the next step: [how to deal with oai sources](./vm_based_simulator_sources.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_main_scripts.md b/ci-scripts/doc/vm_based_simulator_main_scripts.md new file mode 100644 index 0000000000000000000000000000000000000000..91aa88b7ecff3f64eddc6f773babeb0cc0c2f3c3 --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_main_scripts.md @@ -0,0 +1,87 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI CI Virtual-Machine-based Test Environment: the Main Script</font></b> + </td> + </tr> +</table> + +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Sub BASH scripts](#2-sub-bash-scripts) +3. [Main script features](#3-main-script-features) + +# 1. Introduction # + +The file name is `./ci-scripts/oai-ci-vm-tool` from the workspace root. + +```bash +$ cd /tmp/CI-raphael +$ ./ci-scripts/oai-ci-vm-tool --help +OAI CI VM script + Original Author: Raphael Defosseux + Requirements: + -- uvtool uvtool-libvirt apt-cacher + -- xenial image already synced + +Usage: +------ + oai-ci-vm-tool (-h|--help) {create,destroy,build,wait,test,report-build,report-test} ... + +``` + +This is a **BASH** script. + + +# 2. Sub BASH scripts # + +The main script is including a bunch of sub BASH scripts. + +* ci-scripts/createVM.sh +* ci-scripts/buildOnVM.sh +* ci-scripts/waitBuildOnVM.sh +* ci-scripts/destroyAllRunningVM.sh +* ci-scripts/runTestOnVM.sh +* ci-scripts/reportBuildLocally.sh +* ci-scripts/reportTestLocally.sh + +**NOTE: ci-scripts/runTestOnVM.sh is getting big and will certainly be split to facilate maintenance. Start functions will be also factorized.** + +# 3. Main script features # + +The main purpose of the main script is decipher the options and launch the requested function. + +It is also **testing if uvtool and apt-cacher are installed.** + +It finally provides parameters to the requested functions. Parameter definition is centralized there. + +For example: + +for VM instance creation: + +* the instance name: VM_NAME +* the RAM and number of CPUs: VM_MEMORY, VM_CPU + +for OAI variant build: + +* build options: BUILD_OPTIONS +* build log file to parse: LOG_PATTERN +* the number of log files to parse: NB_PATTERN_FILES + +These last 2 variables are very important if you change the build options or if you modify the build system and add more targets to build (especially true for physical simulator). + +There are many more variables. + +--- + +Next step: [how to create one or several VM instances](./vm_based_simulator_create.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_sources.md b/ci-scripts/doc/vm_based_simulator_sources.md new file mode 100644 index 0000000000000000000000000000000000000000..4bba6a8a09580a6ac620fcb90e2c2139fb4f1baa --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_sources.md @@ -0,0 +1,85 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI CI Virtual-Machine-based Simulator OAI source management</font></b> + </td> + </tr> +</table> + +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Centralized Workspace](#2-centralized-workspace) +3. [Create the ZIP file](#3-create-the-zip-file) + +# 1. Introduction # + +The idea of this section is to optimize/uniform source management for several VM instances. + +If we were cloning the same repository in each VM we are creating, we would put so much pressure on the central GitLab repository. + +The solution: + +* clone/fetch on a given clean workspace and tar/zip only the source files without any artifacts. +* we then copy the tar/zip file to each VM instance +* and within each VM instance, unzip + +# 2. Centralized Workspace # + +You can create a brand new workspace by cloning: + +```bash +$ mkdir /tmp/CI-raphael +$ cd /tmp/CI-raphael +$ git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git . +$ git checkout develop +``` + +You can also use your current cloned workspace and any `develop`-based branch. + +```bash +$ cd /home/raphael/openairinterface5g +$ git fetch +$ git checkout develop-improved-documentation +# CAUTION: the following command will remove any file that has not already been added to GIT +$ sudo git clean -x -d -ff +$ git status +On branch develop-improved-documentation +Your branch is up-to-date with 'origin/develop-improved-documentation'. +nothing to commit, working directory clean +``` + +You can also have modified files. + +**The main point is to have NO ARTIFACTS from a previous build in your workspace.** + +Last point, the workspace folder name is not necesseraly `openairinterface5g`. But all the following commands will be run for the root of the workspace. + +For clarity, I will always use `/tmp/CI-raphael` as $WORKSPACE. + +# 3. Create the ZIP file # + +```bash +# go to root of workspace +$ cd /tmp/CI-raphael +$ zip -r -qq localZip.zip . +``` + +The **Jenkins Pipeline** performs automatically these operations. + +In addition, in case of a merge request, it tries to merge with the target branch and might create a dummy local commit. + +See [section](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-master-job#32-verify-guidelines-stage) + +--- + +Next step: [the main scripts](./vm_based_simulator_main_scripts.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_test.md b/ci-scripts/doc/vm_based_simulator_test.md new file mode 100644 index 0000000000000000000000000000000000000000..0be7ae5d3ac721898dca42f77552cd7281d3d7fc --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_test.md @@ -0,0 +1,260 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="../../doc/images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI CI Virtual-Machine-based Test Environment: Testing an OAI variant</font></b> + </td> + </tr> +</table> + +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Detailed Description](#2-detailed-description) +3. [Typical Usage](#3-typical-usage) + 1. [Testing the physical simulators](#31-testing-the-physicals-simulators) + 2. [Testing the basic simulator](#32-testing-the-basic-simulator) + 3. [Testing the RF simulator](#33-testing-the-rf-simulator) + 4. [Testing the L2-nFAPI simulator](#33-testing-the-l2-nfapi-simulator) + +# 1. Introduction # + +Currently 2 build variants can be directly tested: + +* Physical Simulators +* Basic Simulator + +In addition, 2 build variants are used: + +* OAI eNB with ETHERNET transport +* OAI UE with ETHERNET transport + +for the following scenarios: + +* L1 simulator w/ a channel simulator (NOT IMPLEMENTED) +* RF simulator : (IMPLEMENTED but not working as of 2019.w15) +* L2 nFAPI simulator + +Tests are run sequentially in the Jenkins pipeline because: + +* We want to mutualize the VM creation for an EPC +* We have seen performance issues when running in parallel. + + +```bash +./ci-scripts/oai-ci-vm-tool test --help +OAI CI VM script + Original Author: Raphael Defosseux + Requirements: + -- uvtool uvtool-libvirt apt-cacher + -- xenial image already synced + Default: + -- eNB with USRP + +Usage: +------ + oai-ci-vm-tool test [OPTIONS] + +Options: +-------- + --job-name #### OR -jn #### + Specify the name of the Jenkins job. + + --build-id #### OR -id #### + Specify the build ID of the Jenkins job. + + --workspace #### OR -ws #### + Specify the workspace. + + # OpenAirInterface Build Variants + --variant enb-usrp OR -v1 + --variant basic-sim OR -v2 + --variant phy-sim OR -v3 + --variant cppcheck OR -v4 + --variant enb-ethernet OR -v7 + --variant ue-ethernet OR -v8 + # non-OSA Build Variants + --variant flexran-rtc OR -v10 + # OpenAirInterface Test Variants + --variant l1-sim OR -v20 + --variant rf-sim OR -v21 + --variant l2-sim OR -v22 + Specify the variant to build. + + --keep-vm-alive OR -k + Keep the VM alive after the build. + + --help OR -h + Print this help message. +``` + +# 2. Detailed Description # + +Source file concerned: `ci-scripts/run_test_on_vm.sh` + +**TBD when file is re-structured.** + +# 3. Typical Usage # + +## 3.1. Testing the physical simulators ## + +```bash +$ ./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant phy-sim --job-name RAN-CI-develop --build-id 47 +12:54:29 ############################################################ +12:54:29 OAI CI VM script +12:54:29 ############################################################ +12:54:29 VM_NAME = RAN-CI-develop-b47-phy-sim +12:54:29 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt +12:54:29 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +12:54:29 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim/test +12:54:29 ############################################################ +12:54:29 Waiting for VM to be started +12:54:29 ############################################################ +12:54:29 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts. +12:54:30 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220 +... +13:04:48 Test Results are written to /home/ubuntu/tmp/cmake_targets/autotests/log/results_autotests.xml +13:05:00 ############################################################ +13:05:00 Creating a tmp folder to store results and artifacts +13:05:00 ############################################################ +13:05:00 /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim/test /var/jenkins/workspace/RAN-CI-develop +13:05:04 /var/jenkins/workspace/RAN-CI-develop +13:05:04 ############################################################ +13:05:04 Destroying VM +13:05:04 ############################################################ +13:05:06 # Host 192.168.122.220 found: line 21 +13:05:06 /home/eurecom/.ssh/known_hosts updated. +13:05:06 Original contents retained as /home/eurecom/.ssh/known_hosts.old +13:05:06 ############################################################ +13:05:06 Checking run status +13:05:06 ############################################################ +13:05:06 NB_FOUND_FILES = 1 +13:05:06 NB_RUNS = 20 +13:05:06 NB_FAILURES = 0 +13:05:06 STATUS seems OK +``` + +Note that the VM instance is destroyed. You do that when you are sure your test is passing. + +## 3.2. Testing the basic simulator ## + +```bash +$ ./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant basic-sim --job-name RAN-CI-develop --build-id 48 +15:11:13 ############################################################ +15:11:13 OAI CI VM script +15:11:13 ############################################################ +15:11:13 VM_NAME = RAN-CI-develop-b48-basic-sim +15:11:13 VM_CMD_FILE = RAN-CI-develop-b48-basic-sim_cmds.txt +15:11:13 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +15:11:13 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/basic_sim/test +15:11:13 ############################################################ +15:11:13 Waiting for VM to be started +15:11:13 ############################################################ +15:11:14 Warning: Permanently added '192.168.122.29' (ECDSA) to the list of known hosts. +15:11:15 RAN-CI-develop-b48-basic-sim has for IP addr = 192.168.122.29 +15:11:15 ############################################################ +15:11:15 Test EPC on VM (RAN-CI-develop-b48-epc) will be using ltebox +15:11:15 ############################################################ +15:11:15 EPC_VM_CMD_FILE = RAN-CI-develop-b48-epc_cmds.txt +15:11:15 ############################################################ +15:11:15 Creating test EPC VM (RAN-CI-develop-b48-epc) on Ubuntu Cloud Image base +15:11:15 ############################################################ +15:11:18 Waiting for VM to be started +15:13:25 Warning: Permanently added '192.168.122.156' (ECDSA) to the list of known hosts. +15:13:25 RAN-CI-develop-b48-epc has for IP addr = 192.168.122.156 +15:13:25 Warning: Permanently added '192.168.122.156' (ECDSA) to the list of known hosts. +15:13:25 ls: cannot access '/opt/ltebox/tools/start_ltebox': No such file or directory +15:13:25 ############################################################ +15:13:25 Copying ltebox archives into EPC VM (RAN-CI-develop-b48-epc) +15:13:25 ############################################################ +15:13:25 ############################################################ +15:13:25 Install EPC on EPC VM (RAN-CI-develop-b48-epc) +15:13:25 ############################################################ +.... +15:24:39 ############################################################ +15:24:39 Terminate EPC +15:24:39 ############################################################ +15:24:39 cd /opt/ltebox/tools +15:24:39 sudo ./stop_ltebox +15:24:40 sudo daemon --name=simulated_hss --stop +15:24:40 sudo killall --signal SIGKILL hss_sim +15:24:40 ############################################################ +15:24:40 Destroying VMs +15:24:40 ############################################################ +15:24:41 # Host 192.168.122.29 found: line 18 +15:24:41 /home/eurecom/.ssh/known_hosts updated. +15:24:41 Original contents retained as /home/eurecom/.ssh/known_hosts.old +15:24:43 # Host 192.168.122.60 found: line 20 +15:24:43 /home/eurecom/.ssh/known_hosts updated. +15:24:43 Original contents retained as /home/eurecom/.ssh/known_hosts.old +15:24:43 ############################################################ +15:24:43 Checking run status +15:24:43 ############################################################ +15:24:43 STATUS seems OK +``` + +## 3.3. Test the RF simulator ## + +```bash +./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant rf-sim --job-name RAN-CI-develop --build-id 48 --keep-vm-alive +15:24:45 Currently RF-Simulator Testing is not implemented / enabled +15:24:45 Comment out these lines in ./ci-scripts/oai-ci-vm-tool if you want to run it +15:24:45 STATUS seems OK +``` + +## 3.4. Testing the L2-nFAPI simulator + +```bash +./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant l2-sim --job-name RAN-CI-develop --build-id 48 +15:24:47 ############################################################ +15:24:47 OAI CI VM script +15:24:47 ############################################################ +15:24:47 ENB_VM_NAME = RAN-CI-develop-b48-enb-ethernet +15:24:47 ENB_VM_CMD_FILE = RAN-CI-develop-b48-enb-ethernet_cmds.txt +15:24:47 UE_VM_NAME = RAN-CI-develop-b48-ue-ethernet +15:24:47 UE_VM_CMD_FILE = RAN-CI-develop-b48-ue-ethernet_cmds.txt +15:24:47 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +15:24:47 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/l2_sim/test +15:24:47 ############################################################ +15:24:47 Waiting for ENB VM to be started +15:24:47 ############################################################ +15:24:47 Warning: Permanently added '192.168.122.110' (ECDSA) to the list of known hosts. +15:24:48 RAN-CI-develop-b48-enb-ethernet has for IP addr = 192.168.122.110 +15:24:48 ############################################################ +15:24:48 Waiting for UE VM to be started +15:24:48 ############################################################ +15:24:49 Warning: Permanently added '192.168.122.90' (ECDSA) to the list of known hosts. +15:24:50 RAN-CI-develop-b48-ue-ethernet has for IP addr = 192.168.122.90 +15:24:50 ############################################################ +15:24:50 Test EPC on VM (RAN-CI-develop-b48-epc) will be using ltebox +15:24:50 ############################################################ +15:24:50 EPC_VM_CMD_FILE = RAN-CI-develop-b48-epc_cmds.txt +15:24:50 Waiting for VM to be started +15:24:50 Warning: Permanently added '192.168.122.156' (ECDSA) to the list of known hosts. +15:24:51 RAN-CI-develop-b48-epc has for IP addr = 192.168.122.156 +... +15:42:44 ############################################################ +15:42:44 Destroying VMs +15:42:44 ############################################################ +15:42:46 # Host 192.168.122.110 found: line 18 +15:42:46 /home/eurecom/.ssh/known_hosts updated. +15:42:46 Original contents retained as /home/eurecom/.ssh/known_hosts.old +15:42:47 # Host 192.168.122.90 found: line 18 +15:42:47 /home/eurecom/.ssh/known_hosts updated. +15:42:47 Original contents retained as /home/eurecom/.ssh/known_hosts.old +15:42:47 ############################################################ +15:42:47 Checking run status +15:42:47 ############################################################ +15:42:47 STATUS failed? +``` +--- + +Final step: [how to properly destroy all VM instances](./vm_based_simulator_destroy.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 62add8429b754f3e08cb04ce4e7c4da200258075..9fb546f3703550f2326ee5d68e630a922e23b330 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -1,4 +1,3 @@ -#/* # * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more # * contributor license agreements. See the NOTICE file distributed with # * this work for additional information regarding copyright ownership. @@ -50,6 +49,11 @@ MME_PROCESS_OK = +3 SPGW_PROCESS_FAILED = -4 SPGW_PROCESS_OK = +4 UE_IP_ADDRESS_ISSUE = -5 +OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE = -20 +OAI_UE_PROCESS_COULD_NOT_SYNC = -21 +OAI_UE_PROCESS_ASSERTION = -22 +OAI_UE_PROCESS_FAILED = -6 +OAI_UE_PROCESS_OK = +6 #----------------------------------------------------------- # Import @@ -59,6 +63,7 @@ import re # reg import pexpect # pexpect import time # sleep import os +import subprocess import xml.etree.ElementTree as ET import logging import datetime @@ -88,6 +93,7 @@ class SSHConnection(): self.EPCPassword = '' self.EPCSourceCodePath = '' self.EPCType = '' + self.EPC_PcapFileName = '' self.ADBIPAddress = '' self.ADBUserName = '' self.ADBPassword = '' @@ -99,6 +105,9 @@ class SSHConnection(): self.Initialize_eNB_args = '' self.eNBLogFile = '' self.eNB_instance = '' + self.eNBOptions = '' + self.rruOptions = '' + self.rruLogFile = '' self.ping_args = '' self.ping_packetloss_threshold = '' self.iperf_args = '' @@ -113,18 +122,28 @@ class SSHConnection(): self.htmlFooterCreated = False self.htmlUEConnected = -1 self.htmleNBFailureMsg = '' + self.htmlUEFailureMsg = '' self.picocom_closure = False self.idle_sleep_time = 0 self.htmlTabRefs = [] self.htmlTabNames = [] self.htmlTabIcons = [] self.finalStatus = False - self.eNBOsVersion = '' - self.eNBKernelVersion = '' - self.eNBUhdVersion = '' - self.eNBCpuNb = '' - self.eNBCpuModel = '' - self.eNBCpuMHz = '' + self.OsVersion = '' + self.KernelVersion = '' + self.UhdVersion = '' + self.UsrpBoard = '' + self.CpuNb = '' + self.CpuModel = '' + self.CpuMHz = '' + self.UEIPAddress = '' + self.UEUserName = '' + self.UEPassword = '' + self.UE_instance = '' + self.UESourceCodePath = '' + self.UELogFile = '' + self.Build_OAI_UE_args = '' + self.Initialize_OAI_UE_args = '' def open(self, ipaddress, username, password): count = 0 @@ -316,14 +335,72 @@ class SSHConnection(): self.command('mkdir -p log', '\$', 5) self.command('chmod 777 log', '\$', 5) # no need to remove in log (git clean did the trick) - self.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee -a compile_oai_enb.log', 'Bypassing the Tests', 600) + self.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee compile_oai_enb.log', 'Bypassing the Tests|build have failed', 600) + self.command('ls lte_build_oai/build', '\$', 3) + self.command('ls lte_build_oai/build', '\$', 3) + buildStatus = True + result = re.search('lte-softmodem', str(self.ssh.before)) + if result is None: + buildStatus = False self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) self.command('mv compile_oai_enb.log ' + 'build_log_' + self.testCase_id, '\$', 5) - # Workaround to run with develop-nr - self.command('if [ -e ran_build ]; then cp -rf ran_build lte_build_oai; fi', '\$', 30) self.close() - self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) + if buildStatus: + self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) + else: + logging.error('\u001B[1m Building OAI eNB Failed\u001B[0m') + self.CreateHtmlTestRow(self.Build_eNB_args, 'KO', ALL_PROCESSES_OK) + self.CreateHtmlTabFooter(False) + sys.exit(1) + + def BuildOAIUE(self): + if self.UEIPAddress == '' or self.eNBRepository == '' or self.eNBBranch == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': + Usage() + sys.exit('Insufficient Parameter') + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) + self.command('cd ' + self.UESourceCodePath, '\$', 5) + self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.eNBRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600) + # here add a check if git clone or git fetch went smoothly + self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) + self.command('git config user.name "OAI Jenkins"', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30) + # if the commit ID is provided use it to point to it + if self.eNBCommitID != '': + self.command('git checkout -f ' + self.eNBCommitID, '\$', 5) + # if the branch is not develop, then it is a merge request and we need to do + # the potential merge. Note that merge conflicts should already been checked earlier + if (self.eNB_AllowMerge): + if self.eNBTargetBranch == '': + if (self.eNBBranch != 'develop') and (self.eNBBranch != 'origin/develop'): + self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) + else: + logging.debug('Merging with the target branch: ' + self.eNBTargetBranch) + self.command('git merge --ff origin/' + self.eNBTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) + self.command('source oaienv', '\$', 5) + self.command('cd cmake_targets', '\$', 5) + self.command('mkdir -p log', '\$', 5) + self.command('chmod 777 log', '\$', 5) + # no need to remove in log (git clean did the trick) + self.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee compile_oai_ue.log', 'Bypassing the Tests|build have failed', 600) + self.command('ls lte_build_oai/build', '\$', 3) + self.command('ls lte_build_oai/build', '\$', 3) + buildStatus = True + result = re.search('lte-uesoftmodem', str(self.ssh.before)) + if result is None: + buildStatus = False + self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) + self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) + self.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5) + self.close() + if buildStatus: + self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') + else: + logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') + self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE') + self.CreateHtmlTabFooter(False) + sys.exit(1) def InitializeHSS(self): if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': @@ -388,8 +465,9 @@ class SSHConnection(): if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.eNBSourceCodePath == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = True - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = False + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', pStatus) self.CreateHtmlTabFooter(False) @@ -403,13 +481,15 @@ class SSHConnection(): if result is not None: eth_interface = result.group('eth_interface') logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m') - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f /tmp/enb_' + self.testCase_id + '_s1log.pcap', '\$', 5) - self.command('echo $USER; nohup sudo tshark -f "host ' + self.eNBIPAddress +'" -i ' + eth_interface + ' -w /tmp/enb_' + self.testCase_id + '_s1log.pcap > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) + self.EPC_PcapFileName = 'enb_' + self.testCase_id + '_s1log.pcap' + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f /tmp/' + self.EPC_PcapFileName, '\$', 5) + self.command('echo $USER; nohup sudo tshark -f "host ' + self.eNBIPAddress +'" -i ' + eth_interface + ' -w /tmp/' + self.EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) self.close() self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath, '\$', 5) # Initialize_eNB_args usually start with -O and followed by the location in repository full_config_file = self.Initialize_eNB_args.replace('-O ','') + extra_options = '' extIdx = full_config_file.find('.conf') if (extIdx > 0): extra_options = full_config_file[extIdx + 5:] @@ -427,9 +507,19 @@ class SSHConnection(): sys.exit('Insufficient Parameter') ci_full_config_file = config_path + '/ci-' + config_file rruCheck = False - result = re.search('rru', str(config_file)) + result = re.search('rru|du', str(config_file)) if result is not None: rruCheck = True + # do not reset board twice in IF4.5 case + result = re.search('rru|enb|du', str(config_file)) + if result is not None: + self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 10) + result = re.search('type: b200', str(self.ssh.before)) + if result is not None: + logging.debug('Found a B2xx device --> resetting it') + self.command('echo ' + self.eNBPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) + # Reloading FGPA bin firmware + self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 15) # Make a copy and adapt to EPC / eNB IP addresses self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) self.command('sed -i -e \'s/CI_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2); @@ -437,12 +527,17 @@ class SSHConnection(): # Launch eNB with the modified config file self.command('source oaienv', '\$', 5) self.command('cd cmake_targets', '\$', 5) - self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 5) - self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 5) + self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) + self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) if not rruCheck: self.eNBLogFile = 'enb_' + self.testCase_id + '.log' + if extra_options != '': + self.eNBOptions = extra_options + result = re.search('rru|du', str(config_file)) + if result is not None: + self.rruLogFile = 'enb_' + self.testCase_id + '.log' time.sleep(6) doLoop = True loopCounter = 10 @@ -464,25 +559,31 @@ class SSHConnection(): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) logging.debug('\u001B[1m Stopping tshark \u001B[0m') self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) + if self.EPC_PcapFileName != '': + time.sleep(0.5) + self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5) self.close() time.sleep(1) - pcap_log_file = 'enb_' + self.testCase_id + '_s1log.pcap' - copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') - if (copyin_res == 0): - self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') + if self.EPC_PcapFileName != '': + copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.') + if (copyin_res == 0): + self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.EPC_PcapFileName, self.eNBSourceCodePath + '/cmake_targets/.') sys.exit(1) else: - self.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) + self.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting"', '\$', 4) if rruCheck: result = re.search('wait RUs', str(self.ssh.before)) else: - result = re.search('got sync', str(self.ssh.before)) + result = re.search('got sync|Starting F1AP at CU', str(self.ssh.before)) if result is None: time.sleep(6) else: doLoop = False + if rruCheck and extra_options != '': + self.rruOptions = extra_options self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK) logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') + time.sleep(10) self.close() @@ -516,6 +617,125 @@ class SSHConnection(): job.join() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + def InitializeOAIUE(self): + if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': + Usage() + sys.exit('Insufficient Parameter') + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + if result is None: + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) + if (pStatus < 0): + self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus) + self.CreateHtmlTabFooter(False) + sys.exit(1) + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + # b2xx_fx3_utils reset procedure + self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 10) + result = re.search('type: b200', str(self.ssh.before)) + if result is not None: + logging.debug('Found a B2xx device --> resetting it') + self.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) + # Reloading FGPA bin firmware + self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 15) + else: + logging.debug('Did not find any B2xx device') + self.command('cd ' + self.UESourceCodePath, '\$', 5) + self.command('source oaienv', '\$', 5) + self.command('cd cmake_targets/lte_build_oai/build', '\$', 5) + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + # We may have to regenerate the .u* files + if result is None: + self.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5) + # Launch UE with the modified config file + self.command('echo "ulimit -c unlimited && ./lte-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + self.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + self.UELogFile = 'ue_' + self.testCase_id + '.log' + + # We are now looping several times to hope we really sync w/ an eNB + doOutterLoop = True + outterLoopCounter = 5 + gotSyncStatus = True + fullSyncStatus = True + while (doOutterLoop): + self.command('cd ' + self.UESourceCodePath + '/cmake_targets/lte_build_oai/build', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/lte_build_oai/build -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + time.sleep(6) + self.command('cd ../..', '\$', 5) + doLoop = True + loopCounter = 10 + gotSyncStatus = True + # the 'got sync' message is for the UE threads synchronization + while (doLoop): + loopCounter = loopCounter - 1 + if (loopCounter == 0): + # Here should never occur + logging.error('"got sync" message never showed!') + gotSyncStatus = False + doLoop = False + continue + self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) + result = re.search('got sync', str(self.ssh.before)) + if result is None: + time.sleep(6) + else: + doLoop = False + logging.debug('Found "got sync" message!') + if gotSyncStatus == False: + # we certainly need to stop the lte-uesoftmodem process if it is still running! + self.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) + result = re.search('lte-uesoftmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) + time.sleep(3) + # We are now checking if sync w/ eNB DOES NOT OCCUR + # Usually during the cell synchronization stage, the UE returns with No cell synchronization message + doLoop = True + loopCounter = 10 + while (doLoop): + loopCounter = loopCounter - 1 + if (loopCounter == 0): + # Here we do have a great chance that the UE did cell-sync w/ eNB + doLoop = False + doOutterLoop = False + fullSyncStatus = True + continue + self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) + result = re.search('No cell synchronization found', str(self.ssh.before)) + if result is None: + time.sleep(6) + else: + doLoop = False + fullSyncStatus = False + logging.debug('Found: "No cell synchronization" message! --> try again') + time.sleep(6) + self.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) + result = re.search('lte-uesoftmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) + outterLoopCounter = outterLoopCounter - 1 + if (outterLoopCounter == 0): + doOutterLoop = False + + if fullSyncStatus and gotSyncStatus: + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + if result is None: + self.command('ifconfig oaitun_ue1', '\$', 4) + result = re.search('inet addr', str(self.ssh.before)) + if result is not None: + logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m') + else: + logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') + + self.close() + # For the moment we are always OK!!! + self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') + logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m') + def checkDevTTYisUnlocked(self): self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) count = 0 @@ -603,21 +823,155 @@ class SSHConnection(): time.sleep(4) # We should check if we register count = 0 - while count < 3: + attach_cnt = 0 + attach_status = False + while count < 5: self.command('AT+CEREG?', 'OK', 5) - result = re.search('CEREG: 2,(?P<state>[0-9\-]+)', str(self.ssh.before)) + result = re.search('CEREG: 2,(?P<state>[0-9\-]+),', str(self.ssh.before)) if result is not None: mDataConnectionState = int(result.group('state')) if mDataConnectionState is not None: - logging.debug('+CEREG: 2,' + str(mDataConnectionState)) + if mDataConnectionState == 1: + count = 10 + attach_status = True + result = re.search('CEREG: 2,1,"(?P<networky>[0-9A-Z]+)","(?P<networkz>[0-9A-Z]+)"', str(self.ssh.before)) + if result is not None: + networky = result.group('networky') + networkz = result.group('networkz') + logging.debug('\u001B[1m CAT-M module attached to eNB (' + str(networky) + '/' + str(networkz) + ')\u001B[0m') + else: + logging.debug('\u001B[1m CAT-M module attached to eNB\u001B[0m') + else: + logging.debug('+CEREG: 2,' + str(mDataConnectionState)) + attach_cnt = attach_cnt + 1 else: logging.debug(str(self.ssh.before)) + attach_cnt = attach_cnt + 1 count = count + 1 time.sleep(1) + if attach_status: + self.command('AT+CESQ', 'OK', 5) + result = re.search('CESQ: 99,99,255,255,(?P<rsrq>[0-9]+),(?P<rsrp>[0-9]+)', str(self.ssh.before)) + if result is not None: + nRSRQ = int(result.group('rsrq')) + nRSRP = int(result.group('rsrp')) + if (nRSRQ is not None) and (nRSRP is not None): + logging.debug(' RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB') + logging.debug(' RSRP = ' + str(-140+nRSRP) + ' dBm') self.close() self.picocom_closure = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + html_queue = SimpleQueue() self.checkDevTTYisUnlocked() + if attach_status: + html_cell = '<pre style="background-color:white">CAT-M module\nAttachment Completed in ' + str(attach_cnt+4) + ' seconds' + if (nRSRQ is not None) and (nRSRP is not None): + html_cell += '\n RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB' + html_cell += '\n RSRP = ' + str(-140+nRSRP) + ' dBm</pre>' + else: + html_cell += '</pre>' + html_queue.put(html_cell) + self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) + else: + html_cell = '<pre style="background-color:white">CAT-M module\nAttachment Failed</pre>' + html_queue.put(html_cell) + self.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) + + def PingCatM(self): + if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '': + Usage() + sys.exit('Insufficient Parameter') + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) + if (pStatus < 0): + self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.CreateHtmlTabFooter(False) + sys.exit(1) + try: + statusQueue = SimpleQueue() + lock = Lock() + self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + self.command('cd ' + self.EPCSourceCodePath, '\$', 5) + self.command('cd scripts', '\$', 5) + if re.match('OAI', self.EPCType, re.IGNORECASE): + logging.debug('Using the OAI EPC HSS: not implemented yet') + self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.CreateHtmlTabFooter(False) + sys.exit(1) + else: + self.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5) + result = re.search('Allocated ipv4 addr: (?P<ipaddr>[0-9\.]+) from Pool', str(self.ssh.before)) + if result is not None: + moduleIPAddr = result.group('ipaddr') + else: + return + ping_time = re.findall("-c (\d+)",str(self.ping_args)) + device_id = 'catm' + ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + str(moduleIPAddr) + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + # TIMEOUT CASE + if ping_status < 0: + message = 'Ping with UE (' + str(moduleIPAddr) + ') crashed due to TIMEOUT!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() + self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) + return + result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before)) + if result is None: + message = 'Packet Loss Not Found!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() + self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) + return + packetloss = result.group('packetloss') + if float(packetloss) == 100: + message = 'Packet Loss is 100%' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() + self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) + return + result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before)) + if result is None: + message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() + self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) + return + rtt_min = result.group('rtt_min') + rtt_avg = result.group('rtt_avg') + rtt_max = result.group('rtt_max') + pal_msg = 'Packet Loss : ' + packetloss + '%' + min_msg = 'RTT(Min) : ' + rtt_min + ' ms' + avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' + max_msg = 'RTT(Max) : ' + rtt_max + ' ms' + lock.acquire() + logging.debug('\u001B[1;37;44m ping result (' + moduleIPAddr + ') \u001B[0m') + logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') + qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg + packetLossOK = True + if packetloss is not None: + if float(packetloss) > float(self.ping_packetloss_threshold): + qMsg += '\nPacket Loss too high' + logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') + packetLossOK = False + elif float(packetloss) > 0: + qMsg += '\nPacket Loss is not 0%' + logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') + lock.release() + self.close() + html_cell = '<pre style="background-color:white">CAT-M module\nIP Address : ' + moduleIPAddr + '\n' + qMsg + '</pre>' + statusQueue.put(html_cell) + if (packetLossOK): + self.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue) + else: + self.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue) + self.AutoTerminateUEandeNB() + self.CreateHtmlTabFooter(False) + sys.exit(1) + except: + os.kill(os.getppid(),signal.SIGUSR1) def AttachUE_common(self, device_id, statusQueue, lock): try: @@ -670,8 +1024,9 @@ class SSHConnection(): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = False - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', pStatus) self.AutoTerminateUEandeNB() @@ -735,8 +1090,9 @@ class SSHConnection(): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = False - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', pStatus) self.AutoTerminateUEandeNB() @@ -799,8 +1155,9 @@ class SSHConnection(): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = False - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', pStatus) self.CreateHtmlTabFooter(False) @@ -847,6 +1204,18 @@ class SSHConnection(): sys.exit('Insufficient Parameter') ue_ip_status = 0 self.UEIPAddresses = [] + if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): + if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': + Usage() + sys.exit('Insufficient Parameter') + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('ifconfig oaitun_ue1', '\$', 4) + result = re.search('inet addr:(?P<ueipaddress>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', str(self.ssh.before)) + UE_IPAddress = result.group('ueipaddress') + logging.debug('\u001B[1mUE (' + self.UEDevices[0] + ') IP Address is ' + UE_IPAddress + '\u001B[0m') + self.UEIPAddresses.append(UE_IPAddress) + self.close() + return ue_ip_status self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) for device_id in self.UEDevices: count = 0 @@ -866,7 +1235,7 @@ class SSHConnection(): logging.debug('\u001B[1mUE (' + device_id + ') IP Address is ' + UE_IPAddress + '\u001B[0m') for ueipaddress in self.UEIPAddresses: if ueipaddress == UE_IPAddress: - logging.debug('\u001B[1mUE (' + device_id + ') IP Address ' + UE_IPAddress + 'has been existed!' + '\u001B[0m') + logging.debug('\u001B[1mUE (' + device_id + ') IP Address ' + UE_IPAddress + ': has already been allocated to another device !' + '\u001B[0m') ue_ip_status -= 1 continue self.UEIPAddresses.append(UE_IPAddress) @@ -887,29 +1256,33 @@ class SSHConnection(): self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('cd scripts', '\$', 5) ping_time = re.findall("-c (\d+)",str(self.ping_args)) - ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee -a ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) # TIMEOUT CASE if ping_status < 0: message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before)) if result is None: message = 'Packet Loss Not Found!' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return packetloss = result.group('packetloss') if float(packetloss) == 100: message = 'Packet Loss is 100%' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before)) if result is None: message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return rtt_min = result.group('rtt_min') @@ -947,19 +1320,119 @@ class SSHConnection(): except: os.kill(os.getppid(),signal.SIGUSR1) + def PingNoS1(self): + check_eNB = True + check_OAI_UE = True + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) + if (pStatus < 0): + self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.AutoTerminateUEandeNB() + self.CreateHtmlTabFooter(False) + sys.exit(1) + ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) + if ping_from_eNB is not None: + if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '': + Usage() + sys.exit('Insufficient Parameter') + else: + if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': + Usage() + sys.exit('Insufficient Parameter') + try: + if ping_from_eNB is not None: + self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) + self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets/', '\$', 5) + else: + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5) + self.command('cd cmake_targets', '\$', 5) + ping_time = re.findall("-c (\d+)",str(self.ping_args)) + ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '.log', '\$', int(ping_time[0])*1.5) + # TIMEOUT CASE + if ping_status < 0: + message = 'Ping with OAI UE crashed due to TIMEOUT!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + return + result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before)) + if result is None: + message = 'Packet Loss Not Found!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + return + packetloss = result.group('packetloss') + if float(packetloss) == 100: + message = 'Packet Loss is 100%' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + return + result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before)) + if result is None: + message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + return + rtt_min = result.group('rtt_min') + rtt_avg = result.group('rtt_avg') + rtt_max = result.group('rtt_max') + pal_msg = 'Packet Loss : ' + packetloss + '%' + min_msg = 'RTT(Min) : ' + rtt_min + ' ms' + avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' + max_msg = 'RTT(Max) : ' + rtt_max + ' ms' + logging.debug('\u001B[1;37;44m OAI UE ping result \u001B[0m') + logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') + qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg + packetLossOK = True + if packetloss is not None: + if float(packetloss) > float(self.ping_packetloss_threshold): + qMsg += '\nPacket Loss too high' + logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') + packetLossOK = False + elif float(packetloss) > 0: + qMsg += '\nPacket Loss is not 0%' + logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') + self.close() + html_queue = SimpleQueue() + ip_addr = 'TBD' + html_cell = '<pre style="background-color:white">OAI UE ping result\n' + qMsg + '</pre>' + html_queue.put(html_cell) + if packetLossOK: + self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) + else: + self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) + + # copying on the EPC server for logCollection + if ping_from_eNB is not None: + copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') + else: + copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') + if (copyin_res == 0): + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'ping_' + self.testCase_id + '.log', self.EPCSourceCodePath + '/scripts') + except: + os.kill(os.getppid(),signal.SIGUSR1) + def Ping(self): + result = re.search('noS1', str(self.Initialize_eNB_args)) + if result is not None: + self.PingNoS1() + return if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = False - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = True + if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): + check_OAI_UE = True + else: + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.AutoTerminateUEandeNB() self.CreateHtmlTabFooter(False) sys.exit(1) ueIpStatus = self.GetAllUEIPAddresses() if (ueIpStatus < 0): self.CreateHtmlTestRow(self.ping_args, 'KO', UE_IP_ADDRESS_ISSUE) + self.AutoTerminateUEandeNB() self.CreateHtmlTabFooter(False) sys.exit(1) multi_jobs = [] @@ -1300,8 +1773,12 @@ class SSHConnection(): self.close() # Launch iperf client on UE - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + if (device_id == 'OAI-UE'): + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) + else: + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) iperf_time = self.Iperf_ComputeTime() time.sleep(0.5) @@ -1313,12 +1790,16 @@ class SSHConnection(): time.sleep(0.5) self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee -a iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + if (device_id == 'OAI-UE'): + iperf_status = self.command('iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + ' -B ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + else: + iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) # TIMEOUT Case if iperf_status < 0: self.close() message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) @@ -1335,6 +1816,10 @@ class SSHConnection(): os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) + # in case of OAI-UE + if (device_id == 'OAI-UE'): + self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.') + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): try: @@ -1343,43 +1828,60 @@ class SSHConnection(): return useIperf3 = False udpIperf = True - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it - self.command('if [ ! -d ' + self.EPCSourceCodePath + '/scripts ]; then mkdir -p ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - # Checking if iperf / iperf3 are installed - self.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) - result = re.search('iperf3', str(self.ssh.before)) - if result is None: - result = re.search('iperf', str(self.ssh.before)) + if (device_id != 'OAI-UE'): + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it + self.command('if [ ! -d ' + self.EPCSourceCodePath + '/scripts ]; then mkdir -p ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + # Checking if iperf / iperf3 are installed + self.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) + result = re.search('iperf3', str(self.ssh.before)) if result is None: - message = 'Neither iperf nor iperf3 installed on UE!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - else: - useIperf3 = True + result = re.search('iperf', str(self.ssh.before)) + if result is None: + message = 'Neither iperf nor iperf3 installed on UE!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return + else: + useIperf3 = True + self.close() # in case of iperf, UL has its own function if (not useIperf3): result = re.search('-R', str(self.iperf_args)) if result is not None: - self.close() self.Iperf_UL_common(lock, UE_IPAddress, device_id, idx, ue_num, statusQueue) return - if (useIperf3): - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) - else: + # Launch the IPERF server on the UE side for DL + if (device_id == 'OAI-UE'): + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) result = re.search('-u', str(self.iperf_args)) if result is None: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + self.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) udpIperf = False else: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + self.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) + else: + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + if (useIperf3): + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) + else: + self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + result = re.search('-u', str(self.iperf_args)) + if result is None: + self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + udpIperf = False + else: + self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) time.sleep(0.5) self.close() + # Launch the IPERF client on the EPC side for DL self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) iperf_time = self.Iperf_ComputeTime() @@ -1393,12 +1895,12 @@ class SSHConnection(): self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) if (useIperf3): - self.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + self.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) clientStatus = 0 self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue) else: - iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) if iperf_status < 0: self.close() message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' @@ -1408,28 +1910,154 @@ class SSHConnection(): clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) self.close() - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) - result = re.search('shell +(?P<pid>\d+)', str(self.ssh.before)) - if result is not None: - pid_iperf = result.group('pid') - self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) + # Kill the IPERF server that runs in background + if (device_id == 'OAI-UE'): + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('killall iperf', '\$', 5) + else: + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + self.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) + result = re.search('shell +(?P<pid>\d+)', str(self.ssh.before)) + if result is not None: + pid_iperf = result.group('pid') + self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) self.close() + # if the client report is absent, try to analyze the server log file if (clientStatus == -1): time.sleep(1) if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + if (device_id == 'OAI-UE'): + self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + else: + self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) + + # in case of OAI UE: + if (device_id == 'OAI-UE'): + if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): + pass + else: + self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') except: os.kill(os.getppid(),signal.SIGUSR1) + def IperfNoS1(self): + check_eNB = True + check_OAI_UE = True + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) + if (pStatus < 0): + self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) + self.AutoTerminateUEandeNB() + self.CreateHtmlTabFooter(False) + sys.exit(1) + if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': + Usage() + sys.exit('Insufficient Parameter') + server_on_enb = re.search('-R', str(self.iperf_args)) + if server_on_enb is not None: + iServerIPAddr = self.eNBIPAddress + iServerUser = self.eNBUserName + iServerPasswd = self.eNBPassword + iClientIPAddr = self.UEIPAddress + iClientUser = self.UEUserName + iClientPasswd = self.UEPassword + else: + iServerIPAddr = self.UEIPAddress + iServerUser = self.UEUserName + iServerPasswd = self.UEPassword + iClientIPAddr = self.eNBIPAddress + iClientUser = self.eNBUserName + iClientPasswd = self.eNBPassword + # Starting the iperf server + self.open(iServerIPAddr, iServerUser, iServerPasswd) + # args SHALL be "-c client -u any" + # -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1 + # -B 10.0.1.1 -u -s -i 1 -fm + server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args)) + server_options = server_options.replace('-c','-B') + self.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5) + self.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5) + time.sleep(0.5) + self.close() + + # Starting the iperf client + modified_options = self.Iperf_ComputeModifiedBW(0, 1) + modified_options = modified_options.replace('-R','') + iperf_time = self.Iperf_ComputeTime() + self.open(iClientIPAddr, iClientUser, iClientPasswd) + self.command('rm -f /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', 5) + iperf_status = self.command('stdbuf -o0 iperf ' + modified_options + ' 2>&1 | stdbuf -o0 tee /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', int(iperf_time)*5.0) + status_queue = SimpleQueue() + lock = Lock() + if iperf_status < 0: + message = 'iperf on OAI UE crashed due to TIMEOUT !' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + clientStatus = -2 + else: + clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) + self.close() + + # Stopping the iperf server + self.open(iServerIPAddr, iServerUser, iServerPasswd) + self.command('killall --signal SIGKILL iperf', '\$', 5) + time.sleep(0.5) + self.close() + if (clientStatus == -1): + if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')): + os.remove('iperf_server_' + self.testCase_id + '.log') + self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') + self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) + + # copying on the EPC server for logCollection + copyin_res = self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') + if (copyin_res == 0): + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') + copyin_res = self.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log') + if (copyin_res == 0): + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') + iperf_noperf = False + if status_queue.empty(): + iperf_status = False + else: + iperf_status = True + html_queue = SimpleQueue() + while (not status_queue.empty()): + count = status_queue.get() + if (count < 0): + iperf_status = False + if (count > 0): + iperf_noperf = True + device_id = status_queue.get() + ip_addr = status_queue.get() + message = status_queue.get() + html_cell = '<pre style="background-color:white">UE (' + device_id + ')\nIP Address : ' + ip_addr + '\n' + message + '</pre>' + html_queue.put(html_cell) + if (iperf_noperf and iperf_status): + self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) + elif (iperf_status): + self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) + else: + self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) + self.AutoTerminateUEandeNB() + self.CreateHtmlTabFooter(False) + sys.exit(1) + def Iperf(self): + result = re.search('noS1', str(self.Initialize_eNB_args)) + if result is not None: + self.IperfNoS1() + return if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = False - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = True + if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): + check_OAI_UE = True + else: + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) self.AutoTerminateUEandeNB() @@ -1486,26 +2114,37 @@ class SSHConnection(): self.CreateHtmlTabFooter(False) sys.exit(1) - def CheckProcessExist(self, initialize_eNB_flag): + def CheckProcessExist(self, check_eNB, check_OAI_UE): multi_jobs = [] status_queue = SimpleQueue() - p = Process(target = SSH.CheckHSSProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = SSH.CheckMMEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = SSH.CheckSPGWProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - if initialize_eNB_flag == False: + # in noS1 config, no need to check status from EPC + result = re.search('noS1', str(self.Initialize_eNB_args)) + if result is None: + p = Process(target = SSH.CheckHSSProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + p = Process(target = SSH.CheckMMEProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + p = Process(target = SSH.CheckSPGWProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + else: + if (check_eNB == False) and (check_OAI_UE == False): + return 0 + if check_eNB: p = Process(target = SSH.CheckeNBProcess, args = (status_queue,)) p.daemon = True p.start() multi_jobs.append(p) + if check_OAI_UE: + p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) for job in multi_jobs: job.join() @@ -1524,12 +2163,55 @@ class SSHConnection(): logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFile) if logStatus < 0: result = logStatus + self.eNBLogFile = '' return result + def CheckOAIUEProcessExist(self, initialize_OAI_UE_flag): + multi_jobs = [] + status_queue = SimpleQueue() + if initialize_OAI_UE_flag == False: + p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + for job in multi_jobs: + job.join() + + if (status_queue.empty()): + return -15 + else: + result = 0 + while (not status_queue.empty()): + status = status_queue.get() + if (status < 0): + result = status + if result == OAI_UE_PROCESS_FAILED: + fileCheck = re.search('ue_', str(self.UELogFile)) + if fileCheck is not None: + self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') + logStatus = self.AnalyzeLogFile_UE(self.UELogFile) + if logStatus < 0: + result = logStatus + return result + + def CheckOAIUEProcess(self, status_queue): + try: + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) + result = re.search('lte-uesoftmodem', str(self.ssh.before)) + if result is None: + logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m') + status_queue.put(OAI_UE_PROCESS_FAILED) + else: + status_queue.put(OAI_UE_PROCESS_OK) + self.close() + except: + os.kill(os.getppid(),signal.SIGUSR1) + def CheckeNBProcess(self, status_queue): try: self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never lte-softmodem', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) result = re.search('lte-softmodem', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m') @@ -1543,7 +2225,7 @@ class SSHConnection(): def CheckHSSProcess(self, status_queue): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never hss', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never hss | grep -v grep', '\$', 5) if re.match('OAI', self.EPCType, re.IGNORECASE): result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) else: @@ -1560,7 +2242,7 @@ class SSHConnection(): def CheckMMEProcess(self, status_queue): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never mme', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never mme | grep -v grep', '\$', 5) if re.match('OAI', self.EPCType, re.IGNORECASE): result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) else: @@ -1578,10 +2260,10 @@ class SSHConnection(): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) if re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never spgw', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) else: - self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never xGw', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never xGw | grep -v grep', '\$', 5) result = re.search('xGw', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m SPGW Process Not Found! \u001B[0m') @@ -1596,12 +2278,12 @@ class SSHConnection(): if (not os.path.isfile('./' + eNBlogFile)): return -1 enb_log_file = open('./' + eNBlogFile, 'r') + exitSignalReceived = False foundAssertion = False msgAssertion = '' msgLine = 0 foundSegFault = False foundRealTimeIssue = False - rrcSetupRequest = 0 rrcSetupComplete = 0 rrcReleaseRequest = 0 rrcReconfigRequest = 0 @@ -1614,25 +2296,37 @@ class SSHConnection(): uciStatMsgCount = 0 pdcpFailure = 0 ulschFailure = 0 + cdrxActivationMessageCount = 0 + self.htmleNBFailureMsg = '' for line in enb_log_file.readlines(): - result = re.search('[Ss]egmentation [Ff]ault', str(line)) + if self.rruOptions != '': + res1 = re.search('max_rxgain (?P<requested_option>[0-9]+)', self.rruOptions) + res2 = re.search('max_rxgain (?P<applied_option>[0-9]+)', str(line)) + if res1 is not None and res2 is not None: + requested_option = int(res1.group('requested_option')) + applied_option = int(res2.group('applied_option')) + if requested_option == applied_option: + self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ok-circle"></span> Command line option(s) correctly applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.rruOptions + '\n\n' + else: + self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ban-circle"></span> Command line option(s) NOT applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.rruOptions + '\n\n' + result = re.search('Exiting OAI softmodem', str(line)) if result is not None: + exitSignalReceived = True + result = re.search('[Ss]egmentation [Ff]ault', str(line)) + if result is not None and not exitSignalReceived: foundSegFault = True result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None: + if result is not None and not exitSignalReceived: foundSegFault = True result = re.search('[Aa]ssertion', str(line)) - if result is not None: + if result is not None and not exitSignalReceived: foundAssertion = True result = re.search('LLL', str(line)) - if result is not None: + if result is not None and not exitSignalReceived: foundRealTimeIssue = True if foundAssertion and (msgLine < 3): msgLine += 1 msgAssertion += str(line) - result = re.search('Generating LTE_RRCConnectionSetup', str(line)) - if result is not None: - rrcSetupRequest += 1 result = re.search('LTE_RRCConnectionSetupComplete from UE', str(line)) if result is not None: rrcSetupComplete += 1 @@ -1654,6 +2348,9 @@ class SSHConnection(): result = re.search('LTE_RRCConnectionReestablishmentReject', str(line)) if result is not None: rrcReestablishReject += 1 + result = re.search('CDRX configuration activated after RRC Connection', str(line)) + if result is not None: + cdrxActivationMessageCount += 1 result = re.search('uci->stat', str(line)) if result is not None: uciStatMsgCount += 1 @@ -1670,7 +2367,7 @@ class SSHConnection(): if result is not None: rachCanceledProcedure += 1 enb_log_file.close() - self.htmleNBFailureMsg = '' + logging.debug(' File analysis completed') if uciStatMsgCount > 0: statMsg = 'eNB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') @@ -1683,11 +2380,8 @@ class SSHConnection(): statMsg = 'eNB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') self.htmleNBFailureMsg += statMsg + '\n' - if rrcSetupRequest > 0 or rrcSetupComplete > 0: - rrcMsg = 'eNB requested ' + str(rrcSetupRequest) + ' RRC Connection Setup(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcSetupComplete) + ' were completed' + if rrcSetupComplete > 0: + rrcMsg = 'eNB completed ' + str(rrcSetupComplete) + ' RRC Connection Setup(s)' logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') self.htmleNBFailureMsg += rrcMsg + '\n' if rrcReleaseRequest > 0: @@ -1711,6 +2405,10 @@ class SSHConnection(): rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') self.htmleNBFailureMsg += rrcMsg + '\n' + if cdrxActivationMessageCount > 0: + rrcMsg = 'eNB activated the CDRX Configuration for ' + str(cdrxActivationMessageCount) + ' time(s)' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' if rachCanceledProcedure > 0: rachMsg = 'eNB cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)' logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m') @@ -1733,18 +2431,186 @@ class SSHConnection(): return ENB_PROCESS_REALTIME_ISSUE return 0 + def AnalyzeLogFile_UE(self, UElogFile): + if (not os.path.isfile('./' + UElogFile)): + return -1 + ue_log_file = open('./' + UElogFile, 'r') + exitSignalReceived = False + foundAssertion = False + msgAssertion = '' + msgLine = 0 + foundSegFault = False + foundRealTimeIssue = False + uciStatMsgCount = 0 + pdcpDataReqFailedCount = 0 + badDciCount = 0 + rrcConnectionRecfgComplete = 0 + no_cell_sync_found = False + mib_found = False + frequency_found = False + plmn_found = False + self.htmlUEFailureMsg = '' + for line in ue_log_file.readlines(): + result = re.search('Exiting OAI softmodem', str(line)) + if result is not None: + exitSignalReceived = True + result = re.search('System error|[Ss]egmentation [Ff]ault|======= Backtrace: =========|======= Memory map: ========', str(line)) + if result is not None and not exitSignalReceived: + foundSegFault = True + result = re.search('[Cc]ore [dD]ump', str(line)) + if result is not None and not exitSignalReceived: + foundSegFault = True + result = re.search('[Aa]ssertion', str(line)) + if result is not None and not exitSignalReceived: + foundAssertion = True + result = re.search('LLL', str(line)) + if result is not None and not exitSignalReceived: + foundRealTimeIssue = True + if foundAssertion and (msgLine < 3): + msgLine += 1 + msgAssertion += str(line) + result = re.search('uci->stat', str(line)) + if result is not None and not exitSignalReceived: + uciStatMsgCount += 1 + result = re.search('PDCP data request failed', str(line)) + if result is not None and not exitSignalReceived: + pdcpDataReqFailedCount += 1 + result = re.search('bad DCI 1A', str(line)) + if result is not None and not exitSignalReceived: + badDciCount += 1 + result = re.search('Generating RRCConnectionReconfigurationComplete', str(line)) + if result is not None: + rrcConnectionRecfgComplete += 1 + # No cell synchronization found, abandoning + result = re.search('No cell synchronization found, abandoning', str(line)) + if result is not None: + no_cell_sync_found = True + result = re.search("MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P<nidcell>\d{1,3}), N_RB_DL (?P<n_rb_dl>\d{1,3}), PHICH DURATION (?P<phich_duration>\d), PHICH RESOURCE (?P<phich_resource>.{1,4}), TX_ANT (?P<tx_ant>\d)", str(line)) + if result is not None and (not mib_found): + try: + mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2) + self.htmlUEFailureMsg += mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + mibMsg = " nidcell = " + result.group('nidcell') + self.htmlUEFailureMsg += mibMsg + logging.debug('\033[94m' + mibMsg + '\033[0m') + mibMsg = " n_rb_dl = " + result.group('n_rb_dl') + self.htmlUEFailureMsg += mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + mibMsg = " phich_duration = " + result.group('phich_duration') + self.htmlUEFailureMsg += mibMsg + logging.debug('\033[94m' + mibMsg + '\033[0m') + mibMsg = " phich_resource = " + result.group('phich_resource') + self.htmlUEFailureMsg += mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + mibMsg = " tx_ant = " + result.group('tx_ant') + self.htmlUEFailureMsg += mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + mib_found = True + except Exception as e: + logging.error('\033[91m' + "MIB marker was not found" + '\033[0m') + result = re.search("Measured Carrier Frequency (?P<measured_carrier_frequency>\d{1,15}) Hz", str(line)) + if result is not None and (not frequency_found): + try: + mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz' + self.htmlUEFailureMsg += mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + frequency_found = True + except Exception as e: + logging.error('\033[91m' + "Measured Carrier Frequency not found" + '\033[0m') + result = re.search("PLMN MCC (?P<mcc>\d{1,3}), MNC (?P<mnc>\d{1,3}), TAC", str(line)) + if result is not None and (not plmn_found): + try: + mibMsg = 'PLMN MCC = ' + result.group('mcc') + ' MNC = ' + result.group('mnc') + self.htmlUEFailureMsg += mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + plmn_found = True + except Exception as e: + logging.error('\033[91m' + "PLMN not found" + '\033[0m') + result = re.search("Found (?P<operator>[\w,\s]{1,15}) \(name from internal table\)", str(line)) + if result is not None: + try: + mibMsg = "The operator is: " + result.group('operator') + self.htmlUEFailureMsg += mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + except Exception as e: + logging.error('\033[91m' + "Operator name not found" + '\033[0m') + result = re.search("SIB5 InterFreqCarrierFreq element (.{1,4})/(.{1,4})", str(line)) + if result is not None: + try: + mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2) + self.htmlUEFailureMsg += mibMsg + ' -> ' + logging.debug('\033[94m' + mibMsg + '\033[0m') + except Exception as e: + logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m') + result = re.search("DL Carrier Frequency/ARFCN : (?P<carrier_frequency>\d{1,15}/\d{1,4})", str(line)) + if result is not None: + try: + freq = result.group('carrier_frequency') + new_freq = re.sub('/[0-9]+','',freq) + float_freq = float(new_freq) / 1000000 + self.htmlUEFailureMsg += 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz' + logging.debug('\033[94m' + " DL Carrier Frequency is: " + freq + '\033[0m') + except Exception as e: + logging.error('\033[91m' + " DL Carrier Frequency not found" + '\033[0m') + result = re.search("AllowedMeasBandwidth : (?P<allowed_bandwidth>\d{1,7})", str(line)) + if result is not None: + try: + prb = result.group('allowed_bandwidth') + self.htmlUEFailureMsg += ' -- PRB: ' + prb + '\n' + logging.debug('\033[94m' + " AllowedMeasBandwidth: " + prb + '\033[0m') + except Exception as e: + logging.error('\033[91m' + " AllowedMeasBandwidth not found" + '\033[0m') + ue_log_file.close() + if rrcConnectionRecfgComplete > 0: + statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)' + logging.debug('\033[94m' + statMsg + '\033[0m') + self.htmlUEFailureMsg += statMsg + '\n' + if uciStatMsgCount > 0: + statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' + if pdcpDataReqFailedCount > 0: + statMsg = 'UE showed ' + str(pdcpDataReqFailedCount) + ' "PDCP data request failed" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' + if badDciCount > 0: + statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1A" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' + if foundSegFault: + logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') + return ENB_PROCESS_SEG_FAULT + if foundAssertion: + logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m') + self.htmlUEFailureMsg += 'UE showed an assertion!\n' + if not mib_found or not frequency_found: + return OAI_UE_PROCESS_ASSERTION + if foundRealTimeIssue: + logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m') + self.htmlUEFailureMsg += 'UE faced real time issues!\n' + #return ENB_PROCESS_REALTIME_ISSUE + if no_cell_sync_found and not mib_found: + logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m') + self.htmlUEFailureMsg += 'UE could not synchronize!\n' + return OAI_UE_PROCESS_COULD_NOT_SYNC + return 0 + def TerminateeNB(self): self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) - self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5) - time.sleep(5) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep lte-softmodem', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) result = re.search('lte-softmodem', str(self.ssh.before)) if result is not None: - self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5) time.sleep(5) + self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) + result = re.search('lte-softmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) + time.sleep(2) + self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) self.close() # If tracer options is on, stopping tshark on EPC side result = re.search('T_stdout', str(self.Initialize_eNB_args)) @@ -1753,10 +2619,10 @@ class SSHConnection(): logging.debug('\u001B[1m Stopping tshark \u001B[0m') self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) time.sleep(1) - pcap_log_file = self.eNBLogFile.replace('.log', '_s1log.pcap') - self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + pcap_log_file, '\$', 5) - self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') - self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') + if self.EPC_PcapFileName != '': + self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5) + self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.') + self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.EPC_PcapFileName, self.eNBSourceCodePath + '/cmake_targets/.') self.close() logging.debug('\u001B[1m Replaying RAW record file\u001B[0m') self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) @@ -1776,23 +2642,32 @@ class SSHConnection(): self.eNBLogFile = '' else: result = re.search('enb_', str(self.eNBLogFile)) + analyzeFile = False if result is not None: - copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.') + analyzeFile = True + fileToAnalyze = str(self.eNBLogFile) + self.eNBLogFile = '' + else: + result = re.search('enb_', str(self.rruLogFile)) + if result is not None: + analyzeFile = True + fileToAnalyze = str(self.rruLogFile) + self.rruLogFile = '' + if analyzeFile: + copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + fileToAnalyze, '.') if (copyin_res == -1): logging.debug('\u001B[1;37;41m Could not copy eNB logfile to analyze it! \u001B[0m') self.htmleNBFailureMsg = 'Could not copy eNB logfile to analyze it!' self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE) - self.eNBLogFile = '' return logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m') - logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFile) + logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze) if (logStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', logStatus) self.CreateHtmlTabFooter(False) sys.exit(1) else: self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) - self.eNBLogFile = '' else: self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) @@ -1801,14 +2676,13 @@ class SSHConnection(): if re.match('OAI', self.EPCType, re.IGNORECASE): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_hss oai_hss || true', '\$', 5) time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep hss', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep hss | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) if result is not None: self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_hss oai_hss || true', '\$', 5) else: self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('cd scripts', '\$', 5) - self.command('rm -f ./kill_hss.sh', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=simulated_hss --stop', '\$', 5) time.sleep(1) self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL hss_sim', '\$', 5) @@ -1820,7 +2694,7 @@ class SSHConnection(): if re.match('OAI', self.EPCType, re.IGNORECASE): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_mme mme || true', '\$', 5) time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep mme', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep mme | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) if result is not None: self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_mme mme || true', '\$', 5) @@ -1835,7 +2709,7 @@ class SSHConnection(): if re.match('OAI', self.EPCType, re.IGNORECASE): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_spgw spgw || true', '\$', 5) time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep spgw', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) if result is not None: self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_spgw spgw || true', '\$', 5) @@ -1873,28 +2747,99 @@ class SSHConnection(): job.join() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + def TerminateOAIUE(self): + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) + self.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) + result = re.search('lte-uesoftmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.UEPassword + ' | sudo -S daemon --name=ue' + str(self.UE_instance) + '_daemon --stop', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT lte-uesoftmodem || true', '\$', 5) + time.sleep(5) + self.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) + result = re.search('lte-uesoftmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL lte-uesoftmodem || true', '\$', 5) + time.sleep(2) + self.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + self.close() + result = re.search('ue_', str(self.UELogFile)) + if result is not None: + copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') + if (copyin_res == -1): + logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m') + self.htmlUEFailureMsg = 'Could not copy UE logfile to analyze it!' + self.CreateHtmlTestRow('N/A', 'KO', OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE') + self.UELogFile = '' + return + logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m') + logStatus = self.AnalyzeLogFile_UE(self.UELogFile) + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + if result is not None: + ueAction = 'Sniffing' + else: + ueAction = 'Connection' + if (logStatus < 0): + logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') + self.htmlUEFailureMsg = '<b>' + ueAction + ' Failed</b>\n' + self.htmlUEFailureMsg + self.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') + # In case of sniffing on commercial eNBs we have random results + # Not an error then + if (logStatus != OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): + self.Initialize_OAI_UE_args = '' + self.AutoTerminateUEandeNB() + self.CreateHtmlTabFooter(False) + sys.exit(1) + else: + logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') + self.htmlUEFailureMsg = '<b>' + ueAction + ' Completed</b>\n' + self.htmlUEFailureMsg + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + self.UELogFile = '' + else: + self.htmlUEFailureMsg = 'No Log File to analyze!' + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + def AutoTerminateUEandeNB(self): - self.testCase_id = 'AUTO-KILL-UE' - self.desc = 'Automatic Termination of UE' - self.ShowTestID() - self.TerminateUE() - self.testCase_id = 'AUTO-KILL-eNB' - self.desc = 'Automatic Termination of eNB' - self.ShowTestID() - self.eNB_instance = '0' - self.TerminateeNB() + if (self.ADBIPAddress != 'none'): + self.testCase_id = 'AUTO-KILL-UE' + self.desc = 'Automatic Termination of UE' + self.ShowTestID() + self.TerminateUE() + if (self.Initialize_OAI_UE_args != ''): + self.testCase_id = 'AUTO-KILL-UE' + self.desc = 'Automatic Termination of UE' + self.ShowTestID() + self.TerminateOAIUE() + if (self.Initialize_eNB_args != ''): + self.testCase_id = 'AUTO-KILL-eNB' + self.desc = 'Automatic Termination of eNB' + self.ShowTestID() + self.eNB_instance = '0' + self.TerminateeNB() def IdleSleep(self): time.sleep(self.idle_sleep_time) self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK) def LogCollectBuild(self): - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('cd ' + self.eNBSourceCodePath, '\$', 5) + if (self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != ''): + IPAddress = self.eNBIPAddress + UserName = self.eNBUserName + Password = self.eNBPassword + SourceCodePath = self.eNBSourceCodePath + elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''): + IPAddress = self.UEIPAddress + UserName = self.UEUserName + Password = self.UEPassword + SourceCodePath = self.UESourceCodePath + else: + sys.exit('Insufficient Parameter') + self.open(IPAddress, UserName, Password) + self.command('cd ' + SourceCodePath, '\$', 5) self.command('cd cmake_targets', '\$', 5) self.command('rm -f build.log.zip', '\$', 5) self.command('zip build.log.zip build_log_*/*', '\$', 60) - self.command('echo ' + self.eNBPassword + ' | sudo -S rm -rf build_log_*', '\$', 5) + self.command('echo ' + Password + ' | sudo -S rm -rf build_log_*', '\$', 5) self.close() def LogCollecteNB(self): @@ -1962,35 +2907,71 @@ class SSHConnection(): self.command('cp /opt/ltebox/var/log/xGwLog.0 .', '\$', 5) self.command('zip spgw.log.zip xGwLog.0', '\$', 60) self.close() - def RetrieveSystemVersion(self): - if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '': - Usage() - sys.exit('Insufficient Parameter') - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) + + def LogCollectOAIUE(self): + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('cd ' + self.UESourceCodePath, '\$', 5) + self.command('cd cmake_targets', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S rm -f ue.log.zip', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S zip ue.log.zip ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 60) + self.command('echo ' + self.UEPassword + ' | sudo -S rm ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 5) + self.close() + + def RetrieveSystemVersion(self, machine): + if self.eNBIPAddress == 'none' or self.UEIPAddress == 'none': + self.OsVersion = 'Ubuntu 16.04.5 LTS' + self.KernelVersion = '4.15.0-45-generic' + self.UhdVersion = '3.13.0.1-0' + self.UsrpBoard = 'B210' + self.CpuNb = '4' + self.CpuModel = 'Intel(R) Core(TM) i5-6200U' + self.CpuMHz = '2399.996 MHz' + return 0 + if machine == 'eNB': + if self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != '': + IPAddress = self.eNBIPAddress + UserName = self.eNBUserName + Password = self.eNBPassword + else: + return -1 + if machine == 'UE': + if self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != '': + IPAddress = self.UEIPAddress + UserName = self.UEUserName + Password = self.UEPassword + else: + return -1 + + self.open(IPAddress, UserName, Password) self.command('lsb_release -a', '\$', 5) result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', str(self.ssh.before)) if result is not None: - self.eNBOsVersion = result.group('os_type') - logging.debug('OS is: ' + self.eNBOsVersion) + self.OsVersion = result.group('os_type') + logging.debug('OS is: ' + self.OsVersion) self.command('uname -r', '\$', 5) result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', str(self.ssh.before)) if result is not None: - self.eNBKernelVersion = result.group('kernel_version') - logging.debug('Kernel Version is: ' + self.eNBKernelVersion) + self.KernelVersion = result.group('kernel_version') + logging.debug('Kernel Version is: ' + self.KernelVersion) self.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', str(self.ssh.before)) if result is not None: - self.eNBUhdVersion = result.group('uhd_version') - logging.debug('UHD Version is: ' + self.eNBUhdVersion) + self.UhdVersion = result.group('uhd_version') + logging.debug('UHD Version is: ' + self.UhdVersion) + self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 15) + result = re.search('product: (?P<usrp_board>[0-9A-Za-z]+)\\\\r\\\\n', str(self.ssh.before)) + if result is not None: + self.UsrpBoard = result.group('usrp_board') + logging.debug('USRP Board is: ' + self.UsrpBoard) self.command('lscpu', '\$', 5) result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', str(self.ssh.before)) if result is not None: - self.eNBCpuNb = result.group('nb_cpus') - logging.debug('nb_cpus: ' + self.eNBCpuNb) - self.eNBCpuModel = result.group('model') - logging.debug('model: ' + self.eNBCpuModel) - self.eNBCpuMHz = result.group('cpu_mhz') + ' MHz' - logging.debug('cpu_mhz: ' + self.eNBCpuMHz) + self.CpuNb = result.group('nb_cpus') + logging.debug('nb_cpus: ' + self.CpuNb) + self.CpuModel = result.group('model') + logging.debug('model: ' + self.CpuModel) + self.CpuMHz = result.group('cpu_mhz') + ' MHz' + logging.debug('cpu_mhz: ' + self.CpuMHz) self.close() #----------------------------------------------------------- @@ -1998,6 +2979,9 @@ class SSHConnection(): #----------------------------------------------------------- def CreateHtmlHeader(self): if (not self.htmlHeaderCreated): + logging.debug('\u001B[1m----------------------------------------\u001B[0m') + logging.debug('\u001B[1m Creating HTML header \u001B[0m') + logging.debug('\u001B[1m----------------------------------------\u001B[0m') self.htmlFile = open('test_results.html', 'w') self.htmlFile.write('<!DOCTYPE html>\n') self.htmlFile.write('<html class="no-js" lang="en-US">\n') @@ -2055,6 +3039,16 @@ class SSHConnection(): self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-tag"></span> Commit ID </td>\n') self.htmlFile.write(' <td>' + self.eNBCommitID + '</td>\n') self.htmlFile.write(' </tr>\n') + if self.eNB_AllowMerge != '': + commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.eNBCommitID, shell=True, universal_newlines=True) + commit_message = commit_message.strip() + self.htmlFile.write(' <tr>\n') + if (self.eNB_AllowMerge): + self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Source Commit Message </td>\n') + else: + self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-comment"></span> Commit Message </td>\n') + self.htmlFile.write(' <td>' + commit_message + '</td>\n') + self.htmlFile.write(' </tr>\n') if (self.eNB_AllowMerge): self.htmlFile.write(' <tr>\n') self.htmlFile.write(' <td bgcolor = "lightcyan" > <span class="glyphicon glyphicon-log-in"></span> Target Branch </td>\n') @@ -2065,18 +3059,17 @@ class SSHConnection(): self.htmlFile.write(' </tr>\n') self.htmlFile.write(' </table>\n') - terminate_ue_flag = True if (self.ADBIPAddress != 'none'): + terminate_ue_flag = True self.GetAllUEDevices(terminate_ue_flag) self.GetAllCatMDevices(terminate_ue_flag) + self.htmlUEConnected = len(self.UEDevices) + self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server</h2>\n') + self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n') else: - self.UEDevices.append('doughq9rehg') - self.UEDevices.append('dnsgiuahgia') - self.UEDevices.append('uehgieng9') - self.htmlUEConnected = len(self.UEDevices) - - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server</h2>\n') - self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n') + self.UEDevices.append('OAI-UE') + self.htmlUEConnected = len(self.UEDevices) + self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' OAI UE(s) is(are) connected to CI bench</h2>\n') self.htmlFile.write(' <br>\n') self.htmlFile.write(' <ul class="nav nav-pills">\n') count = 0 @@ -2116,9 +3109,7 @@ class SSHConnection(): self.GetAllUEDevices(terminate_ue_flag) self.GetAllCatMDevices(terminate_ue_flag) else: - self.UEDevices.append('doughq9rehg') - self.UEDevices.append('dnsgiuahgia') - self.UEDevices.append('uehgieng9') + self.UEDevices.append('OAI-UE') self.htmlUEConnected = len(self.UEDevices) i = 0 @@ -2143,36 +3134,49 @@ class SSHConnection(): def CreateHtmlFooter(self, passStatus): if (os.path.isfile('test_results.html')): - self.RetrieveSystemVersion() + logging.debug('\u001B[1m----------------------------------------\u001B[0m') + logging.debug('\u001B[1m Creating HTML footer \u001B[0m') + logging.debug('\u001B[1m----------------------------------------\u001B[0m') + self.htmlFile = open('test_results.html', 'a') self.htmlFile.write('</div>\n') self.htmlFile.write(' <p></p>\n') self.htmlFile.write(' <table class="table table-condensed">\n') + + machines = [ 'eNB', 'UE' ] + for machine in machines: + res = self.RetrieveSystemVersion(machine) + if res == -1: + continue + self.htmlFile.write(' <tr>\n') + self.htmlFile.write(' <th colspan=8>' + str(machine) + ' Server Characteristics</th>\n') + self.htmlFile.write(' </tr>\n') + self.htmlFile.write(' <tr>\n') + self.htmlFile.write(' <td>OS Version</td>\n') + self.htmlFile.write(' <td><span class="label label-default">' + self.OsVersion + '</span></td>\n') + self.htmlFile.write(' <td>Kernel Version</td>\n') + self.htmlFile.write(' <td><span class="label label-default">' + self.KernelVersion + '</span></td>\n') + self.htmlFile.write(' <td>UHD Version</td>\n') + self.htmlFile.write(' <td><span class="label label-default">' + self.UhdVersion + '</span></td>\n') + self.htmlFile.write(' <td>USRP Board</td>\n') + self.htmlFile.write(' <td><span class="label label-default">' + self.UsrpBoard + '</span></td>\n') + self.htmlFile.write(' </tr>\n') + self.htmlFile.write(' <tr>\n') + self.htmlFile.write(' <td>Nb CPUs</td>\n') + self.htmlFile.write(' <td><span class="label label-default">' + self.CpuNb + '</span></td>\n') + self.htmlFile.write(' <td>CPU Model Name</td>\n') + self.htmlFile.write(' <td><span class="label label-default">' + self.CpuModel + '</span></td>\n') + self.htmlFile.write(' <td>CPU Frequency</td>\n') + self.htmlFile.write(' <td><span class="label label-default">' + self.CpuMHz + '</span></td>\n') + self.htmlFile.write(' <td></td>\n') + self.htmlFile.write(' <td></td>\n') + self.htmlFile.write(' </tr>\n') self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th colspan=6>eNB Server Characteristics</th>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td>OS Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.eNBOsVersion + '</span></td>\n') - self.htmlFile.write(' <td>Kernel Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.eNBKernelVersion + '</span></td>\n') - self.htmlFile.write(' <td>UHD Version</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.eNBUhdVersion + '</span></td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <td>Nb CPUs</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.eNBCpuNb + '</span></td>\n') - self.htmlFile.write(' <td>CPU Model Name</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.eNBCpuModel + '</span></td>\n') - self.htmlFile.write(' <td>CPU Frequency</td>\n') - self.htmlFile.write(' <td><span class="label label-default">' + self.eNBCpuMHz + '</span></td>\n') - self.htmlFile.write(' </tr>\n') - self.htmlFile.write(' <tr>\n') - self.htmlFile.write(' <th colspan=4 bgcolor = "#33CCFF">Final Status</th>\n') + self.htmlFile.write(' <th colspan=5 bgcolor = "#33CCFF">Final Status</th>\n') if passStatus: - self.htmlFile.write(' <th colspan=2 bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n') + self.htmlFile.write(' <th colspan=3 bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n') else: - self.htmlFile.write(' <th colspan=2 bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n') + self.htmlFile.write(' <th colspan=3 bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n') self.htmlFile.write(' </tr>\n') self.htmlFile.write(' </table>\n') self.htmlFile.write(' <p></p>\n') @@ -2181,7 +3185,7 @@ class SSHConnection(): self.htmlFile.write('</html>\n') self.htmlFile.close() - def CreateHtmlTestRow(self, options, status, processesStatus): + def CreateHtmlTestRow(self, options, status, processesStatus, machine='eNB'): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): self.htmlFile.write(' <tr>\n') self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n') @@ -2194,14 +3198,18 @@ class SSHConnection(): self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') elif (processesStatus == ENB_PROCESS_FAILED): self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process not found</td>\n') + elif (processesStatus == OAI_UE_PROCESS_FAILED): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - OAI UE process not found</td>\n') elif (processesStatus == ENB_PROCESS_SEG_FAULT): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process ended in Segmentation Fault</td>\n') - elif (processesStatus == ENB_PROCESS_ASSERTION): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process ended in Assertion</td>\n') + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Segmentation Fault</td>\n') + elif (processesStatus == ENB_PROCESS_ASSERTION) or (processesStatus == OAI_UE_PROCESS_ASSERTION): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Assertion</td>\n') elif (processesStatus == ENB_PROCESS_REALTIME_ISSUE): - self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process faced Real Time issue(s)</td>\n') - elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE): - self.htmlFile.write(' <td bgcolor = "orange" >OK</td>\n') + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process faced Real Time issue(s)</td>\n') + elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE) or (processesStatus == OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE): + self.htmlFile.write(' <td bgcolor = "orange" >OK?</td>\n') + elif (processesStatus == OAI_UE_PROCESS_COULD_NOT_SYNC): + self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - UE could not sync</td>\n') elif (processesStatus == HSS_PROCESS_FAILED): self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - HSS process not found</td>\n') elif (processesStatus == MME_PROCESS_FAILED): @@ -2223,9 +3231,19 @@ class SSHConnection(): result = re.search('showed|Reestablishment|Could not copy eNB logfile', self.htmleNBFailureMsg) if result is not None: cellBgColor = 'orange' - self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + - cellBgColor + '">' + self.htmleNBFailureMsg + '</pre></td>\n') + self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmleNBFailureMsg + '</pre></td>\n') self.htmleNBFailureMsg = '' + elif (len(str(self.htmlUEFailureMsg)) > 2): + cellBgColor = 'white' + result = re.search('ended with|faced real time issues', self.htmlUEFailureMsg) + if result is not None: + cellBgColor = 'red' + else: + result = re.search('showed|Could not copy UE logfile|No Log File to analyze', self.htmlUEFailureMsg) + if result is not None: + cellBgColor = 'orange' + self.htmlFile.write(' <td bgcolor = "' + cellBgColor + '" colspan=' + str(self.htmlUEConnected) + '><pre style="background-color:' + cellBgColor + '">' + self.htmlUEFailureMsg + '</pre></td>\n') + self.htmlUEFailureMsg = '' else: i = 0 while (i < self.htmlUEConnected): @@ -2306,7 +3324,7 @@ def Usage(): print('------------------------------------------------------------') def CheckClassValidity(action,id): - if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'IdleSleep': + if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep': logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) return False return True @@ -2333,7 +3351,21 @@ def GetParametersFromXML(action): else: SSH.nbMaxUEtoAttach = int(nbMaxUEtoAttach) - if action == 'Ping': + if action == 'Build_OAI_UE': + SSH.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args') + + if action == 'Initialize_OAI_UE': + SSH.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args') + SSH.UE_instance = test.findtext('UE_instance') + if (SSH.UE_instance is None): + SSH.UE_instance = '0' + + if action == 'Terminate_OAI_UE': + SSH.eNB_instance = test.findtext('UE_instance') + if (SSH.UE_instance is None): + SSH.UE_instance = '0' + + if action == 'Ping' or action == 'Ping_CatM_module': SSH.ping_args = test.findtext('ping_args') SSH.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold') @@ -2375,6 +3407,7 @@ SSH = SSHConnection() argvs = sys.argv argc = len(argvs) +cwd = os.getcwd() while len(argvs) > 1: myArgv = argvs.pop(1) # 0th is this file's name @@ -2447,6 +3480,18 @@ while len(argvs) > 1: matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) SSH.testXMLfiles.append(matchReg.group(1)) SSH.nbTestXMLfiles += 1 + elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) + SSH.UEIPAddress = matchReg.group(1) + elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE) + SSH.UEUserName = matchReg.group(1) + elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE) + SSH.UEPassword = matchReg.group(1) + elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE) + SSH.UESourceCodePath = matchReg.group(1) elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE) finalStatus = matchReg.group(1) @@ -2462,11 +3507,17 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE): sys.exit('Insufficient Parameter') SSH.TerminateeNB() elif re.match('^TerminateUE$', mode, re.IGNORECASE): - if SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': + if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''): Usage() sys.exit('Insufficient Parameter') signal.signal(signal.SIGUSR1, receive_signal) SSH.TerminateUE() +elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE): + if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '': + Usage() + sys.exit('Insufficient Parameter') + signal.signal(signal.SIGUSR1, receive_signal) + SSH.TerminateOAIUE() elif re.match('^TerminateHSS$', mode, re.IGNORECASE): if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': Usage() @@ -2483,7 +3534,7 @@ elif re.match('^TerminateSPGW$', mode, re.IGNORECASE): sys.exit('Insufficient Parameter') SSH.TerminateSPGW() elif re.match('^LogCollectBuild$', mode, re.IGNORECASE): - if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '': + if (SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '') and (SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == ''): Usage() sys.exit('Insufficient Parameter') SSH.LogCollectBuild() @@ -2517,36 +3568,53 @@ elif re.match('^LogCollectIperf$', mode, re.IGNORECASE): Usage() sys.exit('Insufficient Parameter') SSH.LogCollectIperf() +elif re.match('^LogCollectOAIUE$', mode, re.IGNORECASE): + if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '': + Usage() + sys.exit('Insufficient Parameter') + SSH.LogCollectOAIUE() elif re.match('^InitiateHtml$', mode, re.IGNORECASE): - if SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': + if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''): Usage() sys.exit('Insufficient Parameter') count = 0 + foundCount = 0 while (count < SSH.nbTestXMLfiles): + xml_test_file = cwd + "/" + SSH.testXMLfiles[count] xml_test_file = sys.path[0] + "/" + SSH.testXMLfiles[count] - xmlTree = ET.parse(xml_test_file) - xmlRoot = xmlTree.getroot() - SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) - SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count))) - SSH.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign')) + if (os.path.isfile(xml_test_file)): + xmlTree = ET.parse(xml_test_file) + xmlRoot = xmlTree.getroot() + SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) + SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count))) + SSH.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign')) + foundCount += 1 count += 1 + if foundCount != SSH.nbTestXMLfiles: + SSH.nbTestXMLfiles = foundCount SSH.CreateHtmlHeader() elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): SSH.CreateHtmlFooter(SSH.finalStatus) -elif re.match('^TesteNB$', mode, re.IGNORECASE): - if SSH.eNBIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': - Usage() - sys.exit('Insufficient Parameter') +elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE): + if re.match('^TesteNB$', mode, re.IGNORECASE): + if SSH.eNBIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': + Usage() + sys.exit('Insufficient Parameter') + + if (SSH.EPCIPAddress != ''): + SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/tcp_iperf_stats.awk", "/tmp") + SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/active_net_interfaces.awk", "/tmp") + else: + if SSH.UEIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '': + Usage() + sys.exit('UE: Insufficient Parameter') - if (SSH.EPCIPAddress != 'none'): - SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/tcp_iperf_stats.awk", "/tmp") - SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/active_net_interfaces.awk", "/tmp") #read test_case_list.xml file # if no parameters for XML file, use default value if (SSH.nbTestXMLfiles != 1): - xml_test_file = sys.path[0] + "/test_case_list.xml" + xml_test_file = cwd + "/test_case_list.xml" else: - xml_test_file = sys.path[0] + "/" + SSH.testXMLfiles[0] + xml_test_file = cwd + "/" + SSH.testXMLfiles[0] xmlTree = ET.parse(xml_test_file) xmlRoot = xmlTree.getroot() @@ -2607,8 +3675,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): SSH.ShowTestID() GetParametersFromXML(action) if action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Ping' or action == 'Iperf' or action == 'Reboot_UE': - terminate_ue_flag = False - SSH.GetAllUEDevices(terminate_ue_flag) + if (SSH.ADBIPAddress != 'none'): + terminate_ue_flag = False + SSH.GetAllUEDevices(terminate_ue_flag) if action == 'Build_eNB': SSH.BuildeNB() elif action == 'Initialize_eNB': @@ -2623,6 +3692,12 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): SSH.AttachUE() elif action == 'Detach_UE': SSH.DetachUE() + elif action == 'Build_OAI_UE': + SSH.BuildOAIUE() + elif action == 'Initialize_OAI_UE': + SSH.InitializeOAIUE() + elif action == 'Terminate_OAI_UE': + SSH.TerminateOAIUE() elif action == 'Initialize_CatM_module': SSH.InitializeCatM() elif action == 'Terminate_CatM_module': @@ -2631,6 +3706,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): SSH.AttachCatM() elif action == 'Detach_CatM_module': SSH.TerminateCatM() + elif action == 'Ping_CatM_module': + SSH.PingCatM() elif action == 'Ping': SSH.Ping() elif action == 'Iperf': diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 6e0a83e07dcde0b825e5a04f191b99ff362750b0..c343e24d80396bd04c24cae6ff17ccd2a014768e 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -34,14 +34,19 @@ function top_usage { } function variant_usage { + echo " # OpenAirInterface Build Variants" echo " --variant enb-usrp OR -v1" echo " --variant basic-sim OR -v2" echo " --variant phy-sim OR -v3" echo " --variant cppcheck OR -v4" echo " --variant enb-ethernet OR -v7" echo " --variant ue-ethernet OR -v8" - echo " --variant l2-sim OR -v9" + echo " # non-OSA Build Variants" echo " --variant flexran-rtc OR -v10" + echo " # OpenAirInterface Test Variants" + echo " --variant l1-sim OR -v20" + echo " --variant rf-sim OR -v21" + echo " --variant l2-sim OR -v22" } MY_DIR=$(dirname $(readlink -f $0)) @@ -69,7 +74,7 @@ VM_MEMORY=2048 VM_CPU=4 ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt -NB_PATTERN_FILES=4 +NB_PATTERN_FILES=7 BUILD_OPTIONS="--eNB -w USRP" KEEP_VM_ALIVE=0 RUN_OPTIONS="none" @@ -231,7 +236,7 @@ case $key in VM_NAME=ci-enb-usrp ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 + NB_PATTERN_FILES=7 BUILD_OPTIONS="--eNB -w USRP --mu" NBARGS=$[$NBARGS+256] shift @@ -264,37 +269,29 @@ case $key in ARCHIVES_LOC=cppcheck LOG_PATTERN=cppcheck.xml NB_PATTERN_FILES=1 - BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2" + BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -j4" NBARGS=$[$NBARGS+256] shift ;; -v7) VM_NAME=ci-enb-ethernet + VM_MEMORY=4096 + VM_CPU=4 ARCHIVES_LOC=enb_eth LOG_PATTERN=.Rel14.txt NB_PATTERN_FILES=6 - BUILD_OPTIONS="--eNB -t ETHERNET --noS1" + BUILD_OPTIONS="--eNB -t ETHERNET" NBARGS=$[$NBARGS+256] shift ;; -v8) VM_NAME=ci-ue-ethernet + VM_MEMORY=4096 + VM_CPU=4 ARCHIVES_LOC=ue_eth LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 - BUILD_OPTIONS="--UE -t ETHERNET --noS1" - NBARGS=$[$NBARGS+256] - shift - ;; - -v9) - VM_NAME=ci-l2-sim - VM_MEMORY=8192 - VM_CPU=8 - ARCHIVES_LOC=l2_sim - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 - BUILD_OPTIONS="--eNB -t ETHERNET" - RUN_OPTIONS="complex" + NB_PATTERN_FILES=10 + BUILD_OPTIONS="--UE -t ETHERNET" NBARGS=$[$NBARGS+256] shift ;; @@ -307,6 +304,27 @@ case $key in NBARGS=$[$NBARGS+256] shift ;; + -v20) + VM_NAME=ci-l1-sim + ARCHIVES_LOC=l1_sim + RUN_OPTIONS="complex" + NBARGS=$[$NBARGS+256] + shift + ;; + -v21) + VM_NAME=ci-rf-sim + ARCHIVES_LOC=rf_sim + RUN_OPTIONS="complex" + NBARGS=$[$NBARGS+256] + shift + ;; + -v22) + VM_NAME=ci-l2-sim + ARCHIVES_LOC=l2_sim + RUN_OPTIONS="complex" + NBARGS=$[$NBARGS+256] + shift + ;; --variant) variant="$2" case $variant in @@ -314,7 +332,7 @@ case $key in VM_NAME=ci-enb-usrp ARCHIVES_LOC=enb_usrp LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 + NB_PATTERN_FILES=7 BUILD_OPTIONS="--eNB -w USRP --mu" NBARGS=$[$NBARGS+256] ;; @@ -340,38 +358,31 @@ case $key in ;; cppcheck) VM_NAME=ci-cppcheck - VM_MEMORY=8192 + VM_MEMORY=4096 ARCHIVES_LOC=cppcheck LOG_PATTERN=cppcheck.xml NB_PATTERN_FILES=1 - BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2" + BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2 --suppressions-list=ci-scripts/cppcheck_suppressions.list -I common/utils -j4" NBARGS=$[$NBARGS+256] ;; enb-ethernet) VM_NAME=ci-enb-ethernet + VM_MEMORY=4096 + VM_CPU=4 ARCHIVES_LOC=enb_eth LOG_PATTERN=.Rel14.txt NB_PATTERN_FILES=6 - BUILD_OPTIONS="--eNB -t ETHERNET --noS1" + BUILD_OPTIONS="--eNB -t ETHERNET" NBARGS=$[$NBARGS+256] ;; ue-ethernet) VM_NAME=ci-ue-ethernet + VM_MEMORY=4096 + VM_CPU=4 ARCHIVES_LOC=ue_eth LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 - BUILD_OPTIONS="--UE -t ETHERNET --noS1" - NBARGS=$[$NBARGS+256] - ;; - l2-sim) - VM_NAME=ci-l2-sim - VM_MEMORY=8192 - VM_CPU=8 - ARCHIVES_LOC=l2_sim - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 - BUILD_OPTIONS="--eNB -t ETHERNET" - RUN_OPTIONS="complex" + NB_PATTERN_FILES=10 + BUILD_OPTIONS="--UE -t ETHERNET" NBARGS=$[$NBARGS+256] ;; flexran-rtc) @@ -382,6 +393,24 @@ case $key in BUILD_OPTIONS="cmake . && make -j2" NBARGS=$[$NBARGS+256] ;; + l1-sim) + VM_NAME=ci-l1-sim + ARCHIVES_LOC=l1_sim + RUN_OPTIONS="complex" + NBARGS=$[$NBARGS+256] + ;; + rf-sim) + VM_NAME=ci-rf-sim + ARCHIVES_LOC=rf_sim + RUN_OPTIONS="complex" + NBARGS=$[$NBARGS+256] + ;; + l2-sim) + VM_NAME=ci-l2-sim + ARCHIVES_LOC=l2_sim + RUN_OPTIONS="complex" + NBARGS=$[$NBARGS+256] + ;; *) echo "" echo "Syntax Error: Invalid Variant option -> $variant" @@ -510,13 +539,16 @@ else fi fi -# Checking uvt-kvm is installed -UVT_KVM_PATH=`which uvt-kvm | grep -c uvt-kvm` -if [ $UVT_KVM_PATH -eq 0 ] +if [ $REPORT_BUILD_CMD -ne 1 ] && [ $REPORT_TEST_CMD -ne 1 ] then - echo "Error: uvt-kvm is not installed" - top_usage - exit 1 + # Checking uvt-kvm is installed + UVT_KVM_PATH=`which uvt-kvm | grep -c uvt-kvm` + if [ $UVT_KVM_PATH -eq 0 ] + then + echo "Error: uvt-kvm is not installed" + top_usage + exit 1 + fi fi if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] @@ -533,11 +565,23 @@ ARCHIVES_LOC=${JENKINS_WKSP}/archives/${ARCHIVES_LOC} STATUS=0 if [ $CREATE_CMD -eq 1 ] then - create_vm + if [[ $VM_NAME =~ .*-l2-sim.* ]] + then + echo "Selected variant is no more a build variant" + exit 0 + else + create_vm + fi fi if [ $BUILD_CMD -eq 1 ] then - build_on_vm + if [[ $VM_NAME =~ .*-l2-sim.* ]] + then + echo "Selected variant is no more a build variant" + exit 0 + else + build_on_vm + fi if [ $DAEMON -eq 0 ] && [ $STATUS -eq 0 ] then check_on_vm_build @@ -545,7 +589,13 @@ then fi if [ $WAIT_CMD -eq 1 ] then - wait_on_vm_build + if [[ $VM_NAME =~ .*-l2-sim.* ]] + then + echo "Selected variant is no more a build variant" + exit 0 + else + wait_on_vm_build + fi if [ $STATUS -eq 0 ] then check_on_vm_build @@ -553,6 +603,24 @@ then fi if [ $TEST_CMD -eq 1 ] then + # Comment out or delete the following lines if you want to run L1-simulator in your branch and/or merge request + if [[ $VM_NAME =~ .*-l1-sim.* ]] + then + echo "Currently L1-Simulator Testing is not implemented / enabled" + echo "Comment out these lines in ./ci-scripts/oai-ci-vm-tool if you want to run it" + echo "STATUS seems OK" + exit $STATUS + fi + # end to comment out for L1-simulator + # Comment out or delete the following lines if you want to run RF-simulator in your branch and/or merge request + if [[ $VM_NAME =~ .*-rf-sim.* ]] + then + echo "Currently RF-Simulator Testing is not implemented / enabled" + echo "Comment out these lines in ./ci-scripts/oai-ci-vm-tool if you want to run it" + echo "STATUS seems OK" + exit $STATUS + fi + # end to comment out for RF-simulator ARCHIVES_LOC=${ARCHIVES_LOC}/test run_test_on_vm fi diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index bfce7acd8fe241ecaea8f4028fe2763eb2cec629..b0709db15a2381ff13bac4bb3c5dd116eb8eb3fa 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -143,13 +143,21 @@ function summary_table_header { echo " <h3>$1</h3>" >> ./build_results.html if [ -f $2/build_final_status.log ] then + if [ `grep -c COMMAND $2/build_final_status.log` -eq 1 ] + then + COMMAND=`grep COMMAND $2/build_final_status.log | sed -e "s#COMMAND: ##"` + else + COMMAND="Unknown" + fi if [ `grep -c BUILD_OK $2/build_final_status.log` -eq 1 ] then echo " <div class=\"alert alert-success\">" >> ./build_results.html + echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <span class=\"glyphicon glyphicon-arrow-right\"></span> " >> ./build_results.html echo " <strong>BUILD was SUCCESSFUL <span class=\"glyphicon glyphicon-ok-circle\"></span></strong>" >> ./build_results.html echo " </div>" >> ./build_results.html else echo " <div class=\"alert alert-danger\">" >> ./build_results.html + echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <span class=\"glyphicon glyphicon-arrow-right\"></span> " >> ./build_results.html echo " <strong>BUILD was a FAILURE! <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html echo " </div>" >> ./build_results.html fi @@ -218,25 +226,89 @@ function sca_summary_table_header { echo " <h3>$2</h3>" >> ./build_results.html NB_ERRORS=`egrep -c "severity=\"error\"" $1` NB_WARNINGS=`egrep -c "severity=\"warning\"" $1` + ADDED_ERRORS="0" + ADDED_WARNINGS="0" + FINAL_LOG=`echo $1 | sed -e "s#cppcheck\.xml#build_final_status.log#"` + if [ `grep -c COMMAND $FINAL_LOG` -eq 1 ] + then + COMMAND=`grep COMMAND $FINAL_LOG | sed -e "s#COMMAND: ##"` + else + COMMAND="Unknown" + fi + if [ $MR_TRIG -eq 1 ] + then + if [ -d ../../cppcheck_archives ] + then + if [ -d ../../cppcheck_archives/$JOB_NAME ] + then + ADDED_ERRORS=`diff $1 ../../cppcheck_archives/$JOB_NAME/cppcheck.xml | egrep --color=never "^<" | egrep -c "severity=\"error"` + ADDED_WARNINGS=`diff $1 ../../cppcheck_archives/$JOB_NAME/cppcheck.xml | egrep --color=never "^<" | egrep -c "severity=\"warning"` + fi + fi + local TOTAL_NUMBER=$[$ADDED_ERRORS+$ADDED_WARNINGS] + if [ -f $JENKINS_WKSP/oai_cppcheck_added_errors.txt ]; then rm -f $JENKINS_WKSP/oai_cppcheck_added_errors.txt; fi + echo "$TOTAL_NUMBER" > $JENKINS_WKSP/oai_cppcheck_added_errors.txt + fi if [ $NB_ERRORS -eq 0 ] && [ $NB_WARNINGS -eq 0 ] then echo " <div class=\"alert alert-success\">" >> ./build_results.html + echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <br><br>" >> ./build_results.html echo " <strong>CPPCHECK found NO error and NO warning <span class=\"glyphicon glyphicon-ok-circle\"></span></strong>" >> ./build_results.html echo " </div>" >> ./build_results.html else if [ $NB_ERRORS -eq 0 ] then echo " <div class=\"alert alert-warning\">" >> ./build_results.html - echo " <strong>CPPCHECK found NO error and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-warning-sign\"></span></strong>" >> ./build_results.html + echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <br><br>" >> ./build_results.html + if [ $PU_TRIG -eq 1 ] + then + echo " <strong>CPPCHECK found NO error and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-warning-sign\"></span></strong>" >> ./build_results.html + fi + if [ $MR_TRIG -eq 1 ] + then + if [ $ADDED_WARNINGS -eq 0 ] + then + echo " <strong>CPPCHECK found NO error and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-warning-sign\"></span></strong>" >> ./build_results.html + else + echo " <strong>CPPCHECK found NO error and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-warning-sign\"></span></strong>" >> ./build_results.html + fi + fi echo " </div>" >> ./build_results.html else echo " <div class=\"alert alert-danger\">" >> ./build_results.html - echo " <strong>CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html + echo " <span class=\"glyphicon glyphicon-expand\"></span> $COMMAND <br><br>" >> ./build_results.html + if [ $PU_TRIG -eq 1 ] + then + echo " <strong>CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html + fi + if [ $MR_TRIG -eq 1 ] + then + if [ $ADDED_ERRORS -eq 0 ] && [ $ADDED_WARNINGS -eq 0 ] + then + echo " <strong>CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-ban-circle\"></span></strong>" >> ./build_results.html + else + echo " <strong>CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings <span class=\"glyphicon glyphicon-ban-circle\"></span>" >> ./build_results.html + echo " <br>" >> ./build_results.html + echo " <br>" >> ./build_results.html + echo " <span class=\"glyphicon glyphicon-alert\"></span> This Merge Request may have introduced up to $ADDED_ERRORS errors and $ADDED_WARNINGS warnings. <span class=\"glyphicon glyphicon-alert\"></span></strong>" >> ./build_results.html + fi + fi echo " </div>" >> ./build_results.html fi fi + if [ $PU_TRIG -eq 1 ] + then + if [ -d ../../cppcheck_archives ] + then + if [ -d ../../cppcheck_archives/$JOB_NAME ] + then + cp $1 ../../cppcheck_archives/$JOB_NAME + fi + fi + fi echo " <button data-toggle=\"collapse\" data-target=\"#oai-cppcheck-details\">More details on CPPCHECK results</button>" >> ./build_results.html echo " <div id=\"oai-cppcheck-details\" class=\"collapse\">" >> ./build_results.html + echo " <br>" >> ./build_results.html echo " <table border = \"1\">" >> ./build_results.html echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html echo " <th>Error / Warning Type</th>" >> ./build_results.html @@ -301,6 +373,43 @@ function sca_summary_table_footer { echo " </table>" >> ./build_results.html echo " <p>Full details in zipped artifact (cppcheck/cppcheck.xml) </p>" >> ./build_results.html echo " <p style=\"margin-left: 30px\">Graphical Interface tool : <strong><code>cppcheck-gui -l cppcheck/cppcheck.xml</code></strong></p>" >> ./build_results.html + + if [ $MR_TRIG -eq 1 ] + then + if [ $ADDED_ERRORS -ne 0 ] || [ $ADDED_WARNINGS -ne 0 ] + then + echo " <table border = \"1\">" >> ./build_results.html + echo " <tr bgcolor = \"#33CCFF\" >" >> ./build_results.html + echo " <th>Potential File(s) impacted by added errors/warnings</th>" >> ./build_results.html + echo " <th>Line Number</th>" >> ./build_results.html + echo " <th>Severity</th>" >> ./build_results.html + echo " <th>Message</th>" >> ./build_results.html + echo " </tr>" >> ./build_results.html + SEVERITY="none" + POTENTIAL_FILES=`diff $1 ../../cppcheck_archives/$JOB_NAME/cppcheck.xml | egrep --color=never "^<" | egrep "location file|severity" | sed -e "s# #@#g"` + for POT_FILE in $POTENTIAL_FILES + do + if [ `echo $POT_FILE | grep -c location` -eq 1 ] + then + FILENAME=`echo $POT_FILE | sed -e "s#^.*file=\"##" -e "s#\"@line.*/>##"` + LINE=`echo $POT_FILE | sed -e "s#^.*line=\"##" -e "s#\"/>##"` + if [[ $SEVERITY != *"none" ]] + then + echo " <tr>" >> ./build_results.html + echo " <td>$FILENAME</td>" >> ./build_results.html + echo " <td>$LINE</td>" >> ./build_results.html + echo " <td>$SEVERITY</td>" >> ./build_results.html + echo " <td>$MESSAGE</td>" >> ./build_results.html + echo " </tr>" >> ./build_results.html + fi + else + SEVERITY=`echo $POT_FILE | sed -e "s#^.*severity=\"##" -e "s#\"@msg=.*##"` + MESSAGE=`echo $POT_FILE | sed -e "s#^.*msg=\"##" -e "s#\"@verbose=.*##" -e "s#@# #g"` + fi + done + echo " </table>" >> ./build_results.html + fi + fi echo " </div>" >> ./build_results.html } @@ -363,6 +472,14 @@ function report_build { echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tag\"></span> Commit ID</td>" >> ./build_results.html echo " <td>$SOURCE_COMMIT_ID</td>" >> ./build_results.html echo " </tr>" >> ./build_results.html + if [ -e .git/CI_COMMIT_MSG ] + then + echo " <tr>" >> ./build_results.html + echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-comment\"></span> Commit Message</td>" >> ./build_results.html + MSG=`cat .git/CI_COMMIT_MSG` + echo " <td>$MSG</td>" >> ./build_results.html + echo " </tr>" >> ./build_results.html + fi fi if [ $MR_TRIG -eq 1 ] then @@ -374,6 +491,14 @@ function report_build { echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tag\"></span> Source Commit ID</td>" >> ./build_results.html echo " <td>$SOURCE_COMMIT_ID</td>" >> ./build_results.html echo " </tr>" >> ./build_results.html + if [ -e .git/CI_COMMIT_MSG ] + then + echo " <tr>" >> ./build_results.html + echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-comment\"></span> Source Commit Message</td>" >> ./build_results.html + MSG=`cat .git/CI_COMMIT_MSG` + echo " <td>$MSG</td>" >> ./build_results.html + echo " </tr>" >> ./build_results.html + fi echo " <tr>" >> ./build_results.html echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-log-in\"></span> Target Branch</td>" >> ./build_results.html echo " <td>$TARGET_BRANCH</td>" >> ./build_results.html @@ -436,7 +561,8 @@ function report_build { summary_table_row "LTE SoftModem - Release 14" ./archives/enb_usrp/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_row1.html summary_table_row "Coding - Release 14" ./archives/enb_usrp/coding.Rel14.txt "Built target coding" ./enb_usrp_row2.html summary_table_row "OAI USRP device if - Release 14" ./archives/enb_usrp/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html - summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_row4.html + summary_table_row "OAI ETHERNET transport - Release 14" ./archives/enb_usrp/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html + summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_row5.html summary_table_footer summary_table_header "OAI Build basic simulator option" ./archives/basic_sim @@ -473,32 +599,37 @@ function report_build { fi summary_table_header "OAI Build eNB -- ETHERNET transport option" ./archives/enb_eth - summary_table_row "LTE SoftModem w/o S1 - Release 14" ./archives/enb_eth/lte-softmodem-nos1.Rel14.txt "Built target lte-softmodem" ./enb_eth_row1.html + summary_table_row "LTE SoftModem - Release 14" ./archives/enb_eth/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_eth_row1.html summary_table_row "Coding - Release 14" ./archives/enb_eth/coding.Rel14.txt "Built target coding" ./enb_eth_row2.html summary_table_row "OAI ETHERNET transport - Release 14" ./archives/enb_eth/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./enb_eth_row3.html summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_eth/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_eth_row4.html - summary_table_row "RB Tools - Release 14" ./archives/enb_eth/rb_tool.Rel14.txt "Built target rb_tool" ./enb_eth_row5.html - summary_table_row "NAS Mesh - Release 14" ./archives/enb_eth/nasmesh.Rel14.txt "Built target nasmesh" ./enb_eth_row6.html + summary_table_row "RF Simulator - Release 14" ./archives/enb_eth/rfsimulator.Rel14.txt "Built target rfsimulator" ./enb_eth_row5.html + summary_table_row "TCP OAI Bridge - Release 14" ./archives/enb_eth/tcp_bridge_oai.Rel14.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html summary_table_footer summary_table_header "OAI Build UE -- ETHERNET transport option" ./archives/ue_eth - summary_table_row "LTE UE SoftModem w/o S1 - Release 14" ./archives/ue_eth/lte-uesoftmodem-nos1.Rel14.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html + summary_table_row "LTE UE SoftModem - Release 14" ./archives/ue_eth/lte-uesoftmodem.Rel14.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html summary_table_row "Coding - Release 14" ./archives/ue_eth/coding.Rel14.txt "Built target coding" ./ue_eth_row2.html summary_table_row "OAI ETHERNET transport - Release 14" ./archives/ue_eth/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./ue_eth_row3.html summary_table_row "Parameters Lib Config - Release 14" ./archives/ue_eth/params_libconfig.Rel14.txt "Built target params_libconfig" ./ue_eth_row4.html - summary_table_row "RB Tools - Release 14" ./archives/ue_eth/rb_tool.Rel14.txt "Built target rb_tool" ./ue_eth_row5.html - summary_table_row "NAS Mesh - Release 14" ./archives/ue_eth/nasmesh.Rel14.txt "Built target nasmesh" ./ue_eth_row6.html + summary_table_row "RF Simulator - Release 14" ./archives/ue_eth/rfsimulator.Rel14.txt "Built target rfsimulator" ./ue_eth_row5.html + summary_table_row "TCP OAI Bridge - Release 14" ./archives/ue_eth/tcp_bridge_oai.Rel14.txt "Built target tcp_bridge_oai" ./ue_eth_row6.html + summary_table_row "Conf 2 UE Data - Release 14" ./archives/ue_eth/conf2uedata.Rel14.txt "Built target conf2uedata" ./ue_eth_row7.html + summary_table_row "NVRAM - Release 14" ./archives/ue_eth/nvram.Rel14.txt "Built target nvram" ./ue_eth_row8.html + summary_table_row "UE IP - Release 14" ./archives/ue_eth/ue_ip.Rel14.txt "Built target ue_ip" ./ue_eth_row9.html + summary_table_row "USIM - Release 14" ./archives/ue_eth/usim.Rel14.txt "Built target usim" ./ue_eth_row9a.html summary_table_footer if [ -e ./archives/red_hat ] then - echo " <h2>Red Hat (CentOS Linux release 7.4.1708) -- Summary</h2>" >> ./build_results.html + echo " <h2>Red Hat Enterprise Linux Server release 7.6) -- Summary</h2>" >> ./build_results.html summary_table_header "Red Hat -- OAI Build eNB -- USRP option" ./archives/red_hat summary_table_row "LTE SoftModem - Release 14" ./archives/red_hat/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_rh_row1.html summary_table_row "Coding - Release 14" ./archives/red_hat/coding.Rel14.txt "Built target coding" ./enb_usrp_rh_row2.html summary_table_row "OAI USRP device if - Release 14" ./archives/red_hat/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_rh_row3.html - summary_table_row "Parameters Lib Config - Release 14" ./archives/red_hat/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_rh_row4.html + summary_table_row "OAI ETHERNET transport - Release 14" ./archives/red_hat/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./enb_usrp_rh_row4.html + summary_table_row "Parameters Lib Config - Release 14" ./archives/red_hat/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_rh_row5.html summary_table_footer fi @@ -506,41 +637,61 @@ function report_build { echo " <button data-toggle=\"collapse\" data-target=\"#oai-compilation-details\">Details for Compilation Errors and Warnings </button>" >> ./build_results.html echo " <div id=\"oai-compilation-details\" class=\"collapse\">" >> ./build_results.html - for DETAILS_TABLE in `ls ./enb_usrp_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - for DETAILS_TABLE in `ls ./basic_sim_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - for DETAILS_TABLE in `ls ./phy_sim_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - - for DETAILS_TABLE in `ls ./gnb_usrp_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - for DETAILS_TABLE in `ls ./nrue_usrp_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - for DETAILS_TABLE in `ls ./enb_eth_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - for DETAILS_TABLE in `ls ./ue_eth_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done - if [ -e ./archives/red_hat ] + if [ -f ./enb_usrp_row1.html ] || [ -f ./enb_usrp_row2.html ] || [ -f ./enb_usrp_row3.html ] || [ -f ./enb_usrp_row4.html ] then - for DETAILS_TABLE in `ls ./enb_usrp_rh_row*.html` - do - cat $DETAILS_TABLE >> ./build_results.html - done + for DETAILS_TABLE in `ls ./enb_usrp_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + fi + if [ -f ./basic_sim_row1.html ] || [ -f ./basic_sim_row2.html ] || [ -f ./basic_sim_row3.html ] + then + for DETAILS_TABLE in `ls ./basic_sim_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + fi + if [ -f ./phy_sim_row1.html ] || [ -f ./phy_sim_row2.html ] || [ -f ./phy_sim_row3.html ] + then + for DETAILS_TABLE in `ls ./phy_sim_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + fi + if [ -f ./gnb_usrp_row1.html ] || [ -f ./gnb_usrp_row2.html ] || [ -f ./gnb_usrp_row3.html ] || [ -f ./gnb_usrp_row4.html ] + then + for DETAILS_TABLE in `ls ./gnb_usrp_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + fi + if [ -f ./nrue_usrp_row1.html ] || [ -f ./nrue_usrp_row2.html ] || [ -f ./nrue_usrp_row3.html ] || [ -f ./nrue_usrp_row4.html ] + then + for DETAILS_TABLE in `ls ./nrue_usrp_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + fi + if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ] + then + for DETAILS_TABLE in `ls ./enb_eth_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + fi + if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ] + then + for DETAILS_TABLE in `ls ./ue_eth_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + fi + if [ -f ./enb_usrp_rh_row1.html ] || [ -f ./enb_usrp_rh_row2.html ] || [ -f ./enb_usrp_rh_row3.html ] || [ -f ./enb_usrp_rh_row4.html ] + then + for DETAILS_TABLE in `ls ./enb_usrp_rh_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done fi rm -f ./*_row*.html diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 004e021de10b293912a5c37774a531d40bf5ca59..e4195edde06a878c5e8e6f12bf596ad2e65e9d98 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -80,6 +80,121 @@ function report_test_usage { echo "" } +function analyzePingFiles { + for PING_CASE in $PING_LOGS + do + echo " <tr>" >> ./test_simulator_results.html + NAME=`echo $PING_CASE | sed -e "s#$ARCHIVES_LOC/##"` + echo " <td>$NAME</td>" >> ./test_simulator_results.html + CMD=`egrep "COMMAND IS" $PING_CASE | sed -e "s#COMMAND IS: ##"` + echo " <td>$CMD</td>" >> ./test_simulator_results.html + FILE_COMPLETE=`egrep -c "ping statistics" $PING_CASE` + if [ $FILE_COMPLETE -eq 0 ] + then + echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html + echo " <td>N/A</td>" >> ./test_simulator_results.html + else + NB_TR_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s# packets transmitted.*##"` + NB_RC_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*packets transmitted, ##" -e "s# received,.*##"` + if [ $NB_TR_PACKETS -eq $NB_RC_PACKETS ] + then + echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html + else + echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html + fi + echo " <td>" >> ./test_simulator_results.html + echo " <pre>" >> ./test_simulator_results.html + STATS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*received, ##" -e "s#, time.*##" -e "s# packet loss##"` + echo "Packet Loss : $STATS" >> ./test_simulator_results.html + RTTMIN=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[1] " " $5}'` + echo "RTT Minimal : $RTTMIN" >> ./test_simulator_results.html + RTTAVG=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[2] " " $5}'` + echo "RTT Average : $RTTAVG" >> ./test_simulator_results.html + RTTMAX=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[3] " " $5}'` + echo "RTT Maximal : $RTTMAX" >> ./test_simulator_results.html + echo " </pre>" >> ./test_simulator_results.html + echo " </td>" >> ./test_simulator_results.html + fi + echo " </tr>" >> ./test_simulator_results.html + done +} + +function analyzeIperfFiles { + for IPERF_CASE in $IPERF_TESTS + do + echo " <tr>" >> ./test_simulator_results.html + NAME=`echo $IPERF_CASE | sed -e "s#$ARCHIVES_LOC/##"` + echo " <td>$NAME</td>" >> ./test_simulator_results.html + CMD=`egrep "COMMAND IS" $IPERF_CASE | sed -e "s#COMMAND IS: ##"` + echo " <td>$CMD</td>" >> ./test_simulator_results.html + REQ_BITRATE=`echo $CMD | sed -e "s#^.*-b ##" -e "s#-i 1.*##"` + if [[ $REQ_BITRATE =~ .*K.* ]] + then + REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#K##"` + FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000.0" | bc -l` + fi + if [[ $REQ_BITRATE =~ .*M.* ]] + then + REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#M##"` + FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000000.0" | bc -l` + fi + if [[ $REQ_BITRATE =~ .*G.* ]] + then + REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#G##"` + FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000000000.0" | bc -l` + fi + FILE_COMPLETE=`egrep -c "Server Report" $IPERF_CASE` + if [ $FILE_COMPLETE -eq 0 ] + then + echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html + SERVER_FILE=`echo $IPERF_CASE | sed -e "s#client#server#"` + FLOAT_EFF_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; printf "%.0f", br}'` + EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}}'` + PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` + JITTER=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*/sec *##" -e "s# *ms.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{jitter=s/n; printf "%.3f ms", jitter}'` + PACKETLOSS_NOSIGN=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*(##" -e "s#%.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{per=s/n; printf "%.1f", per}'` + PACKETLOSS=`echo "${PACKETLOSS_NOSIGN}%"` + else + EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` + if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]] + then + EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Kbits/sec.*##"` + FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000" | bc -l` + fi + if [[ $EFFECTIVE_BITRATE =~ .*Mbits/sec.* ]] + then + EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Mbits/sec.*##"` + FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000000" | bc -l` + fi + if [[ $EFFECTIVE_BITRATE =~ .*Gbits/sec.* ]] + then + EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Gbits/sec.*##"` + FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000000000" | bc -l` + fi + PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` + PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'` + if [[ $PERF_INT -lt 70 ]] + then + echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html + else + echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html + fi + EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` + JITTER=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*Mbits/sec *##" -e "s#ms.*#ms#"` + PACKETLOSS=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*(##" -e "s#).*##"` + fi + echo " <td>" >> ./test_simulator_results.html + echo " <pre>" >> ./test_simulator_results.html + echo "Bitrate : $EFFECTIVE_BITRATE" >> ./test_simulator_results.html + echo "Bitrate Perf : $PERF %" >> ./test_simulator_results.html + echo "Jitter : $JITTER" >> ./test_simulator_results.html + echo "Packet Loss : $PACKETLOSS" >> ./test_simulator_results.html + echo " </pre>" >> ./test_simulator_results.html + echo " </td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + done +} + function report_test { echo "############################################################" echo "OAI CI VM script" @@ -139,6 +254,14 @@ function report_test { echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tag\"></span> Commit ID</td>" >> ./test_simulator_results.html echo " <td>$SOURCE_COMMIT_ID</td>" >> ./test_simulator_results.html echo " </tr>" >> ./test_simulator_results.html + if [ -e .git/CI_COMMIT_MSG ] + then + echo " <tr>" >> ./test_simulator_results.html + echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-comment\"></span> Commit Message</td>" >> ./test_simulator_results.html + MSG=`cat .git/CI_COMMIT_MSG` + echo " <td>$MSG</td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + fi fi if [ $MR_TRIG -eq 1 ] then @@ -150,6 +273,14 @@ function report_test { echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-tag\"></span> Source Commit ID</td>" >> ./test_simulator_results.html echo " <td>$SOURCE_COMMIT_ID</td>" >> ./test_simulator_results.html echo " </tr>" >> ./test_simulator_results.html + if [ -e .git/CI_COMMIT_MSG ] + then + echo " <tr>" >> ./test_simulator_results.html + echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-comment\"></span> Commit Message</td>" >> ./test_simulator_results.html + MSG=`cat .git/CI_COMMIT_MSG` + echo " <td>$MSG</td>" >> ./test_simulator_results.html + echo " </tr>" >> ./test_simulator_results.html + fi echo " <tr>" >> ./test_simulator_results.html echo " <td bgcolor = \"lightcyan\" > <span class=\"glyphicon glyphicon-log-in\"></span> Target Branch</td>" >> ./test_simulator_results.html echo " <td>$TARGET_BRANCH</td>" >> ./test_simulator_results.html @@ -199,6 +330,14 @@ function report_test { BW_CASES=(05 10 20) for TMODE in ${TRANS_MODES[@]} do + echo " <tr bgcolor = \"#8FBC8F\" >" >> ./test_simulator_results.html + if [[ $TMODE =~ .*fdd.* ]] + then + echo " <td align = \"center\" colspan = 4 >Test in FDD</td>" >> ./test_simulator_results.html + else + echo " <td align = \"center\" colspan = 4 >Test in TDD</td>" >> ./test_simulator_results.html + fi + echo " </tr>" >> ./test_simulator_results.html for BW in ${BW_CASES[@]} do ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_enb.log @@ -263,124 +402,11 @@ function report_test { echo " </pre></td>" >> ./test_simulator_results.html echo " </tr>" >> ./test_simulator_results.html fi - PING_CASE=$ARCHIVES_LOC/${TMODE}_${BW}MHz_ping_ue.txt - if [ -f $PING_CASE ] - then - echo " <tr>" >> ./test_simulator_results.html - NAME=`echo $PING_CASE | sed -e "s#$ARCHIVES_LOC/##"` - echo " <td>$NAME</td>" >> ./test_simulator_results.html - CMD=`egrep "COMMAND IS" $PING_CASE | sed -e "s#COMMAND IS: ##"` - echo " <td>$CMD</td>" >> ./test_simulator_results.html - FILE_COMPLETE=`egrep -c "ping statistics" $PING_CASE` - if [ $FILE_COMPLETE -eq 0 ] - then - echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html - echo " <td>N/A</td>" >> ./test_simulator_results.html - else - NB_TR_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s# packets transmitted.*##"` - NB_RC_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*packets transmitted, ##" -e "s# received,.*##"` - if [ $NB_TR_PACKETS -eq $NB_RC_PACKETS ] - then - echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html - else - echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html - fi - echo " <td>" >> ./test_simulator_results.html - echo " <pre>" >> ./test_simulator_results.html - STATS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*received, ##" -e "s#, time.*##" -e "s# packet loss##"` - echo "Packet Loss : $STATS" >> ./test_simulator_results.html - RTTMIN=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[1] " " $5}'` - echo "RTT Minimal : $RTTMIN" >> ./test_simulator_results.html - RTTAVG=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[2] " " $5}'` - echo "RTT Average : $RTTAVG" >> ./test_simulator_results.html - RTTMAX=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[3] " " $5}'` - echo "RTT Maximal : $RTTMAX" >> ./test_simulator_results.html - echo " </pre>" >> ./test_simulator_results.html - echo " </td>" >> ./test_simulator_results.html - fi - echo " </tr>" >> ./test_simulator_results.html - fi + PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_ping_ue.txt 2> /dev/null` + analyzePingFiles - if [ -f $ARCHIVES_LOC/${TMODE}_${BW}*iperf*dl*client*txt ] - then - IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}*iperf*client*txt` - else - echo "There are no iperf files" - IPERF_TESTS="" - fi - for IPERF_CASE in $IPERF_TESTS - do - echo " <tr>" >> ./test_simulator_results.html - NAME=`echo $IPERF_CASE | sed -e "s#$ARCHIVES_LOC/##"` - echo " <td>$NAME</td>" >> ./test_simulator_results.html - CMD=`egrep "COMMAND IS" $IPERF_CASE | sed -e "s#COMMAND IS: ##"` - echo " <td>$CMD</td>" >> ./test_simulator_results.html - REQ_BITRATE=`echo $CMD | sed -e "s#^.*-b ##" -e "s#-i 1.*##"` - if [[ $REQ_BITRATE =~ .*K.* ]] - then - REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#K##"` - FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000.0" | bc -l` - fi - if [[ $REQ_BITRATE =~ .*M.* ]] - then - REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#M##"` - FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000000.0" | bc -l` - fi - if [[ $REQ_BITRATE =~ .*G.* ]] - then - REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#G##"` - FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000000000.0" | bc -l` - fi - FILE_COMPLETE=`egrep -c "Server Report" $IPERF_CASE` - if [ $FILE_COMPLETE -eq 0 ] - then - echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html - SERVER_FILE=`echo $IPERF_CASE | sed -e "s#client#server#"` - FLOAT_EFF_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; printf "%.0f", br}'` - EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}}'` - PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` - JITTER=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*/sec *##" -e "s# *ms.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{jitter=s/n; printf "%.3f ms", jitter}'` - PACKETLOSS_NOSIGN=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*(##" -e "s#%.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{per=s/n; printf "%.1f", per}'` - PACKETLOSS=`echo "${PACKETLOSS_NOSIGN}%"` - else - EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` - if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]] - then - EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Kbits/sec.*##"` - FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000" | bc -l` - fi - if [[ $EFFECTIVE_BITRATE =~ .*Mbits/sec.* ]] - then - EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Mbits/sec.*##"` - FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000000" | bc -l` - fi - if [[ $EFFECTIVE_BITRATE =~ .*Gbits/sec.* ]] - then - EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Gbits/sec.*##"` - FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000000000" | bc -l` - fi - PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` - PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'` - if [[ $PERF_INT -lt 90 ]] - then - echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html - else - echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html - fi - EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` - JITTER=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*Mbits/sec *##" -e "s#ms.*#ms#"` - PACKETLOSS=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*(##" -e "s#).*##"` - fi - echo " <td>" >> ./test_simulator_results.html - echo " <pre>" >> ./test_simulator_results.html - echo "Bitrate : $EFFECTIVE_BITRATE" >> ./test_simulator_results.html - echo "Bitrate Perf : $PERF %" >> ./test_simulator_results.html - echo "Jitter : $JITTER" >> ./test_simulator_results.html - echo "Packet Loss : $PACKETLOSS" >> ./test_simulator_results.html - echo " </pre>" >> ./test_simulator_results.html - echo " </td>" >> ./test_simulator_results.html - echo " </tr>" >> ./test_simulator_results.html - done + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}*iperf*client*txt 2> /dev/null` + analyzeIperfFiles done done @@ -450,13 +476,27 @@ function report_test { echo " <th>Statistics</th>" >> ./test_simulator_results.html echo " </tr>" >> ./test_simulator_results.html + EPC_CONFIGS=("wS1" "noS1") TRANS_MODES=("fdd") BW_CASES=(05) - for TMODE in ${TRANS_MODES[@]} + NB_USERS=(01 04) + for CN_CONFIG in ${EPC_CONFIGS[@]} do + for TMODE in ${TRANS_MODES[@]} + do for BW in ${BW_CASES[@]} do - ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_enb.log + for UES in ${NB_USERS[@]} + do + echo " <tr bgcolor = \"#8FBC8F\" >" >> ./test_simulator_results.html + if [[ $CN_CONFIG =~ .*wS1.* ]] + then + echo " <td align = \"center\" colspan = 4 >Test with EPC (aka withS1): ${TMODE} -- ${BW}MHz -- ${UES} user(s)</td>" >> ./test_simulator_results.html + else + echo " <td align = \"center\" colspan = 4 >Test without EPC (aka noS1): ${TMODE} -- ${BW}MHz -- ${UES} user(s)</td>" >> ./test_simulator_results.html + fi + echo " </tr>" >> ./test_simulator_results.html + ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_enb.log UE_LOG=`echo $ENB_LOG | sed -e "s#enb#ue#"` if [ -f $ENB_LOG ] && [ -f $UE_LOG ] then @@ -496,45 +536,17 @@ function report_test { echo " </pre></td>" >> ./test_simulator_results.html echo " </tr>" >> ./test_simulator_results.html fi - PING_CASE=$ARCHIVES_LOC/${TMODE}_${BW}MHz_ping_epc.txt - if [ -f $PING_CASE ] - then - echo " <tr>" >> ./test_simulator_results.html - NAME=`echo $PING_CASE | sed -e "s#$ARCHIVES_LOC/##"` - echo " <td>$NAME</td>" >> ./test_simulator_results.html - CMD=`egrep "COMMAND IS" $PING_CASE | sed -e "s#COMMAND IS: ##"` - echo " <td>$CMD</td>" >> ./test_simulator_results.html - FILE_COMPLETE=`egrep -c "ping statistics" $PING_CASE` - if [ $FILE_COMPLETE -eq 0 ] - then - echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html - echo " <td>N/A</td>" >> ./test_simulator_results.html - else - NB_TR_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s# packets transmitted.*##"` - NB_RC_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*packets transmitted, ##" -e "s# received,.*##"` - if [ $NB_TR_PACKETS -eq $NB_RC_PACKETS ] - then - echo " <td bgcolor = \"green\" >OK</td>" >> ./test_simulator_results.html - else - echo " <td bgcolor = \"red\" >KO</td>" >> ./test_simulator_results.html - fi - echo " <td>" >> ./test_simulator_results.html - echo " <pre>" >> ./test_simulator_results.html - STATS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*received, ##" -e "s#, time.*##" -e "s# packet loss##"` - echo "Packet Loss : $STATS" >> ./test_simulator_results.html - RTTMIN=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[1] " " $5}'` - echo "RTT Minimal : $RTTMIN" >> ./test_simulator_results.html - RTTAVG=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[2] " " $5}'` - echo "RTT Average : $RTTAVG" >> ./test_simulator_results.html - RTTMAX=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[3] " " $5}'` - echo "RTT Maximal : $RTTMAX" >> ./test_simulator_results.html - echo " </pre>" >> ./test_simulator_results.html - echo " </td>" >> ./test_simulator_results.html - fi - echo " </tr>" >> ./test_simulator_results.html - fi + PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping*.log 2> /dev/null` + analyzePingFiles + + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_dl*client*txt 2> /dev/null` + analyzeIperfFiles + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_ul*client*txt 2> /dev/null` + analyzeIperfFiles + done done + done done echo " </table>" >> ./test_simulator_results.html diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 7ff04e23f89bdbab5583387a29a55cfc97c56810..9433167e5445d96e6300a34f4b9bd613ea206ec5 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -90,9 +90,33 @@ function start_basic_sim_enb { echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 echo "sudo -E daemon --inherit --unsafe --name=enb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/basic_simulator/enb -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1 - sleep 10 + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1 + rm $1 + sleep 5 + + local i="0" + echo "egrep -c \"got sync\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + sleep 5 + i=$[$i+1] + fi + done + ENB_SYNC=0 rm $1 + if [ $i -lt 50 ] + then + ENB_SYNC=0 + echo "Basic-Sim eNB: eNB did NOT got sync" + else + echo "Basic-Sim eNB: eNB GOT SYNC --> waiting for UE to connect" + fi + sleep 5 } function start_basic_sim_ue { @@ -108,15 +132,15 @@ function start_basic_sim_ue { echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_UE_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_UE_LOG_FILE; fi" >> $1 echo "sudo -E daemon --inherit --unsafe --name=ue_daemon --chdir=/home/ubuntu/tmp/cmake_targets/basic_simulator/ue -o /home/ubuntu/tmp/cmake_targets/log/$LOC_UE_LOG_FILE ./my-lte-uesoftmodem-run.sh" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 rm $1 local i="0" - echo "ifconfig oip1 | egrep -c \"inet addr\"" > $1 + echo "ifconfig oaitun_ue1 | egrep -c \"inet addr\"" > $1 while [ $i -lt 10 ] do sleep 5 - CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1` + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1` if [ $CONNECTED -eq 1 ] then i="100" @@ -124,36 +148,96 @@ function start_basic_sim_ue { i=$[$i+1] fi done + UE_SYNC=1 rm $1 if [ $i -lt 50 ] then UE_SYNC=0 + echo "Basic-Sim UE: oaitun_ue1 is DOWN and/or NOT CONFIGURED" else - UE_SYNC=1 + echo "Basic-Sim UE: oaitun_ue1 is UP and CONFIGURED" + fi + i="0" + echo "egrep -c \"Generating RRCConnectionReconfigurationComplete\" /home/ubuntu/tmp/cmake_targets/log/$LOC_UE_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + sleep 5 + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + UE_SYNC=0 + echo "Basic-Sim UE: UE did NOT complete RRC Connection" + else + echo "Basic-Sim UE: UE did COMPLETE RRC Connection" fi } function get_ue_ip_addr { - echo "ifconfig oip1 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $1 - UE_IP_ADDR=`ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1` - echo "UE IP Address for EPC is : $UE_IP_ADDR" + local LOC_IF_ID=$3 + echo "ifconfig oaitun_ue${LOC_IF_ID} | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $1 + UE_IP_ADDR=`ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1` + echo "Test UE${LOC_IF_ID} IP Address is : $UE_IP_ADDR" + rm $1 +} + +function get_enb_noS1_ip_addr { + echo "ifconfig oaitun_enb1 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $1 + ENB_IP_ADDR=`ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1` + echo "Test eNB IP Address is : $ENB_IP_ADDR" rm $1 } function ping_ue_ip_addr { - echo "echo \"ping -c 20 $3\"" > $1 + local LOC_FG_OR_BG=$5 echo "echo \"COMMAND IS: ping -c 20 $3\" > $4" > $1 - echo "ping -c 20 $UE_IP_ADDR | tee -a $4" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + echo "echo \"ping -c 20 $3\"" >> $1 + if [ $LOC_FG_OR_BG -eq 0 ] + then + echo "ping -c 20 $UE_IP_ADDR >> $4 2>&1" >> $1 + echo "tail -3 $4" >> $1 + else + echo "nohup ping -c 20 $UE_IP_ADDR >> $4 &" >> $1 + fi + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 rm -f $1 } function ping_epc_ip_addr { - echo "echo \"COMMAND IS: ping -I oip1 -c 20 $3\" > $4" > $1 - echo "rm -f $4" >> $1 - echo "ping -I oip1 -c 20 $3 | tee -a $4" >> $1 - cat $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + local LOC_IF_ID=$5 + local LOC_FG_OR_BG=$6 + echo "echo \"COMMAND IS: ping -I oaitun_ue${LOC_IF_ID} -c 20 $3\" > $4" > $1 + echo "echo \"ping -I oaitun_ue${LOC_IF_ID} -c 20 $3\"" >> $1 + if [ $LOC_FG_OR_BG -eq 0 ] + then + echo "ping -I oaitun_ue${LOC_IF_ID} -c 20 $3 >> $4 2>&1" >> $1 + echo "tail -3 $4" >> $1 + else + echo "nohup ping -I oaitun_ue${LOC_IF_ID} -c 20 $3 >> $4 &" >> $1 + fi + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm -f $1 +} + +function ping_enb_ip_addr { + local LOC_FG_OR_BG=$5 + echo "echo \"COMMAND IS: ping -I oaitun_enb1 -c 20 $3\" > $4" > $1 + echo "echo \"ping -I oaitun_enb1 -c 20 $3\"" >> $1 + if [ $LOC_FG_OR_BG -eq 0 ] + then + echo "ping -I oaitun_enb1 -c 20 $3 >> $4 2>&1" >> $1 + echo "tail -3 $4" >> $1 + else + echo "nohup ping -I oaitun_enb1 -c 20 $3 >> $4 &" >> $1 + fi + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 rm -f $1 } @@ -173,8 +257,15 @@ function check_ping_result { then echo "got all ping packets" else - echo "got NOT all ping packets" - PING_STATUS=-1 + LOC_NB_PINGS=$[$2-1] + ALL_PACKET_RECEIVED=`egrep -c "$LOC_NB_PINGS received" $LOC_PING_FILE` + if [ $ALL_PACKET_RECEIVED -eq 1 ] + then + echo "got almost all ping packets" + else + echo "got NOT all ping packets" + PING_STATUS=-1 + fi fi fi else @@ -183,94 +274,141 @@ function check_ping_result { fi } -function iperf_dl { - local REQ_BANDWIDTH=$5 - local BASE_LOG_FILE=$6 - echo "echo \"iperf -u -s -i 1\"" > $1 - echo "echo \"COMMAND IS: iperf -u -s -i 1\" > tmp/cmake_targets/log/${BASE_LOG_FILE}_server.txt" > $1 - echo "nohup iperf -u -s -i 1 >> tmp/cmake_targets/log/${BASE_LOG_FILE}_server.txt &" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 - rm $1 - - echo "echo \"iperf -c $UE_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1\"" > $3 - echo "echo \"COMMAND IS: iperf -c $UE_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1\" > ${BASE_LOG_FILE}_client.txt" > $3 - echo "iperf -c $UE_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1 | tee -a ${BASE_LOG_FILE}_client.txt" >> $3 - ssh -o StrictHostKeyChecking=no ubuntu@$4 < $3 - rm -f $3 - - echo "killall --signal SIGKILL iperf" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 - rm $1 -} - -function iperf_ul { - local REQ_BANDWIDTH=$5 - local BASE_LOG_FILE=$6 - echo "echo \"iperf -u -s -i 1\"" > $3 - echo "echo \"COMMAND IS: iperf -u -s -i 1\" > ${BASE_LOG_FILE}_server.txt" > $3 - echo "nohup iperf -u -s -i 1 >> ${BASE_LOG_FILE}_server.txt &" >> $3 - ssh -o StrictHostKeyChecking=no ubuntu@$4 < $3 - rm $3 - - echo "echo \"iperf -c $REAL_EPC_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1\"" > $1 - echo "echo \"COMMAND IS: iperf -c $REAL_EPC_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1\" > /home/ubuntu/tmp/cmake_targets/log/${BASE_LOG_FILE}_client.txt" > $1 - echo "iperf -c $REAL_EPC_IP_ADDR -u -t 30 -b ${REQ_BANDWIDTH}M -i 1 | tee -a /home/ubuntu/tmp/cmake_targets/log/${BASE_LOG_FILE}_client.txt" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 - rm -f $1 +# In DL: iperf server should be on UE side +# -B oaitun_ue{j}-IP-Addr +# iperf client should be on EPC (S1) or eNB (noS1) side +# -c oaitun_ue{j}-IP-Addr -B oaitun_enb1-IP-Addr (in noS1) +# In UL: iperf server should be on EPC (S1) or eNB (noS1) side +# -B oaitun_enb1-IP-Addr +# iperf client should be on UE side +# -c oaitun_enb1-IP-Addr -B oaitun_ue{j}-IP-Addr (in noS1) +function generic_iperf { + local LOC_ISERVER_CMD=$1 + local LOC_ISERVER_IP=$2 + local LOC_ISERVER_BOND_IP=$3 + local LOC_ICLIENT_CMD=$4 + local LOC_ICLIENT_IP=$5 + local LOC_ICLIENT_BOND_IP=$6 + local LOC_REQ_BANDWIDTH=$7 + local LOC_BASE_LOG_FILE=$8 + local LOC_PORT_ID=$[$9+5001] + local LOC_FG_OR_BG=${10} + # Starting Iperf Server + echo "iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 -fm -p ${LOC_PORT_ID}" + echo "nohup iperf -B ${LOC_ISERVER_BOND_IP} -u -s -i 1 -fm -p ${LOC_PORT_ID} > ${LOC_BASE_LOG_FILE}_server.txt 2>&1 &" > ${LOC_ISERVER_CMD} + ssh -T -o StrictHostKeyChecking=no ubuntu@${LOC_ISERVER_IP} < ${LOC_ISERVER_CMD} + rm ${LOC_ISERVER_CMD} + + # Starting Iperf Client + echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}" + echo "echo \"COMMAND IS: iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID}\" > ${LOC_BASE_LOG_FILE}_client.txt" > ${LOC_ICLIENT_CMD} + if [ $LOC_FG_OR_BG -eq 0 ] + then + echo "iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1" >> ${LOC_ICLIENT_CMD} + echo "tail -3 ${LOC_BASE_LOG_FILE}_client.txt | grep -v datagram" >> ${LOC_ICLIENT_CMD} + else + echo "nohup iperf -c ${LOC_ISERVER_BOND_IP} -u -t 30 -b ${LOC_REQ_BANDWIDTH}M -i 1 -fm -B ${LOC_ICLIENT_BOND_IP} -p ${LOC_PORT_ID} >> ${LOC_BASE_LOG_FILE}_client.txt 2>&1 &" >> ${LOC_ICLIENT_CMD} + fi + ssh -T -o StrictHostKeyChecking=no ubuntu@${LOC_ICLIENT_IP} < ${LOC_ICLIENT_CMD} + rm -f ${LOC_ICLIENT_CMD} - echo "killall --signal SIGKILL iperf" >> $3 - ssh -o StrictHostKeyChecking=no ubuntu@$4 < $3 - rm $3 + # Stopping Iperf Server + if [ $LOC_FG_OR_BG -eq 0 ] + then + echo "killall --signal SIGKILL iperf" + echo "killall --signal SIGKILL iperf" > ${LOC_ISERVER_CMD} + ssh -T -o StrictHostKeyChecking=no ubuntu@${LOC_ISERVER_IP} < ${LOC_ISERVER_CMD} + rm ${LOC_ISERVER_CMD} + fi } function check_iperf { local LOC_BASE_LOG=$1 local LOC_REQ_BW=$2 local LOC_REQ_BW_MINUS_ONE=`echo "$LOC_REQ_BW - 1" | bc -l` + local LOC_REQ_BW_MINUS_TWO=`echo "$LOC_REQ_BW - 2" | bc -l` + local LOC_REQ_BW_MINUS_THREE=`echo "$LOC_REQ_BW - 3" | bc -l` + local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl` + local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim` if [ -f ${LOC_BASE_LOG}_client.txt ] then local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt` if [ $FILE_COMPLETE -eq 0 ] then IPERF_STATUS=-1 + echo "File Report not found" else local EFFECTIVE_BANDWIDTH=`tail -n3 ${LOC_BASE_LOG}_client.txt | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` - if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] + if [ $LOC_IS_DL -eq 1 ] && [ $LOC_IS_BASIC_SIM -eq 1 ] then - echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_TWO}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_THREE}.*Mbits.* ]] + then + echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + else + echo "got LESS than requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + IPERF_STATUS=-1 + fi else - IPERF_STATUS=-1 + if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] + then + if [ $LOC_IS_DL -eq 1 ] + then + echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + else + echo "got requested UL bandwidth: $EFFECTIVE_BANDWIDTH" + fi + else + echo "not basic-sim got LESS than requested DL bandwidth: $EFFECTIVE_BANDWIDTH" + IPERF_STATUS=-1 + fi fi fi else IPERF_STATUS=-1 + echo "File not found" fi } function terminate_enb_ue_basic_sim { + # mode = 0 : eNB + UE + # mode = 1 : eNB + # mode = 2 : UE + local LOC_MODE=$3 echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" > $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=enb_daemon --stop\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=enb_daemon --stop; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=ue_daemon --stop\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=ue_daemon --stop; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 - echo "echo \"ps -aux | grep softmodem\"" >> $1 - echo "ps -aux | grep softmodem | grep -v grep" >> $1 - echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGINT lte-softmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGINT lte-softmodem; fi" >> $1 + if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 1 ] + then + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=enb_daemon --stop\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=enb_daemon --stop; fi" >> $1 + fi + if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 2 ] + then + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo daemon --name=ue_daemon --stop\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo daemon --name=ue_daemon --stop; fi" >> $1 + fi echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 echo "echo \"ps -aux | grep softmodem\"" >> $1 echo "ps -aux | grep softmodem | grep -v grep" >> $1 echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-softmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-softmodem; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-uesoftmodem\"; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-uesoftmodem; fi" >> $1 - echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 + if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 1 ] + then + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGINT lte-softmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGINT lte-softmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 + echo "echo \"ps -aux | grep softmodem\"" >> $1 + echo "ps -aux | grep softmodem | grep -v grep" >> $1 + echo "NB_OAI_PROCESSES=\`ps -aux | grep modem | grep -v grep | grep -c softmodem\`" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-softmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-softmodem; fi" >> $1 + fi + if [ $LOC_MODE -eq 0 ] || [ $LOC_MODE -eq 2 ] + then + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then echo \"sudo killall --signal SIGKILL lte-uesoftmodem\"; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sudo killall --signal SIGKILL lte-uesoftmodem; fi" >> $1 + echo "if [ \$NB_OAI_PROCESSES -ne 0 ]; then sleep 5; fi" >> $1 + fi echo "echo \"ps -aux | grep softmodem\"" >> $1 echo "ps -aux | grep softmodem | grep -v grep" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 rm -f $1 } @@ -286,12 +424,39 @@ function recover_core_dump { echo "sudo rm core" >> $1 echo "rm ci-lte-basic-sim.conf" >> $1 echo "sync" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/basic_simulator/enb/basic-simulator-enb-core-${TC}.bz2 $4 rm -f $1 fi } +function full_terminate { + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR 0 + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + sleep 10 +} + +function full_basic_sim_destroy { + if [ $KEEP_VM_ALIVE -eq 0 ] + then + echo "############################################################" + echo "Destroying VMs" + echo "############################################################" + uvt-kvm destroy $VM_NAME + ssh-keygen -R $VM_IP_ADDR + if [ -e $JENKINS_WKSP/flexran/flexran_build_complete.txt ] + then + uvt-kvm destroy $FLEXRAN_CTL_VM_NAME + ssh-keygen -R $FLEXRAN_CTL_VM_IP_ADDR + fi + fi +} + function install_epc_on_vm { local LOC_EPC_VM_NAME=$1 local LOC_EPC_VM_CMDS=$2 @@ -299,7 +464,7 @@ function install_epc_on_vm { if [ -d /opt/ltebox-archives/ ] then # Checking if all ltebox archives are available to run ltebx epc on a brand new VM - if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim.zip ] + if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim-develop.zip ] then echo "############################################################" echo "Test EPC on VM ($EPC_VM_NAME) will be using ltebox" @@ -317,11 +482,18 @@ function install_epc_on_vm { echo "############################################################" echo "Creating test EPC VM ($LOC_EPC_VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" + acquire_vm_create_lock uvt-kvm create $LOC_EPC_VM_NAME release=xenial --unsafe-caching + echo "Waiting for VM to be started" + uvt-kvm wait $LOC_EPC_VM_NAME --insecure + release_vm_create_lock + else + echo "Waiting for VM to be started" + uvt-kvm wait $LOC_EPC_VM_NAME --insecure fi - uvt-kvm wait $LOC_EPC_VM_NAME --insecure local LOC_EPC_VM_IP_ADDR=`uvt-kvm ip $LOC_EPC_VM_NAME` + echo "$LOC_EPC_VM_NAME has for IP addr = $LOC_EPC_VM_IP_ADDR" scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu @@ -330,7 +502,7 @@ function install_epc_on_vm { if [ $LTEBOX -eq 1 ] then echo "ls -ls /opt/ltebox/tools/start_ltebox" > $LOC_EPC_VM_CMDS - RESPONSE=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS` + RESPONSE=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS` NB_EXES=`echo $RESPONSE | grep -c ltebox` if [ $NB_EXES -eq 1 ]; then LTE_BOX_TO_INSTALL=0; fi fi @@ -342,7 +514,7 @@ function install_epc_on_vm { echo "############################################################" scp -o StrictHostKeyChecking=no /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu scp -o StrictHostKeyChecking=no /opt/ltebox-archives/etc-conf.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu - scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu + scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim-develop.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu echo "############################################################" echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)" @@ -356,8 +528,8 @@ function install_epc_on_vm { # Installing HSS echo "echo \"cd /opt\"" >> $LOC_EPC_VM_CMDS echo "cd /opt" >> $LOC_EPC_VM_CMDS - echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim.zip\"" >> $LOC_EPC_VM_CMDS - echo "sudo unzip -qq /home/ubuntu/hss-sim.zip" >> $LOC_EPC_VM_CMDS + echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim-develop.zip\"" >> $LOC_EPC_VM_CMDS + echo "sudo unzip -qq /home/ubuntu/hss-sim-develop.zip" >> $LOC_EPC_VM_CMDS echo "echo \"cd /opt/hss_sim0609\"" >> $LOC_EPC_VM_CMDS echo "cd /opt/hss_sim0609" >> $LOC_EPC_VM_CMDS @@ -374,7 +546,29 @@ function install_epc_on_vm { echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$LOC_EPC_VM_IP_ADDR#' gw.conf" >> $LOC_EPC_VM_CMDS echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$LOC_EPC_VM_IP_ADDR#' mme.conf" >> $LOC_EPC_VM_CMDS - ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS + rm -f $LOC_EPC_VM_CMDS + fi +} + +function add_user_to_epc_lists { + local LOC_EPC_VM_CMDS=$1 + local LOC_EPC_VM_IP_ADDR=$2 + local LOC_NB_USERS=$3 + if [ $LTEBOX -eq 1 ] + then + scp -o StrictHostKeyChecking=no $JENKINS_WKSP/ci-scripts/add_user_to_subscriber_list.awk ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu/ + echo "cd /opt/hss_sim0609" > $LOC_EPC_VM_CMDS + echo "if [ -e subscriber.data.orig ]; then sudo mv subscriber.data.orig subscriber.data; fi" >> $1 + echo "if [ -e profile.data.orig ]; then sudo mv profile.data.orig profile.data; fi" >> $1 + echo "sudo cp subscriber.data subscriber.data.orig" >> $LOC_EPC_VM_CMDS + echo "sudo cp profile.data profile.data.orig" >> $LOC_EPC_VM_CMDS + echo "sudo awk -v num_ues=$LOC_NB_USERS -f /home/ubuntu/add_user_to_subscriber_list.awk subscriber.data.orig > /tmp/subscriber.data" >> $LOC_EPC_VM_CMDS + echo "sudo awk -v num_ues=$LOC_NB_USERS -f /home/ubuntu/add_user_to_subscriber_list.awk profile.data.orig > /tmp/profile.data" >> $LOC_EPC_VM_CMDS + echo "sudo cp /tmp/subscriber.data subscriber.data" >> $LOC_EPC_VM_CMDS + echo "sudo cp /tmp/profile.data profile.data" >> $LOC_EPC_VM_CMDS + + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS rm -f $LOC_EPC_VM_CMDS fi } @@ -398,8 +592,10 @@ function start_epc { echo "cd /opt/ltebox/tools/" >> $LOC_EPC_VM_CMDS echo "echo \"sudo ./start_ltebox\"" >> $LOC_EPC_VM_CMDS echo "nohup sudo ./start_ltebox > /home/ubuntu/ltebox.txt" >> $LOC_EPC_VM_CMDS + echo "touch /home/ubuntu/try.txt" >> $LOC_EPC_VM_CMDS + echo "sudo rm -f /home/ubuntu/*.txt" >> $LOC_EPC_VM_CMDS - ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS rm -f $LOC_EPC_VM_CMDS i="0" @@ -407,7 +603,7 @@ function start_epc { while [ $i -lt 10 ] do sleep 2 - CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS` + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS` if [ $CONNECTED -eq 1 ] then i="100" @@ -437,7 +633,7 @@ function retrieve_real_epc_ip_addr { then # in our configuration file, we are using pool 5 echo "ifconfig tun5 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $LOC_EPC_VM_CMDS - REAL_EPC_IP_ADDR=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS` + REAL_EPC_IP_ADDR=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS` echo "EPC IP Address is : $REAL_EPC_IP_ADDR" rm $LOC_EPC_VM_CMDS fi @@ -454,7 +650,7 @@ function terminate_epc { echo "sudo daemon --name=simulated_hss --stop" >> $1 echo "echo \"sudo killall --signal SIGKILL hss_sim\"" >> $1 echo "sudo killall --signal SIGKILL hss_sim" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 rm $1 fi } @@ -464,7 +660,7 @@ function start_flexran_ctrl { echo "if [ -f cmake_targets/log/flexran_ctl_run.log ]; then rm -f cmake_targets/log/flexran_ctl_run.log cmake_targets/log/flexran_ctl_query*.log; fi" >> $1 echo "echo \" sudo build/rt_controller -c log_config/basic_log\"" >> $1 echo "nohup sudo build/rt_controller -c log_config/basic_log > cmake_targets/log/flexran_ctl_run.log 2>&1 &" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 rm $1 sleep 10 } @@ -472,7 +668,7 @@ function start_flexran_ctrl { function stop_flexran_ctrl { echo "echo \"sudo killall --signal SIGKILL rt_controller\"" > $1 echo "sudo killall --signal SIGKILL rt_controller" > $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 rm $1 sleep 2 } @@ -484,7 +680,7 @@ function query_flexran_ctrl_status { echo "echo \"LOG_NAME: $LOC_MESSAGE\" >> cmake_targets/log/flexran_ctl_query_${LOC_MESSAGE}.log" >> $1 echo "echo \"------------------------------------------------------------\" >> cmake_targets/log/flexran_ctl_query_${LOC_MESSAGE}.log" >> $1 echo "curl http://localhost:9999/stats | jq '.' | tee -a cmake_targets/log/flexran_ctl_query_${LOC_MESSAGE}.log" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 rm $1 } @@ -493,16 +689,6 @@ function build_ue_on_separate_folder { echo "cd tmp-ue" >> $1 echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $1 echo "unzip -qq -DD ../localZip.zip" >> $1 - - # We may have some adaptation to do - if [ -f /opt/ltebox-archives/adapt_ue_l2_sim.txt ] - then - echo "############################################################" - echo "Doing some adaptation on UE side" - echo "############################################################" - cat /opt/ltebox-archives/adapt_ue_l2_sim.txt >> $1 - fi - echo "echo \"source oaienv\"" >> $1 echo "source oaienv" >> $1 echo "cd cmake_targets/" >> $1 @@ -515,16 +701,19 @@ function build_ue_on_separate_folder { echo "sudo chmod 666 /etc/iproute2/rt_tables" >> $1 echo "source init_nas_s1 UE" >> $1 echo "ifconfig" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$2 < $1 rm -f $1 } function start_l2_sim_enb { - local LOC_VM_IP_ADDR=$2 + local LOC_ENB_VM_IP_ADDR=$2 local LOC_EPC_IP_ADDR=$3 - local LOC_LOG_FILE=$4 - local LOC_NB_RBS=$5 - local LOC_CONF_FILE=$6 + local LOC_UE_VM_IP_ADDR=$4 + local LOC_LOG_FILE=$5 + local LOC_NB_RBS=$6 + local LOC_CONF_FILE=$7 + # 1 is with S1 and 0 without S1 aka noS1 + local LOC_S1_CONFIGURATION=$8 echo "cd /home/ubuntu/tmp" > $1 echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1 echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 @@ -532,19 +721,24 @@ function start_l2_sim_enb { echo "source oaienv" >> $1 echo "cd ci-scripts/conf_files/" >> $1 echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1 - echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1 + echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_ENB_VM_IP_ADDR#' -e 's#CI_UE_IP_ADDR#$LOC_UE_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1 echo "echo \"grep N_RB_DL ci-$LOC_CONF_FILE\"" >> $1 echo "grep N_RB_DL ci-$LOC_CONF_FILE | sed -e 's#N_RB_DL.*=#N_RB_DL =#'" >> $1 echo "echo \"cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/\"" >> $1 echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1 echo "cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1 - echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE\" > ./my-lte-softmodem-run.sh " >> $1 + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --noS1\" > ./my-lte-softmodem-run.sh " >> $1 + else + echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE\" > ./my-lte-softmodem-run.sh " >> $1 + fi echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1 echo "cat ./my-lte-softmodem-run.sh" >> $1 echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 echo "sudo -E daemon --inherit --unsafe --name=enb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_VM_IP_ADDR < $1 rm $1 local i="0" @@ -552,7 +746,7 @@ function start_l2_sim_enb { while [ $i -lt 10 ] do sleep 5 - CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1` + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_VM_IP_ADDR < $1` if [ $CONNECTED -ne 0 ] then i="100" @@ -561,30 +755,98 @@ function start_l2_sim_enb { fi done rm $1 + ENB_SYNC=1 if [ $i -lt 50 ] then ENB_SYNC=0 echo "L2-SIM eNB is NOT sync'ed: process still alive?" else - ENB_SYNC=1 echo "L2-SIM eNB is sync'ed: waiting for UE(s) to connect" fi + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "ifconfig oaitun_enb1 | egrep -c \"inet addr\"" > $1 + # Checking oaitun_enb1 interface has now an IP address + i="0" + while [ $i -lt 10 ] + do + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + sleep 5 + fi + done + rm $1 + if [ $i -lt 50 ] + then + ENB_SYNC=0 + echo "L2-SIM eNB oaitun_enb1 is DOWN or NOT CONFIGURED" + else + echo "L2-SIM eNB oaitun_enb1 is UP and CONFIGURED" + fi + fi + sleep 10 +} + +function add_ue_l2_sim_ue { + local LOC_UE_VM_IP_ADDR=$2 + local LOC_NB_UES=$3 + echo "cd /home/ubuntu/tmp/" > $1 + echo "source oaienv" >> $1 + if [ $LOC_NB_UES -gt 1 ] + then + echo "echo \"cd openair3/NAS/TOOLS/\"" >> $1 + echo "cd openair3/NAS/TOOLS/" >> $1 + echo "echo \"awk -v num_ues=$LOC_NB_UES -f /home/ubuntu/tmp/ci-scripts/add_user_to_conf_file.awk ue_eurecom_test_sfr.conf > ue_eurecom_test_sfr_multi_ues.conf\"" >> $1 + echo "awk -v num_ues=$LOC_NB_UES -f /home/ubuntu/tmp/ci-scripts/add_user_to_conf_file.awk ue_eurecom_test_sfr.conf > ue_eurecom_test_sfr_multi_ues.conf" >> $1 + fi + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/\"" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1 + echo "sudo rm -f *.u*" >> $1 + if [ $LOC_NB_UES -eq 1 ] + then + echo "echo \"sudo ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o .\"" >> $1 + echo "sudo ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o . > /home/ubuntu/tmp/cmake_targets/log/ue_adapt.txt 2>&1" >> $1 + else + echo "echo \"sudo ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr_multi_ues.conf -o .\"" >> $1 + echo "sudo ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr_multi_ues.conf -o . > /home/ubuntu/tmp/cmake_targets/log/ue_adapt.txt 2>&1" >> $1 + fi + + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1 + rm $1 } function start_l2_sim_ue { - local LOC_VM_IP_ADDR=$2 - local LOC_LOG_FILE=$3 - local LOC_CONF_FILE=$4 - echo "echo \"cd /home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/\"" >> $1 - echo "sudo chmod 777 /home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/" >> $1 - echo "cd /home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/" >> $1 - echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp-ue/ci-scripts/conf_files/$LOC_CONF_FILE --L2-emul 3 --num-ues 1\" > ./my-lte-softmodem-run.sh " >> $1 + local LOC_UE_VM_IP_ADDR=$2 + local LOC_ENB_VM_IP_ADDR=$3 + local LOC_LOG_FILE=$4 + local LOC_CONF_FILE=$5 + local LOC_NB_UES=$6 + # 1 is with S1 and 0 without S1 aka noS1 + local LOC_S1_CONFIGURATION=$7 + echo "echo \"sudo apt-get --yes --quiet install daemon \"" > $1 + echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "cd /home/ubuntu/tmp/ci-scripts/conf_files/" >> $1 + echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1 + echo "sed -i -e 's#CI_ENB_IP_ADDR#$LOC_ENB_VM_IP_ADDR#' -e 's#CI_UE_IP_ADDR#$LOC_UE_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/\"" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1 + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --L2-emul 3 --num-ues $LOC_NB_UES --nums_ue_thread $LOC_NB_UES --nokrnmod 1 --noS1\" > ./my-lte-softmodem-run.sh " >> $1 + else + echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --L2-emul 3 --num-ues $LOC_NB_UES --nums_ue_thread $LOC_NB_UES --nokrnmod 1\" > ./my-lte-softmodem-run.sh " >> $1 + fi echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1 echo "cat ./my-lte-softmodem-run.sh" >> $1 echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 - echo "sudo -E daemon --inherit --unsafe --name=ue_daemon --chdir=/home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=ue_daemon --chdir=/home/ubuntu/tmp/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1 - ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1 rm $1 local i="0" @@ -592,7 +854,222 @@ function start_l2_sim_ue { while [ $i -lt 10 ] do sleep 5 - CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1` + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + UE_SYNC=1 + if [ $i -lt 50 ] + then + UE_SYNC=0 + echo "L2-SIM UE is NOT sync'ed w/ eNB" + return + else + echo "L2-SIM UE is sync'ed w/ eNB" + fi + local max_interfaces_to_check=1 + if [ $LOC_S1_CONFIGURATION -eq 0 ]; then max_interfaces_to_check=$LOC_NB_UES; fi + local j="1" + while [ $j -le $max_interfaces_to_check ] + do + echo "ifconfig oaitun_ue${j} | egrep -c \"inet addr\"" > $1 + # Checking oaitun_ue1 interface has now an IP address + i="0" + while [ $i -lt 10 ] + do + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + sleep 5 + fi + done + rm $1 + if [ $i -lt 50 ] + then + UE_SYNC=0 + echo "L2-SIM UE oaitun_ue${j} is DOWN or NOT CONFIGURED" + else + echo "L2-SIM UE oaitun_ue${j} is UP and CONFIGURED" + fi + j=$[$j+1] + done + sleep 10 + # for debug + if [ $LOC_S1_CONFIGURATION -eq 1 ] + then + echo "ifconfig" > $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1 + rm $1 + fi +} + +function full_l2_sim_destroy { + if [ $KEEP_VM_ALIVE -eq 0 ] + then + echo "############################################################" + echo "Destroying VMs" + echo "############################################################" + uvt-kvm destroy $ENB_VM_NAME + ssh-keygen -R $ENB_VM_IP_ADDR + uvt-kvm destroy $UE_VM_NAME + ssh-keygen -R $UE_VM_IP_ADDR + fi +} + +function start_rf_sim_enb { + local LOC_ENB_VM_IP_ADDR=$2 + local LOC_EPC_IP_ADDR=$3 + local LOC_LOG_FILE=$4 + local LOC_NB_RBS=$5 + local LOC_CONF_FILE=$6 + # 1 is with S1 and 0 without S1 aka noS1 + local LOC_S1_CONFIGURATION=$7 + echo "cd /home/ubuntu/tmp" > $1 + echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1 + echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "echo \"export RFSIMULATOR=enb\"" >> $1 + echo "export RFSIMULATOR=enb" >> $1 + echo "echo \"source oaienv\"" >> $1 + echo "source oaienv" >> $1 + echo "cd ci-scripts/conf_files/" >> $1 + echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1 + echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_ENB_VM_IP_ADDR#' -e 's#CI_UE_IP_ADDR#$LOC_UE_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1 + echo "echo \"grep N_RB_DL ci-$LOC_CONF_FILE\"" >> $1 + echo "grep N_RB_DL ci-$LOC_CONF_FILE | sed -e 's#N_RB_DL.*=#N_RB_DL =#'" >> $1 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/\"" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1 + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --rfsim --noS1\" > ./my-lte-softmodem-run.sh " >> $1 + else + echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --rfsim\" > ./my-lte-softmodem-run.sh " >> $1 + fi + echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1 + echo "cat ./my-lte-softmodem-run.sh" >> $1 + echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=enb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1 + + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_VM_IP_ADDR < $1 + rm $1 + + local i="0" + echo "egrep -c \"got sync\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_VM_IP_ADDR < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + ENB_SYNC=0 + echo "RF-SIM eNB is NOT sync'ed: process still alive?" + else + ENB_SYNC=1 + echo "RF-SIM eNB is sync'ed: waiting for UE(s) to connect" + fi + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "ifconfig oaitun_enb1 | egrep -c \"inet addr\"" > $1 + # Checking oaitun_enb1 interface has now an IP address + i="0" + while [ $i -lt 10 ] + do + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_ENB_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + sleep 5 + fi + done + rm $1 + if [ $i -lt 50 ] + then + ENB_SYNC=0 + echo "RF-SIM eNB oaitun_enb1 is DOWN or NOT CONFIGURED" + else + echo "RF-SIM eNB oaitun_enb1 is UP and CONFIGURED" + fi + fi + sleep 10 +} + +function start_rf_sim_ue { + local LOC_UE_VM_IP_ADDR=$2 + local LOC_ENB_VM_IP_ADDR=$3 + local LOC_LOG_FILE=$4 + local LOC_PRB=$5 + local LOC_FREQUENCY=$6 + # 1 is with S1 and 0 without S1 aka noS1 + local LOC_S1_CONFIGURATION=$7 + echo "echo \"sudo apt-get --yes --quiet install daemon \"" > $1 + echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 + echo "echo \"export RFSIMULATOR=${LOC_ENB_VM_IP_ADDR}\"" >> $1 + echo "export RFSIMULATOR=${LOC_ENB_VM_IP_ADDR}" >> $1 + echo "echo \"cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/\"" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1 + if [ $LOC_S1_CONFIGURATION -eq 0 ] + then + echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --nokrnmod 1 --rfsim --noS1\" > ./my-lte-softmodem-run.sh " >> $1 + else + echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -C ${LOC_FREQUENCY}000000 -r $LOC_PRB --nokrnmod 1 --rfsim\" > ./my-lte-softmodem-run.sh " >> $1 + fi + echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1 + echo "cat ./my-lte-softmodem-run.sh" >> $1 + echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 + echo "sudo -E daemon --inherit --unsafe --name=ue_daemon --chdir=/home/ubuntu/tmp/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1 + + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1 + rm $1 + + local i="0" + echo "egrep -c \"got sync\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + i=$[$i+1] + fi + done + UE_SYNC=1 + rm $1 + if [ $i -lt 50 ] + then + UE_SYNC=0 + echo "RF-SIM UE is NOT sync'ed w/ eNB" + return + else + echo "RF-SIM UE is sync'ed w/ eNB" + fi + # Checking oaitun_ue1 interface has now an IP address + i="0" + echo "ifconfig oaitun_ue1 | egrep -c \"inet addr\"" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_UE_VM_IP_ADDR < $1` if [ $CONNECTED -eq 1 ] then i="100" @@ -604,35 +1081,66 @@ function start_l2_sim_ue { if [ $i -lt 50 ] then UE_SYNC=0 - echo "L2-SIM UE is NOT sync'ed w/eNB" + echo "RF-SIM UE oaitun_ue1 is DOWN or NOT CONFIGURED" else - UE_SYNC=1 - echo "L2-SIM UE is sync'ed w/eNB" + echo "RF-SIM UE oaitun_ue1 is UP and CONFIGURED" fi sleep 10 } + function run_test_on_vm { echo "############################################################" echo "OAI CI VM script" echo "############################################################" - echo "VM_NAME = $VM_NAME" - echo "VM_CMD_FILE = $VM_CMDS" + if [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-l2-sim.* )) || (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-rf-sim.* )) ]] + then + ENB_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#enb-ethernet#" -e "s#rf-sim#enb-ethernet#"` + ENB_VM_CMDS=${ENB_VM_NAME}_cmds.txt + echo "ENB_VM_NAME = $ENB_VM_NAME" + echo "ENB_VM_CMD_FILE = $ENB_VM_CMDS" + UE_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#ue-ethernet#" -e "s#rf-sim#ue-ethernet#"` + UE_VM_CMDS=${UE_VM_NAME}_cmds.txt + echo "UE_VM_NAME = $UE_VM_NAME" + echo "UE_VM_CMD_FILE = $UE_VM_CMDS" + else + echo "VM_NAME = $VM_NAME" + echo "VM_CMD_FILE = $VM_CMDS" + fi echo "JENKINS_WKSP = $JENKINS_WKSP" echo "ARCHIVES_LOC = $ARCHIVES_LOC" - echo "############################################################" - echo "Waiting for VM to be started" - echo "############################################################" - uvt-kvm wait $VM_NAME --insecure + if [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-l2-sim.* )) || (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-rf-sim.* )) ]] + then + echo "############################################################" + echo "Waiting for ENB VM to be started" + echo "############################################################" + uvt-kvm wait $ENB_VM_NAME --insecure + + ENB_VM_IP_ADDR=`uvt-kvm ip $ENB_VM_NAME` + echo "$ENB_VM_NAME has for IP addr = $ENB_VM_IP_ADDR" + + echo "############################################################" + echo "Waiting for UE VM to be started" + echo "############################################################" + uvt-kvm wait $UE_VM_NAME --insecure + + UE_VM_IP_ADDR=`uvt-kvm ip $UE_VM_NAME` + echo "$UE_VM_NAME has for IP addr = $UE_VM_IP_ADDR" + else + echo "############################################################" + echo "Waiting for VM to be started" + echo "############################################################" + uvt-kvm wait $VM_NAME --insecure - VM_IP_ADDR=`uvt-kvm ip $VM_NAME` - echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + VM_IP_ADDR=`uvt-kvm ip $VM_NAME` + echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + fi if [ "$RUN_OPTIONS" == "none" ] then echo "No run on VM testing for this variant currently" - exit $STATUS + return fi if [[ $RUN_OPTIONS =~ .*run_exec_autotests.* ]] @@ -656,7 +1164,7 @@ function run_test_on_vm { echo "cd log" >> $VM_CMDS echo "zip -r -qq tmp.zip *.* 0*" >> $VM_CMDS - ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS + ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS echo "############################################################" echo "Creating a tmp folder to store results and artifacts" @@ -762,182 +1270,91 @@ function run_test_on_vm { # Retrieve EPC real IP address retrieve_real_epc_ip_addr $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR - # We may have some adaptation to do - if [ -f /opt/ltebox-archives/adapt_ue_sim.txt ] - then - echo "############################################################" - echo "Doing some adaptation on UE side" - echo "############################################################" - ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < /opt/ltebox-archives/adapt_ue_sim.txt - fi - - echo "############################################################" - echo "Starting the eNB in FDD-5MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=fdd_05MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-fdd-basic-sim.conf none - - echo "############################################################" - echo "Starting the UE in FDD-5MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=fdd_05MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 25 2680 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 - fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=fdd_05MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - - echo "############################################################" - echo "Iperf DL" - echo "############################################################" - CURR_IPERF_LOG_BASE=fdd_05MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 - - echo "############################################################" - echo "Iperf UL" - echo "############################################################" - CURR_IPERF_LOG_BASE=fdd_05MHz_iperf_ul - iperf_ul $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 2 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 2 - - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - sleep 10 - - echo "############################################################" - echo "Starting the eNB in FDD-10MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=fdd_10MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-fdd-basic-sim.conf none - - echo "############################################################" - echo "Starting the UE in FDD-10MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=fdd_10MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2680 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 - fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=fdd_10MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - - echo "############################################################" - echo "Iperf DL" - echo "############################################################" - CURR_IPERF_LOG_BASE=fdd_10MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 - - echo "############################################################" - echo "Iperf UL" - echo "############################################################" - CURR_IPERF_LOG_BASE=fdd_10MHz_iperf_ul - iperf_ul $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 2 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 2 - - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - sleep 10 - - echo "############################################################" - echo "Starting the eNB in FDD-20MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=fdd_20MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-fdd-basic-sim.conf none - - echo "############################################################" - echo "Starting the UE in FDD-20MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=fdd_20MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 100 2680 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 - fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=fdd_20MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - - echo "############################################################" - echo "Iperf DL" - echo "############################################################" - CURR_IPERF_LOG_BASE=fdd_20MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 + TRANS_MODES=("fdd" "tdd") + BW_CASES=(05 10 20) - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - sleep 10 + for TMODE in ${TRANS_MODES[@]} + do + for BW in ${BW_CASES[@]} + do + # Not Running in TDD-10MHz and TDD-20MHz : too unstable + #if [[ $TMODE =~ .*tdd.* ]] && [[ $BW =~ .*10.* ]]; then continue; fi + #if [[ $TMODE =~ .*tdd.* ]] && [[ $BW =~ .*20.* ]]; then continue; fi + + if [[ $BW =~ .*05.* ]]; then PRB=25; fi + if [[ $BW =~ .*10.* ]]; then PRB=50; fi + if [[ $BW =~ .*20.* ]]; then PRB=100; fi + if [[ $TMODE =~ .*fdd.* ]]; then FREQUENCY=2680; else FREQUENCY=2350; fi + + echo "############################################################" + echo "Starting the eNB in ${TMODE}-${BW}MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=${TMODE}_${BW}MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE $PRB lte-${TMODE}-basic-sim.conf none + + echo "############################################################" + echo "Starting the UE in ${TMODE}-${BW}MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=${TMODE}_${BW}MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE $PRB $FREQUENCY + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR 0 + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + full_basic_sim_destroy + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + STATUS=-1 + return + fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR 1 + + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=${TMODE}_${BW}MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0 + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + + # Not more testing in any TDD : too unstable + if [[ $TMODE =~ .*tdd.* ]] && [[ $BW =~ .*05.* ]]; then full_terminate; continue; fi + if [[ $TMODE =~ .*tdd.* ]] && [[ $BW =~ .*10.* ]]; then full_terminate; continue; fi + if [[ $TMODE =~ .*tdd.* ]] && [[ $BW =~ .*20.* ]]; then full_terminate; continue; fi + echo "############################################################" + echo "Iperf DL" + echo "############################################################" + if [[ $TMODE =~ .*fdd.* ]] + then + if [[ $BW =~ .*20.* ]]; then THROUGHPUT=12; else THROUGHPUT=10; fi + else + THROUGHPUT=6 + fi + CURR_IPERF_LOG_BASE=${TMODE}_${BW}MHz_iperf_dl + generic_iperf $VM_CMDS $VM_IP_ADDR $UE_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR $REAL_EPC_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 0 0 + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE $THROUGHPUT + + # Not more testing in FDD-20MHz : too unstable + if [[ $TMODE =~ .*fdd.* ]] && [[ $BW =~ .*20.* ]]; then full_terminate; continue; fi + echo "############################################################" + echo "Iperf UL" + echo "############################################################" + THROUGHPUT=2 + CURR_IPERF_LOG_BASE=${TMODE}_${BW}MHz_iperf_ul + generic_iperf $EPC_VM_CMDS $EPC_VM_IP_ADDR $REAL_EPC_IP_ADDR $VM_CMDS $VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 0 0 + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE $THROUGHPUT + + full_terminate + + done + done if [ -d $JENKINS_WKSP/flexran ] then @@ -961,7 +1378,8 @@ function run_test_on_vm { echo "ERROR: compiling flexran controller on vm went wrong" terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi FLEXRAN_CTL_VM_NAME=`echo $VM_NAME | sed -e "s#basic-sim#flexran-rtc#"` FLEXRAN_CTL_VM_CMDS=`echo $VM_CMDS | sed -e "s#cmds#flexran-rtc-cmds#"` @@ -970,8 +1388,10 @@ function run_test_on_vm { then echo "ERROR: Flexran Ctl VM is not alive" terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + full_basic_sim_destroy echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi uvt-kvm wait $FLEXRAN_CTL_VM_NAME --insecure FLEXRAN_CTL_VM_IP_ADDR=`uvt-kvm ip $FLEXRAN_CTL_VM_NAME` @@ -999,23 +1419,24 @@ function run_test_on_vm { if [ $UE_SYNC -eq 0 ] then echo "Problem w/ eNB and UE not syncing" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR 0 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR stop_flexran_ctrl $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 + STATUS=-1 + return fi query_flexran_ctrl_status $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR 03_enb_ue_connected - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR 1 sleep 30 echo "############################################################" echo "Terminate enb/ue simulators" echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR 0 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC @@ -1029,178 +1450,200 @@ function run_test_on_vm { fi echo "############################################################" - echo "Starting the eNB in TDD-5MHz mode" + echo "Terminate EPC" echo "############################################################" - CURRENT_ENB_LOG_FILE=tdd_05MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-tdd-basic-sim.conf none - echo "############################################################" - echo "Starting the UE in TDD-5MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=tdd_05MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 25 2350 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 - fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=tdd_05MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - -# Bug in TDD 5Mhz --- not running it -# echo "############################################################" -# echo "Iperf DL" -# echo "############################################################" -# CURR_IPERF_LOG_BASE=tdd_05MHz_iperf_dl -# iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE -# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC -# check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 + full_basic_sim_destroy echo "############################################################" - echo "Terminate enb/ue simulators" + echo "Checking run status" echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - sleep 10 - echo "############################################################" - echo "Starting the eNB in TDD-10MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=tdd_10MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-tdd-basic-sim.conf none + if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi - echo "############################################################" - echo "Starting the UE in TDD-10MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=tdd_10MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2350 - if [ $UE_SYNC -eq 0 ] + if [ $STATUS -eq 0 ] then - echo "Problem w/ eNB and UE not syncing" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log + else echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=tdd_10MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - - echo "############################################################" - echo "Iperf DL" - echo "############################################################" - CURR_IPERF_LOG_BASE=tdd_10MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 + fi - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - sleep 10 - -# Disabling TDD-20MHz in order to stop getting false negatives -# echo "############################################################" -# echo "Starting the eNB in TDD-20MHz mode" -# echo "############################################################" -# CURRENT_ENB_LOG_FILE=tdd_20MHz_enb.log -# start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-tdd-basic-sim.conf none -# -# echo "############################################################" -# echo "Starting the UE in TDD-20MHz mode" -# echo "############################################################" -# CURRENT_UE_LOG_FILE=tdd_20MHz_ue.log -# start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 100 2350 -# if [ $UE_SYNC -eq 0 ] -# then -# echo "Problem w/ eNB and UE not syncing" -# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC -# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC -# terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR -# echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log -# exit -1 -# fi -# get_ue_ip_addr $VM_CMDS $VM_IP_ADDR -# -# echo "############################################################" -# echo "Pinging the UE" -# echo "############################################################" -# PING_LOG_FILE=tdd_20MHz_ping_ue.txt -# ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE -# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC -# check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 -# -# echo "############################################################" -# echo "Iperf DL" -# echo "############################################################" -# CURR_IPERF_LOG_BASE=tdd_20MHz_iperf_dl -# iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE -# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC -# check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 -# -# echo "############################################################" -# echo "Terminate enb/ue simulators" -# echo "############################################################" -# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC -# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC -# sleep 10 + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]] + then + PING_STATUS=0 + IPERF_STATUS=0 + if [ -d $ARCHIVES_LOC ] + then + rm -Rf $ARCHIVES_LOC + fi + mkdir --parents $ARCHIVES_LOC - echo "############################################################" - echo "Terminate EPC" - echo "############################################################" + # Creating a VM for EPC and installing SW + EPC_VM_NAME=`echo $VM_NAME | sed -e "s#rf-sim#epc#"` + EPC_VM_CMDS=${EPC_VM_NAME}_cmds.txt + LTEBOX=0 + install_epc_on_vm $EPC_VM_NAME $EPC_VM_CMDS + EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME` - terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + # withS1 configuration is not working + #EPC_CONFIGS=("wS1" "noS1") + #TRANS_MODES=("fdd" "tdd") + #BW_CASES=(05 10 20) + EPC_CONFIGS=("noS1") + TRANS_MODES=("fdd") + BW_CASES=(05) + for CN_CONFIG in ${EPC_CONFIGS[@]} + do + if [[ $CN_CONFIG =~ .*wS1.* ]] + then + echo "############################################################" + echo "Start EPC for the wS1 configuration" + echo "############################################################" + start_epc $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR + + # Retrieve EPC real IP address + retrieve_real_epc_ip_addr $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR + S1_NOS1_CFG=1 + else + echo "############################################################" + echo "Terminate EPC" + echo "############################################################" + terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + + echo "############################################################" + echo "Running now in a no-S1 configuration" + echo "############################################################" + S1_NOS1_CFG=0 + fi + for TMODE in ${TRANS_MODES[@]} + do + if [[ $TMODE =~ .*fdd.* ]] + then + CONF_FILE=enb.band7.tm1.50PRB.usrpb210.conf + FREQUENCY=2680 + else + CONF_FILE=enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf + FREQUENCY=2350 + fi + for BW in ${BW_CASES[@]} + do + if [[ $BW =~ .*05.* ]]; then PRB=25; fi + if [[ $BW =~ .*10.* ]]; then PRB=50; fi + if [[ $BW =~ .*20.* ]]; then PRB=100; fi + + echo "############################################################" + echo "${CN_CONFIG} : Starting the eNB in ${TMODE}-${BW}MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_enb.log + start_rf_sim_enb $ENB_VM_CMDS $ENB_VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG + + echo "############################################################" + echo "${CN_CONFIG} : Starting the UE" + echo "############################################################" + CURRENT_UE_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_ue.log + start_rf_sim_ue $UE_VM_CMDS $UE_VM_IP_ADDR $ENB_VM_IP_ADDR $CURRENT_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $ENB_VM_CMDS $ENB_VM_IP_ADDR 1 + terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + if [ $S1_NOS1_CFG -eq 1 ] + then + terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + fi + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + STATUS=-1 + return + fi + + if [ $S1_NOS1_CFG -eq 1 ] + then + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 + + echo "############################################################" + echo "${CN_CONFIG} : Pinging the EPC from UE" + echo "############################################################" + PING_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_ping_epc.log + ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + else + get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR + + echo "############################################################" + echo "${CN_CONFIG} : Pinging the eNB from UE" + echo "############################################################" + PING_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_ping_enb_from_ue.log + ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $ENB_IP_ADDR $PING_LOG_FILE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + fi + + if [ $S1_NOS1_CFG -eq 1 ] + then + echo "############################################################" + echo "${CN_CONFIG} : Pinging the UE from EPC" + echo "############################################################" + PING_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_ping_ue.log + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0 + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + else + echo "############################################################" + echo "${CN_CONFIG} : Pinging the UE from eNB" + echo "############################################################" + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 + PING_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_ping_from_enb_ue.log + ping_enb_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + fi + + if [ $S1_NOS1_CFG -eq 0 ] + then + get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR + echo "############################################################" + echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client" + echo "############################################################" + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_dl + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 + THROUGHPUT=4 + generic_iperf $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $ENB_VM_CMDS $ENB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT + + echo "############################################################" + echo "${CN_CONFIG} : iperf UL -- eNB is server and UE is client" + echo "############################################################" + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${CN_CONFIG}_iperf_ul + THROUGHPUT=2 + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 + generic_iperf $ENB_VM_CMDS $ENB_VM_IP_ADDR $ENB_IP_ADDR $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT + fi + + echo "############################################################" + echo "${CN_CONFIG} : Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $ENB_VM_CMDS $ENB_VM_IP_ADDR 1 + terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + + done + done + done - if [ $KEEP_VM_ALIVE -eq 0 ] - then - echo "############################################################" - echo "Destroying VMs" - echo "############################################################" - uvt-kvm destroy $VM_NAME - ssh-keygen -R $VM_IP_ADDR - uvt-kvm destroy $EPC_VM_NAME - ssh-keygen -R $EPC_VM_IP_ADDR - if [ -e $JENKINS_WKSP/flexran/flexran_build_complete.txt ] - then - uvt-kvm destroy $FLEXRAN_CTL_VM_NAME - ssh-keygen -R $FLEXRAN_CTL_VM_IP_ADDR - fi - fi + full_l2_sim_destroy echo "############################################################" echo "Checking run status" @@ -1208,7 +1651,6 @@ function run_test_on_vm { if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi - if [ $STATUS -eq 0 ] then echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log @@ -1228,80 +1670,298 @@ function run_test_on_vm { mkdir --parents $ARCHIVES_LOC # Building UE elsewhere in VM - build_ue_on_separate_folder $VM_CMDS $VM_IP_ADDR + #build_ue_on_separate_folder $VM_CMDS $VM_IP_ADDR # Creating a VM for EPC and installing SW - EPC_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#l2-epc#"` + EPC_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#epc#"` EPC_VM_CMDS=${EPC_VM_NAME}_cmds.txt LTEBOX=0 install_epc_on_vm $EPC_VM_NAME $EPC_VM_CMDS EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME` - # Starting EPC - start_epc $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR - - # Retrieve EPC real IP address - retrieve_real_epc_ip_addr $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR + # adding 16 users to EPC subscriber lists + add_user_to_epc_lists $EPC_VM_CMDS $EPC_VM_IP_ADDR 16 - echo "############################################################" - echo "Starting the eNB in FDD-5MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=fdd_05MHz_enb.log - start_l2_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 rcc.band7.tm1.nfapi.conf + EPC_CONFIGS=("wS1" "noS1") + TRANS_MODES=("fdd") + BW_CASES=(05) + NB_USERS=(01 04) + for CN_CONFIG in ${EPC_CONFIGS[@]} + do + if [[ $CN_CONFIG =~ .*wS1.* ]] + then + echo "############################################################" + echo "Start EPC for the wS1 configuration" + echo "############################################################" + start_epc $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR + + # Retrieve EPC real IP address + retrieve_real_epc_ip_addr $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR + S1_NOS1_CFG=1 + else + echo "############################################################" + echo "Terminate EPC" + echo "############################################################" + terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + + echo "############################################################" + echo "Running now in a no-S1 configuration" + echo "############################################################" + S1_NOS1_CFG=0 + fi + for TMODE in ${TRANS_MODES[@]} + do + for BW in ${BW_CASES[@]} + do + for UES in ${NB_USERS[@]} + do + INT_NB_UES=`echo $UES | sed -e "s#^0*##"` + echo "############################################################" + echo "${CN_CONFIG} : Adding ${INT_NB_UES} UE(s) to conf file and recompile" + echo "############################################################" + add_ue_l2_sim_ue $UE_VM_CMDS $UE_VM_IP_ADDR $INT_NB_UES + + echo "############################################################" + echo "${CN_CONFIG} : Starting the eNB in ${TMODE}-${BW}MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_enb.log + start_l2_sim_enb $ENB_VM_CMDS $ENB_VM_IP_ADDR $EPC_VM_IP_ADDR $UE_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 rcc.band7.tm1.nfapi.conf $S1_NOS1_CFG + + echo "############################################################" + echo "${CN_CONFIG} : Starting the UE for ${INT_NB_UES} user(s)" + echo "############################################################" + CURRENT_UE_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ue.log + start_l2_sim_ue $UE_VM_CMDS $UE_VM_IP_ADDR $ENB_VM_IP_ADDR $CURRENT_UE_LOG_FILE ue.nfapi.conf $INT_NB_UES $S1_NOS1_CFG + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $ENB_VM_CMDS $ENB_VM_IP_ADDR 1 + terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + if [ $S1_NOS1_CFG -eq 1 ] + then + terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + fi + full_l2_sim_destroy + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + STATUS=-1 + return + fi - echo "############################################################" - echo "Starting the UEs" - echo "############################################################" - CURRENT_UE_LOG_FILE=fdd_05MHz_ue.log - start_l2_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE ue.nfapi.conf - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 - fi + if [ $S1_NOS1_CFG -eq 1 ] + then + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR 1 + + echo "############################################################" + echo "${CN_CONFIG} : Pinging the EPC from UE(s)" + echo "############################################################" + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_epc.log + ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE 1 0 + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + else + get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR + + echo "############################################################" + echo "${CN_CONFIG} : Pinging the eNB from UE(s)" + echo "############################################################" + echo " --- Sequentially ---" + local j="1" + while [ $j -le $INT_NB_UES ] + do + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_enb_seq_from_ue${j}.log + ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $ENB_IP_ADDR $PING_LOG_FILE ${j} 0 + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + j=$[$j+1] + done + if [ $INT_NB_UES -gt 1 ] + then + echo " --- In parallel ---" + j="1" + while [ $j -le $INT_NB_UES ] + do + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_enb_para_from_ue${j}.log + ping_epc_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $ENB_IP_ADDR $PING_LOG_FILE ${j} 1 + j=$[$j+1] + done + sleep 25 + j="1" + while [ $j -le $INT_NB_UES ] + do + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_enb_para_from_ue${j}.log + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + tail -3 $ARCHIVES_LOC/$PING_LOG_FILE + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + j=$[$j+1] + done + fi + fi - echo "############################################################" - echo "Pinging the EPC from UE" - echo "############################################################" - PING_LOG_FILE=fdd_05MHz_ping_epc.txt - ping_epc_ip_addr $VM_CMDS $VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + if [ $S1_NOS1_CFG -eq 1 ] + then + echo "############################################################" + echo "${CN_CONFIG} : Pinging the UE(s) from EPC" + echo "############################################################" + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_ue.log + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0 + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + else + echo "############################################################" + echo "${CN_CONFIG} : Pinging the UE(s) from eNB" + echo "############################################################" + echo " --- Sequentially ---" + local j="1" + while [ $j -le $INT_NB_UES ] + do + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $j + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_from_enb_seq_ue${j}.log + ping_enb_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + j=$[$j+1] + done + if [ $INT_NB_UES -gt 1 ] + then + echo " --- In parallel ---" + j="1" + while [ $j -le $INT_NB_UES ] + do + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $j + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_from_enb_para_ue${j}.log + ping_enb_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 1 + j=$[$j+1] + done + sleep 25 + j="1" + while [ $j -le $INT_NB_UES ] + do + PING_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping_from_enb_para_ue${j}.log + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + tail -3 $ARCHIVES_LOC/$PING_LOG_FILE + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + j=$[$j+1] + done + fi + fi - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + if [ $S1_NOS1_CFG -eq 0 ] + then + get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR + echo "############################################################" + echo "${CN_CONFIG} : iperf DL -- UE is server and eNB is client" + echo "############################################################" + echo " --- Sequentially ---" + local j="1" + while [ $j -le $INT_NB_UES ] + do + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_dl_seq_ue${j} + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $j + THROUGHPUT=3 + generic_iperf $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $ENB_VM_CMDS $ENB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE $j 0 + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT + j=$[$j+1] + done + if [ $INT_NB_UES -gt 1 ] + then + echo " --- In parallel ---" + j="1" + while [ $j -le $INT_NB_UES ] + do + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_dl_para_ue${j} + THROUGHPUT=1 + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $j + generic_iperf $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $ENB_VM_CMDS $ENB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE $j 1 + j=$[$j+1] + done + sleep 35 + echo "killall --signal SIGKILL iperf" + echo "killall --signal SIGKILL iperf" > $UE_VM_CMDS + ssh -T -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR < $UE_VM_CMDS + rm $UE_VM_CMDS + j="1" + while [ $j -le $INT_NB_UES ] + do + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_dl_para_ue${j} + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC + tail -3 $ARCHIVES_LOC/${IPERF_LOG_FILE}_client.txt | grep -v datagram + #check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT + j=$[$j+1] + done + fi + + echo "############################################################" + echo "${CN_CONFIG} : iperf UL -- eNB is server and UE is client" + echo "############################################################" + echo " --- Sequentially ---" + local j="1" + while [ $j -le $INT_NB_UES ] + do + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_ul_seq_ue${j} + THROUGHPUT=2 + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $j + generic_iperf $ENB_VM_CMDS $ENB_VM_IP_ADDR $ENB_IP_ADDR $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE $j 0 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT + j=$[$j+1] + done + if [ $INT_NB_UES -gt 1 ] + then + echo " --- In parallel ---" + j="1" + while [ $j -le $INT_NB_UES ] + do + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_ul_para_ue${j} + THROUGHPUT=1 + get_ue_ip_addr $UE_VM_CMDS $UE_VM_IP_ADDR $j + generic_iperf $ENB_VM_CMDS $ENB_VM_IP_ADDR $ENB_IP_ADDR $UE_VM_CMDS $UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $IPERF_LOG_FILE $j 1 + j=$[$j+1] + done + sleep 35 + echo "killall --signal SIGKILL iperf" + echo "killall --signal SIGKILL iperf" > $UE_VM_CMDS + ssh -T -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR < $UE_VM_CMDS + rm $UE_VM_CMDS + j="1" + while [ $j -le $INT_NB_UES ] + do + IPERF_LOG_FILE=${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_ul_para_ue${j} + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/${IPERF_LOG_FILE}_client.txt $ARCHIVES_LOC + tail -3 $ARCHIVES_LOC/${IPERF_LOG_FILE}_client.txt | grep -v datagram + #check_iperf $ARCHIVES_LOC/$IPERF_LOG_FILE $THROUGHPUT + j=$[$j+1] + done + fi + fi - echo "############################################################" - echo "Terminate EPC" - echo "############################################################" + echo "############################################################" + echo "${CN_CONFIG} : Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $ENB_VM_CMDS $ENB_VM_IP_ADDR 1 + terminate_enb_ue_basic_sim $UE_VM_CMDS $UE_VM_IP_ADDR 2 + scp -o StrictHostKeyChecking=no ubuntu@$ENB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + done + done + done + done - if [ $KEEP_VM_ALIVE -eq 0 ] - then - echo "############################################################" - echo "Destroying VMs" - echo "############################################################" - uvt-kvm destroy $VM_NAME - ssh-keygen -R $VM_IP_ADDR - uvt-kvm destroy $EPC_VM_NAME - ssh-keygen -R $EPC_VM_IP_ADDR - fi + full_l2_sim_destroy echo "############################################################" echo "Checking run status" echo "############################################################" if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi if [ $STATUS -eq 0 ] then echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index 2820b88647c907a58c223d82a865d8b476c57b0b..6bf20a7f4d209fbd42701e755684f1b32b7a0033 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -98,7 +98,7 @@ function wait_on_vm_build { echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS fi - ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS + ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS rm -f $VM_CMDS } @@ -124,11 +124,16 @@ function check_on_vm_build { if [ $KEEP_VM_ALIVE -eq 0 ] then + if [[ "$VM_NAME" == *"-enb-ethernet"* ]] || [[ "$VM_NAME" == *"-ue-ethernet"* ]] + then + echo "Hack to not destroy in current pipeline" + else echo "############################################################" echo "Destroying VM" echo "############################################################" uvt-kvm destroy $VM_NAME ssh-keygen -R $VM_IP_ADDR + fi fi rm -f $VM_CMDS @@ -185,10 +190,16 @@ function check_on_vm_build { fi fi + if [[ "$VM_NAME" == *"-cppcheck"* ]] + then + echo "COMMAND: cppcheck $BUILD_OPTIONS . 2> cppcheck.xml" > $ARCHIVES_LOC/build_final_status.log + else + echo "COMMAND: build_oai -I $BUILD_OPTIONS" > $ARCHIVES_LOC/build_final_status.log + fi if [[ $STATUS -eq 0 ]] then - echo "BUILD_OK" > $ARCHIVES_LOC/build_final_status.log + echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log else - echo "BUILD_KO" > $ARCHIVES_LOC/build_final_status.log + echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log fi } diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_closure.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_closure.xml new file mode 100644 index 0000000000000000000000000000000000000000..8587db959dde6db2d6485cc388bc3026643ee36f --- /dev/null +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_closure.xml @@ -0,0 +1,48 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>epc-closure</htmlTabRef> + <htmlTabName>EPC-Closure</htmlTabName> + <htmlTabIcon>log-out</htmlTabIcon> + <TestCaseRequestedList> + 050201 060201 070201 + </TestCaseRequestedList> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="050201"> + <class>Terminate_HSS</class> + <desc>Terminate HSS</desc> + </testCase> + + <testCase id="060201"> + <class>Terminate_MME</class> + <desc>Terminate MME</desc> + </testCase> + + <testCase id="070201"> + <class>Terminate_SPGW</class> + <desc>Terminate SPGW</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml new file mode 100644 index 0000000000000000000000000000000000000000..e22c5b4da2653b0f9517c36a06ba8470e53f7f7d --- /dev/null +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_epc_start.xml @@ -0,0 +1,47 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>epc-start</htmlTabRef> + <htmlTabName>EPC-Start</htmlTabName> + <htmlTabIcon>log-in</htmlTabIcon> + <TestCaseRequestedList> + 050101 060101 070101 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="050101"> + <class>Initialize_HSS</class> + <desc>Initialize HSS</desc> + </testCase> + + <testCase id="060101"> + <class>Initialize_MME</class> + <desc>Initialize MME</desc> + </testCase> + + <testCase id="070101"> + <class>Initialize_SPGW</class> + <desc>Initialize SPGW</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml new file mode 100644 index 0000000000000000000000000000000000000000..cded08284a7f53e012ad7216e8065c0da25e01c3 --- /dev/null +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1.xml @@ -0,0 +1,117 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>test-05-tm1-nos1-tunnel</htmlTabRef> + <htmlTabName>Test-05MHz-TM1-noS1-tunnel</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <TestCaseRequestedList> + 030201 090109 + 030101 000001 090101 000002 040501 040502 000001 040601 040641 040642 000001 090109 030201 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="000001"> + <class>IdleSleep</class> + <desc>Sleep</desc> + <idle_sleep_time_in_sec>10</idle_sleep_time_in_sec> + </testCase> + + <testCase id="000002"> + <class>IdleSleep</class> + <desc>Sleep</desc> + <idle_sleep_time_in_sec>5</idle_sleep_time_in_sec> + </testCase> + + <testCase id="000003"> + <class>IdleSleep</class> + <desc>Sleep</desc> + <idle_sleep_time_in_sec>60</idle_sleep_time_in_sec> + </testCase> + + <testCase id="030101"> + <class>Initialize_eNB</class> + <desc>Initialize eNB (FDD/Band7/5MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --noS1</Initialize_eNB_args> + </testCase> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate eNB</desc> + </testCase> + + <testCase id="090101"> + <class>Initialize_OAI_UE</class> + <desc>Initialize OAI UE (FDD/Band7/5MHz)</desc> + <Initialize_OAI_UE_args>-C 2680000000 -r 25 --ue-rxgain 120 --ue-txgain 0 --ue-max-power 0 --ue-scan-carrier --nokrnmod 1 --noS1</Initialize_OAI_UE_args> + </testCase> + + <testCase id="090109"> + <class>Terminate_OAI_UE</class> + <desc>Terminate OAI UE</desc> + </testCase> + + <testCase id="040501"> + <class>Ping</class> + <desc>ping (5MHz - 20 sec)(from eNB to OAI UE)</desc> + <ping_args>-I oaitun_enb1 -c 20 10.0.1.2</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040502"> + <class>Ping</class> + <desc>ping (5MHz - 20 sec)(from OAI UE to eNB)</desc> + <ping_args>-I oaitun_ue1 -c 20 10.0.1.1</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040601"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/1Mbps/UDP)(30 sec)</desc> + <iperf_args>-c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + </testCase> + + <testCase id="040602"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/1.2Mbps/UDP)(30 sec)</desc> + <iperf_args>-c 10.0.1.2 -u -b 1.2M -t 30 -i 1 -fm -B 10.0.1.1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + </testCase> + + <testCase id="040641"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/1Mbps/UDP)(30 sec)</desc> + <iperf_args>-c 10.0.1.1 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.2 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + + <testCase id="040642"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/8Mbps/UDP)(30 sec)</desc> + <iperf_args>-c 10.0.1.1 -u -b 8M -t 30 -i 1 -fm -B 10.0.1.2 -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml new file mode 100644 index 0000000000000000000000000000000000000000..15735d94db39cb8df794c356ae18ed422d97ee2d --- /dev/null +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_test_05mhz_tm1_s1.xml @@ -0,0 +1,104 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>test-05-tm1-tunnel</htmlTabRef> + <htmlTabName>Test-05MHz-TM1-tunnel</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <TestCaseRequestedList> + 030201 090109 + 030102 000001 090102 000002 040503 000001 040603 040643 040644 000001 090109 030201 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="000001"> + <class>IdleSleep</class> + <desc>Sleep</desc> + <idle_sleep_time_in_sec>10</idle_sleep_time_in_sec> + </testCase> + + <testCase id="000002"> + <class>IdleSleep</class> + <desc>Sleep</desc> + <idle_sleep_time_in_sec>5</idle_sleep_time_in_sec> + </testCase> + + <testCase id="030102"> + <class>Initialize_eNB</class> + <desc>Initialize eNB (FDD/Band7/5MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf</Initialize_eNB_args> + </testCase> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate eNB</desc> + </testCase> + + <testCase id="090102"> + <class>Initialize_OAI_UE</class> + <desc>Initialize OAI UE (FDD/Band7/5MHz)</desc> + <Initialize_OAI_UE_args>-C 2680000000 -r 25 --ue-rxgain 120 --ue-txgain 0 --ue-max-power 0 --ue-scan-carrier --nokrnmod 1</Initialize_OAI_UE_args> + </testCase> + + <testCase id="090109"> + <class>Terminate_OAI_UE</class> + <desc>Terminate OAI UE</desc> + </testCase> + + <testCase id="040503"> + <class>Ping</class> + <desc>ping (5MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040603"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/1Mbps/UDP)(30 sec)</desc> + <iperf_args>-u -b 1M -t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + </testCase> + + <testCase id="040604"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/1.2Mbps/UDP)(30 sec)</desc> + <iperf_args>-b 1.2M -t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + </testCase> + + <testCase id="040643"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/1Mbps/UDP)(30 sec)</desc> + <iperf_args>-u -b 1M -t 30 -i 1 -fm -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + + <testCase id="040644"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/8Mbps/UDP)(30 sec)</desc> + <iperf_args>-u -b 8M -t 30 -i 1 -fm -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>balanced</iperf_profile> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/enb_usrp210_band13_build.xml b/ci-scripts/xml_files/enb_usrp210_band13_build.xml new file mode 100644 index 0000000000000000000000000000000000000000..24283a52d0b38508ab7c148e664c1fb26b7020bb --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band13_build.xml @@ -0,0 +1,55 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>build-tab</htmlTabRef> + <htmlTabName>Build</htmlTabName> + <htmlTabIcon>wrench</htmlTabIcon> + <TestCaseRequestedList> + 010101 + 050101 060101 070101 + </TestCaseRequestedList> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="010101"> + <class>Build_eNB</class> + <desc>Build eNB (USRP)</desc> + <Build_eNB_args>-w USRP -c --eNB</Build_eNB_args> + </testCase> + + <testCase id="050101"> + <class>Initialize_HSS</class> + <desc>Initialize HSS</desc> + </testCase> + + <testCase id="060101"> + <class>Initialize_MME</class> + <desc>Initialize MME</desc> + </testCase> + + <testCase id="070101"> + <class>Initialize_SPGW</class> + <desc>Initialize SPGW</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml b/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml new file mode 100644 index 0000000000000000000000000000000000000000..07fb6951f8e99a35cabd2ee4e48232d2bd035f41 --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band13_epc_closure.xml @@ -0,0 +1,47 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>epc-closure</htmlTabRef> + <htmlTabName>EPC-Closure</htmlTabName> + <htmlTabIcon>log-out</htmlTabIcon> + <TestCaseRequestedList> + 050201 060201 070201 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="050201"> + <class>Terminate_HSS</class> + <desc>Terminate HSS</desc> + </testCase> + + <testCase id="060201"> + <class>Terminate_MME</class> + <desc>Terminate MME</desc> + </testCase> + + <testCase id="070201"> + <class>Terminate_SPGW</class> + <desc>Terminate SPGW</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml new file mode 100644 index 0000000000000000000000000000000000000000..5425428bc2691da4fc01f58bb463177269a4c117 --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml @@ -0,0 +1,79 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>test-10-tm1</htmlTabRef> + <htmlTabName>Test-10MHz-TM1</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <TestCaseRequestedList> + 030201 + 040102 + 030121 000001 040302 000001 040502 000001 040402 040202 000001 030201 + </TestCaseRequestedList> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="000001"> + <class>IdleSleep</class> + <desc>Waiting for a moment...</desc> + <idle_sleep_time_in_sec>15</idle_sleep_time_in_sec> + </testCase> + + <testCase id="030121"> + <class>Initialize_eNB</class> + <desc>Initialize eNB (FDD/Band13/10MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf</Initialize_eNB_args> + </testCase> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate eNB</desc> + </testCase> + + <testCase id="040102"> + <class>Initialize_CatM_module</class> + <desc>Initialize CAT-M Module</desc> + </testCase> + + <testCase id="040202"> + <class>Terminate_CatM_module</class> + <desc>Terminate CAT-M Module</desc> + </testCase> + + <testCase id="040302"> + <class>Attach_CatM_module</class> + <desc>Attach CAT-M Module</desc> + </testCase> + + <testCase id="040402"> + <class>Detach_CatM_module</class> + <desc>Detach CAT-M Module</desc> + </testCase> + + <testCase id="040502"> + <class>Ping_CatM_module</class> + <desc>ping (10MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml index d5a25c7fa7367f1791cf6657d4dfe6df2ca579aa..7fa7814238613cce645420bd43d22fc4a022e00b 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml @@ -25,8 +25,9 @@ <htmlTabName>Test-05MHz-TM1</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 - 030104 040301 040501 040602 040601 040603 040642 040641 040643 040401 040201 030201 + 030104 040301 040501 040602 040601 040603 040604 040605 040642 040641 040643 040644 040645 040401 040201 030201 </TestCaseRequestedList> <TestCaseExclusionList></TestCaseExclusionList> @@ -92,6 +93,21 @@ <iperf_profile>unbalanced</iperf_profile> </testCase> + <testCase id="040604"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/TCP)(30 sec)(single-ue profile)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040605"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/TCP)(30 sec)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + </testCase> + <testCase id="040641"> <class>Iperf</class> <desc>iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc> @@ -116,4 +132,19 @@ <iperf_profile>unbalanced</iperf_profile> </testCase> + <testCase id="040644"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/TCP)(30 sec)(single-ue)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040645"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/TCP)(30 sec)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + </testCase> + </testCaseList> diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml index ef50933d4a1205e7cc0145073ad747b4d39333ca..7c1b4dc85c4827cdc87ab9242be5ab7d20adda17 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml @@ -25,8 +25,9 @@ <htmlTabName>Test-10MHz-TM1</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 - 030114 040301 040511 040612 040611 040613 040652 040651 040653 040401 040201 030201 + 030114 040301 040511 040612 040611 040613 040614 040615 040652 040651 040653 040654 040655 040401 040201 030201 </TestCaseRequestedList> <TestCaseExclusionList></TestCaseExclusionList> @@ -92,6 +93,21 @@ <iperf_profile>unbalanced</iperf_profile> </testCase> + <testCase id="040614"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/TCP)(30 sec)(single-ue)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040615"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/TCP)(30 sec)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + </testCase> + <testCase id="040651"> <class>Iperf</class> <desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc> @@ -116,4 +132,19 @@ <iperf_profile>unbalanced</iperf_profile> </testCase> + <testCase id="040654"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/TCP)(30 sec)(single-ue)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040655"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/TCP)(30 sec)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + </testCase> + </testCaseList> diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml index 9a96baac3fd87602bff9f77085df0b3c69628b75..bcbf742ef792af47f4a903308166e9aa9be7b6e2 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml @@ -25,8 +25,9 @@ <htmlTabName>Test-20MHz-TM1</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 - 030124 040301 040521 040622 040621 040623 040662 040661 040663 040401 040201 030201 + 030124 040301 040521 040622 040621 040623 040624 040625 040662 040661 040663 040664 040665 040401 040201 030201 </TestCaseRequestedList> <TestCaseExclusionList></TestCaseExclusionList> @@ -92,6 +93,21 @@ <iperf_profile>unbalanced</iperf_profile> </testCase> + <testCase id="040624"> + <class>Iperf</class> + <desc>iperf (20MHz - DL/TCP)(30 sec)(single-ue)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040625"> + <class>Iperf</class> + <desc>iperf (20MHz - DL/TCP)(30 sec)</desc> + <iperf_args>-t 30 -i 1 -fm</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + </testCase> + <testCase id="040661"> <class>Iperf</class> <desc>iperf (20MHz - UL/2Mbps/UDP)(30 sec)(balanced)</desc> @@ -116,4 +132,19 @@ <iperf_profile>unbalanced</iperf_profile> </testCase> + <testCase id="040664"> + <class>Iperf</class> + <desc>iperf (20MHz - UL/TCP)(30 sec)(single-ue)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040665"> + <class>Iperf</class> + <desc>iperf (20MHz - UL/TCP)(30 sec)</desc> + <iperf_args>-t 30 -i 1 -fm -R</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + </testCase> + </testCaseList> diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml index 0057eaefa408c3e599f122a4f7c0b42b0c186c17..edc87c90ff5f5a49e63c4e85c36716337529e5dc 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml @@ -25,6 +25,7 @@ <htmlTabName>Test-05MHz-TM1</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201 </TestCaseRequestedList> diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml index 92ec1efa6e805312892ddccb8c18d9f814cd4d6c..ccbe71cd141d2a724ca9d6106d61caa9ef70f8ec 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml @@ -25,6 +25,7 @@ <htmlTabName>Test-10MHz-TM1</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 030111 040301 040511 040613 040614 040615 040616 040617 040651 040652 040653 040654 040401 040201 030201 </TestCaseRequestedList> diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml index b6c441b19aeac33f6d1710b610b62277ed3d2ff6..03263bb86f8028016596be39b5da179f202cdac5 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml @@ -25,6 +25,7 @@ <htmlTabName>Test-20MHz-TM1</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 030121 040301 040521 040623 040624 040625 040662 040401 040201 030201 </TestCaseRequestedList> diff --git a/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml b/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml new file mode 100644 index 0000000000000000000000000000000000000000..fdf795fb300233f0d5d75a519e533d996dd97e0e --- /dev/null +++ b/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml @@ -0,0 +1,104 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>test-f1-05</htmlTabRef> + <htmlTabName>Test-F1-CU/DU-05MHz</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <TestCaseRequestedList> + 030201 + 040101 + 030142 030141 040301 040541 040601 040641 040401 040201 030201 030202 + </TestCaseRequestedList> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="030141"> + <class>Initialize_eNB</class> + <desc>Initialize DU (FDD/Band7/5MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf</Initialize_eNB_args> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="030142"> + <class>Initialize_eNB</class> + <desc>Initialize CU (FDD/Band7/5MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/cu.band7.tm1.25PRB.conf</Initialize_eNB_args> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate CU</desc> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030202"> + <class>Terminate_eNB</class> + <desc>Terminate DU</desc> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="040101"> + <class>Initialize_UE</class> + <desc>Initialize UE</desc> + </testCase> + + <testCase id="040201"> + <class>Terminate_UE</class> + <desc>Terminate UE</desc> + </testCase> + + <testCase id="040301"> + <class>Attach_UE</class> + <desc>Attach UE</desc> + </testCase> + + <testCase id="040401"> + <class>Detach_UE</class> + <desc>Detach UE</desc> + </testCase> + + <testCase id="040541"> + <class>Ping</class> + <desc>ping (5MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040601"> + <class>Iperf</class> + <desc>iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 15M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040641"> + <class>Iperf</class> + <desc>iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 9M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>60</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/f1_usrp210_band7_test_10mhz.xml b/ci-scripts/xml_files/f1_usrp210_band7_test_10mhz.xml new file mode 100644 index 0000000000000000000000000000000000000000..3592759fc623052b6bc398216a81c341053e883f --- /dev/null +++ b/ci-scripts/xml_files/f1_usrp210_band7_test_10mhz.xml @@ -0,0 +1,104 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>test-f1-10</htmlTabRef> + <htmlTabName>Test-F1-CU/DU-10MHz</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <TestCaseRequestedList> + 030201 + 040101 + 030152 030151 040301 040551 040611 040651 040401 040201 030201 030202 + </TestCaseRequestedList> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="030151"> + <class>Initialize_eNB</class> + <desc>Initialize DU (FDD/Band7/10MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf</Initialize_eNB_args> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="030152"> + <class>Initialize_eNB</class> + <desc>Initialize CU (FDD/Band7/10MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/cu.band7.tm1.50PRB.conf</Initialize_eNB_args> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate CU</desc> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030202"> + <class>Terminate_eNB</class> + <desc>Terminate DU</desc> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="040101"> + <class>Initialize_UE</class> + <desc>Initialize UE</desc> + </testCase> + + <testCase id="040201"> + <class>Terminate_UE</class> + <desc>Terminate UE</desc> + </testCase> + + <testCase id="040301"> + <class>Attach_UE</class> + <desc>Attach UE</desc> + </testCase> + + <testCase id="040401"> + <class>Detach_UE</class> + <desc>Detach UE</desc> + </testCase> + + <testCase id="040551"> + <class>Ping</class> + <desc>ping (10MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040611"> + <class>Iperf</class> + <desc>iperf (10MHz - DL/32Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 32M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040651"> + <class>Iperf</class> + <desc>iperf (10MHz - UL/15Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 15M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>60</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/f1_usrp210_band7_test_20mhz.xml b/ci-scripts/xml_files/f1_usrp210_band7_test_20mhz.xml new file mode 100644 index 0000000000000000000000000000000000000000..f2cb155127072dcf1e516cbd142ac0ce9007049f --- /dev/null +++ b/ci-scripts/xml_files/f1_usrp210_band7_test_20mhz.xml @@ -0,0 +1,104 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>test-f1-20</htmlTabRef> + <htmlTabName>Test-F1-CU/DU-20MHz</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <TestCaseRequestedList> + 030201 + 040101 + 030162 030161 040301 040561 040621 040661 040401 040201 030201 030202 + </TestCaseRequestedList> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="030161"> + <class>Initialize_eNB</class> + <desc>Initialize DU (FDD/Band7/20MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf</Initialize_eNB_args> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="030162"> + <class>Initialize_eNB</class> + <desc>Initialize CU (FDD/Band7/20MHz)</desc> + <Initialize_eNB_args>-O ci-scripts/conf_files/cu.band7.tm1.100PRB.conf</Initialize_eNB_args> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030201"> + <class>Terminate_eNB</class> + <desc>Terminate CU</desc> + <eNB_instance>0</eNB_instance> + </testCase> + + <testCase id="030202"> + <class>Terminate_eNB</class> + <desc>Terminate DU</desc> + <eNB_instance>1</eNB_instance> + </testCase> + + <testCase id="040101"> + <class>Initialize_UE</class> + <desc>Initialize UE</desc> + </testCase> + + <testCase id="040201"> + <class>Terminate_UE</class> + <desc>Terminate UE</desc> + </testCase> + + <testCase id="040301"> + <class>Attach_UE</class> + <desc>Attach UE</desc> + </testCase> + + <testCase id="040401"> + <class>Detach_UE</class> + <desc>Detach UE</desc> + </testCase> + + <testCase id="040561"> + <class>Ping</class> + <desc>ping (20MHz - 20 sec)</desc> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>5</ping_packetloss_threshold> + </testCase> + + <testCase id="040621"> + <class>Iperf</class> + <desc>iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 70M -t 30 -i 1</iperf_args> + <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="040661"> + <class>Iperf</class> + <desc>iperf (20MHz - UL/15Mbps/UDP)(30 sec)(single-ue profile)</desc> + <iperf_args>-u -b 15M -t 30 -i 1 -R</iperf_args> + <iperf_packetloss_threshold>60</iperf_packetloss_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml index 1de23d05d661942c1dd40c19be15cafd4d01a603..daa5c6fa431b169a8e0cf2fa26ed0b2152f6a0b1 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml @@ -25,6 +25,7 @@ <htmlTabName>Test-05MHz</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 030104 030105 040301 040501 040602 040642 040401 040201 030201 030202 </TestCaseRequestedList> @@ -34,7 +35,7 @@ <testCase id="030104"> <class>Initialize_eNB</class> <desc>Initialize RRU (TDD/Band40)</desc> - <Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf</Initialize_eNB_args> + <Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf --RUs.[0].max_rxgain 125</Initialize_eNB_args> <eNB_instance>0</eNB_instance> </testCase> diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml index 6bc37db17a1f1e7d0540bdb8454a9e0aed8dc770..2638814cf694642f9cf4abc11e7aecdca60178f6 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml @@ -25,6 +25,7 @@ <htmlTabName>Test-10MHz</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 030114 030115 040301 040511 040612 040652 040401 040201 030201 030202 </TestCaseRequestedList> @@ -34,7 +35,7 @@ <testCase id="030114"> <class>Initialize_eNB</class> <desc>Initialize RRU (TDD/Band40)</desc> - <Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf</Initialize_eNB_args> + <Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf --RUs.[0].max_rxgain 120</Initialize_eNB_args> <eNB_instance>0</eNB_instance> </testCase> @@ -96,7 +97,7 @@ <class>Iperf</class> <desc>iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue)</desc> <iperf_args>-u -b 2M -t 30 -i 1 -R</iperf_args> - <iperf_packetloss_threshold>50</iperf_packetloss_threshold> + <iperf_packetloss_threshold>60</iperf_packetloss_threshold> <iperf_profile>single-ue</iperf_profile> </testCase> diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml index 512c958105cd9da45c3e081c41bfadce25d3d183..a2356891f1d7be0460b73bffc4c1161fffea9edb 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml @@ -25,6 +25,7 @@ <htmlTabName>Test-20MHz</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 030124 030125 040301 040521 040622 040662 040401 040201 030201 030202 </TestCaseRequestedList> @@ -37,7 +38,7 @@ <Initialize_eNB_args>-O ci-scripts/conf_files/rru.tdd.band40.conf</Initialize_eNB_args> <eNB_instance>0</eNB_instance> </testCase> - + <testCase id="030125"> <class>Initialize_eNB</class> <desc>Initialize RCC (TDD/Band40/20MHz/info)</desc> diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml index b0501e9875fea9822335db9a0e8d07a01dda97ba..1464a4a624438854f2b81f905bcc9c97b33528db 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml @@ -21,10 +21,11 @@ --> <testCaseList> - <htmlTabRef>test-05</htmlTabRef> - <htmlTabName>Test-05MHz</htmlTabName> + <htmlTabRef>test-if4p5-05</htmlTabRef> + <htmlTabName>Test-IF4.5-05MHz</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 030101 030102 040301 040501 040604 040642 040401 040201 030201 030202 </TestCaseRequestedList> @@ -34,7 +35,7 @@ <testCase id="030101"> <class>Initialize_eNB</class> <desc>Initialize RRU (FDD/Band7)</desc> - <Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf</Initialize_eNB_args> + <Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf --RUs.[0].max_rxgain 125</Initialize_eNB_args> <eNB_instance>1</eNB_instance> </testCase> diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml index 88fb30b840caaf8f5fe686b19b59b6d55e045227..1649e91b3e9e30a59feb250dc5f6025f31e0e5b8 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml @@ -21,10 +21,11 @@ --> <testCaseList> - <htmlTabRef>test-10</htmlTabRef> - <htmlTabName>Test-10MHz</htmlTabName> + <htmlTabRef>test-if4p5-10</htmlTabRef> + <htmlTabName>Test-IF4.5-10MHz</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 030111 030112 040301 040511 040614 040652 040401 040201 030201 030202 </TestCaseRequestedList> @@ -34,7 +35,7 @@ <testCase id="030111"> <class>Initialize_eNB</class> <desc>Initialize RRU (FDD/Band7)</desc> - <Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf</Initialize_eNB_args> + <Initialize_eNB_args>-O ci-scripts/conf_files/rru.fdd.band7.conf --RUs.[0].max_rxgain 120</Initialize_eNB_args> <eNB_instance>1</eNB_instance> </testCase> diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml index 798fc1bc8f6fa301e84f155e1656cd6f31cbf4e2..d98fce2e83806872b97dc87d9b403956b4e350d1 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml @@ -21,10 +21,11 @@ --> <testCaseList> - <htmlTabRef>test-20</htmlTabRef> - <htmlTabName>Test-20MHz</htmlTabName> + <htmlTabRef>test-if4p5-20</htmlTabRef> + <htmlTabName>Test-IF4.5-20MHz</htmlTabName> <htmlTabIcon>tasks</htmlTabIcon> <TestCaseRequestedList> + 030201 040101 030121 030122 040301 040521 040624 040662 040401 040201 030201 030202 </TestCaseRequestedList> diff --git a/ci-scripts/xml_files/ue_band20_build.xml b/ci-scripts/xml_files/ue_band20_build.xml new file mode 100644 index 0000000000000000000000000000000000000000..9ca1a2b2346509748444db85a4792054015cf246 --- /dev/null +++ b/ci-scripts/xml_files/ue_band20_build.xml @@ -0,0 +1,38 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>build-tab</htmlTabRef> + <htmlTabName>Build</htmlTabName> + <htmlTabIcon>wrench</htmlTabIcon> + <TestCaseRequestedList> +090101 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="090101"> + <class>Build_OAI_UE</class> + <desc>Build OAI UE</desc> + <Build_OAI_UE_args>-w USRP --UE</Build_OAI_UE_args> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/ue_band20_test_10mhz_orange.xml b/ci-scripts/xml_files/ue_band20_test_10mhz_orange.xml new file mode 100644 index 0000000000000000000000000000000000000000..594ea7b923c339016e750767f1d35f8a1807eaab --- /dev/null +++ b/ci-scripts/xml_files/ue_band20_test_10mhz_orange.xml @@ -0,0 +1,50 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>test-10mhz-orange</htmlTabRef> + <htmlTabName>Test-10Mhz-Orange</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <TestCaseRequestedList> + 090109 + 090110 000001 090109 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="090110"> + <class>Initialize_OAI_UE</class> + <desc>Initialize OAI UE -- sniffing Orange frequency</desc> + <Initialize_OAI_UE_args>-C 816000000 -r 50 --ue-rxgain 135 --ue-scan-carrier --no-L2-connect --nokrnmod 1</Initialize_OAI_UE_args> + </testCase> + + <testCase id="000001"> + <class>IdleSleep</class> + <desc>Sleep</desc> + <idle_sleep_time_in_sec>30</idle_sleep_time_in_sec> + </testCase> + + <testCase id="090109"> + <class>Terminate_OAI_UE</class> + <desc>Terminate OAI UE</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/ue_band20_test_10mhz_sfr.xml b/ci-scripts/xml_files/ue_band20_test_10mhz_sfr.xml new file mode 100644 index 0000000000000000000000000000000000000000..89370be9839370a98e915131bd200b9cf05d6c2c --- /dev/null +++ b/ci-scripts/xml_files/ue_band20_test_10mhz_sfr.xml @@ -0,0 +1,50 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (the "License"); you may not use this file + except in compliance with the License. + You may obtain a copy of the License at + + http://www.openairinterface.org/?page_id=698 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>test-10mHz-sfr</htmlTabRef> + <htmlTabName>Test-10MHz-SFR</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <TestCaseRequestedList> + 090109 + 090111 000001 090109 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="090111"> + <class>Initialize_OAI_UE</class> + <desc>Initialize OAI UE -- sniffing SFR frequency</desc> + <Initialize_OAI_UE_args>-C 806000000 -r 50 --ue-rxgain 130 --ue-scan-carrier --no-L2-connect --nokrnmod 1</Initialize_OAI_UE_args> + </testCase> + + <testCase id="000001"> + <class>IdleSleep</class> + <desc>Sleep</desc> + <idle_sleep_time_in_sec>30</idle_sleep_time_in_sec> + </testCase> + + <testCase id="090109"> + <class>Terminate_OAI_UE</class> + <desc>Terminate OAI UE</desc> + </testCase> + +</testCaseList> diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index ecb9b314f25f4918490333fe0dffe690f97011be..7ff9e112977cef6aec473dd9454c4c5f43722611 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -21,7 +21,7 @@ # Author: laurent THOMAS, Lionel GAUTHIER -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.0) ############################################# # Base directories, compatible with legacy OAI building @@ -169,13 +169,13 @@ endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC ") # add autotools definitions that were maybe used! +set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'") set(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'" + "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER}" ) set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'" + "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D${MKVER}" ) -add_definitions("-DASN_DISABLE_OER_SUPPORT") ######################### @@ -227,7 +227,6 @@ add_definitions("-DPACKAGE_VERSION=\"Branch: ${GIT_BRANCH} Abrev. Hash: ${GIT_CO add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"") - # Debug related options ######################################### add_boolean_option(ASN_DEBUG False "ASN1 coder/decoder Debug") @@ -250,7 +249,7 @@ add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace") add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace") add_boolean_option(DISABLE_LOG_X False "Deactivate all LOG_* macros") add_boolean_option(USRP_REC_PLAY False "Enable USRP record playback mode") -add_boolean_option(UE_NAS_USE_TUN False "Enable UE NAS TUN device instead of ue_ip.ko") +#add_boolean_option(UE_NAS_USE_TUN False "Enable UE NAS TUN device instead of ue_ip.ko") add_boolean_option(BASIC_SIMULATOR False "Has to be True when building the basic simulator, False otherwise") add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering") @@ -382,7 +381,7 @@ file(GLOB S1AP_source ${S1AP_C_DIR}/*.c) add_custom_target ( s1ap_flag ALL ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" "S1AP_" -fno-include-deps - DEPENDS "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" + DEPENDS "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" ) add_library(S1AP_LIB @@ -469,15 +468,62 @@ add_library(X2AP_ENB ${X2AP_DIR}/x2ap_eNB_itti_messaging.c ${X2AP_DIR}/x2ap_eNB_management_procedures.c ${X2AP_DIR}/x2ap_eNB_generate_messages.c + ${X2AP_DIR}/x2ap_ids.c + ${X2AP_DIR}/x2ap_timers.c ) add_dependencies(X2AP_ENB rrc_flag x2_flag) +# F1AP +############## +add_list1_option(F1AP_RELEASE R15 "F1AP ASN.1 grammar version" R15) +set(F1AP_DIR ${OPENAIR2_DIR}/F1AP) +if (${F1AP_RELEASE} STREQUAL "R15") + make_version(F1AP_VERSION 15 2 1) + set (ASN1RELDIR R15.2.1) +endif(${F1AP_RELEASE} STREQUAL "R15") +add_definitions(-DF1AP_VERSION=${F1AP_VERSION}) +set(F1AP_ASN_DIR ${F1AP_DIR}/MESSAGES/ASN1/${ASN1RELDIR}) +set(F1AP_ASN_FILES + ${F1AP_ASN_DIR}/F1AP-CommonDataTypes.asn + ${F1AP_ASN_DIR}/F1AP-Constants.asn + ${F1AP_ASN_DIR}/F1AP-PDU-Descriptions.asn + ${F1AP_ASN_DIR}/F1AP-PDU-Contents.asn + ${F1AP_ASN_DIR}/F1AP-IEs.asn + ${F1AP_ASN_DIR}/F1AP-Containers.asn + ) + +set(F1AP_ASN_GENERATED_C_DIR ${asn1_generated_dir}/F1AP_${ASN1RELDIR}) +message("calling ASN1C_PREFIX=F1AP_ asn1c -gen-PER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps -D ${F1AP_ASN_GENERATED_C_DIR} ${F1AP_ASN_FILES}") +execute_process(COMMAND mkdir -p ${F1AP_ASN_GENERATED_C_DIR} + COMMAND env "ASN1C_PREFIX=F1AP_" asn1c -gen-PER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps -D ${F1AP_ASN_GENERATED_C_DIR} ${F1AP_ASN_FILES} + RESULT_VARIABLE ret + OUTPUT_QUIET + ERROR_QUIET) + +if (NOT ${ret} STREQUAL 0) + message(FATAL_ERROR "asn1c: error") +endif (NOT ${ret} STREQUAL 0) + +file(GLOB F1AP_ASN_GENERATED_C_FILES ${F1AP_ASN_GENERATED_C_DIR}/*.c) +add_library(F1AP_LIB + ${F1AP_ASN_GENERATED_C_FILES} +) + +include_directories ("${F1AP_ASN_GENERATED_C_DIR}") +include_directories ("${F1AP_DIR}") + +file(GLOB F1AP_C_FILES ${F1AP_DIR}/*.c) +add_library(F1AP + ${F1AP_C_FILES} +) + # Hardware dependant options ################################### add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4") add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") -add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR") +add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR" "OAI_SIMU") + add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET") #NOKIA config enhancement @@ -585,6 +631,8 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} ) set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") +add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c) + ########################################################## include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON") @@ -595,7 +643,6 @@ Message("CPU_Affinity flag is ${CPU_AFFINITY}") ############################################################## # ???!!! TO BE DOCUMENTED OPTIONS !!!??? ############################################################## -add_boolean_option(ENABLE_SECURITY True "Enable LTE integrity and ciphering between RRC UE and eNB") add_boolean_option(ENABLE_USE_MME True "eNB connected to MME (INTERFACE S1-C), not standalone eNB") add_boolean_option(NO_RRM True "DO WE HAVE A RADIO RESSOURCE MANAGER: NO") add_boolean_option(RRC_DEFAULT_RAB_IS_AM False "set the RLC mode to AM for the default bearer") @@ -693,10 +740,10 @@ add_boolean_option(TRACE_RLC_UM_TX_STATUS False "TRACE for RLC UM, TO BE CHANGE ########################## # PDCP LAYER OPTIONS ########################## -add_boolean_option(PDCP_USE_NETLINK False "For eNB, PDCP communicate with a NETLINK socket if connected to network driver, else could use a RT-FIFO") -add_boolean_option(PDCP_USE_NETLINK_QUEUES False "When PDCP_USE_NETLINK is true, incoming IP packets are stored in queues") -add_boolean_option(LINK_ENB_PDCP_TO_IP_DRIVER False "For eNB, PDCP communicate with a IP driver") -add_boolean_option(LINK_ENB_PDCP_TO_GTPV1U True "For eNB, PDCP communicate with GTP-U protocol (eNB<->S-GW)") +#add_boolean_option(PDCP_USE_NETLINK False "For eNB, PDCP communicate with a NETLINK socket if connected to network driver, else could use a RT-FIFO") +#add_boolean_option(PDCP_USE_NETLINK_QUEUES False "When PDCP_USE_NETLINK is true, incoming IP packets are stored in queues") +#add_boolean_option(LINK_ENB_PDCP_TO_IP_DRIVER False "For eNB, PDCP communicate with a IP driver") +#add_boolean_option(LINK_ENB_PDCP_TO_GTPV1U True "For eNB, PDCP communicate with GTP-U protocol (eNB<->S-GW)") ########################## # RRC LAYER OPTIONS @@ -743,6 +790,8 @@ include_directories("${NFAPI_DIR}/sim_common/inc") include_directories("${NFAPI_DIR}/pnf_sim/inc") include_directories("${OPENAIR1_DIR}") include_directories("${OPENAIR2_DIR}") +include_directories("${OPENAIR3_DIR}/NAS/TOOLS") +include_directories("${OPENAIR2_DIR}/ENB_APP") include_directories("${OPENAIR2_DIR}/LAYER2/RLC") include_directories("${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0") include_directories("${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0") @@ -765,19 +814,21 @@ include_directories("${OPENAIR3_DIR}/SECU") include_directories("${OPENAIR3_DIR}/SCTP") include_directories("${OPENAIR3_DIR}/S1AP") include_directories("${OPENAIR2_DIR}/X2AP") +include_directories("${OPENAIR2_DIR}/F1AP") include_directories("${OPENAIR3_DIR}/UDP") include_directories("${OPENAIR3_DIR}/GTPV1-U") include_directories("${OPENAIR_DIR}/targets/COMMON") include_directories("${OPENAIR_DIR}/targets/ARCH/COMMON") include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/USERSPACE/LIB/") include_directories("${OPENAIR_DIR}/targets/ARCH/EXMIMO/DEFS") -include_directories("${OPENAIR2_DIR}/ENB_APP") +include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC") include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP") include_directories("${OPENAIR2_DIR}/UTIL/OSA") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds6.1.1/liblfds611/inc") include_directories("${OPENAIR2_DIR}/UTIL/LFDS/liblfds7.0.0/liblfds700/inc") +include_directories("${OPENAIR2_DIR}/LAYER2/PROTO_AGENT") include_directories("${OPENAIR2_DIR}/UTIL/MEM") include_directories("${OPENAIR2_DIR}/UTIL/LISTS") include_directories("${OPENAIR2_DIR}/UTIL/FIFO") @@ -819,7 +870,7 @@ set(FLPT_MSG_FILES ${FLPT_MSG_DIR}/control_delegation.proto ) -set(FLPT_C_DIR ${protobuf_generated_dir}/${FLPTDIR}) +set(FLPT_C_DIR ${protobuf_generated_dir}/FLPT_${FLPTDIR}) #message("calling protoc_call=${protoc_call} FLPT_C_DIR=${FLPT_C_DIR} FLPT_MSG_FILES=${FLPT_MSG_FILES}") execute_process(COMMAND ${protoc_call} ${FLPT_C_DIR} ${FLPT_MSG_DIR} ${FLPT_MSG_FILES}) file(GLOB FLPT_source ${FLPT_C_DIR}/*.c) @@ -862,6 +913,7 @@ add_library(FLEXRAN_AGENT ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_timer.c ${OPENAIR2_DIR}/ENB_APP/flexran_agent_common_internal.c + ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -887,6 +939,63 @@ MARK_AS_ADVANCED(LIBYAML_INCLUDE_DIR LIBYAML_LIBRARIES) #set(PROTOBUF_LIB "protobuf") #for Cpp +# set the version of protobuf messages, V3 not supported yet +add_list1_option(FSPT_VERSION V2 "FSPT MSG protobuf grammar version" V2 V3) + +if (${FSPT_VERSION} STREQUAL "V2") + set (FSPTDIR V2) +elseif (${FSPT_VERSION} STREQUAL "V3") + set (FSPTDIR V3) +endif(${FSPT_VERSION} STREQUAL "V2") + +set(FSPT_MSG_DIR ${OPENAIR_DIR}/targets/COMMON/MESSAGES/${FSPTDIR} ) +set(FSPT_MSG_FILES + ${FSPT_MSG_DIR}/flexsplit.proto + ) + +set(FSPT_C_DIR ${protobuf_generated_dir}/FSPT_${FSPTDIR}) +message("calling protoc_call=${protoc_call} FSPT_C_DIR=${FSPT_C_DIR} FSPT_MSG_DIR=${FSPT_MSG_DIR} FSPT_MSG_FILES=${FSPT_MSG_FILES}") +execute_process(COMMAND ${protoc_call} ${FSPT_C_DIR} ${FSPT_MSG_DIR} ${FSPT_MSG_FILES}) +file(GLOB FSPT_source ${FSPT_C_DIR}/*.c) +set(FSPT_OAI_generated + ${FSPT_C_DIR}/flexsplit.pb-c.c + ) + +file(GLOB fspt_h ${FSPT_C_DIR}/*.h) +set(fspt_h ${fspt_h} ) + +add_library(FSPT_MSG + ${FSPT_OAI_generated} + ${FSPT_source} + ) +set(FSPT_MSG_LIB FSPT_MSG) +message("fspt c dir is : ${FSPT_C_DIR}") +include_directories (${FSPT_C_DIR}) + +# add_library(ASYNC_IF +# ${OPENAIR2_DIR}/UTIL/ASYNC_IF/socket_link.c +# ${OPENAIR2_DIR}/UTIL/ASYNC_IF/link_manager.c +# ${OPENAIR2_DIR}/UTIL/ASYNC_IF/message_queue.c +# ${OPENAIR2_DIR}/UTIL/ASYNC_IF/ringbuffer_queue.c +# ) +# set(ASYNC_IF_LIB ASYNC_IF) +# include_directories(${OPENAIR2_DIR}/UTIL/ASYNC_IF) + +add_library(PROTO_AGENT + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_handler.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_common.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_net_comm.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_async.c + ) +set(PROTO_AGENT_LIB PROTO_AGENT) +include_directories(${OPENAIR2_DIR}/LAYER2/PROTO_AGENT) + + + +set(PROTOBUF_LIB "protobuf-c") + +#set(PROTOBUF_LIB "protobuf") #for Cpp add_library(HASHTABLE ${OPENAIR_DIR}/common/utils/hashtable/hashtable.c @@ -909,7 +1018,7 @@ set(UTIL_SRC ${OPENAIR_DIR}/common/utils/LOG/log.c # ${OPENAIR2_DIR}/UTIL/LOG/vcd_signal_dumper.c ${OPENAIR2_DIR}/UTIL/MATH/oml.c - ${OPENAIR2_DIR}/UTIL/MEM/mem_block.c + #${OPENAIR2_DIR}/UTIL/MEM/mem_block.c # ${OPENAIR2_DIR}/UTIL/OCG/OCG.c # ${OPENAIR2_DIR}/UTIL/OCG/OCG_create_dir.c # ${OPENAIR2_DIR}/UTIL/OCG/OCG_detect_file.c @@ -1284,7 +1393,7 @@ set(L2_SRC ${RLC_DIR}/rlc.c ${RLC_DIR}/rlc_rrc.c ${RLC_DIR}/rlc_mpls.c - ${RRC_DIR}/rrc_UE.c +# ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_eNB.c ${RRC_DIR}/rrc_eNB_S1AP.c ${RRC_DIR}/rrc_eNB_UE_context.c @@ -1950,6 +2059,8 @@ add_executable(lte-softmodem ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c @@ -1967,11 +2078,39 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 - ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} LFDS7 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) +add_executable(cu_test + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/cu_test.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_handler.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_common.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_net_comm.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_async.c + ${T_SOURCE} +) +target_link_libraries(cu_test + ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FSPT_MSG_LIB} ${PROTOBUF_LIB} + ${PROTO_AGENT_LIB} pthread UTIL ${T_LIB} dl ${ITTI_LIB} +) + +add_executable(du_test + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/du_test.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_handler.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_common.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_net_comm.c + ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/proto_agent_async.c + ${T_SOURCE} +) +target_link_libraries(du_test + ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FSPT_MSG_LIB} ${PROTOBUF_LIB} + ${PROTO_AGENT_LIB} pthread UTIL ${T_LIB} dl ${ITTI_LIB} +) + target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES}) @@ -1994,26 +2133,29 @@ add_executable(lte-softmodem-nos1 ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c + ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c + ${GTPU_need_ITTI} ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${T_SOURCE} ${CONFIG_SOURCES} ${SHLIB_LOADER_SOURCES} ) + add_dependencies(lte-softmodem-nos1 rrc_flag s1ap_flag x2_flag) + target_link_libraries (lte-softmodem-nos1 -Wl,--start-group - RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 ${RAL_LIB} ${ITTI_LIB} - ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + RRC_LIB F1AP F1AP_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} LFDS7 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB - -Wl,--end-group z dl ) + -Wl,--end-group z dl) target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${T_LIB}) - # lte-uesoftmodem is UE implementation ####################################### @@ -2027,6 +2169,8 @@ add_executable(lte-uesoftmodem ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c @@ -2043,7 +2187,7 @@ add_executable(lte-uesoftmodem add_dependencies(lte-uesoftmodem rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-uesoftmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU + RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) @@ -2070,6 +2214,7 @@ add_executable(lte-uesoftmodem-nos1 ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c + ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c ${XFORMS_SOURCE} @@ -2080,18 +2225,18 @@ add_executable(lte-uesoftmodem-nos1 ) add_dependencies(lte-uesoftmodem-nos1 rrc_flag s1ap_flag x2_flag) + target_link_libraries (lte-uesoftmodem-nos1 -Wl,--start-group - RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU ${RAL_LIB} ${ITTI_LIB} - ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} + RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB - -Wl,--end-group z dl ) + -Wl,--end-group z dl) target_link_libraries (lte-uesoftmodem-nos1 ${LIBXML2_LIBRARIES}) target_link_libraries (lte-uesoftmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (lte-uesoftmodem-nos1 ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-uesoftmodem-nos1 ${T_LIB}) - # USIM process ################# #add_executable(usim @@ -2142,11 +2287,12 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr ${T_SOURCE} ${CONFIG_SOURCES} ${SHLIB_LOADER_SOURCES} + ${NFAPI_USER_DIR}/nfapi.c ) target_link_libraries (${myExe} -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY PHY_UE PHY_RU LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group - pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl + pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl ) endforeach(myExe) @@ -2159,7 +2305,7 @@ add_executable(test_epc_generate_scenario ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h ) target_link_libraries (test_epc_generate_scenario - -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} + -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} ) add_executable(test_epc_play_scenario @@ -2178,7 +2324,7 @@ add_executable(test_epc_play_scenario ) target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_link_libraries (test_epc_play_scenario - -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} + -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES} ) @@ -2212,15 +2358,15 @@ if (${T_TRACER}) #all "add_executable" definitions (except tests, rb_tool, updatefw) lte-softmodem lte-softmodem-nos1 lte-uesoftmodem lte-uesoftmodem-nos1 dlsim_tm4 dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim - pdcchsim pucchsim prachsim syncsim ulsim + pdcchsim pucchsim prachsim syncsim ulsim cu_test du_test #all "add_library" definitions - ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB + ITTI RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP_LIB F1AP oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_eth_transpro FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO SECU_OSA - SECU_CN SCHED_LIB PHY L2 default_sched remote_sched RAL CN_UTILS - GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS LFDS7 SIMU OPENAIR0_LIB PHY_MEX - coding) + SECU_CN SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY L2 default_sched + remote_sched RAL CN_UTILS GTPV1U SCTP_CLIENT UDP LIB_NAS_UE LFDS + LFDS7 SIMU OPENAIR0_LIB PHY_MEX coding) if (TARGET ${i}) add_dependencies(${i} generate_T) endif() diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index fc4567269e51fd2b3f3c1f90a7b9fc2815ba2b8d..bf3d57af0dbbec3c3ce877662e813c21132f2fa0 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -990,11 +990,11 @@ <pre_exec>$OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash</pre_exec> <pre_exec_args></pre_exec_args> <main_exec> $OPENAIR_DIR/targets/bin/ulsim.Rel14</main_exec> - <main_exec_args> -BnbRBs=25 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 - -BnbRBs=25 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 - -BnbRBs=50 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 - -BnbRBs=50 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 - -BnbRBs=100 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + <main_exec_args> -BnbRBs=25 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=25 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=50 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=50 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 + -BnbRBs=100 -mcs=5 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=6 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 -BnbRBs=100 -mcs=16 -yN_rx=1 -gchannel=N -xTransmission=1 -snr=12 -wsnrInterrupt=1.0 -e_snr_step=.1 -P -nb_frame=500 -Operf=70 </main_exec_args> <tags>ulsim.test1 ulsim.test2 ulsim.test3 ulsim.test4 ulsim.test5 ulsim.test6</tags> <search_expr_true>"passed"</search_expr_true> diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf index 398b76388898bd51b8814bd036ade8d45520a6cd..d99ca88807d0fb16a714f3092aad74e9172e6129 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf index 46b648473742a635aba7181cae46388b6d090372..86c54a82f710a602d371c6377719e3237f6a248d 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf index 93b82773e6461939d1dc6e9cb74e49e428fc2c18..dad0ab5a2301dcef69e43366bdf150a548760195 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf index b412b00e523074bbe34f547c76d2978572fdb451..369b6184fd8f46460fbe26ff74a0ba2927f284d6 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf index f0d688903a6894508928af20ac76002badb57798..14ae99c80ca81be2c5dc5df9e25009e8a03fd122 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf index 929c91fffbdb6c1a2b4a00db9208c760f23bf8b6..9302ac7c5828ea2cafe367336a0df1be19008919 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf index 98358eb269bd7305c7a94c28e3278ae4f49a3e29..0ae9e659b41f300942f7b466ba739b690038c45c 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf index bc31e051e57db834520b1bc29ccf60fac7ce97d7..1d22c19ec872f758658d7706f106f6a8590b0864 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf index 2cfc227e67aeef229152a853908bbb9648da88be..3f35175ff49af72a4fa64ab8f37d45ea42f342be 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf index 9b135a94982c8214a6bfc17270d04c4e1b815cab..0a6a8cccc69087e49bc70f8043bd7e8e91e6a3c1 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf @@ -143,6 +143,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf index 9f84057299cd8ce552598399e85d52edd45c142e..7ffdd063a659fa8c7be540b7dc35498de93a036c 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf @@ -143,6 +143,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf index 7197e93322e56c63a6b77abd0a4256bdc6fdaeee..409fa49910153f92fbde234666dcbe5a293c95c9 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf @@ -143,6 +143,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth3"; diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 2728cac9b1721298ccad67a1867709cfd71defde..9d8a6096714e704569f93930158907a4ba8569ab 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -76,7 +76,7 @@ trap handle_ctrl_c INT function print_help() { echo_info " This program installs OpenAirInterface Software -You should have ubuntu 14.xx, updated, and the Linux kernel >= 3.14 +You should have ubuntu 16.xx or 18.04 updated Options -h This help @@ -103,6 +103,8 @@ Options Specify conf_nvram_path (default \"$conf_nvram_path\") --UE-gen-nvram [output path] Specify gen_nvram_path (default \"$gen_nvram_path\") +-a | --agent + Enables agent for software-defined control of the eNB -r | --3gpp-release default is Rel14, Rel8 limits the implementation to 3GPP Release 8 version @@ -167,6 +169,9 @@ Options --basic-simulator Generates a basic [1 UE + 1 eNB + no channel] simulator. See targets/ARCH/tcp_bridge/README.tcp_bridge_oai for documentation. +--rfsimulator + Generate virtual RF driver + to use it, set the environement variable RFSIMULATOR to \"enb\" in the eNB and to the eNB IP address in the UEs Usage (first build): NI/ETTUS B201 + COTS UE : ./build_oai -I --eNB -x --install-system-files -w USRP Usage (Regular): @@ -234,25 +239,21 @@ function main() { echo_info "Setting release to: $REL" shift 2;; -w | --hardware) - HW="$2" #"${i#*=}" # Use OAI_USRP as the key word USRP is used inside UHD driver - if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" -a "$HW" != "IRIS" ] ; then - echo_fatal "Unknown HW type $HW will exit..." - else - if [ "$HW" == "USRP" ] ; then - HW="OAI_USRP" - fi - if [ "$HW" == "BLADERF" ] ; then - HW="OAI_BLADERF" - fi - if [ "$HW" == "LMSSDR" ] ; then - HW="OAI_LMSSDR" - fi - if [ "$HW" == "IRIS" ] ; then - HW="OAI_IRIS" - fi + case "$2" in + "EXMIMO") + HW="EXMIMO" + ;; + "USRP" | "BLADERF" | "LMSSDR" | "IRIS" | "SIMU") + HW="OAI_"$2 + ;; + "None") + HW="None" + ;; + *) + echo_fatal "Unknown HW type $HW: exit..." + esac echo_info "Setting hardware to: $HW" - fi shift 2;; -t | --transport_protocol) TP="$2" #"${i#*=}" @@ -374,6 +375,10 @@ function main() { BASIC_SIMULATOR=1 echo_info "Compiling the basic simulator" shift 1;; + --rfsimulator) + RFSIMULATOR=true + echo_info "Compiling the RF simulator" + shift 1;; -h | --help) print_help exit 1;; @@ -386,11 +391,6 @@ function main() { CMAKE_CMD="$CMAKE_CMD .." echo_info "CMAKE_CMD=$CMAKE_CMD" - if [ "$eNB" = "1" ] && [ "$UE" = "1" ]; then - echo_error "Cannot build UE and eNB on one build_oai execution" - echo_error "use 2 build_oai invocations" - exit - fi ######################################################### # check validity of HW and TP parameters for eNB ######################################################### @@ -409,33 +409,17 @@ function main() { fi echo_info "RF HW set to $HW" - #Now we set flags to enable deadline scheduler settings - #By default: USRP: disable, - #By default: BLADERF: enable, - #By default: EXMIMO: enable - if [ "$FORCE_DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then - if [ "$HW" = "EXMIMO" ] ; then + # If the user doesn't specify the Linux scheduler to use, we set a value + if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then + case "$HW" in + "EXMIMO") DEADLINE_SCHEDULER_FLAG_USER="True" - elif [ "$HW" = "ETHERNET" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "OAI_USRP" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "OAI_BLADERF" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "OAI_LMSSDR" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "OAI_IRIS" ] ; then + ;; + *) DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "None" ] ; then - DEADLINE_SCHEDULER_FLAG_USER="False" - else - echo_error "Unknown HW type $HW. Exiting now..." - exit - fi - else - DEADLINE_SCHEDULER_FLAG_USER=$FORCE_DEADLINE_SCHEDULER_FLAG_USER + ;; + esac fi - #Disable CPU Affinity for deadline scheduler if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "True" ] ; then CPU_AFFINITY_FLAG_USER="False" @@ -516,26 +500,19 @@ function main() { echo_info "3. building the compilation directives ..." DIR=$OPENAIR_DIR/cmake_targets - if [ "$NOS1" = "1" ] ; then - lte_build_dir=lte_noS1_build_oai - if [ "$eNB" = "1" ] ; then - lte_exec=lte-softmodem-nos1 - fi - if [ "$UE" = "1" ] ; then - lte_exec=lte-uesoftmodem-nos1 + + if [ "$T_TRACER" = "False" ] ; then + noLOGDirsuffix="_noLOG" fi + if [ "$NOS1" = "1" ] ; then + noS1Dir="_noS1" + bin_suffix="-nos1" else lte_build_dir=lte_build_oai - if [ "$eNB" = "1" ] ; then - lte_exec=lte-softmodem - fi - if [ "$UE" = "1" ] ; then - lte_exec=lte-uesoftmodem - fi - fi - if [ "$T_TRACER" = "False" ] ; then - lte_build_dir=${lte_build_dir}_noLOG + bin_suffix="" fi + + lte_build_dir="lte${noS1Dir}_build_oai${noLOGDirsuffix}" # configuration module libraries, one currently available, using libconfig config_libconfig_shlib=params_libconfig @@ -547,9 +524,9 @@ function main() { mkdir -p $DIR/$lte_build_dir/build cmake_file=$DIR/$lte_build_dir/CMakeLists.txt echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file - if [ "$NOS1" = "1" ] ; then - cat $DIR/$lte_build_dir/CMakeLists.template >> $cmake_file - fi +# if [ "$NOS1" = "1" ] ; then +# cat $DIR/$lte_build_dir/CMakeLists.template >> $cmake_file +# fi echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >> $cmake_file echo "set ( XFORMS $XFORMS )" >> $cmake_file @@ -580,8 +557,8 @@ function main() { eval $CMAKE_CMD fi - if [ "$eNB" = "1" -o "$UE" = "1" ] ; then - echo_info "Compiling $lte_exec" + if [ "$eNB" = "1" ] ; then + lte_exec=lte-softmodem${bin_suffix} compilations \ $lte_build_dir $lte_exec \ $lte_exec $dbin/$lte_exec.$REL @@ -605,7 +582,29 @@ function main() { fi fi - if [ "$UE" = 1 -a "$NOS1" = "0" ] ; then + if [ "$UE" = 1 ] ; then + lte_exec=lte-uesoftmodem${bin_suffix} + compilations \ + $lte_build_dir $lte_exec \ + $lte_exec $dbin/$lte_exec.$REL + + # mandatory shared lib + compilations \ + $lte_build_dir $config_libconfig_shlib \ + lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so + compilations \ + $lte_build_dir coding \ + libcoding.so $dbin/libcoding.so + + if [ "$NOS1" = "1" ] ; then + compilations \ + $lte_build_dir nasmesh \ + CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko + compilations \ + $lte_build_dir rb_tool \ + rb_tool $dbin/rb_tool + cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin + else # ue_ip driver compilation echo_info "Compiling UE specific part" compilations \ @@ -645,6 +644,7 @@ function main() { echo_warning "not generated UE NAS files: binaries not found" fi fi + fi if [ "$SIMUS_PHY" = "1" -o "$SIMUS_CORE" = "1" ] ; then cd $OPENAIR_DIR/cmake_targets/lte-simulators @@ -709,23 +709,19 @@ function main() { cp $OPENAIR_DIR/cmake_targets/tools/init_exmimo2 $dbin fi - - # Telnet server compilation ##################### if [ "$BUILD_TELNETSRV" = "1" ] ; then - build_dir=$lte_build_dir compilations \ - $build_dir telnetsrv \ + $lte_build_dir telnetsrv \ libtelnetsrv.so $dbin/libtelnetsrv.so fi - # Telnet server compilation + # msc library compilation ##################### if [ "$MSC_GEN" = "1" ] ; then - build_dir=$lte_build_dir compilations \ - $build_dir msc \ + $lte_build_dir msc \ libmsc.so $dbin/libmsc.so fi @@ -733,8 +729,6 @@ function main() { ##################################### if [ "$eNB" = "1" -o "$UE" = "1" ] ; then - build_dir=$lte_build_dir - # build RF device libraries if [ "$HW" != "None" ] ; then rm -f liboai_device.so @@ -743,7 +737,7 @@ function main() { # link liboai_device.so with the selected RF device library if [ "$HW" == "EXMIMO" ] ; then compilations \ - $build_dir oai_exmimodevif \ + $lte_build_dir oai_exmimodevif \ liboai_exmimodevif.so $dbin/liboai_exmimodevif.so.$REL ln -sf liboai_exmimodevif.so liboai_device.so @@ -751,7 +745,7 @@ function main() { echo_info "liboai_device.so is linked to EXMIMO device library" elif [ "$HW" == "OAI_USRP" ] ; then compilations \ - $build_dir oai_usrpdevif \ + $lte_build_dir oai_usrpdevif \ liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL ln -sf liboai_usrpdevif.so liboai_device.so @@ -760,7 +754,7 @@ function main() { elif [ "$HW" == "OAI_BLADERF" ] ; then if [ -f "/usr/include/libbladeRF.h" ] ; then compilations \ - $build_dir oai_bladerfdevif \ + $lte_build_dir oai_bladerfdevif \ liboai_bladerfdevif.so $dbin/liboai_bladerfdevif.so.$REL fi @@ -768,18 +762,18 @@ function main() { ln -sf $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so echo_info "liboai_device.so is linked to BLADERF device library" elif [ "$HW" == "OAI_LMSSDR" ] ; then -# if [ -f "/usr/include/libbladeRF.h" ] ; then + # if [ -f "/usr/include/libbladeRF.h" ] ; then compilations \ - $build_dir oai_lmssdrdevif \ + $lte_build_dir oai_lmssdrdevif \ liboai_lmssdrdevif.so $dbin/liboai_lmssdrdevif.so.$REL -# fi + # fi ln -sf liboai_lmssdrdevif.so liboai_device.so ln -sf $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so echo_info "liboai_device.so is linked to LMSSDR device library" elif [ "$HW" == "OAI_IRIS" ] ; then compilations \ - $build_dir oai_irisdevif \ + $lte_build_dir oai_irisdevif \ liboai_irisdevif.so $dbin/liboai_irisdevif.so.$REL ln -s liboai_irisdevif.so liboai_device.so @@ -790,22 +784,33 @@ function main() { fi fi - # build trasport protocol libraries (currently only ETHERNET is available) - if [ "$TP" != "None" ] ; then + # build simulators devices + echo_info "Compiling rfsimulator" + compilations \ + $lte_build_dir rfsimulator \ + librfsimulator.so $dbin/librfsimulator.so.$REL + echo_info "Compiling basicsimulator" + compilations \ + $lte_build_dir tcp_bridge_oai \ + libtcp_bridge_oai.so $dbin/libtcp_bridge_oai.so.$REL + # build transport protocol libraries (currently only ETHERNET is available) + rm -f liboai_transpro.so rm -f $dbin/liboai_transpro.so - - if [ "$TP" == "ETHERNET" ] ; then compilations \ - $build_dir oai_eth_transpro \ + $lte_build_dir oai_eth_transpro \ liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL ln -sf liboai_eth_transpro.so liboai_transpro.so ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so - echo_info "liboai_transpro.so is linked with ETHERNET library" - fi + echo_info "liboai_transpro.so is linked to ETHERNET transport" fi -fi + if [ "$RFSIMULATOR" == "true" -o "$HW" == "OAI_SIMU" ] ; then + echo_info "Compiling rfsimulator" + compilations \ + $lte_build_dir rfsimulator \ + librfsimulator.so $dbin/librfsimulator.so.$REL + fi # Doxygen Support ##################### @@ -936,7 +941,7 @@ fi echo "set (LINUX True )" >> $cmake_file echo "set (PDCP_USE_NETLINK True )" >> $cmake_file echo "set (BASIC_SIMULATOR \"True\" )" >> $cmake_file - echo "set (UE_NAS_USE_TUN \"True\" )" >> $cmake_file +# echo "set (UE_NAS_USE_TUN \"True\" )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.txt)' >> $cmake_file echo_info "Build UE" diff --git a/cmake_targets/epc_test/CMakeLists.template b/cmake_targets/epc_test/CMakeLists.template index e046bb75391a178a605ed390cbb13a91b05bcbd7..7a097fffb027f81f94a210f50f8ea37939639bee 100644 --- a/cmake_targets/epc_test/CMakeLists.template +++ b/cmake_targets/epc_test/CMakeLists.template @@ -9,7 +9,6 @@ set ( EMIT_ASN_DEBUG False ) set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING True ) set ( ENABLE_NEW_MULTICAST True ) -set ( ENABLE_SECURITY True ) set ( ENABLE_STANDALONE_EPC False) set ( ENABLE_USE_CPU_EXECUTION_TIME True ) set ( ENABLE_USE_MME True ) diff --git a/cmake_targets/oaisim_build_oai/CMakeLists.template b/cmake_targets/oaisim_build_oai/CMakeLists.template index 22faac75b5855fd33b2fb6630c5dde36e8fe83a4..cffbddc93c5b5170dcb83896f2af5c90c5ef311a 100644 --- a/cmake_targets/oaisim_build_oai/CMakeLists.template +++ b/cmake_targets/oaisim_build_oai/CMakeLists.template @@ -8,7 +8,6 @@ set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING True ) set ( ENABLE_NEW_MULTICAST True ) set ( ENABLE_RAL False ) -set ( ENABLE_SECURITY True ) set ( ENABLE_STANDALONE_EPC False) set ( ENABLE_USE_CPU_EXECUTION_TIME True ) set ( ENABLE_USE_MME True ) diff --git a/cmake_targets/oaisim_mme_build_oai/CMakeLists.template b/cmake_targets/oaisim_mme_build_oai/CMakeLists.template index b18b23ee9abf72e93a74a9d70a9edede932a0b8c..eac29006da6ad83a48c6b3256fbe564fba59ade4 100644 --- a/cmake_targets/oaisim_mme_build_oai/CMakeLists.template +++ b/cmake_targets/oaisim_mme_build_oai/CMakeLists.template @@ -8,7 +8,6 @@ set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING False ) set ( ENABLE_NEW_MULTICAST False ) set ( ENABLE_RAL False ) -set ( ENABLE_SECURITY False ) set ( ENABLE_STANDALONE_EPC False ) set ( ENABLE_USE_CPU_EXECUTION_TIME False ) set ( ENABLE_USE_MME False ) diff --git a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template b/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template index bc416cff55fef58c4a19492585c07addd4f60115..343e9280902b4074740fbea0d0fb3b1427394e17 100644 --- a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template +++ b/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template @@ -7,7 +7,6 @@ set ( ENABLE_ITTI True ) set ( ENABLE_NAS_UE_LOGGING False ) set ( ENABLE_NEW_MULTICAST True ) set ( ENABLE_RAL False ) -set ( ENABLE_SECURITY False ) set ( ENABLE_STANDALONE_EPC False) set ( ENABLE_USE_CPU_EXECUTION_TIME True ) set ( ENABLE_USE_MME False ) diff --git a/cmake_targets/s1c_mme_test/CMakeLists.template b/cmake_targets/s1c_mme_test/CMakeLists.template index 9f1ff3e36015965cf5403c37472f259f32d29a25..e62df04bc6f345783c35f0d8749a7af523e1e68f 100644 --- a/cmake_targets/s1c_mme_test/CMakeLists.template +++ b/cmake_targets/s1c_mme_test/CMakeLists.template @@ -9,7 +9,6 @@ set ( ENABLE_NAS_UE_LOGGING True ) set ( ENABLE_NEW_MULTICAST True ) set ( ENABLE_PDCP_NETLINK_FIFO False ) set ( ENABLE_RAL False ) -set ( ENABLE_SECURITY True ) set ( ENABLE_STANDALONE_EPC False) set ( ENABLE_USE_CPU_EXECUTION_TIME True ) set ( ENABLE_USE_MME True ) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index acfb75b1a8531a0a67bcf1c5bcdebd0e9d3c2872..0021b673f2bdb3f5145c75aea02d3501f4aaafe5 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -102,6 +102,7 @@ check_supported_distribution() { "ubuntu14.04") return 0 ;; "fedora24") return 0 ;; "rhel7") return 0 ;; + "rhel7.6") return 0 ;; "centos7") return 0 ;; esac return 1 @@ -310,10 +311,20 @@ install_usrp_uhd_driver() { # On newer kernels, it fails to install $SUDO apt-get -y install uhd-host fi + # quick workaround for RHE7.6 + local distribution=$(get_distribution_release) if [ -z $1 ]; then - $SUDO uhd_images_downloader + if [[ "$distribution" == "rhel7.6" ]]; then + $SUDO /usr/local/bin/uhd_images_downloader + else + $SUDO uhd_images_downloader + fi else - $SUDO uhd_images_downloader -i $1 + if [[ "$distribution" == "rhel7.6" ]]; then + $SUDO /usr/local/bin/uhd_images_downloader -i $1 + else + $SUDO uhd_images_downloader -i $1 + fi fi } @@ -628,8 +639,6 @@ check_install_oai_software() { libidn2-0-dev \ libidn11-dev \ libmysqlclient-dev \ - liboctave-dev \ - libpgm-dev \ libpython2.7-dev \ libsctp1 \ libsctp-dev \ @@ -640,7 +649,6 @@ check_install_oai_software() { libxml2-dev \ libxslt1-dev \ mscgen \ - octave \ octave-signal \ openssh-client \ openssh-server \ @@ -652,7 +660,8 @@ check_install_oai_software() { pydb \ libyaml-dev \ wget \ - libxpm-dev + libxpm-dev \ + libboost-all-dev $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET" @@ -700,8 +709,6 @@ check_install_oai_software() { libidn2-devel \ libidn-devel \ mariadb-devel \ - octave-devel \ - openpgm-devel \ lksctp-tools \ lksctp-tools-devel \ openssl-devel \ @@ -711,8 +718,6 @@ check_install_oai_software() { libxml2 \ libxml2-devel \ libxslt-devel \ - octave \ - octave-signal \ openssh-clients \ openssh-server \ openssl \ @@ -735,7 +740,7 @@ check_install_oai_software() { libyaml-devel fi - install_asn1c_from_source + install_asn1c_from_source $1 $SUDO rm -fr /opt/ssh $SUDO git clone https://gist.github.com/2190472.git /opt/ssh } diff --git a/cmake_targets/tools/fix_asn1 b/cmake_targets/tools/fix_asn1 index fe819c27162df2174c27cc2cc93aa250b00c3bd1..1486589a0c5b3ef76c488a5853faf137bcb4cd72 100755 --- a/cmake_targets/tools/fix_asn1 +++ b/cmake_targets/tools/fix_asn1 @@ -23,7 +23,7 @@ reset_color="$(tput sgr0)" function error() { echo -e "$red_color"ERROR: "$@""$reset_color" - exit 1 +# exit 1 } function check_sha1() @@ -56,11 +56,11 @@ function patch_file() echo -e "$green_color""patch file $file with $OPENAIR_DIR/cmake_targets/tools/$patch""$reset_color" - patch "$file" "$OPENAIR_DIR/cmake_targets/tools/$patch" - if [ $? -ne 0 ] - then - error "patching of $file with $OPENAIR_DIR/cmake_targets/tools/$patch failed" - fi +# patch "$file" "$OPENAIR_DIR/cmake_targets/tools/$patch" +# if [ $? -ne 0 ] +# then +# error "patching of $file with $OPENAIR_DIR/cmake_targets/tools/$patch failed" +# fi } function apply_patches() @@ -140,6 +140,22 @@ function patch_s1ap() esac } +function patch_f1ap() +{ + local directory="$1" + local version="$2" + + case "$version" in + R15 ) + #nothing to do anymore (fixes went to asn1c) + ;; + * ) + error unknwon/unhandled F1AP version \'"$version"\' + ;; + esac +} + + function main() { if [ $# -ne 3 ] @@ -167,6 +183,9 @@ function main() S1AP ) patch_s1ap "$directory" "$version" ;; + F1AP ) + patch_f1ap "$directory" "$version" + ;; * ) error unknown module "$module" ;; diff --git a/cmake_targets/tools/generate_asn1 b/cmake_targets/tools/generate_asn1 index 79becbf28881395dd495bad7921ee11dce02100b..b382730c6a74f117d3dedb13006ffc60824fb3f7 100755 --- a/cmake_targets/tools/generate_asn1 +++ b/cmake_targets/tools/generate_asn1 @@ -2,23 +2,29 @@ function main() { -mkdir -p $1 -cd $1 +PROTOCOL_DIR=$1 +mkdir -p ${PROTOCOL_DIR} +cd ${PROTOCOL_DIR} + +# Because use $* also include directory, so we need shift shift -#if this script is called with only 2 arguments (so 1 here after the shift), it's for RRC -#(there may be a better way...) -if [ $# -eq 1 ]; then +# There are three types parameter for asn1c +# One is for RRC +# and one is for F1AP +# another is for other protocols + +if echo ${PROTOCOL_DIR} | grep -q "RRC"; then -#asn1c does not work well with extension groups, we need the following fix: -# replace [[ by '<name> SEQUENCE {' -# and ]] by '} OPTIONAL' -#<name> is ext<N> with N starting from 1 and incremented at each new [[ ]] just -#following another [[ ]] -# -#this is what the following C program does + #asn1c does not work well with extension groups, we need the following fix: + # replace [[ by '<name> SEQUENCE {' + # and ]] by '} OPTIONAL' + #<name> is ext<N> with N starting from 1 and incremented at each new [[ ]] just + #following another [[ ]] + # + #this is what the following C program does -echo generate asnfix.c + echo generate asnfix.c cat << EOF > asnfix.c /* transforms: @@ -85,30 +91,34 @@ int main(void) } EOF -echo compile asnfix.c + echo compile asnfix.c -gcc -Wall -o asnfix asnfix.c + gcc -Wall -o asnfix asnfix.c -echo run asnfix on $1 + echo run asnfix on $1 -./asnfix < $1 > fixed_grammar.asn + ./asnfix < $1 > fixed_grammar.asn -rm -f asnfix asnfix.c + rm -f asnfix asnfix.c -echo done with asnfix + echo done with asnfix -echo running asn1c + echo running asn1c -asn1c -gen-PER -fcompound-names fixed_grammar.asn 2>&1 | grep -v -- '->' | grep -v '^Compiled' |grep -v sample + asn1c -gen-PER -fcompound-names -no-gen-example fixed_grammar.asn 2>&1 | grep -v -- '->' | grep -v '^Compiled' |grep -v sample -rm -f fixed_grammar.asn + rm -f fixed_grammar.asn -echo asn1c done + echo asn1c done +elif echo ${PROTOCOL_DIR} | grep -q "F1AP"; then + + asn1c -gen-PER -fcompound-names -no-gen-example -findirect-choice -fno-include-deps $* 2>&1 | grep -v -- '->' | grep -v '^Compiled' |grep -v sample + else - -asn1c -gen-PER -fcompound-names $* 2>&1 | grep -v -- '->' | grep -v '^Compiled' |grep -v sample - + + asn1c -gen-PER -fcompound-names -no-gen-example $* 2>&1 | grep -v -- '->' | grep -v '^Compiled' |grep -v sample + fi awk ' diff --git a/cmake_targets/tools/make_asn1c_includes.sh b/cmake_targets/tools/make_asn1c_includes.sh index bd4254c9388e1a577ba8ca27ec4370f700022581..a7f480f90f3653e71743c113a7bb60dc69b5c633 100755 --- a/cmake_targets/tools/make_asn1c_includes.sh +++ b/cmake_targets/tools/make_asn1c_includes.sh @@ -3,11 +3,11 @@ GENERATED_FULL_DIR=$1 shift ASN1_SOURCE_DIR=$1 shift -export ASN1C_PREFIX=$1 +export ASN1C_PREFIX=$1 shift options=$* done_flag="$GENERATED_FULL_DIR"/done -if [ "$done_flag" -ot $ASN1_SOURCE_DIR ] ; then +if [ "$done_flag" -ot $ASN1_SOURCE_DIR ] ; then rm -f "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}*.c "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}*.h mkdir -p "$GENERATED_FULL_DIR" asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example $options -D $GENERATED_FULL_DIR $ASN1_SOURCE_DIR |& egrep -v "^Copied|^Compiled" | sort -u diff --git a/common/config/DOC/config/arch.md b/common/config/DOC/config/arch.md index 170241500b3672984105ad7eb9f43cafcfcb11f4..f888724c4116ed1062f0c096ada1947f601b2839 100644 --- a/common/config/DOC/config/arch.md +++ b/common/config/DOC/config/arch.md @@ -1,7 +1,7 @@ # config module source files - + # config module components  -[Configuration module home](../config.md) \ No newline at end of file +[Configuration module home](../config.md) diff --git a/common/config/DOC/config/devusage.md b/common/config/DOC/config/devusage.md index bfc1180ab8b90b1af108da3a4e0acbbbb926a6f6..151ffeafa8c435786927e900c3316e2d4aaf2d88 100644 --- a/common/config/DOC/config/devusage.md +++ b/common/config/DOC/config/devusage.md @@ -1,17 +1,17 @@ -The configuration module objectives are +The configuration module objectives are 1. Allow easy parameters management in oai, helping the development of a flexible, modularized and fully configurable softmodem. 1. Use a common configuration API in all oai modules -1. Allow development of alternative configuration sources without modifying the oai code. Today the only delivered configuration source is the libconfig format configuration file. +1. Allow development of alternative configuration sources without modifying the oai code. Today the only delivered configuration source is the libconfig format configuration file. As a developer you may need to look at these sections: * [add parameters in an existing section](devusage/addaparam.md) * [add a parameter set, in a new section](devusage/addparamset.md) -* [configuration module API](devusage/api.md) -* [configuration module public structures](devusage/struct.md) +* [configuration module API](devusage/api.md) +* [configuration module public structures](devusage/struct.md) -Whatever your need is, configuration module usage examples can be found in oai sources: -* complex example, using all the configuration module functionalities, including parameter checking: +Whatever your need is, configuration module usage examples can be found in oai sources: +* complex example, using all the configuration module functionalities, including parameter checking: [NB-IoT configuration code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/ENB_APP/NB_IoT_config.c) and [NB-IoT configuration include file](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/ENB_APP/NB_IoT_paramdef.h) * very simple example, just reading a parameter set corresponding to a dedicated section: the telnetsrv_autoinit function in [common/utils/telnetsrv/telnetsrv.c, around line 726](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv.c#L726) * an example with run-time definition of parameters, in the logging sub-system: the log_getconfig function at the top of [openair2/UTIL/LOG/log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/UTIL/LOG/log.c) diff --git a/common/config/DOC/config/devusage/addaparam.md b/common/config/DOC/config/devusage/addaparam.md index b7bb8a73b90df5f1e7f17a61d47266b68bc1982c..246c49452613a2da5c5e4ecc287a32d9064dca22 100644 --- a/common/config/DOC/config/devusage/addaparam.md +++ b/common/config/DOC/config/devusage/addaparam.md @@ -1,6 +1,6 @@ -To add a new parameter in an existing section you insert an item in a `paramdef_t` array, which describes the parameters to be read in the existing `config_get` call. You also need to increment the numparams argument. +To add a new parameter in an existing section you insert an item in a `paramdef_t` array, which describes the parameters to be read in the existing `config_get` call. You also need to increment the numparams argument. -existing code: +existing code: ```c unsigned int varopt1; paramdef_t someoptions[] = { @@ -11,10 +11,10 @@ paramdef_t someoptions[] = { {"opt1", "<help opt1>", 0, uptr:&varopt1, defuintval:0, TYPE_UINT, 0 }, }; -config_get( someoptions,sizeof(someoptions)/sizeof(paramdef_t),"somesection"); +config_get( someoptions,sizeof(someoptions)/sizeof(paramdef_t),"somesection"); ``` -new code: +new code: ```c unsigned int varopt1; @@ -31,7 +31,7 @@ paramdef_t someoptions[] = { {"opt2", "<help opt2>", 0, strptr:&varopt2,defstrval:"",TYPE_STRING,0 }, }; -config_get( someoptions,sizeof(someoptions)/sizeof(paramdef_t),"somesection"); +config_get( someoptions,sizeof(someoptions)/sizeof(paramdef_t),"somesection"); ``` @@ -57,10 +57,10 @@ The configuration module provides a mechanism to check the parameter value read A `checkedparam_t` structure array provides the parameter verification procedures: ```c -/* +/* definition of the verification to be done on param opt1 and opt2. opt1 is an integer option we must be set to 0,2,3,4 or 7 in the - config source. + config source. if opt1 is set to 0 in the config file, it will be set to 1, etc opt2 is C string option with the authorize values "zero","oneThird","twoThird","one" */ @@ -82,5 +82,5 @@ for(int i=0 ; i < sizeof(someoptions)/sizeof(paramdesc_t) ; i ++) { ``` When you need a specific verification algorithm, you can provide your own verification function and use it in place of the available ones, in the `checkedparam_t` union. If no existing structure definition match your need, you can enhance the configuration module. You then have to add a new verification function in https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_userapi.c and add a new structure definition in the `checkedparam_t` type defined in https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h -[Configuration module developer main page](../../config/devusage.md) +[Configuration module developer main page](../../config/devusage.md) [Configuration module home](../../config.md) diff --git a/common/config/DOC/config/devusage/addparamset.md b/common/config/DOC/config/devusage/addparamset.md index 130a7eda749033beb1492332c9367df5311f4447..49448e11da79fd2292f0e8105456f6fb3e6ca81a 100644 --- a/common/config/DOC/config/devusage/addparamset.md +++ b/common/config/DOC/config/devusage/addparamset.md @@ -1,7 +1,7 @@ The configuration module maps a configuration file section to a `paramdef_t` structure array. One `config_get` call can be used to return the values of all the parameters described in the `paramdef_t` array. Retrieving a single occurence of a parameter set ( a group in the libconfig terminology) is just a two steps task: 1. describe the parameters in a `paramdef_t` array -1. call the `config_get` function +1. call the `config_get` function [config_get example](../../config/devusage/addaparam.md) @@ -30,19 +30,19 @@ NB-IoT_MACRLCs = ); ``` -The configuration module provides the `config_getlist` call to support lists of group of parameters. Below is a commented code example, using the config_getlist call. +The configuration module provides the `config_getlist` call to support lists of group of parameters. Below is a commented code example, using the config_getlist call. ```c /* name of section containing the list */ #define NBIOT_MACRLCLIST_CONFIG_STRING "NB-IoT_MACRLCs" -/* +/* The following macro define the parameters names, as used in the configuration file -*/ -#define CONFIG_STRING_MACRLC_CC "num_cc" +*/ +#define CONFIG_STRING_MACRLC_CC "num_cc" ..... -#define CONFIG_MACRLC_S_PORTD "remote_s_portd" +#define CONFIG_MACRLC_S_PORTD "remote_s_portd" /* now define a macro which will be used to initialize the NbIoT_MacRLC_Params @@ -51,16 +51,16 @@ configuration file module allocate the memory for the parameters values. */ /*------------------------------------------------------------------------------------------------------------*/ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ /*------------------------------------------------------------------------------------------------------------*/ #define MACRLCPARAMS_DESC { \ {CONFIG_STRING_MACRLC_CC, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ ............. \ {CONFIG_MACRLC_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ -} +} -/* +/* the following macros define the indexes used to access the NbIoT_MacRLC_Params array items. They must be maintained consistent with the previous MACRLCPARAMS_DESC macro which is used to initialize the NbIoT_MacRLC_Params variable @@ -72,60 +72,60 @@ which is used to initialize the NbIoT_MacRLC_Params variable void RCconfig_NbIoTmacrlc(void) { - + /* define and initialize the array of paramdef_t structures describing the groups of - parameters we want to read. It will be passed as the second argument of the + parameters we want to read. It will be passed as the second argument of the config_getlist call, which will use it as an input only argument. */ paramdef_t NbIoT_MacRLC_Params[] = MACRLCPARAMS_DESC; -/* +/* now define and initialize a paramlist_def_t structure which will be passed to the config_getlist call. The first field is the only one to be initialized - it contains the name of the section to be read. + it contains the name of the section to be read. that section contains the list of group of parameters. The two other fields are output parameters used to return respectively - a pointer to a two dimensional array of paramdef_t structures pointers, and the + a pointer to a two dimensional array of paramdef_t structures pointers, and the number of items in the list of groups (size of first dimension, the second one being the number of parameters in each group. -*/ +*/ paramlist_def_t NbIoT_MacRLC_ParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0}; - /* - the config_getlist will allocate the second field of the paramlist_def_t structure, a -two dimensional array of paramdef_t pointers. In each param_def item it will allocate + /* + the config_getlist will allocate the second field of the paramlist_def_t structure, a +two dimensional array of paramdef_t pointers. In each param_def item it will allocate the value pointer and set the value to what it will get from the config source. The numelt field of the paramlist_def_t structure will be set to the number of groups of parameters in the list. in this example the last argument of config_getlist is unused, it may contain a character string, used as a prefix for the section name. It has to be specified when the list to be read is under another section. -*/ +*/ config_getlist( &NbIoT_MacRLC_ParamList,NbIoT_MacRLC_Params, - sizeof(NbIoT_MacRLC_Params)/sizeof(paramdef_t), + sizeof(NbIoT_MacRLC_Params)/sizeof(paramdef_t), NULL); - -/* + +/* start a loop in the nuber of groups in the list, the numelt field of the paramlist_def_t structure has been set in the config_getlist call */ for (j=0 ; j<NbIoT_MacRLC_ParamList.numelt ; j++) { .......... - + /* access the MACRLC_REMOTE_S_PORTD parameter in the j ieme group of the list */ - RC.nb_iot_mac[j]->eth_params_s.remote_portd = + RC.nb_iot_mac[j]->eth_params_s.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); ............ - + } // MacRLC_ParamList.numelt > 0 } -``` +``` -[Configuration module developer main page](../../config/devusage.md) +[Configuration module developer main page](../../config/devusage.md) [Configuration module home](../../config.md) diff --git a/common/config/DOC/config/devusage/api.md b/common/config/DOC/config/devusage/api.md index 050abc5315cf86384a35e2006551b3a2d47d3399..06c22dba6fe53c91034e48900d90913bb6167f52 100644 --- a/common/config/DOC/config/devusage/api.md +++ b/common/config/DOC/config/devusage/api.md @@ -25,14 +25,14 @@ int config_get(paramdef_t *params,int numparams, char *prefix) - `PARAMFLAG_DISABLECMDLINE`: parameter cannot be modified via the command line - `PARAMFLAG_DONOTREAD`: ignore the parameter, can be used at run-time, to alter a pre-defined `paramdef_t` array which is used in several `config_get` or/and `config_getlist` calls. - `PARAMFLAG_NOFREE`: do not free the memory possibly allocated by the config module to store the value of the parameter. Default behavior is for the config module to free the memory it has allocated when the `config_end` function is called. - - `PARAMFLAG_BOOL`: Only relevant for integer types. tell the config module that when processing the command line, the corresponding option can be specified without any arggument and that in this case it must set the value to 1. + - `PARAMFLAG_BOOL`: Only relevant for integer types. tell the config module that when processing the command line, the corresponding option can be specified without any arggument and that in this case it must set the value to 1. * `params` is also used as an output parameter, `< XXX >ptr >` field is used by the config module to store the value it has read. The following bits can possibly be set in the `paramflags` mask after the call: - `PARAMFLAG_MALLOCINCONFIG`: memory has been allocated for the ` < XXX >ptr > ` field - `PARAMFLAG_PARAMSET`: parameter has been found in the config source, it is not set to default value. - `PARAMFLAG_PARAMSET`: parameter has been set to its default value * `numparams` is the number of entries in the params array -* `prefix` is a character string to be appended to the parameters name, it defines the parameters position in the configuration file hierarchy (the section name in libconfig terminology). +* `prefix` is a character string to be appended to the parameters name, it defines the parameters position in the configuration file hierarchy (the section name in libconfig terminology). * The returned value is the number of parameters which have been assigned a value or -1 if a severe error occured ```c @@ -42,8 +42,8 @@ int config_libconfig_getlist(paramlist_def_t *ParamList, paramdef_t *params, int * Calls the `config_<config source>_get` function for each list occurrence * `params` points to an array of `paramdef_t` structures which describes the parameters in each occurrence of the list * `ParamList` points to a structure, where `paramarray` field points to an array of `paramdef_t` structure, allocated by the function. It is used to return the values of the parameters. -* The returned value is the number of occurrences in the list or -1 in case of severe error +* The returned value is the number of occurrences in the list or -1 in case of severe error -[Configuration module developer main page](../../config/devusage.md) +[Configuration module developer main page](../../config/devusage.md) [Configuration module home](../../config.md) diff --git a/common/config/DOC/config/devusage/struct.md b/common/config/DOC/config/devusage/struct.md index 236c1b4e0387f50add8ee03085ead2c568169c4a..e8b15fc0f1e549e03e5ef5692346b8c6e9941c90 100644 --- a/common/config/DOC/config/devusage/struct.md +++ b/common/config/DOC/config/devusage/struct.md @@ -10,11 +10,11 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla | `type` | Supported parameter types are defined as integer macros. Supported simple types are `TYPE_STRING`, parameter value is returned in `strptr` field, `TYPE_INT8` `TYPE_UINT8` `TYPE_INT16` `TYPE_UINT16` `TYPE_INT32` `TYPE_UINT32` `TYPE_INT64` `TYPE_UINT64`, parameter value is returned in the corresponding uXptr or iXptr, `TYPE_MASK`, value is returned in `u32ptr`, `TYPE_DOUBLE` value is returned in `dblptr`, `TYPE_IPV4ADDR` value is returned in binary, network bytes order in `u32ptr` field. `TYPE_STRINGLIST`, `TYPE_INTARRAY` and `TYPE_UINTARRAY` are multiple values types. Multiple values are returned in respectively, `strlistptr`, `iptr` and `uptr` fields which then point to arrays. The `numelt` field gives the number of item in the array. | I | | `numelt` | For `TYPE_STRING` where `strptr` points to a preallocated string, this field must contain the size in bytes of the available memory. For all multiple values types, this field contains the number of values in the value field.| I/O | | `chkPptr` | possible pointer to the structure containing the info used to check parameter values | I | -| `processedvalue` | When `chkPptr` is not `ǸULL`, is used to return a value, computed from the original parameter, as read from the configuration source. | O | - +| `processedvalue` | When `chkPptr` is not `ǸULL`, is used to return a value, computed from the original parameter, as read from the configuration source. | O | + # `paramlist_def_t`structure -It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160). -It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters. +It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160). +It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters. | Fields | Description | I/O | |:-----------|:------------------------------------------------------------------|----:| @@ -23,11 +23,11 @@ It is used as an argument to `config_getlist` calls, to get values of multiple o | `numelt` | Number of items in the `paramarray` field | O | # `checkedparam_t` union -It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L62). +It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L62). This union of structures is used to provide a parameter checking mechanism. Each `paramdef_t` instance may include a pointer to a `checkedparam_t`structure which is then used by the configuration module to check the value it got from the config source. Each structure in the union provides one parameter verification method, which returns `-1` when the verification fails. Currently the following structures are defined in the `checkedparam_t` union: -| structure name | Description | +| structure name | Description | |:-----------|:------------------------------------------------------------------|----:| | `s1` | check an integer against a list of authorized values | | `s1a` | check an integer against a list of authorized values and set the parameter value to another integer depending on the read value| @@ -40,14 +40,14 @@ each of these structures provide the required fields to perform the specified pa The configuration module provides an implementation of the functions to be used to check parameters, qs described below. ## `s1` structure -| field | Description | +| field | Description | |:-----------|:------------------------------------------------------------------| | `f1` | pointer to the checking function. Initialize to `config_check_intval` to use the config module implementation | | `okintval` | array of `CONFIG_MAX_NUMCHECKVAL` integers containing the authorized values | | `num_okintval` | number of used values in `okintval` | ## `s1a` structure -| field | Description | +| field | Description | |:-----------|:------------------------------------------------------------------| | `f1a` | pointer to the checking function. Initialize to `config_check_modify_integer` to use the config module implementation | | `okintval` | array of `CONFIG_MAX_NUMCHECKVAL` integers containing the authorized values | @@ -55,13 +55,13 @@ The configuration module provides an implementation of the functions to be used | `num_okintval` | number of used values in `okintval` and `setintval` | ## `s2` structure -| field | Description | +| field | Description | |:-----------|:------------------------------------------------------------------| | `f2` | pointer to the checking function. Initialize to `config_check_intrange` to use the config module implementation | | `okintrange` | array of 2 integers containing the min and max values for the parameter | ## `s3` structure -| field | Description | +| field | Description | |:-----------|:------------------------------------------------------------------| | `f3` | pointer to the checking function. Initialize to `config_check_strval` to use the config module implementation | | `okstrval` | array of `CONFIG_MAX_NUMCHECKVAL` C string pointers containing the authorized values | @@ -69,7 +69,7 @@ The configuration module provides an implementation of the functions to be used ## `s3a` structure -| field | Description | +| field | Description | |:-----------|:------------------------------------------------------------------| | `f3a` | pointer to the checking function. Initialize to `config_checkstr_assign_integer` to use the config module implementation | | `okstrval` | array of `CONFIG_MAX_NUMCHECKVAL` C string pointers containing the authorized values | @@ -77,9 +77,9 @@ The configuration module provides an implementation of the functions to be used | `num_okstrval` | number of used values in `okintval` and `setintval` | ## `s4` and `s5` structures -| field | Description | +| field | Description | |:-----------|:------------------------------------------------------------------| | `f4` or `f5` | pointer to the checking function. they are generic structures to be used when no existing structure provides the required parameter verification. `f4` takes one argument, the `paramdef_t` structure corresponding to the parameter to be checked (`int (*f4)(paramdef_t *param)`), `f5` taxes no argument (`void (*checkfunc)(void)`) | -[Configuration module developer main page](../../config/devusage.md) +[Configuration module developer main page](../../config/devusage.md) [Configuration module home](../../config.md) diff --git a/common/config/DOC/config/rtusage.md b/common/config/DOC/config/rtusage.md index 109ba84bba2b1503fab255045b11415c5b20bf44..10cbee24950bb3972f80118745f4efb65a50b516 100644 --- a/common/config/DOC/config/rtusage.md +++ b/common/config/DOC/config/rtusage.md @@ -1,34 +1,34 @@ - - -O is the only mandatory command line option to start the eNodeb softmodem (lte-softmodem executable), it is used to specify the configuration source with the associated parameters: + + -O is the only mandatory command line option to start the eNodeb softmodem (lte-softmodem executable), it is used to specify the configuration source with the associated parameters: ```bash $ ./lte-softmodem -O <configsource>:<parameter1>:<parameter2>:... ``` - The configuration module can also be used without a configuration source, ie to only parse the command line. In this case the -O switch is optional. This mode is used in the ue-softmodem executable and by the phy_simulators executables (ulsim, dlsim) + The configuration module can also be used without a configuration source, ie to only parse the command line. In this case the -O switch is optional. This mode is used in the ue-softmodem executable and by the phy_simulators executables (ulsim, dlsim) Currently the available config sources are: -- **libconfig**: libconfig file. [libconfig file format](http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files) Parameter1 is the file path and parameter 2 can be used to specify the level of console messages printed by the configuration module. +- **libconfig**: libconfig file. [libconfig file format](http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files) Parameter1 is the file path and parameter 2 can be used to specify the level of console messages printed by the configuration module. ```bash $ ./lte-softmodem -O libconfig:<config>:dbgl<debuglevel> ``` - **cmdlineonly**: command line only, the default mode for lte-uesoftmodem and the phy simiulators. In this case -O may be used to specify the config module debug level. -The debug level is a mask: -* bit 1: print parameters values +The debug level is a mask: +* bit 1: print parameters values * bit 2: print memory allocation/free performed by the config module * bit 3: print command line processing messages * bit 4: disable execution abort when parameters checking fails -As a oai user, you may have to use bit 1 (dbgl1) , to check your configuration and get the full name of a parameter you would like to modify on the command line. Other bits are for developers usage, (dbgl7 will print all debug messages). +As a oai user, you may have to use bit 1 (dbgl1) , to check your configuration and get the full name of a parameter you would like to modify on the command line. Other bits are for developers usage, (dbgl7 will print all debug messages). ```bash -$ ./lte-softmodem -O libconfig:<config>:dbgl1 +$ ./lte-softmodem -O libconfig:<config>:dbgl1 ``` ```bash $ ./lte-uesoftmodem -O cmdlineonly:dbgl1 ``` To get help on supported parameters you can use specific options: -* ---help: print help for command line only parameters and for parameters not defined in a specific section +* ---help: print help for command line only parameters and for parameters not defined in a specific section * ---help_< prefix > : print help for parameters defined under the section < prefix > ``` @@ -49,23 +49,23 @@ To get help on supported parameters you can use specific options: -C: Set the downlink frequency for all component carriers -a: Channel id offset -d: Enable soft scope and L1 and L2 stats (Xforms) - -q: Enable processing timing measurement of lte softmodem on per subframe basis - -S: Skip the missed slots/subframes + -q: Enable processing timing measurement of lte softmodem on per subframe basis + -S: Skip the missed slots/subframes --numerology: adding numerology for 5G --parallel-config: three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT' --worker-config: two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE' --nbiot-disable: disable nb-iot, even if defined in config --noS1: Disable s1 interface - --nokrnmod: (noS1 only): Use tun instead of namesh module + --nokrnmod: (noS1 only): Use tun instead of namesh module -------------------------------------------------------------------- [LIBCONFIG] (root): 4/4 parameters successfully set, (4 to default value) -----Help for section (root section) : 004 entries------ - -R: Enable online log + -R: Enable online log -g: Set the global log level, valide options: (4:trace, 3:debug, 2:info, 1:warn, (0:error)) - --telnetsrv: Start embedded telnet server - --msc: Enable the MSC tracing utility + --telnetsrv: Start embedded telnet server + --msc: Enable the MSC tracing utility -------------------------------------------------------------------- [LIBCONFIG] loader: 2/2 parameters successfully set, (2 to default value) @@ -84,13 +84,13 @@ Getting ENBSParams ``` -For the lte-softmodem (the eNodeB) The config source parameter defaults to libconfig, preserving the initial -O option format. In this case you cannot specify the debug level. +For the lte-softmodem (the eNodeB) The config source parameter defaults to libconfig, preserving the initial -O option format. In this case you cannot specify the debug level. ```bash $ ./lte-softmodem -O <config> ``` -Configuration file parameters, except for the configuration file path, can be specified in a **config** section in the configuration file: +Configuration file parameters, except for the configuration file path, can be specified in a **config** section in the configuration file: ``` config: @@ -102,8 +102,8 @@ Configuration files examples can be found in the targets/PROJECTS/GENERIC-LTE-EP ```bash $ ./lte-softmodem -O <config> --eNBs.[0].component_carriers.[0].N_RB_DL 100 -``` +``` As specified earlier, use the dbgl1 debug level to get the full name of a parameter you would like to modify on the command line. -[Configuration module home](../config.md) \ No newline at end of file +[Configuration module home](../config.md) diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index 4d32e9726fd86f0eaf8b820459cfa917ee8a7fd8..0083c2e66bf779924e549c1ee3506d8a721824e8 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -166,13 +166,14 @@ int config_check_unknown_cmdlineopt(char *prefix) { int unknowndetected=0; char testprefix[CONFIG_MAXOPTLENGTH]; int finalcheck = 0; + memset(testprefix,0,sizeof(testprefix)); memset(testprefix,0,sizeof(testprefix)); if (prefix != NULL) { if (strcmp(prefix,CONFIG_CHECKALLSECTIONS) == 0) finalcheck = 1; else if (strlen(prefix) > 0) { - sprintf(testprefix,"--%.*s.",CONFIG_MAXOPTLENGTH-1,prefix); + sprintf(testprefix,"--%.*s.",CONFIG_MAXOPTLENGTH-4,prefix); } } diff --git a/common/ngran_types.h b/common/ngran_types.h new file mode 100644 index 0000000000000000000000000000000000000000..224a85def5c704f03f873e139f3a1a4de05123f0 --- /dev/null +++ b/common/ngran_types.h @@ -0,0 +1,51 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file common/ngran_types.h +* \brief Definitions for NGRAN node types +* \author R. Knopp +* \date 2018 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ + +#ifndef __NGRAN_TYPES_H__ +#define __NGRAN_TYPES_H__ + +typedef enum { + ngran_eNB = 0, + ngran_ng_eNB = 1, + ngran_gNB = 2, + ngran_eNB_CU = 3, + ngran_ng_eNB_CU = 4, + ngran_gNB_CU = 5, + ngran_eNB_DU = 6, + ngran_gNB_DU = 7 +} ngran_node_t; + +#define NODE_IS_MONOLITHIC(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB || (nOdE_TyPe) == ngran_ng_eNB || (nOdE_TyPe) == ngran_gNB) +#define NODE_IS_CU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_CU || (nOdE_TyPe) == ngran_ng_eNB_CU || (nOdE_TyPe) == ngran_gNB_CU) +#define NODE_IS_DU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU) + +#endif diff --git a/common/ran_context.h b/common/ran_context.h index 08c05411c98fa36829c39cb5cf04ec35c0f95dfc..c0b58d2af2cc79bc09b179245a1d3e132b278ad9 100644 --- a/common/ran_context.h +++ b/common/ran_context.h @@ -39,6 +39,8 @@ #include "PHY/types.h" #include "PHY/impl_defs_top.h" #include "PHY/impl_defs_lte.h" + +#include "ENB_APP/enb_config.h" #include "RRC/LTE/rrc_defs.h" #include "flexran_agent_defs.h" @@ -49,7 +51,11 @@ #include "gtpv1u_eNB_defs.h" #include "PHY/defs_L1_NB_IoT.h" + #include "RRC/LTE/defs_NB_IoT.h" + + + typedef struct { /// RAN context config file name char *config_file_name; diff --git a/common/utils/DOC/loader/arch.md b/common/utils/DOC/loader/arch.md index 6fd1f47e7b94ec7faa8605aacaa4ec9191589bde..52ffd428ddba5fa31f9a3ddcdb784a174f606039 100644 --- a/common/utils/DOC/loader/arch.md +++ b/common/utils/DOC/loader/arch.md @@ -2,6 +2,6 @@ The oai shared library loader is implemented in two source files, located in [common/utils](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils) 1. [load_module_shlib.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.c) contains the loader implementation -1. [load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.h) is the loader include file containing both private and public data type definitions. It also contain API prototypes. +1. [load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.h) is the loader include file containing both private and public data type definitions. It also contain API prototypes. -[loader home page](../loader.md) \ No newline at end of file +[loader home page](../loader.md) diff --git a/common/utils/DOC/loader/devusage.md b/common/utils/DOC/loader/devusage.md index 915075c361d9f89c5ac38e892d95ecf4362d3481..bd45c88a85223ce1123877f339c4bfbf19663e94 100644 --- a/common/utils/DOC/loader/devusage.md +++ b/common/utils/DOC/loader/devusage.md @@ -1,16 +1,16 @@ -The loader objectives are +The loader objectives are 1. provides a common mechanism to prevent an executable to include code that is only used under specific configurations, without rebuilding the code 1. Provide a common mechanism to allow to choose between different implementations of a given set of functions, without rebuilding the code As a developer you may need to look at these sections: * [loading a shared library](devusage/loading.md) -* [loader API](devusage/api.md) -* [loader public structures](devusage/struct.md) +* [loader API](devusage/api.md) +* [loader public structures](devusage/struct.md) -Loader usage examples can be found in oai sources: +Loader usage examples can be found in oai sources: -* device and transport initialization code: [function `load_lib` in *targets/ARCH/COMMON/__common_lib.c__* ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/targets/ARCH/COMMON/common_lib.c#L91) +* device and transport initialization code: [function `load_lib` in *targets/ARCH/COMMON/__common_lib.c__* ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/targets/ARCH/COMMON/common_lib.c#L91) * turbo encoder and decoder initialization: [function `load_codinglib`in *openair1/PHY/CODING/__coding_load.c__*](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/CODING/coding_load.c#L113) [loader home page](../loader.md) diff --git a/common/utils/DOC/loader/devusage/api.md b/common/utils/DOC/loader/devusage/api.md index 21c2a1d25372e848f0723db766aafa4188edc24a..a6e59c593800ab34b93e98453660c1db73f00034 100644 --- a/common/utils/DOC/loader/devusage/api.md +++ b/common/utils/DOC/loader/devusage/api.md @@ -1,12 +1,12 @@ - Loader API is defined in the [common/utils/load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/load_module_shlib.h) include file. + Loader API is defined in the [common/utils/load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/load_module_shlib.h) include file. ```c int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) ``` -* possibly initializes the loader, if it has not been already initialized -* Formats the full shared library path, using the `modname` argument and the loader `shlibpath` and `shlibversion`configuration parameters. +* possibly initializes the loader, if it has not been already initialized +* Formats the full shared library path, using the `modname` argument and the loader `shlibpath` and `shlibversion`configuration parameters. * loads the shared library, using the dlopen system call * looks for `< modname >_autoinit` symbol, using the `dlsym` system call and possibly call the corresponding function. -* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set by the `< modname >_checkbuildver` function. +* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set by the `< modname >_checkbuildver` function. * If the farray pointer is null, looks for `< modname >_getfarray` symbol, calls the corresponding function when the symbol is found. `< modname >_getfarray` takes one argument, a pointer to a `loader_shlibfunc_t` array, and returns the number of items in this array, as defined by the `getfarrayfunc_t` type. The `loader_shlibfunc_t` array returned by the shared library must be fully filled (both `fname` and `fptr` fields). * looks for the `numf` function symbols listed in the `farray[i].fname` arguments and set the corresponding `farray[i].fptr`function pointers @@ -14,7 +14,7 @@ int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) ```c void * get_shlibmodule_fptr(char *modname, char *fname) ``` -Returns a pointer to the symbol `fname`, defined in module `modname`, or `NULL` if the symbol is not found. +Returns a pointer to the symbol `fname`, defined in module `modname`, or `NULL` if the symbol is not found. -[loader home page](../../loader.md) -[loader developer home page](../devusage.md) \ No newline at end of file +[loader home page](../../loader.md) +[loader developer home page](../devusage.md) diff --git a/common/utils/DOC/loader/devusage/loading.md b/common/utils/DOC/loader/devusage/loading.md index 766bf854620779b9c20d688feb044273850b7b16..b34782ecd3dabbd7fc5f6f9d9c22dcd6197f1bb8 100644 --- a/common/utils/DOC/loader/devusage/loading.md +++ b/common/utils/DOC/loader/devusage/loading.md @@ -10,16 +10,16 @@ Typical loader usage looks like: /* shared library loader include file */ #include "common/utils/load_module_shlib.h" ............. -/* - define and initialize the array, describing the list of functions +/* + define and initialize the array, describing the list of functions implemented in "mymodule" */ loader_shlibfunc_t mymodule_fdesc[2]; - mymodule_fdesc[0].fname="mymodule_f1"; - mymodule_fdesc[1].fname="mymodule_f2"; + mymodule_fdesc[0].fname="mymodule_f1"; + mymodule_fdesc[1].fname="mymodule_f2"; /* - load the library, it's name must be libmymod.so. Configuration can be + load the library, it's name must be libmymod.so. Configuration can be used to specify a specific path to look for libmymod.so. Configuration can also specify a version, for example "V1", in this case the loader will look for libmymodV1.so @@ -28,13 +28,13 @@ Typical loader usage looks like: if (ret < 0) { fprintf(stderr,"Library couldn't be loaded\n"); } else { -/* +/* library has been loaded, we probably want to call some functions... */ ret=((funcf1_t)mymodule_fdesc[0].fptr)(); .................. -/* +/* later and/or somewhere else in the code you may want to call function "mymodule_f2" You can use the loader get_shlibmodule_fptr(char *modname, char *fname) function to retrieve the pointer to that function @@ -50,7 +50,7 @@ if (f2 != NULL) { } ............... ``` -When loading a shared library the loader looks for a symbol named `< module name > _autoinit` and, if it finds it, calls it. The `autoinit` function is called without any argument and the returned value, if any, is not tested. +When loading a shared library the loader looks for a symbol named `< module name > _autoinit` and, if it finds it, calls it. The `autoinit` function is called without any argument and the returned value, if any, is not tested. -[loader home page](../loader.md) -[loader developer home page](../../loader/devusage.md) \ No newline at end of file +[loader home page](../loader.md) +[loader developer home page](../../loader/devusage.md) diff --git a/common/utils/DOC/loader/devusage/struct.md b/common/utils/DOC/loader/devusage/struct.md index 17504f3866fd8ebef73454c9d9c7b21841084fe2..08d4ce955893d23d6b5ef6594e81d8c2bc16ad1e 100644 --- a/common/utils/DOC/loader/devusage/struct.md +++ b/common/utils/DOC/loader/devusage/struct.md @@ -6,5 +6,5 @@ It is defined in include file [ common/util/load_module_shlib.h ](https://gitlab | `fname` | symbol name, is passed to the [`dlsym`](http://man7.org/linux/man-pages/man3/dlsym.3.html) system call performed by the loader to get a pointer to the symbol | I | | `fptr` | pointer to the symbol name, set by the loader. `fptr` is defined as a `int (*fptr)(void)` function type | O | -[loader home page](../../loader.md) -[loader developer home page](../devusage.md) \ No newline at end of file +[loader home page](../../loader.md) +[loader developer home page](../devusage.md) diff --git a/common/utils/DOC/loader/rtusage.md b/common/utils/DOC/loader/rtusage.md index bf87316e13483fc7d42f47b16ed2f165878a2a34..0bcdf6429f7a830bd7f64f7be021578408cf87a4 100644 --- a/common/utils/DOC/loader/rtusage.md +++ b/common/utils/DOC/loader/rtusage.md @@ -6,7 +6,7 @@ Shared library full names are built by the loader using the format: 1. the < *module version* > and < *path* > optional parameters, are defined at run-time, depending on the configuration. ## loader parameters -The loader is using the [configuration module](../../../config/DOC/config.md), and defines global and per library parameters. Global parameters must be specified under the **loader** section and library specific parameters under a **loader.<*module name*>** section. Module specific parameters override the global parameters. +The loader is using the [configuration module](../../../config/DOC/config.md), and defines global and per library parameters. Global parameters must be specified under the **loader** section and library specific parameters under a **loader.<*module name*>** section. Module specific parameters override the global parameters. ### Global loader parameters | name | type | default | description | |:---:|:---:|:---:|:----| @@ -39,7 +39,7 @@ If you want to load a device called *liboai_device_USRP.so* without writting a s With this latest example, nn the softmodem logs, you can check that the right device library has been loaded: ```bash -[LIBCONFIG] loader.oai_device.shlibpath not found in /usr/local/oai/develop-nb-iot-merge/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.nbiot.band7.tm1.50PRB.usrpb210.conf +[LIBCONFIG] loader.oai_device.shlibpath not found in /usr/local/oai/develop-nb-iot-merge/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.nbiot.band7.tm1.50PRB.usrpb210.conf [LIBCONFIG] loader.oai_device.shlibversion set to default value "" [LIBCONFIG] loader.oai_device: 1/2 parameters successfully set, (1 to default value) [CONFIG] shlibversion set to _USRP from command line @@ -47,4 +47,4 @@ With this latest example, nn the softmodem logs, you can check that the right de ``` -[loader home page](../loader.md) \ No newline at end of file +[loader home page](../loader.md) diff --git a/common/utils/LOG/DOC/addconsoletrace.md b/common/utils/LOG/DOC/addconsoletrace.md index d850ac1036c110f9f282c016bc9aae372819a013..9ab90cf12009e8de2bc2a5885f34dd67c4708295 100644 --- a/common/utils/LOG/DOC/addconsoletrace.md +++ b/common/utils/LOG/DOC/addconsoletrace.md @@ -12,11 +12,11 @@ these macros are used in place of the printf C function. The additionnal ***comp | macro | level letter | level value | level name | |:---------|:---------------|:---------------|----------------:| -| LOG_E | E | 0 | error | +| LOG_E | E | 0 | error | | LOG_W | W | 1 | warning | | LOG_I | I | 2 | informational | | LOG_D | D | 3 | debug | -| LOG_T | T | 4 | trace | +| LOG_T | T | 4 | trace | component list is defined as an `enum` in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h). A new component can be defined by adding an item in this type, it must also be defined in the T tracer [T_messages.txt ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/T/T_messages.txt). @@ -27,18 +27,18 @@ Most oai sources are including LOG macros. ```C LOG_DEBUGFLAG(<flag>) ``` -this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md) +this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md) ```C if ( LOG_DEBUGFLAG(<flag>) { -/* +/* the code below is only executed if the corresponding <flag>_debug option is set. - */ + */ ...................... ...................... } ``` -[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c#L396) +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c#L396) #### memory dump macros ```C @@ -47,16 +47,16 @@ LOG_DUMPFLAG(<flag>) this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md). It is mainly provided to surround LOG_M macros or direct calls to `log_dump`which otherwise would be unconditionals. ```C if ( LOG_DUMPFLAG(<flag>) { -/* +/* the code below is only executed if the corresponding <flag>_dump option is set. - */ + */ LOG_M(............. LOG_M(............. log_dump(... } -[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) #### matlab format dump ```C LOG_M(file, vector, data, len, dec, format) @@ -71,13 +71,13 @@ LOG_M(file, vector, data, len, dec, format) |format| int | defines the type of data to be dumped| This macro can be used to dump a buffer in a format that can be used for analyze via tools like matlab or octave. **It must be surrounded by LOG_DEBUGFLAG or LOG_DUMPFLAG macros, to prevent the dump to be built unconditionally.** The LOG_M macro points to the `write_file_matlab` function implemented in [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). **This function should be revisited for more understandable implementation and ease of use (format parameter ???)** -[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) #### hexadecimal format dump ```C LOG_DUMPMSG(c, f, b, s, x...) ``` -dumps a memory region if the corresponding debug flag `f` is set as explained here [run time usage page](rtusage.md) +dumps a memory region if the corresponding debug flag `f` is set as explained here [run time usage page](rtusage.md) |argument| type| description | |:-----------|:-------|-----------------:| @@ -88,12 +88,12 @@ dumps a memory region if the corresponding debug flag `f` is set as explained he | x...| printf format and arguments| text string to be printed at the top of the dump| This macro can be used to conditionaly dump a buffer, bytes by bytes, giving the integer value of each byte in hexadecimal form. -[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/RRC/LTE/rrc_eNB.c#L1181) +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/RRC/LTE/rrc_eNB.c#L1181) This macro points to the `log_dump` function, implemented in [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). This function can also dump buffers containing `double` data via the LOG_UDUMPMSG macro ```C -LOG_UDUMPMSG(c, b, s, f, x...) +LOG_UDUMPMSG(c, b, s, f, x...) ``` |argument| type| description | |:-----------|:-------|-----------------:| @@ -103,8 +103,8 @@ LOG_UDUMPMSG(c, b, s, f, x...) |f| int | format of dumped data LOG_DUMP_CHAR or LOG_DUMP_DOUBLE| | x...| printf format and arguments| text string to be printed at the top of the dump| -[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/SIMULATION/LTE_PHY/dlsim.c#L1974) +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/SIMULATION/LTE_PHY/dlsim.c#L1974) -[logging facility developer main page](devusage.md) -[logging facility main page](log.md) -[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file +[logging facility developer main page](devusage.md) +[logging facility main page](log.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/LOG/DOC/arch.md b/common/utils/LOG/DOC/arch.md index b9302927be83f5458d34fbd4c728c28fc9bb0096..1d6aeae6aa1b963c88a4c0164592e75c5806b978 100644 --- a/common/utils/LOG/DOC/arch.md +++ b/common/utils/LOG/DOC/arch.md @@ -2,11 +2,11 @@ The oai logging facility is implemented in two source files, located in [common/utils/LOG](LOG) 1. [log.c](../log.c) contains logging implementation -1. [log.h](../log.h) is the logging facility include file containing both private and public data type definitions. It also contain API prototypes. +1. [log.h](../log.h) is the logging facility include file containing both private and public data type definitions. It also contain API prototypes. The logging facility doesn't create any thread, all api's are executed in the context of the caller. The tracing macro's `LOG_<X>` are all using the logRecord_mt function to output the messages. To keep this function thread safe it must perform a single system call to the output stream. The buffer used to build the message must be specific to the calling thread, which is today enforced by using a variable in the logRecord_mt stack. Data used by the logging utility are defined by the `log_t` structure which is allocated at init time, when calling the `logInit` function. -[logging facility main page](log.md) -[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file +[logging facility main page](log.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/LOG/DOC/configurelog.md b/common/utils/LOG/DOC/configurelog.md index c671c043bd30d5ae13c82d445998edfb0e00b4e4..862c02162b1d516d5f74fba0619457bb68f4675a 100644 --- a/common/utils/LOG/DOC/configurelog.md +++ b/common/utils/LOG/DOC/configurelog.md @@ -4,7 +4,7 @@ ```C int logInit (void); ``` -Allocate the internal data used by the logging utility, set the configuration, using the [configuration module](../../../config/DOC/config.md) +Allocate the internal data used by the logging utility, set the configuration, using the [configuration module](../../../config/DOC/config.md) ```C void logClean (void) @@ -30,9 +30,9 @@ void close_component_filelog(int comp) Redirect or reset to stdout the output stream used by the logging facility. When the output stream is redirected to a file, it is created under /tmp with a hard-coded filename including the componemt name. ```C -SET_LOG_DEBUG(flag) +SET_LOG_DEBUG(flag) CLEAR_LOG_DEBUG(flag) -SET_LOG_DUMP(flag) +SET_LOG_DUMP(flag) CLEAR_LOG_DUMP(flag) ``` These macros are used to set or clear the corresponding bit flag, trigerring the activation or un-activation of conditional code or memory dumps generation. @@ -42,8 +42,8 @@ Example of using the logging utility APIs can be found, for initialization and c #### components and debug flags definitions Adding a new component is just adding an item in the `comp_name_t` enum defined in [log.h](../log.h) . You must also declare it in the T Tracer facility [message fefinitions](../../T/T_messages.txt). -To add a flag than can then be used for adding conditional code or memory dumps you have to add the flag definition in the `LOG_MASKMAP_INIT` macro, in [log.h](../log.h). +To add a flag than can then be used for adding conditional code or memory dumps you have to add the flag definition in the `LOG_MASKMAP_INIT` macro, in [log.h](../log.h). -[logging facility developer main page](devusage.md) -[logging facility main page](log.md) -[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file +[logging facility developer main page](devusage.md) +[logging facility main page](log.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/LOG/DOC/devusage.md b/common/utils/LOG/DOC/devusage.md index d7790917fc942f03b17ab891ca58a8beb44c7f29..61d25734e0a82733bd51116374f5453f1da4ccb4 100644 --- a/common/utils/LOG/DOC/devusage.md +++ b/common/utils/LOG/DOC/devusage.md @@ -1,14 +1,14 @@ ### logging facility developer usage -The logging facility objectives are -1. provide a common console tracing mechanism +The logging facility objectives are +1. provide a common console tracing mechanism 1. Allow a flexible activation of console traces, by configuration or dynamically at any time while code is running. -Most developpers will only use the log macros to add console messages to the code. The logging facility also provides an api that is used for initialization and configuration. +Most developpers will only use the log macros to add console messages to the code. The logging facility also provides an api that is used for initialization and configuration. -[Adding console traces in oaicode](addconsoletrace.md) +[Adding console traces in oaicode](addconsoletrace.md) -[Configuring the logging facility](configurelog.md) +[Configuring the logging facility](configurelog.md) -[logging facility main page](log.md) +[logging facility main page](log.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/LOG/DOC/log.md b/common/utils/LOG/DOC/log.md index 121e227f3d92233e021941f5e9c1ca0f1cdab204..4b3e5981e1da3b4205bdc7f126fd92773d65730f 100644 --- a/common/utils/LOG/DOC/log.md +++ b/common/utils/LOG/DOC/log.md @@ -1,6 +1,6 @@ # OAI console logging facility -oai includes a console logging facility that any component should use when writting informational or debugging messages to the softmodem or uesoftmodem stdout stream. +oai includes a console logging facility that any component should use when writting informational or debugging messages to the softmodem or uesoftmodem stdout stream. By default, this facility is included at build-time and activated at run-time. The T Tracer and the Logging facility share common options for activation: - To disable the logging facility (and T Tracer) at build-time use the *--disable-T-Tracer* switch: diff --git a/common/utils/LOG/DOC/rtusage.md b/common/utils/LOG/DOC/rtusage.md index 60835bafaf1edfaff43e76e739fa6dab5cedbb4b..445f335725c57fcc3675b9df0a608b8e2f3cab90 100644 --- a/common/utils/LOG/DOC/rtusage.md +++ b/common/utils/LOG/DOC/rtusage.md @@ -1,5 +1,5 @@ ## configuring the logging facility -The logging facility is fully configurable and it uses the [config module](../../../config/config.md) to get its parameters at init time. The [telnet server](../../telnetsrv/DOC/telnetsrv.md) includes a set of commands which can be used to dynamically modify the logging facility behavior +The logging facility is fully configurable and it uses the [config module](../../../config/config.md) to get its parameters at init time. The [telnet server](../../telnetsrv/DOC/telnetsrv.md) includes a set of commands which can be used to dynamically modify the logging facility behavior All logging facility parameters are defined in the log_config section. Some parameters are global to the logging facility, they modify the way messages are printed to stdout. Conversely, some parameters are specific to a component and only modify the behavior for messages issued by a given component. A third type of parameters can be used to activate conditional debug code or dump messages or buffers. @@ -14,7 +14,7 @@ All logging facility parameters are defined in the log_config section. Some para ### Component specific parameters | name | type | default | description | |:---:|:---:|:---:|:----| -| `<component>_log_level` | `boolean` | global log level, as defined by the `global_log_level ` parameter) | +| `<component>_log_level` | `boolean` | global log level, as defined by the `global_log_level ` parameter) | | `<component>_log_infile` | `boolean` | 0 = false| Triggers the redirection of log messages printed by the specified component in a file. The file path and name is /tmp/<componemt>.[extension] the extension is optional and component dependant, it can be `log `, `dat `, `txt `| The list of components defined within oai can be retrieved from the [config module](../../../config/config.md) traces, when asking for config module debugging info on the command line: @@ -215,7 +215,7 @@ The list of components defined within oai can be retrieved from the [config mod log init done ``` -It can also be retrieved when using the telnet server, as explained [below](### Using the telnet server to configure the logging facility) +It can also be retrieved when using the telnet server, as explained [below](### Using the telnet server to configure the logging facility) ### parameters to activate conditional code | name | type | default | description | @@ -238,15 +238,15 @@ The following example sets all components log level to info, exept for hw,phy,ma }; ``` ### Using the command line to configure the logging facility -Command line parameter values supersedes values specified in the configuration file. +Command line parameter values supersedes values specified in the configuration file. ```bash -./lte-softmodem -O --log_config.global_log_options nocolor,level,thread --log_config.prach_log_level debug --log_config.PRACH_debug +./lte-softmodem -O --log_config.global_log_options nocolor,level,thread --log_config.prach_log_level debug --log_config.PRACH_debug ``` In this example to get all the debug PRACH messages it is necessary to also set the PRACH_debug flag. This is a choice from the developper. The log messages will be printed whithout color and the header will include the lmessage evel and the thread name: ```bash -[PHY]I ru thread Time in secs now: 104652566 -[PHY]I ru thread Time in secs last pps: 91827117 +[PHY]I ru thread Time in secs now: 104652566 +[PHY]I ru thread Time in secs last pps: 91827117 [PHY]I ru thread RU 0 rf device ready [PHY]I ru thread RU 0 no asynch_south interface [MAC]E rxtx processing SCHED_MODE=0 @@ -256,10 +256,10 @@ The log messages will be printed whithout color and the header will include the [PHY]I lte-softmodem PRACH (eNB) : running rx_prach for subframe 1, prach_FreqOffset 2, prach_ConfigIndex 0 , rootSequenceIndex 0 [PHY]I lte-softmodem PRACH (eNB) : running rx_prach for subframe 1, prach_FreqOffset 2, prach_ConfigIndex 0 , rootSequenceIndex 0 ``` - + ### Using the telnet server to configure the logging facility The telnet server includes a `log` command which can be used to dymically modify the logging facility configuration parameters. -[telnet server ***softmodem log*** commands](../../telnetsrv/DOC/telnetlog.md) +[telnet server ***softmodem log*** commands](../../telnetsrv/DOC/telnetlog.md) -[logging facility main page](log.md) +[logging facility main page](log.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 7a2f2b99f44862db82e43a41e8db1ed797745533..87150650db697c5f3c6e2127c125039f6a0e3269 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -303,8 +303,8 @@ void log_getconfig(log_t *g_log) { logparams_dump[i].numelt = 0; } - config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX); - config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX); + config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX); + config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX); config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX); /* set the debug mask according to the debug parameters values */ @@ -385,7 +385,6 @@ int logInit (void) { register_log_component("OCG","",OCG); register_log_component("PERF","",PERF); register_log_component("OIP","",OIP); - register_log_component("CLI","",CLI); register_log_component("MSC","log",MSC); register_log_component("OCM","log",OCM); register_log_component("HW","",HW); @@ -394,20 +393,25 @@ int logInit (void) { register_log_component("mRAL","",RAL_UE); register_log_component("ENB_APP","log",ENB_APP); register_log_component("FLEXRAN_AGENT","log",FLEXRAN_AGENT); + register_log_component("PROTO_AGENT","log",PROTO_AGENT); register_log_component("TMR","",TMR); register_log_component("USIM","txt",USIM); register_log_component("SIM","txt",SIM); /* following log component are used for the localization*/ + /* following log component are used for the localization*/ register_log_component("LOCALIZE","log",LOCALIZE); register_log_component("NAS","log",NAS); register_log_component("UDP","",UDP_); register_log_component("GTPV1U","",GTPU); register_log_component("S1AP","",S1AP); + register_log_component("F1AP","",F1AP); register_log_component("X2AP","",X2AP); register_log_component("SCTP","",SCTP); register_log_component("X2AP","",X2AP); register_log_component("LOADER","log",LOADER); register_log_component("ASN","log",ASN); + register_log_component("NFAPI_PNF","log",NFAPI_PNF); + register_log_component("NFAPI_VNF","log",NFAPI_VNF); for (int i=0 ; log_level_names[i].name != NULL ; i++) g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name @@ -438,7 +442,7 @@ char *log_getthreadname(char *threadname, int bufsize) { static int log_header(char *log_buffer, int buffsize, int comp, int level,const char *format) { char threadname[PR_SET_NAME]; - return snprintf(log_buffer, buffsize , "%s%s[%s]%c %s %s%s", + return snprintf(log_buffer, buffsize, "%s%s[%s]%c %s %s%s", log_level_highlight_end[level], ( (g_log->flag & FLAG_NOCOLOR)?"":log_level_highlight_start[level]), g_log->log_component[comp].name, @@ -452,11 +456,17 @@ void logRecord_mt(const char *file, const char *func, int line, int comp, int le char log_buffer[MAX_LOG_TOTAL]; va_list args; va_start(args, format); - log_header(log_buffer,MAX_LOG_TOTAL ,comp, level,format); + log_header(log_buffer,MAX_LOG_TOTAL,comp, level,format); g_log->log_component[comp].vprint(g_log->log_component[comp].stream,log_buffer, args); va_end(args); } +void vlogRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, va_list args ) { + char log_buffer[MAX_LOG_TOTAL]; + log_header(log_buffer,MAX_LOG_TOTAL,comp, level,format); + g_log->log_component[comp].vprint(g_log->log_component[comp].stream,log_buffer, args); +} + void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... ) { va_list args; char *wbuf; @@ -474,7 +484,7 @@ void log_dump(int component, void *buffer, int buffsize,int datatype, const char if (wbuf != NULL) { va_start(args, format); - int pos=log_header(wbuf,MAX_LOG_TOTAL ,component, OAILOG_INFO,""); + int pos=log_header(wbuf,MAX_LOG_TOTAL,component, OAILOG_INFO,""); int pos2=vsprintf(wbuf+pos,format, args); pos=pos+pos2; va_end(args); diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 5d8ad06bec03c5f92698397f01f58a8cae62b145..dea756a3acf58618aaa2c53cc041b83f53c1b6a5 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -198,13 +198,13 @@ typedef enum { NAS, PERF, OIP, - CLI, MSC, OCM, UDP_, GTPU, SPGW, S1AP, + F1AP, SCTP, HW, OSA, @@ -215,9 +215,13 @@ typedef enum { TMR, USIM, LOCALIZE, + PROTO_AGENT, + F1U, X2AP, LOADER, ASN, + NFAPI_VNF, + NFAPI_PNF, MAX_LOG_PREDEF_COMPONENTS, } comp_name_t; @@ -286,6 +290,7 @@ extern "C" { int logInit (void); int isLogInitDone (void); void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7))); +void vlogRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, va_list args ); void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... ); int set_log(int component, int level); void set_glog(int level); @@ -365,9 +370,9 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int # define LOG_I(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} else { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ;}} while (0) # define LOG_D(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} else { T(T_LEGACY_ ## c ## _DEBUG, T_PRINTF(x)) ;}} while (0) # define LOG_T(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} else { T(T_LEGACY_ ## c ## _TRACE, T_PRINTF(x)) ;}} while (0) +# define VLOG(c,l, f, args) do { if (T_stdout) { if( g_log->log_component[c].level >= l ) vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, l, f, args) ;} } while (0) /* macro used to dump a buffer or a message as in openair2/RRC/LTE/RRC_eNB.c, replaces LOG_F macro */ # define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */ -# define nfapi_log(FILE, FNC, LN, COMP, LVL, F...) do { if (T_stdout) { logRecord_mt(__FILE__, __FUNCTION__, __LINE__,COMP, LVL, F) ;}} while (0) /* */ /* bitmask dependant macros, to isolate debugging code */ # define LOG_DEBUGFLAG(D) (g_log->debug_mask & D) diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index d7f439f351475747d3f6f3b4903c68f5b2f9a3a5..db2385ea85cc39cd904507427e03c13392e05189 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -189,7 +189,15 @@ const char* eurecomVariablesNames[] = { "ue0_trx_write_ns_missing", "enb_thread_rxtx_CPUID", "ru_thread_CPUID", - "ru_thread_tx_CPUID" + "ru_thread_tx_CPUID", + "ue0_on_duration_timer", + "ue0_drx_inactivity", + "ue0_drx_short_cycle", + "ue0_short_drx_cycle_number", + "ue0_drx_long_cycle", + "ue0_drx_retransmission_harq0", + "ue0_drx_active_time", + "ue0_drx_active_time_condition" }; const char* eurecomFunctionsNames[] = { diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index d77722f581f4d8d9c2186ddc194bc119a1c883bc..fca1aa40bd52357d763c2c074cbd55bce1044557 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -167,6 +167,14 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX, VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD, VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX, + VCD_SIGNAL_DUMPER_VARIABLES_ON_DURATION_TIMER, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_SHORT_CYCLE, + VCD_SIGNAL_DUMPER_VARIABLES_SHORT_DRX_CYCLE_NUMBER, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_LONG_CYCLE, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_ACTIVE_TIME, + VCD_SIGNAL_DUMPER_VARIABLES_DRX_ACTIVE_TIME_CONDITION, VCD_SIGNAL_DUMPER_VARIABLES_END } vcd_signal_dump_variables; diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 95440337a76d00ad8ea6926f81df57be2a08cb92..ecb6f9389d34964f959a6d491d05b4e7a80c4f23 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -44,7 +44,7 @@ typedef struct { #define VCD_NUM_FUNCTIONS 195 /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_VARIABLES 128 +#define VCD_NUM_VARIABLES 136 /* first VCD function (to be kept up to date! see in T_messages.txt) */ #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index ea4b6b8476b1f33d5fbbbf4892121b1b76126f84..68dcc24e44d17d324eff177a83146090e7830657 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -629,7 +629,7 @@ ID = LEGACY_OCM_DEBUG FORMAT = string,log ID = LEGACY_OCM_TRACE DESC = OCM legacy logs - trace level - GROUP = ALL:LEGACY_OCM:LEGACY_GROUP_TRACE:LEGACY + OGROUP = ALL:LEGACY_OCM:LEGACY_GROUP_TRACE:LEGACY FORMAT = string,log ID = LEGACY_OIP_INFO @@ -800,6 +800,47 @@ ID = LEGACY_SIM_TRACE GROUP = ALL:LEGACY_SIM:LEGACY_GROUP_TRACE:LEGACY FORMAT = string,log +ID = LEGACY_NFAPI_VNF_INFO + DESC = NFAPI_VNF legacy logs - info level + GROUP = ALL:LEGACY_NFAPI_VNF:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_NFAPI_VNF_ERROR + DESC = NFAPI_VNF legacy logs - error level + GROUP = ALL:LEGACY_NFAPI_VNF:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_NFAPI_VNF_WARNING + DESC = NFAPI_VNF legacy logs - warning level + GROUP = ALL:LEGACY_NFAPI_VNF:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_NFAPI_VNF_DEBUG + DESC = NFAPI_VNF legacy logs - debug level + GROUP = ALL:LEGACY_NFAPI_VNF:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_NFAPI_VNF_TRACE + DESC = NFAPI_VNF legacy logs - trace level + GROUP = ALL:LEGACY_NFAPI_VNF:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log + +ID = LEGACY_NFAPI_PNF_INFO + DESC = NFAPI_PNF legacy logs - info level + GROUP = ALL:LEGACY_NFAPI_PNF:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_NFAPI_PNF_ERROR + DESC = NFAPI_PNF legacy logs - error level + GROUP = ALL:LEGACY_NFAPI_PNF:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_NFAPI_PNF_WARNING + DESC = NFAPI_PNF legacy logs - warning level + GROUP = ALL:LEGACY_NFAPI_PNF:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_NFAPI_PNF_DEBUG + DESC = NFAPI_PNF legacy logs - debug level + GROUP = ALL:LEGACY_NFAPI_PNF:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_NFAPI_PNF_TRACE + DESC = NFAPI_PNF legacy logs - trace level + GROUP = ALL:LEGACY_NFAPI_PNF:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log # this is a bad hack but I won't fix (function util_print_hex_octets # in openairinterface5g/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c # does funky things with the LOG_x macros but we work on the C pre-processor @@ -845,26 +886,62 @@ ID = LEGACY_componentP_TRACE GROUP = ALL:LEGACY_componentP:LEGACY_GROUP_TRACE:LEGACY FORMAT = string,log -#needed? -ID = LEGACY_CLI_INFO - DESC = CLI legacy logs - info level - GROUP = ALL:LEGACY_CLI:LEGACY_GROUP_INFO:LEGACY + + +ID = LEGACY_PROTO_AGENT_DEBUG + DESC = PROTO AGENT DEBUG LEVEL + GROUP = ALL:LEGACY_PROTO:LEGACY_GROUP_DEBUG:LEGACY FORMAT = string,log -ID = LEGACY_CLI_ERROR - DESC = CLI legacy logs - error level - GROUP = ALL:LEGACY_CLI:LEGACY_GROUP_ERROR:LEGACY + +ID = LEGACY_PROTO_AGENT_INFO + DESC = PROTO AGENT INFO LEVEL + GROUP = ALL:LEGACY_PROTO:LEGACY_GROUP_INFO:LEGACY FORMAT = string,log -ID = LEGACY_CLI_WARNING - DESC = CLI legacy logs - warning level - GROUP = ALL:LEGACY_CLI:LEGACY_GROUP_WARNING:LEGACY + +ID = LEGACY_PROTO_AGENT_WARNING + DESC = PROTO AGENT WARNING LEVEL + GROUP = ALL:LEGACY_PROTO:LEGACY_GROUP_WARNING:LEGACY FORMAT = string,log -ID = LEGACY_CLI_DEBUG - DESC = CLI legacy logs - debug level - GROUP = ALL:LEGACY_CLI:LEGACY_GROUP_DEBUG:LEGACY + +ID = LEGACY_PROTO_AGENT_ERROR + DESC = PROTO AGENT ERROR LEVEL + GROUP = ALL:LEGACY_PROTO:LEGACY_GROUP_ERROR:LEGACY FORMAT = string,log -ID = LEGACY_CLI_TRACE - DESC = CLI legacy logs - trace level - GROUP = ALL:LEGACY_CLI:LEGACY_GROUP_TRACE:LEGACY + +ID = LEGACY_F1U_DEBUG + DESC = F1U DEBUG LEVEL + GROUP = ALL:LEGACY_F1U:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log + +ID = LEGACY_F1U_INFO + DESC = F1U INFO LEVEL + GROUP = ALL:LEGACY_F1U:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log + +ID = LEGACY_F1U_ERROR + DESC = F1U ERROR LEVEL + GROUP = ALL:LEGACY_F1U:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log + +ID = LEGACY_F1AP_TRACE + DESC = F1AP TRACE LEVEL + GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log +ID = LEGACY_F1AP_DEBUG + DESC = F1AP DEBUG LEVEL + GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_F1AP_INFO + DESC = F1AP INFO LEVEL + GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_F1AP_WARNING + DESC = F1AP WARNING LEVEL + GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_F1AP_ERROR + DESC = F1AP ERROR LEVEL + GROUP = ALL:LEGACY_F1AP:LEGACY_GROUP_ERROR:LEGACY FORMAT = string,log ################# @@ -1599,6 +1676,46 @@ ID = VCD_VARIABLE_CPUID_RU_THREAD_TX GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value VCD_NAME = ru_thread_tx_CPUID +ID = VCD_VARIABLE_ON_DURATION_TIMER + DESC = VCD variable ON_DURATION_TIMER + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_on_duration_timer +ID = VCD_VARIABLE_DRX_INACTIVITY + DESC = VCD variable DRX_INACTIVITY + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_inactivity +ID = VCD_VARIABLE_DRX_SHORT_CYCLE + DESC = VCD variable DRX_SHORT_CYCLE + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_short_cycle +ID = VCD_VARIABLE_SHORT_DRX_CYCLE_NUMBER + DESC = VCD variable SHORT_DRX_CYCLE_NUMBER + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_short_drx_cycle_number +ID = VCD_VARIABLE_DRX_LONG_CYCLE + DESC = VCD variable DRX_LONG_CYCLE + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_long_cycle +ID = VCD_VARIABLE_DRX_RETRANSMISSION_HARQ0 + DESC = VCD variable DRX_RETRANSMISSION_HARQ0 + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_retransmission_harq0 +ID = VCD_VARIABLE_DRX_ACTIVE_TIME + DESC = VCD variable DRX_ACTIVE_TIME + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_active_time +ID = VCD_VARIABLE_DRX_ACTIVE_TIME_CONDITION + DESC = VCD variable DRX_ACTIVE_TIME_CONDITION + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ue0_drx_active_time_condition #functions diff --git a/common/utils/T/local_tracer.c b/common/utils/T/local_tracer.c index f8e92881a96e79a000e57fcad814e8440719a895..4be0b35d16a28c3fa9492e5a60a81401d0ff9e5e 100644 --- a/common/utils/T/local_tracer.c +++ b/common/utils/T/local_tracer.c @@ -31,7 +31,7 @@ typedef struct { int remote_port; pthread_mutex_t lock; pthread_cond_t cond; - databuf * volatile head, *tail; + databuf *volatile head, *tail; uint64_t memusage; uint64_t last_warning_memusage; } forward_data; @@ -40,80 +40,115 @@ typedef struct { /* utility functions */ /****************************************************************************/ -static void new_thread(void *(*f)(void *), void *data) -{ +static void new_thread(void *(*f)(void *), void *data) { pthread_t t; pthread_attr_t att; - if (pthread_attr_init(&att)) - { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } - if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) - { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } - if (pthread_attr_setstacksize(&att, 10000000)) - { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } - if (pthread_create(&t, &att, f, data)) - { fprintf(stderr, "pthread_create err\n"); exit(1); } - if (pthread_attr_destroy(&att)) - { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } + if (pthread_attr_init(&att)) { + fprintf(stderr, "pthread_attr_init err\n"); + exit(1); + } + + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) { + fprintf(stderr, "pthread_attr_setdetachstate err\n"); + exit(1); + } + + if (pthread_attr_setstacksize(&att, 10000000)) { + fprintf(stderr, "pthread_attr_setstacksize err\n"); + exit(1); + } + + if (pthread_create(&t, &att, f, data)) { + fprintf(stderr, "pthread_create err\n"); + exit(1); + } + + if (pthread_attr_destroy(&att)) { + fprintf(stderr, "pthread_attr_destroy err\n"); + exit(1); + } } -static int get_connection(char *addr, int port) -{ +static int get_connection(char *addr, int port) { struct sockaddr_in a; socklen_t alen; int s, t; - printf("T tracer: waiting for connection on %s:%d\n", addr, port); - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) { perror("socket"); exit(1); } + + if (s == -1) { + perror("socket"); + exit(1); + } + t = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) - { perror("setsockopt"); exit(1); } + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int))) { + perror("setsockopt"); + exit(1); + } a.sin_family = AF_INET; a.sin_port = htons(port); a.sin_addr.s_addr = inet_addr(addr); - if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } - if (listen(s, 5)) { perror("bind"); exit(1); } + if (bind(s, (struct sockaddr *)&a, sizeof(a))) { + perror("bind"); + exit(1); + } + + if (listen(s, 5)) { + perror("bind"); + exit(1); + } + alen = sizeof(a); t = accept(s, (struct sockaddr *)&a, &alen); - if (t == -1) { perror("accept"); exit(1); } - close(s); - printf("T tracer: connected\n"); + if (t == -1) { + perror("accept"); + exit(1); + } + close(s); + printf("T tracer: connected\n"); return t; } static void forward(void *_forwarder, char *buf, int size); -void send_T_messages_txt(void *forwarder) -{ +void send_T_messages_txt(void *forwarder) { char buf[T_BUFFER_MAX]; char *T_LOCAL_buf = buf; int T_LOCAL_size; unsigned char *src; int src_len; - /* trace T_message.txt * Send several messages -1 with content followed by message -2. */ src = T_messages_txt; src_len = T_messages_txt_len; + while (src_len) { int send_size = src_len; + if (send_size > T_PAYLOAD_MAXSIZE - sizeof(int)) send_size = T_PAYLOAD_MAXSIZE - sizeof(int); + /* TODO: be careful, we use internal T stuff, to rewrite? */ T_LOCAL_size = 0; T_HEADER(T_ID(-1)); - T_PUT_buffer(1, ((T_buffer){addr:(src), length:(send_size)})); + T_PUT_buffer(1, ((T_buffer) { +addr: +(src), length: + (send_size) + })); forward(forwarder, buf, T_LOCAL_size); src += send_size; src_len -= send_size; } + T_LOCAL_size = 0; T_HEADER(T_ID(-2)); forward(forwarder, buf, T_LOCAL_size); @@ -123,49 +158,54 @@ void send_T_messages_txt(void *forwarder) /* forward functions */ /****************************************************************************/ -static void *data_sender(void *_f) -{ +static void *data_sender(void *_f) { forward_data *f = _f; databuf *cur; char *buf, *b; int size; - wait: + if (pthread_mutex_lock(&f->lock)) abort(); + while (f->head == NULL) if (pthread_cond_wait(&f->cond, &f->lock)) abort(); + cur = f->head; buf = cur->d; size = cur->l; f->head = cur->next; f->memusage -= size; + if (f->head == NULL) f->tail = NULL; + if (pthread_mutex_unlock(&f->lock)) abort(); + free(cur); goto process; - process: b = buf; + if (f->socket_remote != -1) - while (size) { - int l = write(f->socket_remote, b, size); - if (l <= 0) { - printf("T tracer: forward error\n"); - close(f->socket_remote); - f->socket_remote = -1; - break; + while (size) { + int l = write(f->socket_remote, b, size); + + if (l <= 0) { + printf("T tracer: forward error\n"); + close(f->socket_remote); + f->socket_remote = -1; + break; + } + + size -= l; + b += l; } - size -= l; - b += l; - } free(buf); - goto wait; } -static void *forward_remote_messages(void *_f) -{ + +static void *forward_remote_messages(void *_f) { #define PUT(x) do { \ if (bufsize == bufmaxsize) { \ bufmaxsize += 4096; \ @@ -180,7 +220,6 @@ static void *forward_remote_messages(void *_f) int len = l; \ while (len) { PUT(*zz); zz++; len--; } \ } while (0) - forward_data *f = _f; int from; int to; @@ -190,43 +229,53 @@ static void *forward_remote_messages(void *_f) int bufsize = 0; int bufmaxsize = 0; char t; - again: while (1) { from = f->socket_remote; to = f->socket_local; - bufsize = 0; - /* let's read and process messages */ - len = read(from, &t, 1); if (len <= 0) goto dead; + len = read(from, &t, 1); + + if (len <= 0) goto dead; + PUT(t); switch (t) { - case 0: - case 1: - /* message 0 and 1: get a length and then 'length' numbers */ - if (read(from, &len, sizeof(int)) != sizeof(int)) goto dead; - PUT_BUF(&len, 4); - while (len) { - if (read(from, &l, sizeof(int)) != sizeof(int)) goto dead; - PUT_BUF(&l, 4); - len--; - } - break; + case 0: + case 1: + + /* message 0 and 1: get a length and then 'length' numbers */ + if (read(from, &len, sizeof(int)) != sizeof(int)) goto dead; + + PUT_BUF(&len, 4); + + while (len) { + if (read(from, &l, sizeof(int)) != sizeof(int)) goto dead; + + PUT_BUF(&l, 4); + len--; + } + + break; + + case 2: + break; - case 2: break; - default: - printf("%s:%d:%s: unhandled message type %d\n", - __FILE__, __LINE__, __FUNCTION__, t); - abort(); + default: + printf("%s:%d:%s: unhandled message type %d\n", + __FILE__, __LINE__, __FUNCTION__, t); + abort(); } b = buf; + while (bufsize) { l = write(to, b, bufsize); + if (l <= 0) abort(); + bufsize -= l; b += l; } @@ -236,71 +285,80 @@ dead: /* socket died, let's stop all traces and wait for another tracer */ /* TODO: be careful with those write, they might write less than wanted */ buf[0] = 1; + if (write(to, buf, 1) != 1) abort(); + len = T_NUMBER_OF_IDS; + if (write(to, &len, sizeof(int)) != sizeof(int)) abort(); + l = 0; + while (len) { if (write(to, &l, sizeof(int)) != sizeof(int)) abort(); + len--; }; close(f->socket_remote); + f->socket_remote = get_connection("0.0.0.0", f->remote_port); + send_T_messages_txt(f); + goto again; return NULL; } -static void *forwarder(int port, int s) -{ +static void *forwarder(int port, int s) { forward_data *f; + f = malloc(sizeof(*f)); - f = malloc(sizeof(*f)); if (f == NULL) abort(); + if (f == NULL) abort(); pthread_mutex_init(&f->lock, NULL); pthread_cond_init(&f->cond, NULL); - f->socket_local = s; f->head = f->tail = NULL; - f->memusage = 0; f->last_warning_memusage = 0; - printf("T tracer: waiting for remote tracer on port %d\n", port); - f->remote_port = port; f->socket_remote = get_connection("0.0.0.0", port); send_T_messages_txt(f); - new_thread(data_sender, f); new_thread(forward_remote_messages, f); - return f; } -static void forward(void *_forwarder, char *buf, int size) -{ +static void forward(void *_forwarder, char *buf, int size) { forward_data *f = _forwarder; int32_t ssize = size; databuf *new; + new = malloc(sizeof(*new)); - new = malloc(sizeof(*new)); if (new == NULL) abort(); + if (new == NULL) abort(); if (pthread_mutex_lock(&f->lock)) abort(); - new->d = malloc(size + 4); if (new->d == NULL) abort(); + new->d = malloc(size + 4); + + if (new->d == NULL) abort(); + /* put the size of the message at the head */ memcpy(new->d, &ssize, 4); memcpy(new->d+4, buf, size); new->l = size+4; new->next = NULL; + if (f->head == NULL) f->head = new; + if (f->tail != NULL) f->tail->next = new; - f->tail = new; + f->tail = new; #if BASIC_SIMULATOR + /* When runnng the basic simulator, the tracer may be too slow. * Let's not take too much memory in the tracee and * wait if there is too much data to send. 200MB is @@ -308,26 +366,30 @@ static void forward(void *_forwarder, char *buf, int size) */ while (f->memusage > 200 * 1024 * 1024) { if (pthread_cond_signal(&f->cond)) abort(); + if (pthread_mutex_unlock(&f->lock)) abort(); + usleep(1000); + if (pthread_mutex_lock(&f->lock)) abort(); } -#endif /* BASIC_SIMULATOR */ +#endif /* BASIC_SIMULATOR */ f->memusage += size+4; + /* warn every 100MB */ if (f->memusage > f->last_warning_memusage && f->memusage - f->last_warning_memusage > 100000000) { f->last_warning_memusage += 100000000; printf("T tracer: WARNING: memory usage is over %"PRIu64"MB\n", f->last_warning_memusage / 1000000); - } else - if (f->memusage < f->last_warning_memusage && - f->last_warning_memusage - f->memusage > 100000000) { + } else if (f->memusage < f->last_warning_memusage && + f->last_warning_memusage - f->memusage > 100000000) { f->last_warning_memusage = (f->memusage/100000000) * 100000000; } if (pthread_cond_signal(&f->cond)) abort(); + if (pthread_mutex_unlock(&f->lock)) abort(); } @@ -335,14 +397,12 @@ static void forward(void *_forwarder, char *buf, int size) /* local functions */ /****************************************************************************/ -static void wait_message(void) -{ +static void wait_message(void) { while ((T_local_cache[T_busylist_head].busy & 0x02) == 0) usleep(1000); } void T_local_tracer_main(int remote_port, int wait_for_tracer, - int local_socket, void *shm_array) -{ + int local_socket, void *shm_array) { int s; int port = remote_port; int dont_wait = wait_for_tracer ? 0 : 1; @@ -350,16 +410,16 @@ void T_local_tracer_main(int remote_port, int wait_for_tracer, /* write on a socket fails if the other end is closed and we get SIGPIPE */ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { - printf("local tracer received SIGPIPE\n"); - abort(); + printf("local tracer received SIGPIPE\n"); + abort(); } T_local_cache = shm_array; - s = local_socket; if (dont_wait) { char t = 2; + if (write(s, &t, 1) != 1) abort(); } diff --git a/common/utils/T/tracer/gui/notify.c b/common/utils/T/tracer/gui/notify.c index 7ff40069411a1bd9bae7d0106b686c41b04b6ef6..5798a0121985aa0535413bf1244e122bd1a08f90 100644 --- a/common/utils/T/tracer/gui/notify.c +++ b/common/utils/T/tracer/gui/notify.c @@ -5,62 +5,56 @@ #include <string.h> unsigned long register_notifier(gui *_g, char *notification, widget *w, - notifier handler, void *private) -{ + notifier handler, void *private) { struct gui *g = _g; unsigned long ret; - glock(g); if (g->next_notifier_id == 2UL * 1024 * 1024 * 1024) ERR("%s:%d: report a bug\n", __FILE__, __LINE__); g->notifiers = realloc(g->notifiers, - (g->notifiers_count+1) * sizeof(struct notifier)); + (g->notifiers_count+1) * sizeof(struct notifier)); + if (g->notifiers == NULL) abort(); ret = g->next_notifier_id; - g->notifiers[g->notifiers_count].handler = handler; g->notifiers[g->notifiers_count].id = g->next_notifier_id; g->next_notifier_id++; g->notifiers[g->notifiers_count].notification = strdup(notification); + if (g->notifiers[g->notifiers_count].notification == NULL) abort(); + g->notifiers[g->notifiers_count].w = w; g->notifiers[g->notifiers_count].private = private; /* initialize done to 1 so as not to call the handler if it's created * by the call of another one that is in progress */ g->notifiers[g->notifiers_count].done = 1; - g->notifiers_count++; - gunlock(g); - return ret; } -void unregister_notifier(gui *_g, unsigned long notifier_id) -{ +void unregister_notifier(gui *_g, unsigned long notifier_id) { struct gui *g = _g; int i; - glock(g); for (i = 0; i < g->notifiers_count; i++) if (g->notifiers[i].id == notifier_id) break; if (i == g->notifiers_count) - ERR("%s:%d: notifier_id %ld not found\n", __FILE__,__LINE__,notifier_id); + ERR("%s:%d: notifier_id %lu not found\n", __FILE__,__LINE__,notifier_id); free(g->notifiers[i].notification); - memmove(g->notifiers + i, g->notifiers + i + 1, - (g->notifiers_count-1 - i) * sizeof(struct notifier)); - + (g->notifiers_count-1 - i) * sizeof(struct notifier)); g->notifiers_count--; g->notifiers = realloc(g->notifiers, - g->notifiers_count * sizeof(struct notifier)); + g->notifiers_count * sizeof(struct notifier)); + if (g->notifiers == NULL) abort(); gunlock(g); @@ -68,19 +62,19 @@ void unregister_notifier(gui *_g, unsigned long notifier_id) /* called with lock ON */ void gui_notify(struct gui *g, char *notification, widget *w, - void *notification_data) -{ + void *notification_data) { void *private; notifier handler; int i; - /* this function is not re-entrant, for the moment keep as is * and if the need is there, we'll make a new thread to handle * notifications (or something) * for now let's crash in case of recursive call */ static int inside = 0; + if (inside) ERR("%s:%d: BUG! contact the authors\n", __FILE__, __LINE__); + inside = 1; /* clear all handlers */ @@ -91,26 +85,25 @@ void gui_notify(struct gui *g, char *notification, widget *w, * need to be careful here */ loop: + for (i = 0; i < g->notifiers_count; i++) { if (g->notifiers[i].done == 1 || g->notifiers[i].w != w || strcmp(g->notifiers[i].notification, notification) != 0) continue; + break; } + if (i == g->notifiers_count) goto done; g->notifiers[i].done = 1; - handler = g->notifiers[i].handler; private = g->notifiers[i].private; - gunlock(g); handler(private, g, notification, w, notification_data); glock(g); - goto loop; - done: inside = 0; } diff --git a/common/utils/T/tracer/gui/xy_plot.c b/common/utils/T/tracer/gui/xy_plot.c index 0f15f4862a3f99d3374e000487a6ba47b0b2b609..c10b76c6ee167ac671ff2dc24883b18884ad23f1 100644 --- a/common/utils/T/tracer/gui/xy_plot.c +++ b/common/utils/T/tracer/gui/xy_plot.c @@ -130,9 +130,13 @@ static void paint(gui *_gui, widget *_this) this->common.y + FLIP(y), this->common.x + this->vrule_width + 5, this->common.y + FLIP(y)); + /* do not print out of the widget (take care of top) */ + y = FLIP(y)-this->label_height/2+this->label_baseline; + if (y - this->label_baseline < 0) + y = this->label_baseline; x_draw_string(g->x, g->xwin, DEFAULT_FONT, FOREGROUND_COLOR, this->common.x + this->vrule_width - vwidth - 2, - this->common.y + FLIP(y)-this->label_height/2+this->label_baseline, + this->common.y + y, v); } break; diff --git a/common/utils/T/tracer/hacks/Makefile b/common/utils/T/tracer/hacks/Makefile index f49e437bf542f823e1b71ac85653ae2736c01876..af2663e48f575eb1b0eb011acd15a5073b915486 100644 --- a/common/utils/T/tracer/hacks/Makefile +++ b/common/utils/T/tracer/hacks/Makefile @@ -3,7 +3,7 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. -I.. LIBS=-lX11 -lm -lpng -lXft -all: dump_nack_signal time_meas timeplot +all: dump_nack_signal time_meas timeplot multi-rru-clean dump_nack_signal: ../utils.o ../database.o ../config.o ../event.o \ dump_nack_signal.o @@ -16,6 +16,9 @@ time_meas: ../utils.o ../database.o ../config.o ../event.o \ timplot: timeplot.o $(CC) $(CFLAGS) -o timeplot $^ $(LIBS) +multi-rru-clean: ../utils.o ../database.o ../event.o ../config.o multi-rru-clean.o + $(CC) $(CFLAGS) -o $@ $^ $(LIBS) + .PHONY: all %.o: %.c diff --git a/common/utils/T/tracer/hacks/dump_nack_signal.c b/common/utils/T/tracer/hacks/dump_nack_signal.c index bb8f1a9477bda7894ba8465a068b2825db5e6737..02825202fb14544eb3074da8fdb0dbe1c5323cf6 100644 --- a/common/utils/T/tracer/hacks/dump_nack_signal.c +++ b/common/utils/T/tracer/hacks/dump_nack_signal.c @@ -7,21 +7,19 @@ #include "config.h" #include "../T_defs.h" -void usage(void) -{ +void usage(void) { printf( -"options:\n" -" -d <database file> this option is mandatory\n" -" -ip <host> connect to given IP address (default %s)\n" -" -p <port> connect to given port (default %d)\n", - DEFAULT_REMOTE_IP, - DEFAULT_REMOTE_PORT + "options:\n" + " -d <database file> this option is mandatory\n" + " -ip <host> connect to given IP address (default %s)\n" + " -p <port> connect to given port (default %d)\n", + DEFAULT_REMOTE_IP, + DEFAULT_REMOTE_PORT ); exit(1); } -int main(int n, char **v) -{ +int main(int n, char **v) { char *database_filename = NULL; void *database; char *ip = DEFAULT_REMOTE_IP; @@ -36,11 +34,28 @@ int main(int n, char **v) for (i = 1; i < n; i++) { if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); - if (!strcmp(v[i], "-d")) - { if (i > n-2) usage(); database_filename = v[++i]; continue; } - if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } - if (!strcmp(v[i], "-p")) - { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + + if (!strcmp(v[i], "-d")) { + if (i > n-2) usage(); + + database_filename = v[++i]; + continue; + } + + if (!strcmp(v[i], "-ip")) { + if (i > n-2) usage(); + + ip = v[++i]; + continue; + } + + if (!strcmp(v[i], "-p")) { + if (i > n-2) usage(); + + port = atoi(v[++i]); + continue; + } + usage(); } @@ -50,71 +65,92 @@ int main(int n, char **v) } database = parse_database(database_filename); - load_config_file(database_filename); - number_of_events = number_of_ids(database); is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) abort(); on_off(database, "ENB_PHY_INPUT_SIGNAL", is_on, 1); on_off(database, "ENB_PHY_ULSCH_UE_NACK", is_on, 1); on_off(database, "ENB_PHY_ULSCH_UE_ACK", is_on, 1); - ev_input = event_id_from_name(database, "ENB_PHY_INPUT_SIGNAL"); ev_nack = event_id_from_name(database, "ENB_PHY_ULSCH_UE_NACK"); ev_ack = event_id_from_name(database, "ENB_PHY_ULSCH_UE_ACK"); - socket = connect_to(ip, port); - t = 1; + if (socket_send(socket, &t, 1) == -1 || socket_send(socket, &number_of_events, sizeof(int)) == -1 || socket_send(socket, is_on, number_of_events * sizeof(int)) == -1) abort(); OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; - char dump[10][T_BUFFER_MAX]; event dump_ev[10]; -FILE *z = fopen("/tmp/dd", "w"); if (z == NULL) abort(); + FILE *z = fopen("/tmp/dd", "w"); + + if (z == NULL) abort(); + while (1) { char *v; event e; e = get_event(socket, &ebuf, database); v = ebuf.obuf; + if (e.type == -1) break; + if (e.type == ev_input) { int sf = e.e[2].i; - if (ebuf.osize > T_BUFFER_MAX) - { printf("event size too big\n"); exit(1); } + + if (ebuf.osize > T_BUFFER_MAX) { + printf("event size too big\n"); + exit(1); + } + memcpy(dump[sf], ebuf.obuf, ebuf.osize); dump_ev[sf] = e; printf("input %d/%d\n", e.e[1].i, sf); -if (fwrite(dump_ev[sf].e[4].b, dump_ev[sf].e[4].bsize, 1, z) != 1) abort(); -fflush(z); + + if (fwrite(dump_ev[sf].e[4].b, dump_ev[sf].e[4].bsize, 1, z) != 1) abort(); + + fflush(z); } + if (e.type == ev_nack) { int sf = e.e[2].i; printf("nack %d/%d\n", e.e[1].i, sf); - FILE *f = fopen("/tmp/dump.raw", "w"); if (f == NULL) abort(); + FILE *f = fopen("/tmp/dump.raw", "w"); + + if (f == NULL) abort(); + if (fwrite(dump[sf] + ((char *)dump_ev[sf].e[4].b - v), - dump_ev[sf].e[4].bsize, 1, f) != 1) abort(); + dump_ev[sf].e[4].bsize, 1, f) != 1) abort(); + if (fclose(f)) abort(); + printf("dumped... press enter (delta %d)\n", (int)((char *)dump_ev[sf].e[4].b - v)); -// getchar(); + // getchar(); } + if (e.type == ev_ack) { int sf = e.e[2].i; printf("ack %d/%d\n", e.e[1].i, sf); - FILE *f = fopen("/tmp/dump.raw", "w"); if (f == NULL) abort(); + FILE *f = fopen("/tmp/dump.raw", "w"); + + if (f == NULL) abort(); + if (fwrite(dump[sf] + ((char *)dump_ev[sf].e[4].b - v), - dump_ev[sf].e[4].bsize, 1, f) != 1) abort(); + dump_ev[sf].e[4].bsize, 1, f) != 1) abort(); + if (fclose(f)) abort(); + printf("dumped... press enter (delta %d)\n", (int)((char *)dump_ev[sf].e[4].b - v)); -// getchar(); + // getchar(); } } + if (z) + fclose(z); return 0; } diff --git a/common/utils/T/tracer/hacks/multi-rru-clean.c b/common/utils/T/tracer/hacks/multi-rru-clean.c new file mode 100644 index 0000000000000000000000000000000000000000..c85dc0de7f5ceadcfee64207ec64b49b50ddd8c9 --- /dev/null +++ b/common/utils/T/tracer/hacks/multi-rru-clean.c @@ -0,0 +1,230 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "database.h" +#include "utils.h" +#include "event.h" +#include "../T_defs.h" + +void usage(void) +{ + printf( + "usage: <number of tags> <input record file> <output curated record file>\n" + "options:\n" + " -d <database file> this option is mandatory\n" + ); + exit(1); +} + +#define ERR printf("ERROR: read file %s failed\n", input_filename) + +typedef struct { + OBUF b; + struct timespec t; + int filled; + int error; +} cache_t; + +void clear_cache(int n, cache_t *c) +{ + int i; + for (i = 0; i < n; i++) { + c[i].filled = 0; + c[i].error = 0; + c[i].b.osize = 0; + } +} + +void store_in_cache(cache_t *c, int pos, OBUF *b) +{ + int i; + for (i = 0; i < b->osize; i++) + PUTC(&c[pos].b, b->obuf[i]); +} + +int get_field(database_event_format *f, char *field, char *type) +{ + int i; + for (i = 0; i < f->count; i++) + if (!strcmp(f->name[i], field)) { + if (strcmp(f->type[i], type)) break; + return i; + } + printf("bad field %s, check that it exists and has type '%s'\n",field,type); + exit(1); +} + +void process_cache(FILE *out, cache_t *c, int n, int frame, int subframe) +{ + int i; + struct tm *t; + + for (i = 0; i < n; i++) + if (c[i].filled == 0 || c[i].error == 1) + goto error; + + for (i = 0; i < n; i++) + fwrite(c[i].b.obuf, c[i].b.osize, 1, out); + + clear_cache(n, c); + return; + +error: + printf("ERROR: incorrect data at frame %d subframe %d", frame, subframe); + for (i = 0; i < n; i++) if (c[i].filled) { + t = localtime(&c[i].t.tv_sec); + printf(" [tag %d time %2.2d:%2.2d:%2.2d.%9.9ld]", i, + t->tm_hour, t->tm_min, t->tm_sec, c[i].t.tv_nsec); + } + printf("\n"); + clear_cache(n, c); +} + +int main(int n, char **v) +{ + char *database_filename = NULL; + void *database; + int channel_estimate_id; + int number_of_tags = -1; + char *input_filename = NULL; + char *output_filename = NULL; + int i; + FILE *in; + FILE *out; + database_event_format f; + int frame_arg; + int subframe_arg; + int tag_arg; + + cache_t *cache; + int cur_frame = -1; + int cur_subframe = -1; + int frame; + int subframe; + int tag; + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-d")) { if (i > n-2) usage(); + database_filename = v[++i]; continue; } + if (number_of_tags == -1) { number_of_tags = atoi(v[i]); + if (number_of_tags <= 0) {usage();} continue; } + if (input_filename == NULL) { input_filename = v[i]; continue; } + if (output_filename == NULL) { output_filename = v[i]; continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + if (output_filename == NULL || input_filename == NULL || number_of_tags == -1) + usage(); + + database = parse_database(database_filename); + + channel_estimate_id = event_id_from_name(database, "CALIBRATION_CHANNEL_ESTIMATES"); + f = get_format(database, channel_estimate_id); + + frame_arg = get_field(&f, "frame", "int"); + subframe_arg = get_field(&f, "subframe", "int"); + tag_arg = get_field(&f, "tag", "int"); + + in = fopen(input_filename, "r"); + if (in == NULL) { perror(input_filename); abort(); } + out = fopen(output_filename, "w"); + if (out == NULL) { perror(output_filename); abort(); } + + cache = calloc(number_of_tags, sizeof(cache_t)); + if (cache == NULL) { perror("malloc"); exit(1); } + + clear_cache(number_of_tags, cache); + + OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; + + while (1) { + int type; + int32_t length; + char *v; + int vpos = 0; + struct timespec t; + char *buf; + + /* read event from file */ + if (fread(&length, 4, 1, in) != 1) break; + if (ebuf.omaxsize < length) { + ebuf.omaxsize = (length + 65535) & ~65535; + ebuf.obuf = realloc(ebuf.obuf, ebuf.omaxsize); + if (ebuf.obuf == NULL) { printf("out of memory\n"); exit(1); } + } + v = ebuf.obuf; + memcpy(v+vpos, &length, 4); + vpos += 4; +#ifdef T_SEND_TIME + if (length < sizeof(struct timespec)) { ERR; break; } + if (fread(&t, sizeof(struct timespec), 1, in) != 1) { ERR; break; } + memcpy(v+vpos, &t, sizeof(struct timespec)); + vpos += sizeof(struct timespec); + length -= sizeof(struct timespec); +#endif + if (length < sizeof(int)) { ERR; break; } + if (fread(&type, sizeof(int), 1, in) != 1) { ERR; break; } + memcpy(v+vpos, &type, sizeof(int)); + vpos += sizeof(int); + length -= sizeof(int); + if (length) if (fread(v+vpos, length, 1, in) != 1) { ERR; break; } + buf = v + vpos; + vpos += length; + ebuf.osize = vpos; + + if (type != channel_estimate_id) continue; + + event e; +#ifdef T_SEND_TIME + e = new_event(t, type, length, buf, database); +#else + e = new_event(type, length, buf, database); +#endif + + frame = e.e[frame_arg].i; + subframe = e.e[subframe_arg].i; + tag = e.e[tag_arg].i; + + if (tag < 0 || tag >= number_of_tags) { + struct tm *tt; + tt = localtime(&t.tv_sec); + printf("ERROR: invalid tag (%d), skipping event for frame %d subframe %d (time %2.2d:%2.2d:%2.2d.%9.9ld)\n", + tag, frame, subframe, + tt->tm_hour, tt->tm_min, tt->tm_sec, t.tv_nsec); + continue; + } + + if (cur_frame != frame || cur_subframe != subframe) + if (cur_frame != -1) + process_cache(out, cache, number_of_tags, cur_frame, cur_subframe); + + cur_frame = frame; + cur_subframe = subframe; + + if (cache[tag].filled) { + struct tm *tt; + tt = localtime(&t.tv_sec); + printf("ERROR: tag %d present twice at frame %d subframe %d (time %2.2d:%2.2d:%2.2d.%9.9ld)\n", + tag, frame, subframe, + tt->tm_hour, tt->tm_min, tt->tm_sec, t.tv_nsec); + cache[tag].error = 1; + continue; + } + + store_in_cache(cache, tag, &ebuf); + cache[tag].filled = 1; + cache[tag].t = t; + } + + if (fclose(in)) perror(input_filename); + if (fclose(out)) perror(output_filename); + free(cache); + + return 0; +} diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c index d9bcb8b7f5f255cca66ba4a36ffa561687aa0baf..8720efd8c0834e0a75b5452b12030420f7da082c 100644 --- a/common/utils/T/tracer/macpdu2wireshark.c +++ b/common/utils/T/tracer/macpdu2wireshark.c @@ -58,14 +58,11 @@ typedef struct { } ev_data; void trace(ev_data *d, int direction, int rnti_type, int rnti, - int frame, int subframe, void *buf, int bufsize, int preamble) -{ + int frame, int subframe, void *buf, int bufsize, int preamble) { ssize_t ret; int fsf; int i; - d->buf.osize = 0; - PUTS(&d->buf, MAC_LTE_START_STRING); PUTC(&d->buf, FDD_RADIO); PUTC(&d->buf, direction); @@ -92,16 +89,17 @@ void trace(ev_data *d, int direction, int rnti_type, int rnti, } PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); + for (i = 0; i < bufsize; i++) - PUTC(&d->buf, ((char*)buf)[i]); + PUTC(&d->buf, ((char *)buf)[i]); ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, - (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); + (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); + if (ret != d->buf.osize) abort(); } -void ul(void *_d, event e) -{ +void ul(void *_d, event e) { ev_data *d = _d; trace(d, DIRECTION_UPLINK, C_RNTI, e.e[d->ul_rnti].i, e.e[d->ul_frame].i, e.e[d->ul_subframe].i, @@ -109,13 +107,14 @@ void ul(void *_d, event e) NO_PREAMBLE); } -void dl(void *_d, event e) -{ +void dl(void *_d, event e) { ev_data *d = _d; if (e.e[d->dl_rnti].i == 0xffff) { if (d->no_sib) return; + if (d->max_sib && d->cur_sib == d->max_sib) return; + d->cur_sib++; } @@ -126,22 +125,21 @@ void dl(void *_d, event e) NO_PREAMBLE); } -void mib(void *_d, event e) -{ +void mib(void *_d, event e) { ev_data *d = _d; if (d->no_mib) return; + if (d->max_mib && d->cur_mib == d->max_mib) return; - d->cur_mib++; + d->cur_mib++; trace(d, DIRECTION_DOWNLINK, NO_RNTI, 0, e.e[d->mib_frame].i, e.e[d->mib_subframe].i, e.e[d->mib_data].b, e.e[d->mib_data].bsize, NO_PREAMBLE); } -void preamble(void *_d, event e) -{ +void preamble(void *_d, event e) { ev_data *d = _d; trace(d, DIRECTION_UPLINK, NO_RNTI, 0, e.e[d->preamble_frame].i, e.e[d->preamble_subframe].i, @@ -149,8 +147,7 @@ void preamble(void *_d, event e) e.e[d->preamble_preamble].i); } -void rar(void *_d, event e) -{ +void rar(void *_d, event e) { ev_data *d = _d; trace(d, DIRECTION_DOWNLINK, RA_RNTI, e.e[d->rar_rnti].i, e.e[d->rar_frame].i, e.e[d->rar_subframe].i, @@ -159,114 +156,118 @@ void rar(void *_d, event e) } void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id, - int preamble_id, int rar_id) -{ + int preamble_id, int rar_id) { database_event_format f; int i; - d->ul_rnti = -1; d->ul_frame = -1; d->ul_subframe = -1; d->ul_data = -1; - d->dl_rnti = -1; d->dl_frame = -1; d->dl_subframe = -1; d->dl_data = -1; - d->mib_frame = -1; d->mib_subframe = -1; d->mib_data = -1; - d->preamble_frame = -1; d->preamble_subframe = -1; d->preamble_preamble = -1; - d->rar_rnti = -1; d->rar_frame = -1; d->rar_subframe = -1; d->rar_data = -1; - #define G(var_name, var_type, var) \ if (!strcmp(f.name[i], var_name)) { \ if (strcmp(f.type[i], var_type)) goto error; \ var = i; \ continue; \ } - /* ul: rnti, frame, subframe, data */ f = get_format(database, ul_id); + for (i = 0; i < f.count; i++) { G("rnti", "int", d->ul_rnti); G("frame", "int", d->ul_frame); G("subframe", "int", d->ul_subframe); G("data", "buffer", d->ul_data); } + if (d->ul_rnti == -1 || d->ul_frame == -1 || d->ul_subframe == -1 || d->ul_data == -1) goto error; /* dl: rnti, frame, subframe, data */ f = get_format(database, dl_id); + for (i = 0; i < f.count; i++) { G("rnti", "int", d->dl_rnti); G("frame", "int", d->dl_frame); G("subframe", "int", d->dl_subframe); G("data", "buffer", d->dl_data); } + if (d->dl_rnti == -1 || d->dl_frame == -1 || d->dl_subframe == -1 || d->dl_data == -1) goto error; /* MIB: frame, subframe, data */ f = get_format(database, mib_id); + for (i = 0; i < f.count; i++) { G("frame", "int", d->mib_frame); G("subframe", "int", d->mib_subframe); G("data", "buffer", d->mib_data); } + if (d->mib_frame == -1 || d->mib_subframe == -1 || d->mib_data == -1) goto error; /* preamble: frame, subframe, preamble */ f = get_format(database, preamble_id); + for (i = 0; i < f.count; i++) { G("frame", "int", d->preamble_frame); G("subframe", "int", d->preamble_subframe); G("preamble", "int", d->preamble_preamble); } + if (d->preamble_frame == -1 || d->preamble_subframe == -1 || d->preamble_preamble == -1) goto error; /* rar: rnti, frame, subframe, data */ f = get_format(database, rar_id); + for (i = 0; i < f.count; i++) { G("rnti", "int", d->rar_rnti); G("frame", "int", d->rar_frame); G("subframe", "int", d->rar_subframe); G("data", "buffer", d->rar_data); } + if (d->rar_rnti == -1 || d->rar_frame == -1 || d->rar_subframe == -1 || d->rar_data == -1) goto error; #undef G - return; - error: printf("bad T_messages.txt\n"); abort(); } -void *receiver(void *_d) -{ +void *receiver(void *_d) { ev_data *d = _d; int s; char buf[100000]; - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s == -1) { perror("socket"); abort(); } - if (bind(s, (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)) == -1) - { perror("bind"); abort(); } + if (s == -1) { + perror("socket"); + abort(); + } + + if (bind(s, (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)) == -1) { + perror("bind"); + abort(); + } while (1) { if (recv(s, buf, 100000, 0) <= 0) abort(); @@ -275,33 +276,31 @@ void *receiver(void *_d) return 0; } -void usage(void) -{ +void usage(void) { printf( -"options:\n" -" -d <database file> this option is mandatory\n" -" -i <dump file> read events from this dump file\n" -" -ip <IP address> send packets to this IP address (default %s)\n" -" -p <port> send packets to this port (default %d)\n" -" -no-mib do not report MIB\n" -" -no-sib do not report SIBs\n" -" -max-mib <n> report at maximum n MIB\n" -" -max-sib <n> report at maximum n SIBs\n" -" -live run live\n" -" -live-ip <IP address> tracee's IP address (default %p)\n" -" -live-port <por> tracee's port (default %d)\n" -"-i and -live are mutually exclusive options. One of them must be provided\n" -"but not both.\n", - DEFAULT_IP, - DEFAULT_PORT, - DEFAULT_LIVE_IP, - DEFAULT_LIVE_PORT + "options:\n" + " -d <database file> this option is mandatory\n" + " -i <dump file> read events from this dump file\n" + " -ip <IP address> send packets to this IP address (default %s)\n" + " -p <port> send packets to this port (default %d)\n" + " -no-mib do not report MIB\n" + " -no-sib do not report SIBs\n" + " -max-mib <n> report at maximum n MIB\n" + " -max-sib <n> report at maximum n SIBs\n" + " -live run live\n" + " -live-ip <IP address> tracee's IP address (default %s)\n" + " -live-port <port> tracee's port (default %d)\n" + "-i and -live are mutually exclusive options. One of them must be provided\n" + "but not both.\n", + DEFAULT_IP, + DEFAULT_PORT, + DEFAULT_LIVE_IP, + DEFAULT_LIVE_PORT ); exit(1); } -int main(int n, char **v) -{ +int main(int n, char **v) { char *database_filename = NULL; char *input_filename = NULL; void *database; @@ -315,28 +314,82 @@ int main(int n, char **v) char *live_ip = DEFAULT_LIVE_IP; int live_port = DEFAULT_LIVE_PORT; int live = 0; - memset(&d, 0, sizeof(ev_data)); for (i = 1; i < n; i++) { if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); - if (!strcmp(v[i], "-d")) - { if (i > n-2) usage(); database_filename = v[++i]; continue; } - if (!strcmp(v[i], "-i")) - { if (i > n-2) usage(); input_filename = v[++i]; continue; } - if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } - if (!strcmp(v[i], "-p")) {if(i>n-2)usage(); port=atoi(v[++i]); continue; } - if (!strcmp(v[i], "-no-mib")) { d.no_mib = 1; continue; } - if (!strcmp(v[i], "-no-sib")) { d.no_sib = 1; continue; } - if (!strcmp(v[i], "-max-mib")) - { if (i > n-2) usage(); d.max_mib = atoi(v[++i]); continue; } - if (!strcmp(v[i], "-max-sib")) - { if (i > n-2) usage(); d.max_sib = atoi(v[++i]); continue; } - if (!strcmp(v[i], "-live")) { live = 1; continue; } - if (!strcmp(v[i], "-live-ip")) - { if (i > n-2) usage(); live_ip = v[++i]; continue; } - if (!strcmp(v[i], "-live-port")) - { if (i > n-2) usage(); live_port = atoi(v[++i]); continue; } + + if (!strcmp(v[i], "-d")) { + if (i > n-2) usage(); + + database_filename = v[++i]; + continue; + } + + if (!strcmp(v[i], "-i")) { + if (i > n-2) usage(); + + input_filename = v[++i]; + continue; + } + + if (!strcmp(v[i], "-ip")) { + if (i > n-2) usage(); + + ip = v[++i]; + continue; + } + + if (!strcmp(v[i], "-p")) { + if(i>n-2)usage(); + + port=atoi(v[++i]); + continue; + } + + if (!strcmp(v[i], "-no-mib")) { + d.no_mib = 1; + continue; + } + + if (!strcmp(v[i], "-no-sib")) { + d.no_sib = 1; + continue; + } + + if (!strcmp(v[i], "-max-mib")) { + if (i > n-2) usage(); + + d.max_mib = atoi(v[++i]); + continue; + } + + if (!strcmp(v[i], "-max-sib")) { + if (i > n-2) usage(); + + d.max_sib = atoi(v[++i]); + continue; + } + + if (!strcmp(v[i], "-live")) { + live = 1; + continue; + } + + if (!strcmp(v[i], "-live-ip")) { + if (i > n-2) usage(); + + live_ip = v[++i]; + continue; + } + + if (!strcmp(v[i], "-live-port")) { + if (i > n-2) usage(); + + live_port = atoi(v[++i]); + continue; + } + usage(); } @@ -357,25 +410,34 @@ int main(int n, char **v) if (live == 0) { in = open(input_filename, O_RDONLY); - if (in == -1) { perror(input_filename); return 1; } + + if (in == -1) { + perror(input_filename); + return 1; + } } else in = connect_to(live_ip, live_port); database = parse_database(database_filename); load_config_file(database_filename); - h = new_handler(database); if (live) { char mt = 1; int number_of_events = number_of_ids(database); int *is_on = calloc(number_of_events, sizeof(int)); - if (is_on == NULL) { printf("ERROR: out of memory\n"); exit(1); } + + if (is_on == NULL) { + printf("ERROR: out of memory\n"); + exit(1); + } + on_off(database, "ENB_MAC_UE_UL_PDU_WITH_DATA", is_on, 1); on_off(database, "ENB_MAC_UE_DL_PDU_WITH_DATA", is_on, 1); on_off(database, "ENB_PHY_MIB", is_on, 1); on_off(database, "ENB_PHY_INITIATE_RA_PROCEDURE", is_on, 1); on_off(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA", is_on, 1); + /* activate selected traces */ if (socket_send(in, &mt, 1) == -1 || socket_send(in, &number_of_events, sizeof(int)) == -1 || @@ -383,6 +445,7 @@ int main(int n, char **v) printf("ERROR: socket_send failed\n"); exit(1); } + free(is_on); } @@ -392,31 +455,34 @@ int main(int n, char **v) preamble_id = event_id_from_name(database, "ENB_PHY_INITIATE_RA_PROCEDURE"); rar_id = event_id_from_name(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA"); setup_data(&d, database, ul_id, dl_id, mib_id, preamble_id, rar_id); - register_handler_function(h, ul_id, ul, &d); register_handler_function(h, dl_id, dl, &d); register_handler_function(h, mib_id, mib, &d); register_handler_function(h, preamble_id, preamble, &d); register_handler_function(h, rar_id, rar, &d); - d.socket = socket(AF_INET, SOCK_DGRAM, 0); - if (d.socket == -1) { perror("socket"); exit(1); } + + if (d.socket == -1) { + perror("socket"); + exit(1); + } d.to.sin_family = AF_INET; d.to.sin_port = htons(port); d.to.sin_addr.s_addr = inet_addr(ip); - new_thread(receiver, &d); - OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL }; /* read messages */ while (1) { event e; e = get_event(in, &ebuf, database); + if (e.type == -1) break; + if (!(e.type == ul_id || e.type == dl_id || e.type == mib_id || e.type == preamble_id || e.type == rar_id)) continue; + handle_event(h, e); } diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index a123bf9bf518b9104d224c5a3d849c5cc690e7af..f83cc7efd3c98a421641ec49cf50200eac1cd0b6 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -195,5 +195,8 @@ int main(int n, char **v) handle_event(h, e); } + free(on_off_name); + free(on_off_action); + return 0; } diff --git a/common/utils/T/tracer/ue.c b/common/utils/T/tracer/ue.c index 7b03210cd2cb3d7884fa57c6531e08d58a3aa141..bafa0384f2cdbe092829636661fe5b02d81bbcba 100644 --- a/common/utils/T/tracer/ue.c +++ b/common/utils/T/tracer/ue.c @@ -23,9 +23,6 @@ typedef struct { view *pdcpview; view *rrcview; view *legacy; - widget *current_ue_label; - widget *prev_ue_button; - widget *next_ue_button; widget *pdsch_iq_ue_xy_plot; widget *dl_estimate_ue_xy_plot; widget *pdcch_energy_ue_xy_plot; @@ -121,15 +118,14 @@ static void *gui_thread(void *_g) return NULL; } -static filter *ticktime_filter(void *database, char *event, int i, int ue) +static filter *ticktime_filter(void *database, char *event, int i) { - /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0" */ + /* filter is "harq_pid == i and eNB_id == 0" */ return filter_and( filter_eq(filter_evarg(database, event, "harq_pid"), filter_int(i)), - filter_and( - filter_eq(filter_evarg(database, event, "UE_id"), filter_int(ue)), - filter_eq(filter_evarg(database, event, "eNB_ID"), filter_int(0)))); + filter_eq(filter_evarg(database, event, "eNB_ID"), filter_int(0))); + } static void set_current_ue(gui *g, ue_data *e, int ue) @@ -137,8 +133,6 @@ static void set_current_ue(gui *g, ue_data *e, int ue) int i; char s[256]; - sprintf(s, "[UE %d] ", ue); - label_set_text(g, e->e->current_ue_label, s); sprintf(s, "PDSCH IQ [UE %d]", ue); xy_plot_set_title(g, e->e->pdsch_iq_ue_xy_plot, s); sprintf(s, "DL estimated channel [UE %d]", ue); @@ -161,97 +155,24 @@ static void set_current_ue(gui *g, ue_data *e, int ue) xy_plot_set_title(g, e->e->pucch_power_xy_plot, s); sprintf(s, "PHY Measurements [UE %d]", ue); xy_plot_set_title(g, e->e->phy_meas_xy_plot, s); - - logger_set_filter(e->e->pdsch_iq_ue_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_PDSCH_IQ", "UE_ID"), - filter_int(ue))); - logger_set_filter(e->e->dl_estimate_ue_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_DL_CHANNEL_ESTIMATE", "UE_ID"), - filter_int(ue))); - logger_set_filter(e->e->pdcch_energy_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_PDCCH_ENERGY", "UE_ID"), - filter_int(ue))); - logger_set_filter(e->e->pdsch_energy_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_PDSCH_ENERGY", "UE_ID"), - filter_int(ue))); - logger_set_filter(e->e->phy_meas_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_MEAS", "UE_ID"), - filter_int(ue))); - /*logger_set_filter(e->pucch1_energy_ue_energy_logger, - filter_eq( - filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"), - filter_int(ue)));*/ - /*logger_set_filter(e->e->pdcch_iq_ue_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_PDCCH_IQ", "UE_ID"), - filter_int(ue)));*/ + for (i = 0; i < 8; i++) { logger_set_filter(e->e->dl_dci_logger[i], - ticktime_filter(e->database, "UE_PHY_DLSCH_UE_DCI", i, ue)); + ticktime_filter(e->database, "UE_PHY_DLSCH_UE_DCI", i)); logger_set_filter(e->e->dl_ack_logger[i], - ticktime_filter(e->database, "UE_PHY_DLSCH_UE_ACK", i, ue)); + ticktime_filter(e->database, "UE_PHY_DLSCH_UE_ACK", i)); logger_set_filter(e->e->dl_nack_logger[i], - ticktime_filter(e->database, "UE_PHY_DLSCH_UE_NACK", i, ue)); + ticktime_filter(e->database, "UE_PHY_DLSCH_UE_NACK", i)); logger_set_filter(e->e->ul_dci_logger[i], - ticktime_filter(e->database, "UE_PHY_ULSCH_UE_DCI", i, ue)); + ticktime_filter(e->database, "UE_PHY_ULSCH_UE_DCI", i)); /*logger_set_filter(e->ul_dci_retransmission_logger[i], ticktime_filter(e->database, - "ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", i, ue));*/ + "ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", i));*/ logger_set_filter(e->e->ul_ack_logger[i], - ticktime_filter(e->database, "UE_PHY_ULSCH_UE_ACK", i, ue)); + ticktime_filter(e->database, "UE_PHY_ULSCH_UE_ACK", i)); logger_set_filter(e->e->ul_nack_logger[i], - ticktime_filter(e->database, "UE_PHY_ULSCH_UE_NACK", i, ue)); + ticktime_filter(e->database, "UE_PHY_ULSCH_UE_NACK", i)); } - logger_set_filter(e->e->dl_mcs_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_DLSCH_UE_DCI", "UE_id"), - filter_int(ue))); - logger_set_filter(e->e->ul_mcs_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_ULSCH_UE_DCI", "UE_id"), - filter_int(ue))); - logger_set_filter(e->e->pusch_power_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_PUSCH_TX_POWER", "UE_id"), - filter_int(ue))); - logger_set_filter(e->e->pusch_ampl_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_PUSCH_TX_POWER", "UE_id"), - filter_int(ue))); - logger_set_filter(e->e->pucch_power_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_PUCCH_TX_POWER", "UE_id"), - filter_int(ue))); - logger_set_filter(e->e->pucch_ampl_logger, - filter_eq( - filter_evarg(e->database, "UE_PHY_PUCCH_TX_POWER", "UE_id"), - filter_int(ue))); -} - -static void click(void *private, gui *g, - char *notification, widget *w, void *notification_data) -{ - int *d = notification_data; - int button = d[0]; - ue_data *ed = private; - ue_gui *e = ed->e; - int ue = ed->ue; - - if (button != 1) return; - if (w == e->prev_ue_button) { ue--; if (ue < 0) ue = 0; } - if (w == e->next_ue_button) ue++; - - if (pthread_mutex_lock(&ed->lock)) abort(); - if (ue != ed->ue) { - set_current_ue(g, ed, ue); - ed->ue = ue; - } - if (pthread_mutex_unlock(&ed->lock)) abort(); } static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, @@ -271,7 +192,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, widget *text; view *textview; int i; - widget *w, *w2; + widget *w; view *v; logger *l; @@ -283,24 +204,8 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, top_container, line, -1); logo = new_image(g, openair_logo_png, openair_logo_png_len); - /* logo + prev/next UE buttons */ - col = new_container(g, VERTICAL); - widget_add_child(g, col, logo, -1); - w = new_container(g, HORIZONTAL); - widget_add_child(g, col, w, -1); - w2 = new_label(g, ""); - widget_add_child(g, w, w2, -1); - e->current_ue_label = w2; - /* TODO: use button widget, not label widget */ - w2 = new_label(g, " [prev UE] "); - widget_add_child(g, w, w2, -1); - label_set_clickable(g, w2, 1); - e->prev_ue_button = w2; - w2 = new_label(g, " [next UE] "); - widget_add_child(g, w, w2, -1); - label_set_clickable(g, w2, 1); - e->next_ue_button = w2; - widget_add_child(g, line, col, -1); + /* logo */ + widget_add_child(g, line, logo, -1); input_signal_plot = new_xy_plot(g, 256, 55, "input signal", 20); widget_add_child(g, line, input_signal_plot, -1); @@ -356,7 +261,73 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, v = new_view_tti(10, g, w, new_color(g, "#0c720c")); logger_add_view(l, v); e->phy_meas_logger = l; - + + /* a bit of space */ + line = new_container(g, HORIZONTAL); + widget_add_child(g, top_container, line, -1); + w = new_space(g, 1, 10); + widget_add_child(g, line, w, -1); + + /* UE x DL mcs */ + line = new_container(g, HORIZONTAL); + widget_add_child(g, top_container, line, -1); + w = new_xy_plot(g, 128, 55, "", 20); + xy_plot_set_range(g, w, 0, 1024*10, -2, 30); + e->dl_mcs_xy_plot = w; + widget_add_child(g, line, w, -1); + l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe", + "UE_PHY_DLSCH_UE_DCI", "mcs", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + logger_add_view(l, v); + e->dl_mcs_logger = l; + + /* UE x UL mcs */ + w = new_xy_plot(g, 128, 55, "", 20); + xy_plot_set_range(g, w, 0, 1024*10, -2, 30); + e->ul_mcs_xy_plot = w; + widget_add_child(g, line, w, -1); + l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe", + "UE_PHY_ULSCH_UE_DCI", "mcs", 0, -1); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + logger_add_view(l, v); + e->ul_mcs_logger = l; + + /* UE x PUSCH TX Power */ +// line = new_container(g, HORIZONTAL); +// widget_add_child(g, top_container, line, -1); + w = new_xy_plot(g, 128, 55, "", 20); + e->pusch_power_xy_plot = w; + widget_add_child(g, line, w, -1); + xy_plot_set_range(g, w, 0, 1024*10, -30, 50); + l = new_ttilog(h, database, + "UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "p0_pusch", 0); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + logger_add_view(l, v); + e->pusch_power_logger = l; + l = new_ttilog(h, database, + "UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "ampl", 1); + v = new_view_tti(10, g, w, new_color(g, "#720c0c")); + logger_add_view(l, v); + e->pusch_ampl_logger = l; + + /* UE x PUCCH TX Power */ +// line = new_container(g, HORIZONTAL); +// widget_add_child(g, top_container, line, -1); + w = new_xy_plot(g, 128, 55, "", 20); + e->pucch_power_xy_plot = w; + widget_add_child(g, line, w, -1); + xy_plot_set_range(g, w, 0, 1024*10, -30, 50); + l = new_ttilog(h, database, + "UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "p0_pucch", 0); + v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); + logger_add_view(l, v); + e->pucch_power_logger = l; + l = new_ttilog(h, database, + "UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "ampl", 1); + v = new_view_tti(10, g, w, new_color(g, "#720c0c")); + logger_add_view(l, v); + e->pucch_ampl_logger = l; + /* UE x PDSCH energy */ w = new_xy_plot(g, 128, 55, "", 50); e->pdsch_energy_ue_xy_plot = w; @@ -376,13 +347,13 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, "UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level10", 1); v = new_view_tti(10, g, w, new_color(g, "#0f0f0f")); logger_add_view(l, v); - e->pdsch_energy_logger = l; + e->pdsch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDSCH_ENERGY", "frame", "subframe", "pdsch_ch_level11", 1); v = new_view_tti(10, g, w, new_color(g, "#0000ff")); logger_add_view(l, v); e->pdsch_energy_logger = l; - + /* UE x PDCCH energy */ w = new_xy_plot(g, 128, 55, "", 50); e->pdcch_energy_ue_xy_plot = w; @@ -402,13 +373,13 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level10", 1); v = new_view_tti(10, g, w, new_color(g, "#0f0f0f")); logger_add_view(l, v); - e->pdcch_energy_logger = l; + e->pdcch_energy_logger = l; l = new_ttilog(h, database, "UE_PHY_PDCCH_ENERGY", "frame", "subframe", "pdcch_ch_level11", 1); v = new_view_tti(10, g, w, new_color(g, "#0000ff")); logger_add_view(l, v); e->pdcch_energy_logger = l; - + /* UE x PDCCH IQ data */ w = new_xy_plot(g, 55, 55, "", 50); e->pdcch_iq_ue_xy_plot = w; @@ -419,7 +390,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, v = new_view_xy(100*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE); logger_add_view(l, v); e->pdcch_iq_ue_logger = l; - + /* UE x PDCCH IQ data */ /*w = new_xy_plot(g, 55, 55, "", 50); e->pdcch_iq_ue_xy_plot = w; @@ -429,68 +400,8 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, v = new_view_xy(500, 10, g, w, new_color(g,"#000"), XY_LOOP_MODE); logger_add_view(l, v); e->pdcch_iq_ue_logger = l;*/ - - /* UE x DL mcs */ - line = new_container(g, HORIZONTAL); - widget_add_child(g, top_container, line, -1); - w = new_xy_plot(g, 128, 55, "", 20); - xy_plot_set_range(g, w, 0, 1024*10, -2, 30); - e->dl_mcs_xy_plot = w; - widget_add_child(g, line, w, -1); - l = new_ticked_ttilog(h, database, "UE_PHY_DL_TICK", "frame", "subframe", - "UE_PHY_DLSCH_UE_DCI", "mcs", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); - logger_add_view(l, v); - e->dl_mcs_logger = l; - /* UE x UL mcs */ - w = new_xy_plot(g, 128, 55, "", 20); - xy_plot_set_range(g, w, 0, 1024*10, -2, 30); - e->ul_mcs_xy_plot = w; - widget_add_child(g, line, w, -1); - l = new_ticked_ttilog(h, database, "UE_PHY_UL_TICK", "frame", "subframe", - "UE_PHY_ULSCH_UE_DCI", "mcs", 0, -1); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); - logger_add_view(l, v); - e->ul_mcs_logger = l; - /* UE x PUSCH TX Power */ -// line = new_container(g, HORIZONTAL); -// widget_add_child(g, top_container, line, -1); - w = new_xy_plot(g, 128, 55, "", 20); - e->pusch_power_xy_plot = w; - widget_add_child(g, line, w, -1); - xy_plot_set_range(g, w, 0, 1024*10, -30, 50); - l = new_ttilog(h, database, - "UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "p0_pusch", 0); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); - logger_add_view(l, v); - e->pusch_power_logger = l; - l = new_ttilog(h, database, - "UE_PHY_PUSCH_TX_POWER", "frame", "subframe", "ampl", 1); - v = new_view_tti(10, g, w, new_color(g, "#720c0c")); - logger_add_view(l, v); - e->pusch_ampl_logger = l; - - /* UE x PUCCH TX Power */ -// line = new_container(g, HORIZONTAL); -// widget_add_child(g, top_container, line, -1); - w = new_xy_plot(g, 128, 55, "", 20); - e->pucch_power_xy_plot = w; - widget_add_child(g, line, w, -1); - xy_plot_set_range(g, w, 0, 1024*10, -30, 50); - l = new_ttilog(h, database, - "UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "p0_pucch", 0); - v = new_view_tti(10, g, w, new_color(g, "#0c0c72")); - logger_add_view(l, v); - e->pucch_power_logger = l; - l = new_ttilog(h, database, - "UE_PHY_PUCCH_TX_POWER", "frame", "subframe", "ampl", 1); - v = new_view_tti(10, g, w, new_color(g, "#720c0c")); - logger_add_view(l, v); - e->pucch_ampl_logger = l; - - /* downlink/uplink UE DCIs */ widget_add_child(g, top_container, new_label(g,"DL/UL TICK/DCI/ACK/NACK [all UEs]"), -1); @@ -600,14 +511,14 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, logger_add_view(timelog, subview); e->ul_dci_logger[i] = timelog; /* retransmission */ - + timelog = new_ticklog(h, database, "ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION", "frame", "subframe"); subview = new_subview_ticktime(timeview, i+9+1, new_color(g,"#99f"), 3600*1000); logger_add_view(timelog, subview); e->ul_dci_retransmission_logger[i] = timelog; - + } /* UL ACK */ @@ -707,8 +618,6 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, #endif set_current_ue(g, ed, 0); - register_notifier(g, "click", e->prev_ue_button, click, ed); - register_notifier(g, "click", e->next_ue_button, click, ed); } void view_add_log(view *v, char *log, event_handler *h, void *database, @@ -824,13 +733,11 @@ int main(int n, char **v) on_off(database, "UE_PHY_PUSCH_TX_POWER", is_on, 1); on_off(database, "UE_PHY_PUCCH_TX_POWER", is_on, 1); on_off(database, "UE_PHY_MEAS", is_on, 1); - + on_off(database, "LEGACY_GROUP_INFO", is_on, 1); on_off(database, "LEGACY_GROUP_ERROR", is_on, 1); on_off(database, "LEGACY_GROUP_WARNING", is_on, 1); - - view_add_log(eg.phyview, "UE_PHY_UL_TICK", h, database, is_on); - view_add_log(eg.phyview, "UE_PHY_DL_TICK", h, database, is_on); + view_add_log(eg.phyview, "UE_PHY_DLSCH_UE_DCI", h, database, is_on); view_add_log(eg.phyview, "UE_PHY_DLSCH_UE_ACK", h, database, is_on); view_add_log(eg.phyview, "UE_PHY_DLSCH_UE_NACK",h, database, is_on); @@ -838,8 +745,6 @@ int main(int n, char **v) view_add_log(eg.phyview, "UE_PHY_ULSCH_UE_ACK", h, database, is_on); view_add_log(eg.phyview, "UE_PHY_ULSCH_UE_NACK", h, database, is_on); - - /* deactivate those two by default, they are a bit heavy */ //on_off(database, "ENB_MAC_UE_UL_SDU_WITH_DATA", is_on, 0); //on_off(database, "ENB_MAC_UE_UL_PDU_WITH_DATA", is_on, 0); diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index 7f58b6f5aa0061189d01a5107d8e6dcea035138a..39e04fb9734cdd1ff8b3b7c5357a89489503fedd 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -9,27 +9,38 @@ #include <arpa/inet.h> #include <math.h> -void new_thread(void *(*f)(void *), void *data) -{ +void new_thread(void *(*f)(void *), void *data) { pthread_t t; pthread_attr_t att; - if (pthread_attr_init(&att)) - { fprintf(stderr, "pthread_attr_init err\n"); exit(1); } - if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) - { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); } - if (pthread_attr_setstacksize(&att, 10000000)) - { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); } - if (pthread_create(&t, &att, f, data)) - { fprintf(stderr, "pthread_create err\n"); exit(1); } - if (pthread_attr_destroy(&att)) - { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } + if (pthread_attr_init(&att)) { + fprintf(stderr, "pthread_attr_init err\n"); + exit(1); + } + + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) { + fprintf(stderr, "pthread_attr_setdetachstate err\n"); + exit(1); + } + + if (pthread_attr_setstacksize(&att, 10000000)) { + fprintf(stderr, "pthread_attr_setstacksize err\n"); + exit(1); + } + + if (pthread_create(&t, &att, f, data)) { + fprintf(stderr, "pthread_create err\n"); + exit(1); + } + + if (pthread_attr_destroy(&att)) { + fprintf(stderr, "pthread_attr_destroy err\n"); + exit(1); + } } -void sleepms(int ms) -{ +void sleepms(int ms) { struct timespec t; - t.tv_sec = ms / 1000; t.tv_nsec = (ms % 1000) * 1000000L; @@ -37,12 +48,15 @@ void sleepms(int ms) if (nanosleep(&t, NULL)) abort(); } -void bps(char *out, float v, char *suffix) -{ +void bps(char *out, float v, char *suffix) { static char *bps_unit[4] = { "", "k", "M", "G" }; int flog; - if (v < 1000) flog = 0; else flog = floor(floor(log10(v)) / 3); + + if (v < 1000) flog = 0; + else flog = floor(floor(log10(v)) / 3); + if (flog > 3) flog = 3; + v /= pow(10, flog*3); sprintf(out, "%g%s%s", round(v*100)/100, bps_unit[flog], suffix); } @@ -51,25 +65,31 @@ void bps(char *out, float v, char *suffix) /* list */ /****************************************************************************/ -list *list_remove_head(list *l) -{ +list *list_remove_head(list *l) { list *ret; + if (l == NULL) return NULL; + ret = l->next; + if (ret != NULL) ret->last = l->last; + free(l); return ret; } -list *list_append(list *l, void *data) -{ +list *list_append(list *l, void *data) { list *new = calloc(1, sizeof(list)); + if (new == NULL) abort(); + new->data = data; + if (l == NULL) { new->last = new; return new; } + l->last->next = new; l->last = new; return l; @@ -79,88 +99,107 @@ list *list_append(list *l, void *data) /* socket */ /****************************************************************************/ -int create_listen_socket(char *addr, int port) -{ +int create_listen_socket(char *addr, int port) { struct sockaddr_in a; int s; int v; - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) { perror("socket"); exit(1); } + + if (s == -1) { + perror("socket"); + exit(1); + } + v = 1; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(int))) - { perror("setsockopt"); exit(1); } + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(int))) { + perror("setsockopt"); + exit(1); + } a.sin_family = AF_INET; a.sin_port = htons(port); a.sin_addr.s_addr = inet_addr(addr); - if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); } - if (listen(s, 5)) { perror("listen"); exit(1); } + if (bind(s, (struct sockaddr *)&a, sizeof(a))) { + perror("bind"); + exit(1); + } + + if (listen(s, 5)) { + perror("listen"); + exit(1); + } return s; } -int socket_accept(int s) -{ +int socket_accept(int s) { struct sockaddr_in a; socklen_t alen; alen = sizeof(a); return accept(s, (struct sockaddr *)&a, &alen); } -int socket_send(int socket, void *buffer, int size) -{ +int socket_send(int socket, void *buffer, int size) { char *x = buffer; int ret; + while (size) { ret = write(socket, x, size); + if (ret <= 0) return -1; + size -= ret; x += ret; } + return 0; } -int get_connection(char *addr, int port) -{ +int get_connection(char *addr, int port) { int s, t; - printf("waiting for connection on %s:%d\n", addr, port); - s = create_listen_socket(addr, port); - t = socket_accept(s); - if (t == -1) { perror("accept"); exit(1); } - close(s); - printf("connected\n"); + if (t == -1) { + perror("accept"); + exit(1); + } + close(s); + printf("connected\n"); return t; } -int fullread(int fd, void *_buf, int count) -{ +int fullread(int fd, void *_buf, int count) { char *buf = _buf; int ret = 0; int l; + while (count) { l = read(fd, buf, count); + if (l <= 0) return -1; + count -= l; buf += l; ret += l; } + return ret; } -int try_connect_to(char *addr, int port) -{ +int try_connect_to(char *addr, int port) { int s; struct sockaddr_in a; - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) { perror("socket"); exit(1); } + + if (s == -1) { + perror("socket"); + exit(1); + } a.sin_family = AF_INET; a.sin_port = htons(port); @@ -175,14 +214,12 @@ int try_connect_to(char *addr, int port) return s; } -int connect_to(char *addr, int port) -{ +int connect_to(char *addr, int port) { int s; - printf("connecting to %s:%d\n", addr, port); - again: s = try_connect_to(addr, port); + if (s == -1) { printf("trying again in 1s\n"); sleep(1); @@ -196,50 +233,46 @@ again: /* buffer */ /****************************************************************************/ -void PUTC(OBUF *o, char c) -{ +void PUTC(OBUF *o, char c) { if (o->osize == o->omaxsize) { o->omaxsize += 512; o->obuf = realloc(o->obuf, o->omaxsize); + if (o->obuf == NULL) abort(); } + o->obuf[o->osize] = c; o->osize++; } -void PUTS(OBUF *o, char *s) -{ +void PUTS(OBUF *o, char *s) { while (*s) PUTC(o, *s++); } -static int clean(char c) -{ +static int clean(char c) { if (!isprint(c)) c = ' '; + return c; } -void PUTS_CLEAN(OBUF *o, char *s) -{ +void PUTS_CLEAN(OBUF *o, char *s) { while (*s) PUTC(o, clean(*s++)); } -void PUTI(OBUF *o, int i) -{ +void PUTI(OBUF *o, int i) { char s[64]; sprintf(s, "%d", i); PUTS(o, s); } -void PUTX2(OBUF *o, int i) -{ +void PUTX2(OBUF *o, int i) { char s[64]; sprintf(s, "%2.2x", i); PUTS(o, s); } -void PUTUL(OBUF *o, unsigned long l) -{ +void PUTUL(OBUF *o, unsigned long l) { char s[128]; - sprintf(s, "%ld", l); + sprintf(s, "%lu", l); PUTS(o, s); } diff --git a/common/utils/assertions.h b/common/utils/assertions.h index 77e939affe4b7393aadb286b86c8b8551cc5d25f..97f186627488de5f14c5660a4c40884f157876ec 100644 --- a/common/utils/assertions.h +++ b/common/utils/assertions.h @@ -35,13 +35,11 @@ void output_log_mem(void); #define _Assert_Exit_ \ -{ \ fprintf(stderr, "\nExiting execution\n"); \ display_backtrace(); \ fflush(stdout); \ fflush(stderr); \ exit(EXIT_FAILURE); \ -} #define _Assert_(cOND, aCTION, fORMAT, aRGS...) \ do { \ diff --git a/common/utils/backtrace.c b/common/utils/backtrace.c index 889e0d84d148f3694ce363a2f74ac33065cbeb26..f6de74f156ce1bc04ddb58aeb65c3097c8c1ba47 100644 --- a/common/utils/backtrace.c +++ b/common/utils/backtrace.c @@ -31,18 +31,18 @@ #include "backtrace.h" /* Obtain a backtrace and print it to stdout. */ -void display_backtrace(void) -{ +void display_backtrace(void) { void *array[10]; size_t size; char **strings; size_t i; - char* test=getenv("NO_BACKTRACE"); - if (test!=0) *((int*)0)=0; + char *test=getenv("NO_BACKTRACE"); + + if (test!=0) *((int *)0)=0; + size = backtrace(array, 10); strings = backtrace_symbols(array, size); - - printf("Obtained %zd stack frames.\n", size); + printf("Obtained %u stack frames.\n", (unsigned int)size); for (i = 0; i < size; i++) printf("%s\n", strings[i]); @@ -50,8 +50,7 @@ void display_backtrace(void) free(strings); } -void backtrace_handle_signal(siginfo_t *info) -{ +void backtrace_handle_signal(siginfo_t *info) { display_backtrace(); //exit(EXIT_FAILURE); } diff --git a/common/utils/hashtable/hashtable.c b/common/utils/hashtable/hashtable.c index 2c7b35744ca7cf766044f7efc2341aff5b9a2fb5..7b0fc422139c6bf566ea8c824924b5f40047c4d9 100644 --- a/common/utils/hashtable/hashtable.c +++ b/common/utils/hashtable/hashtable.c @@ -2,9 +2,9 @@ * 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 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. + * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 @@ -28,17 +28,33 @@ //------------------------------------------------------------------------------------------------------------------------------- -char* hashtable_rc_code2string(hashtable_rc_t rcP) +char *hashtable_rc_code2string(hashtable_rc_t rcP) //------------------------------------------------------------------------------------------------------------------------------- { - switch (rcP) { - case HASH_TABLE_OK: return "HASH_TABLE_OK";break; - case HASH_TABLE_INSERT_OVERWRITTEN_DATA: return "HASH_TABLE_INSERT_OVERWRITTEN_DATA";break; - case HASH_TABLE_KEY_NOT_EXISTS: return "HASH_TABLE_KEY_NOT_EXISTS";break; - case HASH_TABLE_KEY_ALREADY_EXISTS: return "HASH_TABLE_KEY_ALREADY_EXISTS";break; - case HASH_TABLE_BAD_PARAMETER_HASHTABLE: return "HASH_TABLE_BAD_PARAMETER_HASHTABLE";break; - default: return "UNKNOWN hashtable_rc_t"; - } + switch (rcP) { + case HASH_TABLE_OK: + return "HASH_TABLE_OK"; + break; + + case HASH_TABLE_INSERT_OVERWRITTEN_DATA: + return "HASH_TABLE_INSERT_OVERWRITTEN_DATA"; + break; + + case HASH_TABLE_KEY_NOT_EXISTS: + return "HASH_TABLE_KEY_NOT_EXISTS"; + break; + + case HASH_TABLE_KEY_ALREADY_EXISTS: + return "HASH_TABLE_KEY_ALREADY_EXISTS"; + break; + + case HASH_TABLE_BAD_PARAMETER_HASHTABLE: + return "HASH_TABLE_BAD_PARAMETER_HASHTABLE"; + break; + + default: + return "UNKNOWN hashtable_rc_t"; + } } //------------------------------------------------------------------------------------------------------------------------------- /* @@ -46,7 +62,7 @@ char* hashtable_rc_code2string(hashtable_rc_t rcP) * hash_free_int_func() is used when this hashtable is used to store int values as data (pointer = value). */ -void hash_free_int_func(void* memoryP){} +void hash_free_int_func(void *memoryP) {} //------------------------------------------------------------------------------------------------------------------------------- /* @@ -55,9 +71,8 @@ void hash_free_int_func(void* memoryP){} * This is a simple/naive hash function which adds the key's ASCII char values. It will probably generate lots of collisions on large hash tables. */ -static hash_size_t def_hashfunc(const uint64_t keyP) -{ - return (hash_size_t)keyP; +static hash_size_t def_hashfunc(const uint64_t keyP) { + return (hash_size_t)keyP; } //------------------------------------------------------------------------------------------------------------------------------- @@ -67,132 +82,147 @@ static hash_size_t def_hashfunc(const uint64_t keyP) * The user can also specify a hash function. If the hashfunc argument is NULL, a default hash function is used. * If an error occurred, NULL is returned. All other values in the returned hash_table_t pointer should be released with hashtable_destroy(). */ -hash_table_t *hashtable_create(const hash_size_t sizeP, hash_size_t (*hashfuncP)(const hash_key_t ), void (*freefuncP)(void*)) -{ - hash_table_t *hashtbl = NULL; +hash_table_t *hashtable_create(const hash_size_t sizeP, hash_size_t (*hashfuncP)(const hash_key_t ), void (*freefuncP)(void *)) { + hash_table_t *hashtbl = NULL; - if(!(hashtbl=malloc(sizeof(hash_table_t)))) { - return NULL; - } + if(!(hashtbl=malloc(sizeof(hash_table_t)))) { + return NULL; + } - if(!(hashtbl->nodes=calloc(sizeP, sizeof(hash_node_t*)))) { - free(hashtbl); - return NULL; - } + if(!(hashtbl->nodes=calloc(sizeP, sizeof(hash_node_t *)))) { + free(hashtbl); + return NULL; + } - hashtbl->size=sizeP; + hashtbl->size=sizeP; - if(hashfuncP) hashtbl->hashfunc=hashfuncP; - else hashtbl->hashfunc=def_hashfunc; + if(hashfuncP) hashtbl->hashfunc=hashfuncP; + else hashtbl->hashfunc=def_hashfunc; - if(freefuncP) hashtbl->freefunc=freefuncP; - else hashtbl->freefunc=free; + if(freefuncP) hashtbl->freefunc=freefuncP; + else hashtbl->freefunc=free; - return hashtbl; + return hashtbl; } //------------------------------------------------------------------------------------------------------------------------------- /* * Cleanup * The hashtable_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the hash_table_t. */ -hashtable_rc_t hashtable_destroy(hash_table_t * hashtblP) -{ - hash_size_t n; - hash_node_t *node, *oldnode; +hashtable_rc_t hashtable_destroy(hash_table_t **hashtblP) { + hash_size_t n; + hash_node_t *node, *oldnode; - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } + if (*hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + + for(n=0; n<(*hashtblP)->size; ++n) { + node=(*hashtblP)->nodes[n]; - for(n=0; n<hashtblP->size; ++n) { - node=hashtblP->nodes[n]; - while(node) { - oldnode=node; - node=node->next; - if (oldnode->data) { - hashtblP->freefunc(oldnode->data); - } - free(oldnode); - } + while(node) { + oldnode=node; + node=node->next; + + if (oldnode->data) { + (*hashtblP)->freefunc(oldnode->data); + } + + free(oldnode); } - free(hashtblP->nodes); - free(hashtblP); - hashtblP=NULL; - return HASH_TABLE_OK; + } + + free((*hashtblP)->nodes); + free((*hashtblP)); + *hashtblP=NULL; + return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- -hashtable_rc_t hashtable_is_key_exists (const hash_table_t * const hashtblP, const hash_key_t keyP) +hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtblP, const hash_key_t keyP) //------------------------------------------------------------------------------------------------------------------------------- { - hash_node_t *node = NULL; - hash_size_t hash = 0; + hash_node_t *node = NULL; + hash_size_t hash = 0; - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } - hash=hashtblP->hashfunc(keyP)%hashtblP->size; - node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - return HASH_TABLE_OK; - } - node=node->next; + hash=hashtblP->hashfunc(keyP)%hashtblP->size; + node=hashtblP->nodes[hash]; + + while(node) { + if(node->key == keyP) { + return HASH_TABLE_OK; } - return HASH_TABLE_KEY_NOT_EXISTS; + + node=node->next; + } + + return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- -hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void functP(hash_key_t keyP, void* dataP, void* parameterP), void* parameterP) +hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void functP(hash_key_t keyP, void *dataP, void *parameterP), void *parameterP) //------------------------------------------------------------------------------------------------------------------------------- { - hash_node_t *node = NULL; - unsigned int i = 0; - unsigned int num_elements = 0; - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) { - if (hashtblP->nodes[i] != NULL) { - node=hashtblP->nodes[i]; - while(node) { - num_elements += 1; - functP(node->key, node->data, parameterP); - node=node->next; - } - } - i += 1; + hash_node_t *node = NULL; + unsigned int i = 0; + unsigned int num_elements = 0; + + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + + while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) { + if (hashtblP->nodes[i] != NULL) { + node=hashtblP->nodes[i]; + + while(node) { + num_elements += 1; + functP(node->key, node->data, parameterP); + node=node->next; + } } - return HASH_TABLE_OK; + + i += 1; + } + + return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- -hashtable_rc_t hashtable_dump_content (const hash_table_t * const hashtblP, char * const buffer_pP, int * const remaining_bytes_in_buffer_pP ) +hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP ) //------------------------------------------------------------------------------------------------------------------------------- { - hash_node_t *node = NULL; - unsigned int i = 0; - if (hashtblP == NULL) { + hash_node_t *node = NULL; + unsigned int i = 0; + + if (hashtblP == NULL) { + *remaining_bytes_in_buffer_pP = snprintf( + buffer_pP, + *remaining_bytes_in_buffer_pP, + "HASH_TABLE_BAD_PARAMETER_HASHTABLE"); + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + + while ((i < hashtblP->size) && (*remaining_bytes_in_buffer_pP > 0)) { + if (hashtblP->nodes[i] != NULL) { + node=hashtblP->nodes[i]; + + while(node) { *remaining_bytes_in_buffer_pP = snprintf( - buffer_pP, - *remaining_bytes_in_buffer_pP, - "HASH_TABLE_BAD_PARAMETER_HASHTABLE"); - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - while ((i < hashtblP->size) && (*remaining_bytes_in_buffer_pP > 0)) { - if (hashtblP->nodes[i] != NULL) { - node=hashtblP->nodes[i]; - while(node) { - *remaining_bytes_in_buffer_pP = snprintf( - buffer_pP, - *remaining_bytes_in_buffer_pP, - "Key 0x%"PRIx64" Element %p\n", - node->key, - node->data); - node=node->next; - } - } - i += 1; + buffer_pP, + *remaining_bytes_in_buffer_pP, + "Key 0x%"PRIx64" Element %p\n", + node->key, + node->data); + node=node->next; + } } - return HASH_TABLE_OK; + + i += 1; + } + + return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- @@ -200,97 +230,110 @@ hashtable_rc_t hashtable_dump_content (const hash_table_t * const hashtblP, char * Adding a new element * To make sure the hash value is not bigger than size, the result of the user provided hash function is used modulo size. */ -hashtable_rc_t hashtable_insert(hash_table_t * const hashtblP, const hash_key_t keyP, void *dataP) -{ - hash_node_t *node = NULL; - hash_size_t hash = 0; - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - hash=hashtblP->hashfunc(keyP)%hashtblP->size; +hashtable_rc_t hashtable_insert(hash_table_t *const hashtblP, const hash_key_t keyP, void *dataP) { + hash_node_t *node = NULL; + hash_size_t hash = 0; - node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - if (node->data) { - hashtblP->freefunc(node->data); - } - node->data=dataP; - return HASH_TABLE_INSERT_OVERWRITTEN_DATA; - } - node=node->next; - } - if(!(node=malloc(sizeof(hash_node_t)))) return -1; - node->key=keyP; - node->data=dataP; - if (hashtblP->nodes[hash]) { - node->next=hashtblP->nodes[hash]; - } else { - node->next = NULL; + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + + hash=hashtblP->hashfunc(keyP)%hashtblP->size; + node=hashtblP->nodes[hash]; + + while(node) { + if(node->key == keyP) { + if (node->data) { + hashtblP->freefunc(node->data); + } + + node->data=dataP; + return HASH_TABLE_INSERT_OVERWRITTEN_DATA; } - hashtblP->nodes[hash]=node; - hashtblP->num_elements += 1; - return HASH_TABLE_OK; + + node=node->next; + } + + if(!(node=malloc(sizeof(hash_node_t)))) return -1; + + node->key=keyP; + node->data=dataP; + + if (hashtblP->nodes[hash]) { + node->next=hashtblP->nodes[hash]; + } else { + node->next = NULL; + } + + hashtblP->nodes[hash]=node; + hashtblP->num_elements += 1; + return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- /* * To remove an element from the hash table, we just search for it in the linked list for that hash value, * and remove it if it is found. If it was not found, it is an error and -1 is returned. */ -hashtable_rc_t hashtable_remove(hash_table_t * const hashtblP, const hash_key_t keyP) -{ - hash_node_t *node, *prevnode=NULL; - hash_size_t hash = 0; +hashtable_rc_t hashtable_remove(hash_table_t *const hashtblP, const hash_key_t keyP) { + hash_node_t *node, *prevnode=NULL; + hash_size_t hash = 0; - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - hash=hashtblP->hashfunc(keyP)%hashtblP->size; - node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - if(prevnode) prevnode->next=node->next; - else hashtblP->nodes[hash]=node->next; - if (node->data) { - hashtblP->freefunc(node->data); - } - free(node); - hashtblP->num_elements -= 1; - return HASH_TABLE_OK; - } - prevnode=node; - node=node->next; + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + + hash=hashtblP->hashfunc(keyP)%hashtblP->size; + node=hashtblP->nodes[hash]; + + while(node) { + if(node->key == keyP) { + if(prevnode) prevnode->next=node->next; + else hashtblP->nodes[hash]=node->next; + + if (node->data) { + hashtblP->freefunc(node->data); + } + + free(node); + hashtblP->num_elements -= 1; + return HASH_TABLE_OK; } - return HASH_TABLE_KEY_NOT_EXISTS; + + prevnode=node; + node=node->next; + } + + return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- /* * Searching for an element is easy. We just search through the linked list for the corresponding hash value. * NULL is returned if we didn't find it. */ -hashtable_rc_t hashtable_get(const hash_table_t * const hashtblP, const hash_key_t keyP, void** dataP) -{ - hash_node_t *node = NULL; - hash_size_t hash = 0; +hashtable_rc_t hashtable_get(const hash_table_t *const hashtblP, const hash_key_t keyP, void **dataP) { + hash_node_t *node = NULL; + hash_size_t hash = 0; - if (hashtblP == NULL) { - *dataP = NULL; - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - hash=hashtblP->hashfunc(keyP)%hashtblP->size; -/* fprintf(stderr, "hashtable_get() key=%s, hash=%d\n", key, hash);*/ + if (hashtblP == NULL) { + *dataP = NULL; + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } - node=hashtblP->nodes[hash]; + hash=hashtblP->hashfunc(keyP)%hashtblP->size; + /* fprintf(stderr, "hashtable_get() key=%s, hash=%d\n", key, hash);*/ + node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - *dataP = node->data; - return HASH_TABLE_OK; - } - node=node->next; + while(node) { + if(node->key == keyP) { + *dataP = node->data; + return HASH_TABLE_OK; } - *dataP = NULL; - return HASH_TABLE_KEY_NOT_EXISTS; + + node=node->next; + } + + *dataP = NULL; + return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- /* @@ -304,36 +347,33 @@ hashtable_rc_t hashtable_get(const hash_table_t * const hashtblP, const hash_key * After that, we can just free the old table and copy the elements from newtbl to hashtbl. */ -hashtable_rc_t hashtable_resize(hash_table_t * const hashtblP, const hash_size_t sizeP) -{ - hash_table_t newtbl; - hash_size_t n; - hash_node_t *node,*next; - - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } +hashtable_rc_t hashtable_resize(hash_table_t *const hashtblP, const hash_size_t sizeP) { + hash_table_t newtbl; + hash_size_t n; + hash_node_t *node,*next; - newtbl.size = sizeP; - newtbl.hashfunc = hashtblP->hashfunc; + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } - if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t*)))) return -1; + newtbl.size = sizeP; + newtbl.hashfunc = hashtblP->hashfunc; - for(n=0; n<hashtblP->size; ++n) { - for(node=hashtblP->nodes[n]; node; node=next) { - next = node->next; - hashtable_insert(&newtbl, node->key, node->data); - // Lionel GAUTHIER: BAD CODE TO BE REWRITTEN - hashtable_remove(hashtblP, node->key); + if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t *)))) return -1; - } + for(n=0; n<hashtblP->size; ++n) { + for(node=hashtblP->nodes[n]; node; node=next) { + next = node->next; + hashtable_insert(&newtbl, node->key, node->data); + // Lionel GAUTHIER: BAD CODE TO BE REWRITTEN + hashtable_remove(hashtblP, node->key); } + } - free(hashtblP->nodes); - hashtblP->size=newtbl.size; - hashtblP->nodes=newtbl.nodes; - - return HASH_TABLE_OK; + free(hashtblP->nodes); + hashtblP->size=newtbl.size; + hashtblP->nodes=newtbl.nodes; + return HASH_TABLE_OK; } diff --git a/common/utils/hashtable/hashtable.h b/common/utils/hashtable/hashtable.h index 62002fb60f89c738d8d2a941d9cd31fac9e268f5..3f770684fae9996f8973b4268f106a6526dafd0b 100644 --- a/common/utils/hashtable/hashtable.h +++ b/common/utils/hashtable/hashtable.h @@ -2,9 +2,9 @@ * 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 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. + * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 @@ -31,41 +31,41 @@ typedef uint64_t hash_key_t; #define HASHTABLE_NOT_A_KEY_VALUE ((uint64_t)-1) typedef enum hashtable_return_code_e { - HASH_TABLE_OK = 0, - HASH_TABLE_INSERT_OVERWRITTEN_DATA = 1, - HASH_TABLE_KEY_NOT_EXISTS = 2, - HASH_TABLE_KEY_ALREADY_EXISTS = 3, - HASH_TABLE_BAD_PARAMETER_HASHTABLE = 4, - HASH_TABLE_SYSTEM_ERROR = 5, - HASH_TABLE_CODE_MAX + HASH_TABLE_OK = 0, + HASH_TABLE_INSERT_OVERWRITTEN_DATA = 1, + HASH_TABLE_KEY_NOT_EXISTS = 2, + HASH_TABLE_KEY_ALREADY_EXISTS = 3, + HASH_TABLE_BAD_PARAMETER_HASHTABLE = 4, + HASH_TABLE_SYSTEM_ERROR = 5, + HASH_TABLE_CODE_MAX } hashtable_rc_t; typedef struct hash_node_s { - hash_key_t key; - void *data; - struct hash_node_s *next; + hash_key_t key; + void *data; + struct hash_node_s *next; } hash_node_t; typedef struct hash_table_s { - hash_size_t size; - hash_size_t num_elements; - struct hash_node_s **nodes; - hash_size_t (*hashfunc)(const hash_key_t); - void (*freefunc)(void*); + hash_size_t size; + hash_size_t num_elements; + struct hash_node_s **nodes; + hash_size_t (*hashfunc)(const hash_key_t); + void (*freefunc)(void *); } hash_table_t; -char* hashtable_rc_code2string(hashtable_rc_t rcP); -void hash_free_int_func(void* memoryP); -hash_table_t *hashtable_create (const hash_size_t size, hash_size_t (*hashfunc)(const hash_key_t ), void (*freefunc)(void*)); -hashtable_rc_t hashtable_destroy(hash_table_t * const hashtbl); -hashtable_rc_t hashtable_is_key_exists (const hash_table_t * const hashtbl, const uint64_t key); -hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t * const hashtblP, void funct(hash_key_t keyP, void* dataP, void* parameterP), void* parameterP); -hashtable_rc_t hashtable_dump_content (const hash_table_t * const hashtblP, char * const buffer_pP, int * const remaining_bytes_in_buffer_pP ); -hashtable_rc_t hashtable_insert (hash_table_t * const hashtbl, const hash_key_t key, void *data); -hashtable_rc_t hashtable_remove (hash_table_t * const hashtbl, const hash_key_t key); -hashtable_rc_t hashtable_get (const hash_table_t * const hashtbl, const hash_key_t key, void **dataP); -hashtable_rc_t hashtable_resize (hash_table_t * const hashtbl, const hash_size_t size); +char *hashtable_rc_code2string(hashtable_rc_t rcP); +void hash_free_int_func(void *memoryP); +hash_table_t *hashtable_create (const hash_size_t size, hash_size_t (*hashfunc)(const hash_key_t ), void (*freefunc)(void *)); +hashtable_rc_t hashtable_destroy(hash_table_t **hashtbl); +hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtbl, const uint64_t key); +hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void funct(hash_key_t keyP, void *dataP, void *parameterP), void *parameterP); +hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP ); +hashtable_rc_t hashtable_insert (hash_table_t *const hashtbl, const hash_key_t key, void *data); +hashtable_rc_t hashtable_remove (hash_table_t *const hashtbl, const hash_key_t key); +hashtable_rc_t hashtable_get (const hash_table_t *const hashtbl, const hash_key_t key, void **dataP); +hashtable_rc_t hashtable_resize (hash_table_t *const hashtbl, const hash_size_t size); diff --git a/common/utils/hashtable/obj_hashtable.c b/common/utils/hashtable/obj_hashtable.c index 7fb68d16817993c86e75f211e2b0b2c257039e19..643dcce552ad72381f62b38f954e4d217e0ecb5a 100644 --- a/common/utils/hashtable/obj_hashtable.c +++ b/common/utils/hashtable/obj_hashtable.c @@ -2,9 +2,9 @@ * 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 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. + * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 @@ -30,13 +30,12 @@ * This is a simple/naive hash function which adds the key's ASCII char values. It will probably generate lots of collisions on large hash tables. */ -static hash_size_t def_hashfunc(const void *keyP, int key_sizeP) -{ - hash_size_t hash=0; +static hash_size_t def_hashfunc(const void *keyP, int key_sizeP) { + hash_size_t hash=0; - while(key_sizeP) hash^=((unsigned char*)keyP)[key_sizeP --]; + while(key_sizeP) hash^=((unsigned char *)keyP)[key_sizeP --]; - return hash; + return hash; } //------------------------------------------------------------------------------------------------------------------------------- @@ -46,201 +45,221 @@ static hash_size_t def_hashfunc(const void *keyP, int key_sizeP) * The user can also specify a hash function. If the hashfunc argument is NULL, a default hash function is used. * If an error occurred, NULL is returned. All other values in the returned obj_hash_table_t pointer should be released with hashtable_destroy(). */ -obj_hash_table_t *obj_hashtable_create(hash_size_t sizeP, hash_size_t (*hashfuncP)(const void*, int ), void (*freekeyfuncP)(void*), void (*freedatafuncP)(void*)) -{ - obj_hash_table_t *hashtbl; +obj_hash_table_t *obj_hashtable_create(hash_size_t sizeP, hash_size_t (*hashfuncP)(const void *, int ), void (*freekeyfuncP)(void *), void (*freedatafuncP)(void *)) { + obj_hash_table_t *hashtbl; - if(!(hashtbl=malloc(sizeof(obj_hash_table_t)))) return NULL; + if(!(hashtbl=malloc(sizeof(obj_hash_table_t)))) return NULL; - if(!(hashtbl->nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) { - free(hashtbl); - return NULL; - } + if(!(hashtbl->nodes=calloc(sizeP, sizeof(obj_hash_node_t *)))) { + free(hashtbl); + return NULL; + } - hashtbl->size=sizeP; + hashtbl->size=sizeP; - if(hashfuncP) hashtbl->hashfunc=hashfuncP; - else hashtbl->hashfunc=def_hashfunc; + if(hashfuncP) hashtbl->hashfunc=hashfuncP; + else hashtbl->hashfunc=def_hashfunc; - if(freekeyfuncP) hashtbl->freekeyfunc=freekeyfuncP; - else hashtbl->freekeyfunc=free; + if(freekeyfuncP) hashtbl->freekeyfunc=freekeyfuncP; + else hashtbl->freekeyfunc=free; - if(freedatafuncP) hashtbl->freedatafunc=freedatafuncP; - else hashtbl->freedatafunc=free; + if(freedatafuncP) hashtbl->freedatafunc=freedatafuncP; + else hashtbl->freedatafunc=free; - return hashtbl; + return hashtbl; } //------------------------------------------------------------------------------------------------------------------------------- /* * Cleanup * The hashtable_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the obj_hash_table_t. */ -hashtable_rc_t obj_hashtable_destroy(obj_hash_table_t *hashtblP) -{ - hash_size_t n; - obj_hash_node_t *node, *oldnode; +hashtable_rc_t obj_hashtable_destroy(obj_hash_table_t *hashtblP) { + hash_size_t n; + obj_hash_node_t *node, *oldnode; - for(n=0; n<hashtblP->size; ++n) { - node=hashtblP->nodes[n]; - while(node) { - oldnode=node; - node=node->next; - hashtblP->freekeyfunc(oldnode->key); - hashtblP->freedatafunc(oldnode->data); - free(oldnode); - } + for(n=0; n<hashtblP->size; ++n) { + node=hashtblP->nodes[n]; + + while(node) { + oldnode=node; + node=node->next; + hashtblP->freekeyfunc(oldnode->key); + hashtblP->freedatafunc(oldnode->data); + free(oldnode); } - free(hashtblP->nodes); - free(hashtblP); - return HASH_TABLE_OK; + } + + free(hashtblP->nodes); + free(hashtblP); + return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- -hashtable_rc_t obj_hashtable_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP) +hashtable_rc_t obj_hashtable_is_key_exists (obj_hash_table_t *hashtblP, void *keyP, int key_sizeP) //------------------------------------------------------------------------------------------------------------------------------- { - obj_hash_node_t *node; - hash_size_t hash; + obj_hash_node_t *node; + hash_size_t hash; - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; - node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - return HASH_TABLE_OK; - } else if (node->key_size == key_sizeP) { - if (memcmp(node->key, keyP, key_sizeP) == 0) { - return HASH_TABLE_OK; - } - } - node=node->next; + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + + hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; + node=hashtblP->nodes[hash]; + + while(node) { + if(node->key == keyP) { + return HASH_TABLE_OK; + } else if (node->key_size == key_sizeP) { + if (memcmp(node->key, keyP, key_sizeP) == 0) { + return HASH_TABLE_OK; + } } - return HASH_TABLE_KEY_NOT_EXISTS; + + node=node->next; + } + + return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- /* * Adding a new element * To make sure the hash value is not bigger than size, the result of the user provided hash function is used modulo size. */ -hashtable_rc_t obj_hashtable_insert(obj_hash_table_t *hashtblP, void* keyP, int key_sizeP, void *dataP) -{ - obj_hash_node_t *node; - hash_size_t hash; +hashtable_rc_t obj_hashtable_insert(obj_hash_table_t *hashtblP, void *keyP, int key_sizeP, void *dataP) { + obj_hash_node_t *node; + hash_size_t hash; - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; - node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - if (node->data) { - hashtblP->freedatafunc(node->data); - } - node->data=dataP; - // waste of memory here (keyP is lost) we should free it now - return HASH_TABLE_INSERT_OVERWRITTEN_DATA; - } - node=node->next; - } - if(!(node=malloc(sizeof(obj_hash_node_t)))) return -1; - node->key=keyP; - node->data=dataP; - if (hashtblP->nodes[hash]) { - node->next=hashtblP->nodes[hash]; - } else { - node->next = NULL; + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + + hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; + node=hashtblP->nodes[hash]; + + while(node) { + if(node->key == keyP) { + if (node->data) { + hashtblP->freedatafunc(node->data); + } + + node->data=dataP; + // waste of memory here (keyP is lost) we should free it now + return HASH_TABLE_INSERT_OVERWRITTEN_DATA; } - hashtblP->nodes[hash]=node; - return HASH_TABLE_OK; + + node=node->next; + } + + if(!(node=malloc(sizeof(obj_hash_node_t)))) return -1; + + node->key=keyP; + node->data=dataP; + + if (hashtblP->nodes[hash]) { + node->next=hashtblP->nodes[hash]; + } else { + node->next = NULL; + } + + hashtblP->nodes[hash]=node; + return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- /* * To remove an element from the hash table, we just search for it in the linked list for that hash value, * and remove it if it is found. If it was not found, it is an error and -1 is returned. */ -hashtable_rc_t obj_hashtable_remove(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP) -{ - obj_hash_node_t *node, *prevnode=NULL; - hash_size_t hash; +hashtable_rc_t obj_hashtable_remove(obj_hash_table_t *hashtblP, const void *keyP, int key_sizeP) { + obj_hash_node_t *node, *prevnode=NULL; + hash_size_t hash; - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } - hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; - node=hashtblP->nodes[hash]; - while(node) { - if ((node->key == keyP) || ((node->key_size == key_sizeP) && (memcmp(node->key, keyP, key_sizeP) == 0))){ - if(prevnode) { - prevnode->next=node->next; - } else { - hashtblP->nodes[hash]=node->next; - } - hashtblP->freekeyfunc(node->key); - hashtblP->freedatafunc(node->data); - free(node); - return HASH_TABLE_OK; - } - prevnode=node; - node=node->next; + hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; + node=hashtblP->nodes[hash]; + + while(node) { + if ((node->key == keyP) || ((node->key_size == key_sizeP) && (memcmp(node->key, keyP, key_sizeP) == 0))) { + if(prevnode) { + prevnode->next=node->next; + } else { + hashtblP->nodes[hash]=node->next; + } + + hashtblP->freekeyfunc(node->key); + hashtblP->freedatafunc(node->data); + free(node); + return HASH_TABLE_OK; } - return HASH_TABLE_KEY_NOT_EXISTS; + + prevnode=node; + node=node->next; + } + + return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- /* * Searching for an element is easy. We just search through the linked list for the corresponding hash value. * NULL is returned if we didn't find it. */ -hashtable_rc_t obj_hashtable_get(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void** dataP) -{ - obj_hash_node_t *node; - hash_size_t hash; +hashtable_rc_t obj_hashtable_get(obj_hash_table_t *hashtblP, const void *keyP, int key_sizeP, void **dataP) { + obj_hash_node_t *node; + hash_size_t hash; - if (hashtblP == NULL) { - *dataP = NULL; - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; - node=hashtblP->nodes[hash]; - while(node) { - if(node->key == keyP) { - *dataP = node->data; - return HASH_TABLE_OK; - } else if (node->key_size == key_sizeP) { - if (memcmp(node->key, keyP, key_sizeP) == 0) { - *dataP = node->data; - return HASH_TABLE_OK; - } - } - node=node->next; - } + if (hashtblP == NULL) { *dataP = NULL; - return HASH_TABLE_KEY_NOT_EXISTS; + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } + + hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size; + node=hashtblP->nodes[hash]; + + while(node) { + if(node->key == keyP) { + *dataP = node->data; + return HASH_TABLE_OK; + } else if (node->key_size == key_sizeP) { + if (memcmp(node->key, keyP, key_sizeP) == 0) { + *dataP = node->data; + return HASH_TABLE_OK; + } + } + + node=node->next; + } + + *dataP = NULL; + return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- /* * Function to return all keys of an object hash table */ -hashtable_rc_t obj_hashtable_get_keys(obj_hash_table_t *hashtblP, void ** keysP, unsigned int *sizeP) -{ - size_t n = 0; - obj_hash_node_t *node = NULL; - obj_hash_node_t *next = NULL; - - *sizeP = 0; - keysP = calloc(hashtblP->num_elements, sizeof(void *)); - if (keysP) { - for(n=0; n<hashtblP->size; ++n) { - for(node=hashtblP->nodes[n]; node; node=next) { - keysP[*sizeP++] = node->key; - next = node->next; - } - } - return HASH_TABLE_OK; + +hashtable_rc_t obj_hashtable_get_keys(obj_hash_table_t *hashtblP, void **keysP, unsigned int *sizeP) { + size_t n = 0; + obj_hash_node_t *node = NULL; + obj_hash_node_t *next = NULL; + *sizeP = 0; + keysP = calloc(hashtblP->num_elements, sizeof(void *)); + + if (keysP) { + for(n=0; n<hashtblP->size; ++n) { + for(node=hashtblP->nodes[n]; node; node=next) { + keysP[*sizeP++] = node->key; + next = node->next; + } } - return HASH_TABLE_SYSTEM_ERROR; + + // cppcheck-suppress memleak + return HASH_TABLE_OK; + } + + return HASH_TABLE_SYSTEM_ERROR; } //------------------------------------------------------------------------------------------------------------------------------- /* @@ -253,34 +272,32 @@ hashtable_rc_t obj_hashtable_get_keys(obj_hash_table_t *hashtblP, void ** keysP, * This allows us to reuse hashtable_insert() and hashtable_remove(), when moving the elements to the new table. * After that, we can just free the old table and copy the elements from newtbl to hashtbl. */ -hashtable_rc_t obj_hashtable_resize(obj_hash_table_t *hashtblP, hash_size_t sizeP) -{ - obj_hash_table_t newtbl; - hash_size_t n; - obj_hash_node_t *node,*next; +hashtable_rc_t obj_hashtable_resize(obj_hash_table_t *hashtblP, hash_size_t sizeP) { + obj_hash_table_t newtbl; + hash_size_t n; + obj_hash_node_t *node,*next; - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } + if (hashtblP == NULL) { + return HASH_TABLE_BAD_PARAMETER_HASHTABLE; + } - newtbl.size = sizeP; - newtbl.hashfunc = hashtblP->hashfunc; + newtbl.size = sizeP; + newtbl.hashfunc = hashtblP->hashfunc; - if(!(newtbl.nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) return HASH_TABLE_SYSTEM_ERROR; + if(!(newtbl.nodes=calloc(sizeP, sizeof(obj_hash_node_t *)))) return HASH_TABLE_SYSTEM_ERROR; - for(n=0; n<hashtblP->size; ++n) { - for(node=hashtblP->nodes[n]; node; node=next) { - next = node->next; - obj_hashtable_insert(&newtbl, node->key, node->key_size, node->data); - obj_hashtable_remove(hashtblP, node->key, node->key_size); - } + for(n=0; n<hashtblP->size; ++n) { + for(node=hashtblP->nodes[n]; node; node=next) { + next = node->next; + obj_hashtable_insert(&newtbl, node->key, node->key_size, node->data); + obj_hashtable_remove(hashtblP, node->key, node->key_size); } + } - free(hashtblP->nodes); - hashtblP->size=newtbl.size; - hashtblP->nodes=newtbl.nodes; - - return HASH_TABLE_OK; + free(hashtblP->nodes); + hashtblP->size=newtbl.size; + hashtblP->nodes=newtbl.nodes; + return HASH_TABLE_OK; } diff --git a/common/utils/memory_pools.c b/common/utils/memory_pools.c index 78b6923dc863f982683d57a126c539651ef3817d..9f37e4708083dfa9139186da76ac2aa57db88671 100644 --- a/common/utils/memory_pools.c +++ b/common/utils/memory_pools.c @@ -23,19 +23,19 @@ #include "memory_pools.h" #if T_TRACER -#include <string.h> -#include "T.h" + #include <string.h> + #include "T.h" #endif /*------------------------------------------------------------------------------*/ const static int mp_debug = 0; # define MP_DEBUG(x, args...) do { if (mp_debug) fprintf(stdout, "[MP][D]"x, ##args); fflush (stdout); } \ - while(0) + while(0) /*------------------------------------------------------------------------------*/ #ifndef CHARS_TO_UINT32 -#define CHARS_TO_UINT32(c1, c2, c3, c4) (((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4)) + #define CHARS_TO_UINT32(c1, c2, c3, c4) (((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4)) #endif #define MEMORY_POOL_ITEM_INFO_NUMBER 2 @@ -129,33 +129,25 @@ static const pool_start_mark_t POOL_START_MARK = CHARS_TO_UINT32 ('P' static const pools_start_mark_t POOLS_START_MARK = CHARS_TO_UINT32 ('P', 'S', 's', 't'); /*------------------------------------------------------------------------------*/ -static inline uint32_t items_group_number_items (items_group_t *items_group) -{ +static inline uint32_t items_group_number_items (items_group_t *items_group) { return items_group->number_plus_one - 1; } -static inline uint32_t items_group_free_items (items_group_t *items_group) -{ +static inline uint32_t items_group_free_items (items_group_t *items_group) { items_group_positions_t positions; uint32_t free_items; - positions.all = items_group->positions.all; - free_items = items_group->number_plus_one + positions.ind.put - positions.ind.get; free_items %= items_group->number_plus_one; - return free_items; } -static inline items_group_index_t items_group_get_free_item (items_group_t *items_group) -{ +static inline items_group_index_t items_group_get_free_item (items_group_t *items_group) { items_group_position_t get_raw; items_group_position_t put; items_group_position_t get; items_group_position_t free_items; - items_group_index_t index = ITEMS_GROUP_INDEX_INVALID; - /* Get current put position */ put = items_group->positions.ind.put % items_group->number_plus_one; /* Get current get position and increase it */ @@ -193,11 +185,9 @@ static inline items_group_index_t items_group_get_free_item (items_group_t *item return (index); } -static inline int items_group_put_free_item (items_group_t *items_group, items_group_index_t index) -{ +static inline int items_group_put_free_item (items_group_t *items_group, items_group_index_t index) { items_group_position_t put_raw; items_group_position_t put; - /* Get current put position and increase it */ put_raw = __sync_fetch_and_add (&items_group->positions.ind.put, 1); put = put_raw % items_group->number_plus_one; @@ -209,70 +199,54 @@ static inline int items_group_put_free_item (items_group_t *items_group, items_g AssertError (items_group->indexes[put] <= ITEMS_GROUP_INDEX_INVALID, return (EXIT_FAILURE), "Index at current put position (%d) is not marked as free (%d)!\n", put, items_group->number_plus_one); - /* Save freed item index at current put position */ items_group->indexes[put] = index; return (EXIT_SUCCESS); } /*------------------------------------------------------------------------------*/ -static inline memory_pools_t *memory_pools_from_handler (memory_pools_handle_t memory_pools_handle) -{ +static inline memory_pools_t *memory_pools_from_handler (memory_pools_handle_t memory_pools_handle) { memory_pools_t *memory_pools; - /* Recover memory_pools */ memory_pools = (memory_pools_t *) memory_pools_handle; /* Sanity check on passed handle */ AssertError (memory_pools->start_mark == POOLS_START_MARK, memory_pools = NULL, "Handle %p is not a valid memory pools handle, start mark is missing!\n", memory_pools_handle); - return (memory_pools); } -static inline memory_pool_item_t *memory_pool_item_from_handler (memory_pool_item_handle_t memory_pool_item_handle) -{ +static inline memory_pool_item_t *memory_pool_item_from_handler (memory_pool_item_handle_t memory_pool_item_handle) { void *address; memory_pool_item_t *memory_pool_item; - /* Recover memory_pools */ address = memory_pool_item_handle - sizeof(memory_pool_item_start_t); memory_pool_item = (memory_pool_item_t *) address; - /* Sanity check on passed handle */ AssertError (memory_pool_item->start.start_mark == POOL_ITEM_START_MARK, memory_pool_item = NULL, "Handle %p is not a valid memory pool item handle, start mark is missing!\n", memory_pool_item); - return (memory_pool_item); } -static inline memory_pool_item_t *memory_pool_item_from_index (memory_pool_t *memory_pool, items_group_index_t index) -{ +static inline memory_pool_item_t *memory_pool_item_from_index (memory_pool_t *memory_pool, items_group_index_t index) { void *address; - address = (void *) memory_pool->items; address += index * memory_pool->pool_item_size; - return (address); } /*------------------------------------------------------------------------------*/ -memory_pools_handle_t memory_pools_create (uint32_t pools_number) -{ +memory_pools_handle_t memory_pools_create (uint32_t pools_number) { memory_pools_t *memory_pools; pool_id_t pool; - AssertFatal (pools_number <= MAX_POOLS_NUMBER, "Too many memory pools requested (%d/%d)!\n", pools_number, MAX_POOLS_NUMBER); /* Limit to a reasonable number of pools */ - /* Allocate memory_pools */ memory_pools = malloc (sizeof(memory_pools_t)); AssertFatal (memory_pools != NULL, "Memory pools structure allocation failed!\n"); - /* Initialize memory_pools */ { memory_pools->start_mark = POOLS_START_MARK; memory_pools->pools_number = pools_number; memory_pools->pools_defined = 0; - /* Allocate pools */ memory_pools->pools = calloc (pools_number, sizeof(memory_pool_t)); AssertFatal (memory_pools->pools != NULL, "Memory pools allocation failed!\n"); @@ -282,12 +256,10 @@ memory_pools_handle_t memory_pools_create (uint32_t pools_number) memory_pools->pools[pool].start_mark = POOL_START_MARK; } } - return ((memory_pools_handle_t) memory_pools); } -char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle) -{ +char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle) { memory_pools_t *memory_pools; pool_id_t pool; char *statistics; @@ -296,13 +268,10 @@ char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle) uint32_t allocated_pools_memory = 0; items_group_t *items_group; uint32_t pool_items_size; - /* Recover memory_pools */ memory_pools = memory_pools_from_handler (memory_pools_handle); AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - statistics = malloc(memory_pools->pools_defined * 200); - printed_chars = sprintf (&statistics[0], "Pool: size, number, minimum, free, address space and memory used in Kbytes\n"); for (pool = 0; pool < memory_pools->pools_defined; pool++) { @@ -321,32 +290,25 @@ char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle) } printed_chars = sprintf (&statistics[printed_chars], "Pools memory %u Kbytes\n", allocated_pools_memory / (1024)); - return (statistics); } -int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t pool_items_number, uint32_t pool_item_size) -{ +int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t pool_items_number, uint32_t pool_item_size) { memory_pools_t *memory_pools; memory_pool_t *memory_pool; pool_id_t pool; items_group_index_t item_index; memory_pool_item_t *memory_pool_item; - AssertFatal (pool_items_number <= MAX_POOL_ITEMS_NUMBER, "Too many items for a memory pool (%u/%d)!\n", pool_items_number, MAX_POOL_ITEMS_NUMBER); /* Limit to a reasonable number of items */ AssertFatal (pool_item_size <= MAX_POOL_ITEM_SIZE, "Item size is too big for memory pool items (%u/%d)!\n", pool_item_size, MAX_POOL_ITEM_SIZE); /* Limit to a reasonable item size */ - /* Recover memory_pools */ memory_pools = memory_pools_from_handler (memory_pools_handle); AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - /* Check number of already created pools */ AssertFatal (memory_pools->pools_defined < memory_pools->pools_number, "Can not allocate more memory pool (%d)!\n", memory_pools->pools_number); - /* Select pool */ pool = memory_pools->pools_defined; memory_pool = &memory_pools->pools[pool]; - /* Initialize pool */ { memory_pool->pool_id = pool; @@ -357,7 +319,6 @@ int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t p memory_pool->items_group_free.minimum = pool_items_number; memory_pool->items_group_free.positions.ind.put = pool_items_number; memory_pool->items_group_free.positions.ind.get = 0; - /* Allocate free indexes */ memory_pool->items_group_free.indexes = malloc(memory_pool->items_group_free.number_plus_one * sizeof(items_group_index_t)); AssertFatal (memory_pool->items_group_free.indexes != NULL, "Memory pool indexes allocation failed!\n"); @@ -369,7 +330,6 @@ int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t p /* Last index is not allocated */ memory_pool->items_group_free.indexes[item_index] = ITEMS_GROUP_INDEX_INVALID; - /* Allocate items */ memory_pool->items = calloc (pool_items_number, memory_pool->pool_item_size); AssertFatal (memory_pool->items != NULL, "Memory pool items allocation failed!\n"); @@ -383,20 +343,16 @@ int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t p memory_pool_item->data[memory_pool->item_data_number] = POOL_ITEM_END_MARK; } } - memory_pools->pools_defined ++; - return (0); } -memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_pools_handle, uint32_t item_size, uint16_t info_0, uint16_t info_1) -{ +memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_pools_handle, uint32_t item_size, uint16_t info_0, uint16_t info_1) { memory_pools_t *memory_pools; memory_pool_item_t *memory_pool_item; memory_pool_item_handle_t memory_pool_item_handle = NULL; pool_id_t pool; items_group_index_t item_index = ITEMS_GROUP_INDEX_INVALID; - /* Recover memory_pools */ memory_pools = memory_pools_from_handler (memory_pools_handle); AssertError (memory_pools != NULL, {}, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); @@ -424,12 +380,10 @@ memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_po /* Sanity check on item status, must be free */ AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_FREE, "Item status is not set to free (%d) in pool %u, item %d!\n", memory_pool_item->start.item_status, pool, item_index); - memory_pool_item->start.item_status = ITEM_STATUS_ALLOCATED; memory_pool_item->start.info[0] = info_0; memory_pool_item->start.info[1] = info_1; memory_pool_item_handle = memory_pool_item->data; - MP_DEBUG(" Alloc [%2u][%6d]{%6d}, %3u %3u, %6u, %p, %p, %p\n", pool, item_index, items_group_free_items (&memory_pools->pools[pool].items_group_free), @@ -445,8 +399,7 @@ memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_po return memory_pool_item_handle; } -int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, uint16_t info_0) -{ +int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, uint16_t info_0) { memory_pools_t *memory_pools; memory_pool_item_t *memory_pool_item; pool_id_t pool; @@ -455,36 +408,29 @@ int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_it uint32_t pool_item_size; uint16_t info_1; int result; - /* Recover memory_pools */ memory_pools = memory_pools_from_handler (memory_pools_handle); AssertError (memory_pools != NULL, return (EXIT_FAILURE), "Failed to retrieve memory pools for handle %p!\n", memory_pools_handle); - /* Recover memory pool item */ memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle); AssertError (memory_pool_item != NULL, return (EXIT_FAILURE), "Failed to retrieve memory pool item for handle %p!\n", memory_pool_item_handle); - info_1 = memory_pool_item->start.info[1]; - /* Recover pool index */ pool = memory_pool_item->start.pool_id; AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined); - item_size = memory_pools->pools[pool].item_data_number; pool_item_size = memory_pools->pools[pool].pool_item_size; item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size; - MP_DEBUG(" Free [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n", pool, item_index, items_group_free_items (&memory_pools->pools[pool].items_group_free), memory_pool_item->start.info[0], info_1, memory_pool_item_handle, memory_pool_item, memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t)))); - /* Sanity check on calculated item index */ AssertFatal (memory_pool_item == memory_pool_item_from_index(&memory_pools->pools[pool], item_index), "Incorrect memory pool item address (%p, %p) for pool %u, item %d!\n", - memory_pool_item, memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index); + memory_pool_item,(void *)memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index); /* Sanity check on end marker, must still be present (no write overflow) */ AssertFatal (memory_pool_item->data[item_size] == POOL_ITEM_END_MARK, "Memory pool item is corrupted, end mark is not present for pool %u, item %d!\n", pool, item_index); @@ -492,31 +438,23 @@ int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_it AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_ALLOCATED, "Trying to free a non allocated (%x) memory pool item (pool %u, item %d)!\n", memory_pool_item->start.item_status, pool, item_index); - memory_pool_item->start.item_status = ITEM_STATUS_FREE; - result = items_group_put_free_item(&memory_pools->pools[pool].items_group_free, item_index); - AssertError (result == EXIT_SUCCESS, {}, "Failed to free memory pool item (pool %u, item %d)!\n", pool, item_index); - return (result); } -void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, int index, uint16_t info) -{ +void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, int index, uint16_t info) { memory_pools_t *memory_pools; memory_pool_item_t *memory_pool_item; pool_id_t pool; items_group_index_t item_index; uint32_t item_size; uint32_t pool_item_size; - AssertFatal (index < MEMORY_POOL_ITEM_INFO_NUMBER, "Incorrect info index (%d/%d)!\n", index, MEMORY_POOL_ITEM_INFO_NUMBER); - /* Recover memory pool item */ memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle); AssertFatal (memory_pool_item != NULL, "Failed to retrieve memory pool item for handle %p!\n", memory_pool_item_handle); - /* Set info[1] */ memory_pool_item->start.info[index] = info; @@ -525,26 +463,22 @@ void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_po /* Recover memory_pools */ memory_pools = memory_pools_from_handler (memory_pools_handle); AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - /* Recover pool index */ pool = memory_pool_item->start.pool_id; AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined); - item_size = memory_pools->pools[pool].item_data_number; pool_item_size = memory_pools->pools[pool].pool_item_size; item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size; - MP_DEBUG(" Info [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n", pool, item_index, items_group_free_items (&memory_pools->pools[pool].items_group_free), memory_pool_item->start.info[0], memory_pool_item->start.info[1], memory_pool_item_handle, memory_pool_item, memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t)))); - /* Sanity check on calculated item index */ AssertFatal (memory_pool_item == memory_pool_item_from_index(&memory_pools->pools[pool], item_index), "Incorrect memory pool item address (%p, %p) for pool %u, item %d!\n", - memory_pool_item, memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index); + memory_pool_item, (void *)memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index); /* Sanity check on end marker, must still be present (no write overflow) */ AssertFatal (memory_pool_item->data[item_size] == POOL_ITEM_END_MARK, "Memory pool item is corrupted, end mark is not present for pool %u, item %d!\n", pool, item_index); diff --git a/common/utils/msc/msc.c b/common/utils/msc/msc.c index 7cb6da21b513b99f6a9f184131df47c5893812bf..ae87a8e3266f662f5851824aa2e4523488a844d7 100644 --- a/common/utils/msc/msc.c +++ b/common/utils/msc/msc.c @@ -150,7 +150,7 @@ int msc_init(const msc_env_t envP, const int max_threadsP) pointer_p = malloc(MSC_MAX_MESSAGE_LENGTH); AssertFatal (pointer_p, "malloc failed!\n"); rv = lfds611_stack_guaranteed_push( g_msc_memory_stack_p, pointer_p ); - AssertFatal (rv, "lfds611_stack_guaranteed_push failed for item %u\n", i); + AssertFatal (rv, "lfds611_stack_guaranteed_push failed for item %d\n", i); } for (i = MIN_MSC_PROTOS; i < MAX_MSC_PROTOS; i++) { @@ -476,7 +476,20 @@ int msc_init(const msc_env_t envP, const int max_threadsP) } break; - + case MSC_F1AP_CU: + rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "F1AP_CU"); + if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;} + //if ((envP == MSC_E_UTRAN) || (envP == MSC_MME_GW) || (envP == MSC_MME)) { + msc_log_declare_proto(i); + //} + break; + case MSC_F1AP_DU: + rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "F1AP_DU"); + if (rv >= MSC_MAX_PROTO_NAME_LENGTH) {g_msc_proto2str[i][MSC_MAX_PROTO_NAME_LENGTH-1] = 0;} + //if ((envP == MSC_E_UTRAN) || (envP == MSC_MME_GW) || (envP == MSC_MME)) { + msc_log_declare_proto(i); + //} + break; default: rv = snprintf(&g_msc_proto2str[i][0], MSC_MAX_PROTO_NAME_LENGTH, "UNKNOWN"); diff --git a/common/utils/msc/msc.h b/common/utils/msc/msc.h index 4a71d52ffa8741d0834d75c7cab321090a666000..49c99abb56cf12b0bcdc6d1d93683d427cc50fb0 100644 --- a/common/utils/msc/msc.h +++ b/common/utils/msc/msc.h @@ -62,9 +62,11 @@ typedef enum { MSC_S11_MME, MSC_S6A_MME, MSC_HSS, - MAX_MSC_PROTOS, + MSC_F1AP_CU, + MSC_F1AP_DU, MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, + MAX_MSC_PROTOS, } msc_proto_t; diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h index f4395724009085aaffd9fa62385f321cb34b10e8..bbbe576e1bf94fb0d5b5cff0d448d2a15bfcfc90 100644 --- a/common/utils/ocp_itti/all_msg.h +++ b/common/utils/ocp_itti/all_msg.h @@ -13,3 +13,4 @@ #include "openair2/COMMON/udp_messages_def.h" #include "openair2/COMMON/gtpv1_u_messages_def.h" #include "openair2/COMMON/flexran_messages_def.h" +#include "openair2/COMMON/f1ap_messages_def.h" diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index 5b8d1a430e02cef93126e71a61f69ae7e6513d94..3d0bd0e1a34024673b8055351c21559ef5e44c2a 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -1,6 +1,6 @@ /* Author: Laurent THOMAS, Open Cells - copyleft: OpenAirInterface Software Alliance and it's licence + copyleft: OpenAirInterface Software Alliance and it's licence */ #include <vector> #include <map> @@ -122,7 +122,7 @@ extern "C" { pthread_mutex_unlock (&t->queue_cond_lock); t->admin.func(NULL); pthread_mutex_lock (&t->queue_cond_lock); - } + } pthread_mutex_unlock (&t->queue_cond_lock); return ret; } @@ -290,12 +290,12 @@ extern "C" { struct sched_param sparam; memset(&sparam, 0, sizeof(sparam)); sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-10; - policy = SCHED_FIFO ; + policy = SCHED_FIFO ; if (pthread_setschedparam(t->thread, policy, &sparam) != 0) { LOG_E(TMR,"task %s : Failed to set pthread priority\n", itti_get_task_name(task_id) ); } } -#endif +#endif return 0; } diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 227e9b0b3e702040f97a1477f50dd133b31209c3..159265c6a8241762078665537dd726483afe141a 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -1,6 +1,6 @@ /* Author: Laurent THOMAS, Open Cells - Copyleft: OpenAirInterface software alliance and it's licence + Copyleft: OpenAirInterface software alliance and it's licence */ #ifndef INTERTASK_INTERFACE_H_ #define INTERTASK_INTERFACE_H_ @@ -300,6 +300,8 @@ typedef struct { TASK_DEF(TASK_MSC, TASK_PRIORITY_MED, 200, NULL, NULL)\ TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL)\ TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL)\ + TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_MAX, TASK_PRIORITY_MED, 200, NULL, NULL) #define TASK_DEF(TaskID, pRIO, qUEUEsIZE, FuNc, ThreadFunc) { pRIO, qUEUEsIZE, #TaskID, FuNc, ThreadFunc }, diff --git a/common/utils/telnetsrv/DOC/telnetaddcmd.md b/common/utils/telnetsrv/DOC/telnetaddcmd.md index ef5af3fb7ee34219d9d2d44c197cbcfe0a263824..c7591282549fd30cc51863cbf3ec9b32c63b20b3 100644 --- a/common/utils/telnetsrv/DOC/telnetaddcmd.md +++ b/common/utils/telnetsrv/DOC/telnetaddcmd.md @@ -3,15 +3,15 @@ The following example is extracted from [the oai `openair1/PHY/CODING/coding_load.c` file](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/CODING/coding_load.c). ```c -/* +/* include the telnet server data structures and API definitions */ -#include "common/utils/telnetsrv/telnetsrv.h" +#include "common/utils/telnetsrv/telnetsrv.h" /* define the null terminated array of telnetshell_cmddef_t structures -which map each sub-command string to a function implementing it. +which map each sub-command string to a function implementing it. you may also provide a help string which will be printed when the global help command is used. The prototype for the function implementing sub commands must match the `cmdfunc_t` type defined @@ -25,7 +25,7 @@ static telnetshell_cmddef_t coding_cmdarray[] = { /* define the null terminated list of telnetshell_vardef_t structures defining the -variables that can be set and get using the pre-defined get and set command +variables that can be set and get using the pre-defined get and set command of the telnet server */ telnetshell_vardef_t coding_vardef[] = { @@ -34,7 +34,7 @@ telnetshell_vardef_t coding_vardef[] = { }; ................. /* - look for telnet server, if it is loaded, add the coding commands to it + look for telnet server, if it is loaded, add the coding commands to it we use the shared library loader API to check the telnet server availibility The telnet server TELNET_ADDCMD_FNAME function takes three arguments: 1. The name of the telnet command to be added, here "coding" @@ -43,9 +43,9 @@ The telnet server TELNET_ADDCMD_FNAME function takes three arguments: */ add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); if (addcmd != NULL) { - addcmd("coding",coding_vardef,coding_cmdarray); + addcmd("coding",coding_vardef,coding_cmdarray); ....... -/* +/* functions implementing the "coding mode" sub command, as defined in the `coding_cmdarray` passed earlier to the TELNET_ADDCMD_FNAME function. This function will be called by the telnet server, when the `coding_cmdarray` @@ -53,15 +53,15 @@ The telnet server TELNET_ADDCMD_FNAME function takes three arguments: */ int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt) { - /* + /* 1. buff argument is an input argument, pointer to the string received from the telnet client, the command and sub-command parts are removed In this case it points after "coding setmod" and is of no use as - we don't have second level sub-commands. + we don't have second level sub-commands. 1. debug argument is an input argument set by the telnet server - 1. prnt arguments is also an input argument, a function pointer, to be used + 1. prnt arguments is also an input argument, a function pointer, to be used in place of printf to print messages on the telnet client interface. As this function - is called by the telnet server stdout points to the main executable console, + is called by the telnet server stdout points to the main executable console, */ if (debug > 0) prnt( "coding_setmod_cmd received %s\n",buff); @@ -89,28 +89,28 @@ int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt) ```c int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd) ``` -Add a command and the `cmd` list of sub-commands to the telnet server. After a successful call to `add_telnetcmd` function, the telnet server calls the function defined for each sub-commands in the null terminated `cmd` array, when the character string received from the telnet client matches the command and sub-command strings. -Also adds the list of variables described in the `var` array to the list of variable which can be set and read. -The function returns -1 if one argument is NULL. -The telnet server is dynamically loaded, to use the `add_telnetcmd` function, the shared library loader API should be used to check the availability of the telnet server and retrieve it's address, as shown in [the example at the top of this page](telnetaddcmd.md#code-example-of-adding-a-command-to-the-telnet-server). +Add a command and the `cmd` list of sub-commands to the telnet server. After a successful call to `add_telnetcmd` function, the telnet server calls the function defined for each sub-commands in the null terminated `cmd` array, when the character string received from the telnet client matches the command and sub-command strings. +Also adds the list of variables described in the `var` array to the list of variable which can be set and read. +The function returns -1 if one argument is NULL. +The telnet server is dynamically loaded, to use the `add_telnetcmd` function, the shared library loader API should be used to check the availability of the telnet server and retrieve it's address, as shown in [the example at the top of this page](telnetaddcmd.md#code-example-of-adding-a-command-to-the-telnet-server). # telnet server public data types -## `telnetshell_vardef_t`structure +## `telnetshell_vardef_t`structure This structure is used by developers to describe the variables that can be set or read using the get,set and getall sub-commands. -| Fields | type |Description | +| Fields | type |Description | |:-----------|:------:|:-----------------------| | `varname` | `char[TELNET_CMD_MAXSIZE]` | variable name, as specified when using the get and set commands. | | `vartype` | `char` | Defines the type of the variable pointed by the `varvalptr`field. Supported values: TELNET_VARTYPE_INT32 TELNET_VARTYPE_INT16 TELNET_VARTYPE_INT64 TELNET_VARTYPE_STRING TELNET_VARTYPE_DOUBLE | | `varvalptr` | `void*` | Defines the type of the variable pointed by the `varvalptr`field | -## `telnetshell_cmddef_t`structure +## `telnetshell_cmddef_t`structure This structure is used by developers to describe the first level sub-commands to be added to the telnet server. -| Fields | type |Description | +| Fields | type |Description | |:-----------|:------:|:-----------------------| | `cmdname` | `char[TELNET_CMD_MAXSIZE]` | command name, as tested by the telnet server to check it should call the `cmdfunc` function | | `helpstr` | `char[TELNET_HELPSTR_SIZE]` | character string to print when the elp`command is received from the telnet client | | `cmdfunc` | `cmdfunc_t` | pointer to the function implementing the `cmdname` sub command. | -[oai telnet server home](telnetsrv.md) \ No newline at end of file +[oai telnet server home](telnetsrv.md) diff --git a/common/utils/telnetsrv/DOC/telnetarch.md b/common/utils/telnetsrv/DOC/telnetarch.md index f31a51b352b06bf98961d96fc97b0edf446fd3a5..ebb2342c22304f7c9a08c44880a358e34a187dcd 100644 --- a/common/utils/telnetsrv/DOC/telnetarch.md +++ b/common/utils/telnetsrv/DOC/telnetarch.md @@ -4,18 +4,18 @@ The oai telnet server is implemented in a shared library to be loaded by the [oa Currently the telnet server only supports one user connection. The same dedicated thread is used to wait for a user connection and process the input received from this connection. -The telnet server provides an API which can be used by any oai component to add new CLI commands to the server. A pre-defined command can be used to get or set a list of variables. +The telnet server provides an API which can be used by any oai component to add new CLI commands to the server. A pre-defined command can be used to get or set a list of variables. + - # telnet server source files telnet server source files are located in [common/utils/telnetsrv](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv) -1. [telnetsrv.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.c) contains the telnet server implementation, including the implementation of the telnet CLI command. +1. [telnetsrv.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.c) contains the telnet server implementation, including the implementation of the telnet CLI command. 1. [telnetsrv.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.h) is the telnet server include file containing both private and public data type definitions. It also contains API prototypes for functions that are used to register a new command in the server. 1. `telnetsrv\_\<XXX\>.c`: implementation of \<XXX\> CLI command which are delivered with the telnet server. 1. `telnetsrv\_\<XXX\>.h`: include file for the implementation of XXX CLI command. Usually included only in the corresponding `.c`file 1. [telnetsrv_CMakeLists.txt](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv_CMakeLists.txt): CMakelists file containing the cmake instructions to build the telnet server. this file is included in the [global oai CMakelists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt). -[oai telnet server home](telnetsrv.md) \ No newline at end of file +[oai telnet server home](telnetsrv.md) diff --git a/common/utils/telnetsrv/DOC/telnetgetset.md b/common/utils/telnetsrv/DOC/telnetgetset.md index e0b2c90d79cd787f3316611d2c7bc7d250b4e59b..d851e90a8fdaec05fbde85e03413c6c9288f3a75 100644 --- a/common/utils/telnetsrv/DOC/telnetgetset.md +++ b/common/utils/telnetsrv/DOC/telnetgetset.md @@ -10,12 +10,12 @@ telnet, phypb = 65000 telnet, hsize = 50 telnet, hfile = "oaitelnet.history" softmodem> telnet set loopc 100 -telnet, loopc set to +telnet, loopc set to 100 softmodem> telnet get loopc telnet, loopc = 100 -softmodem> +softmodem> ``` -[oai telnetserver home](telnetsrv.md) -[oai telnetserver usage home](telnetusage.md) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) diff --git a/common/utils/telnetsrv/DOC/telnethelp.md b/common/utils/telnetsrv/DOC/telnethelp.md index 63183fb61189430149b6e4faac78f303090abd48..b18f5caae7b528898e2ba23f25dc7547af95a8c5 100644 --- a/common/utils/telnetsrv/DOC/telnethelp.md +++ b/common/utils/telnetsrv/DOC/telnethelp.md @@ -22,7 +22,7 @@ softmodem> help softmodem show loglvl|thread|config softmodem log (enter help for details) softmodem thread (enter help for details) - softmodem exit + softmodem exit module 2 = phy: phy disp [phycnt,uedump,uestat UE<x>] module 3 = loader: @@ -34,24 +34,24 @@ softmodem> help module 4 = coding: coding [get set] maxiter <value> coding mode [sse,avx2,stdc,none] -softmodem> -``` +softmodem> +``` -# oai telnet server, specific commands help +# oai telnet server, specific commands help ``` bash softmodem> softmodem log help - log sub commands: - show: display current log configuration - online, noonline: enable or disable console logs - enable, disable id1-id2: enable or disable logs for components index id1 to id2 - level_<level> id1-id2: set log level to <level> for components index id1 to id2 - level_<verbosity> id1-id2: set log verbosity to <verbosity> for components index id1 to id2 -use the show command to get the values for <level>, <verbosity> and the list of component indexes that can be used for id1 and id2 + log sub commands: + show: display current log configuration + online, noonline: enable or disable console logs + enable, disable id1-id2: enable or disable logs for components index id1 to id2 + level_<level> id1-id2: set log level to <level> for components index id1 to id2 + level_<verbosity> id1-id2: set log verbosity to <verbosity> for components index id1 to id2 +use the show command to get the values for <level>, <verbosity> and the list of component indexes that can be used for id1 and id2 softmodem> ``` -[oai telnetserver home](telnetsrv.md) -[oai telnetserver usage home](telnetusage.md) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) diff --git a/common/utils/telnetsrv/DOC/telnethist.md b/common/utils/telnetsrv/DOC/telnethist.md index d938435a2405c474fc29ee6b2459f5843b7e5086..b7cf152502802be199a66391e85485819b4ef46c 100644 --- a/common/utils/telnetsrv/DOC/telnethist.md +++ b/common/utils/telnetsrv/DOC/telnethist.md @@ -40,5 +40,5 @@ softmodem> ``` -[oai telnetserver home](telnetsrv.md) -[oai telnetserver usage home](telnetusage.md) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) diff --git a/common/utils/telnetsrv/DOC/telnetloader.md b/common/utils/telnetsrv/DOC/telnetloader.md index 9250524989a67da5ea8a22108b3aeb7f86cd77a6..d6a0f158c6fcd9bef3bd6fdc5979042ee730f660 100644 --- a/common/utils/telnetsrv/DOC/telnetloader.md +++ b/common/utils/telnetsrv/DOC/telnetloader.md @@ -43,5 +43,5 @@ softmodem> loader show modules softmodem> ``` -[oai telnetserver home](telnetsrv.md) -[oai telnetserver usage home](telnetusage.md) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) diff --git a/common/utils/telnetsrv/DOC/telnetlog.md b/common/utils/telnetsrv/DOC/telnetlog.md index 0faaf9c02e25791a9c4850ad4ad5e33b27e6fa7e..36c5cfb3486d5ff79efebb8921860ed4f185d1a3 100644 --- a/common/utils/telnetsrv/DOC/telnetlog.md +++ b/common/utils/telnetsrv/DOC/telnetlog.md @@ -38,10 +38,10 @@ log level/verbosity comp 33 USIM set to info / medium (disabled) log level/verbosity comp 34 LOCALIZE set to info / medium (disabled) log level/verbosity comp 35 RRH set to info / medium (disabled) softmodem> softmodem log show -Available log levels: - emerg alert crit error warn notice info debug file trace -Available verbosity: - none low medium high full +Available log levels: + emerg alert crit error warn notice info debug file trace +Available verbosity: + none low medium high full component verbosity level enabled 00 PHY: medium info N 01 MAC: medium info N @@ -89,8 +89,8 @@ log level/verbosity comp 3 OCG set to error / medium (enabled) log level/verbosity comp 4 OMG set to error / medium (enabled) softmodem> exit Connection closed by foreign host. -``` +``` -[oai telnetserver home](telnetsrv.md) +[oai telnetserver home](telnetsrv.md) [oai telnetserver usage home](telnetusage.md) -[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/telnetsrv/DOC/telnetloop.md b/common/utils/telnetsrv/DOC/telnetloop.md index f045e8a7161d150edad0b58f798f64e1ff2cf176..a86baad6eb547dd24c4e1dbc029ffb8cf4cf4032 100644 --- a/common/utils/telnetsrv/DOC/telnetloop.md +++ b/common/utils/telnetsrv/DOC/telnetloop.md @@ -1,4 +1,4 @@ -The telnet server includes a **_loop_** command that can be used to iterate a given command. The number of iterations and the delay, in ms between two iterations can be modified, as shown in the following example: +The telnet server includes a **_loop_** command that can be used to iterate a given command. The number of iterations and the delay, in ms between two iterations can be modified, as shown in the following example: ```bash softmodem> telnet get loopc @@ -6,35 +6,35 @@ telnet, loopc = 10 softmodem> telnet get loopd telnet, loopd = 2000 softmodem> telnet set loopd 1000 -telnet, loopd set to +telnet, loopd set to 1000 softmodem> loop softmodem show thread 2018-03-27 17:58:49.000 2/10 - id name state USRmod KRNmod prio nice vsize proc pol + id name state USRmod KRNmod prio nice vsize proc pol - 3946 lte-softmodem S 20005 9440 20 0 236560384 2 0 other + 3946 lte-softmodem S 20005 9440 20 0 236560384 2 0 other - 3946 lte-softmodem S 7 95 20 0 236560384 2 0 other - 3948 telnet R 0 0 20 0 236560384 2 0 other - 3949 ITTI acceptor S 2 9 20 0 236560384 2 0 other - 3951 ITTI 12 S 2 2 20 0 236560384 7 0 other - 3952 ITTI 11 S 0 0 20 0 236560384 0 0 other - 3953 ITTI 9 S 0 0 20 0 236560384 1 0 other - 3954 ITTI 7 S 0 0 20 0 236560384 7 0 other - 3955 ITTI 8 S 0 0 20 0 236560384 7 0 other - 3956 ITTI 4 S 35 0 20 0 236560384 2 0 other - 3957 ru_thread S 15366 3072 -10 0 236560384 0 2 rt: rr - 3958 ru_thread_prach S 0 0 -10 0 236560384 7 1 rt: fifo - 3959 fep_thread S 1874 123 -10 0 236560384 5 1 rt: fifo - 3960 feptx_thread S 1554 101 -10 0 236560384 7 1 rt: fifo - 3969 ru_thread S 0 0 -10 0 236560384 0 2 rt: rr - 3970 ru_thread S 1313 5522 -10 0 236560384 5 2 rt: rr - 3971 ru_thread S 4 6 -10 0 236560384 1 2 rt: rr - 3972 lte-softmodem S 318 9 -10 0 236560384 7 1 rt: fifo - 3973 lte-softmodem S 6 13 -10 0 236560384 4 1 rt: fifo + 3946 lte-softmodem S 7 95 20 0 236560384 2 0 other + 3948 telnet R 0 0 20 0 236560384 2 0 other + 3949 ITTI acceptor S 2 9 20 0 236560384 2 0 other + 3951 ITTI 12 S 2 2 20 0 236560384 7 0 other + 3952 ITTI 11 S 0 0 20 0 236560384 0 0 other + 3953 ITTI 9 S 0 0 20 0 236560384 1 0 other + 3954 ITTI 7 S 0 0 20 0 236560384 7 0 other + 3955 ITTI 8 S 0 0 20 0 236560384 7 0 other + 3956 ITTI 4 S 35 0 20 0 236560384 2 0 other + 3957 ru_thread S 15366 3072 -10 0 236560384 0 2 rt: rr + 3958 ru_thread_prach S 0 0 -10 0 236560384 7 1 rt: fifo + 3959 fep_thread S 1874 123 -10 0 236560384 5 1 rt: fifo + 3960 feptx_thread S 1554 101 -10 0 236560384 7 1 rt: fifo + 3969 ru_thread S 0 0 -10 0 236560384 0 2 rt: rr + 3970 ru_thread S 1313 5522 -10 0 236560384 5 2 rt: rr + 3971 ru_thread S 4 6 -10 0 236560384 1 2 rt: rr + 3972 lte-softmodem S 318 9 -10 0 236560384 7 1 rt: fifo + 3973 lte-softmodem S 6 13 -10 0 236560384 4 1 rt: fifo -``` -A **_loop_** command can be interrupted by pressing the **_enter_** key till getting the prompt. +``` +A **_loop_** command can be interrupted by pressing the **_enter_** key till getting the prompt. -[oai telnetserver home](telnetsrv.md) -[oai telnetserver usage home](telnetusage.md) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) diff --git a/common/utils/telnetsrv/DOC/telnetsrv.md b/common/utils/telnetsrv/DOC/telnetsrv.md index e8909595d9e4c9770690958a119cbbd7de7cc662..11c6cf071fdd1c32b9489487dde1b0e8082f2de4 100644 --- a/common/utils/telnetsrv/DOC/telnetsrv.md +++ b/common/utils/telnetsrv/DOC/telnetsrv.md @@ -3,5 +3,5 @@ The oai embedded telnet server is an optional monitoring and debugging tool. It * [Using the telnet server](telnetusage.md) * [Adding commands to the oai telnet server](telnetaddcmd.md) * [telnet server architecture ](telnetarch.md) - -[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file + +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/telnetsrv/DOC/telnetusage.md b/common/utils/telnetsrv/DOC/telnetusage.md index f8319d5ef28911bb18f89545e2d3ac6c10a04421..03561432265076dc279e82b797f7cbf02b43512a 100644 --- a/common/utils/telnetsrv/DOC/telnetusage.md +++ b/common/utils/telnetsrv/DOC/telnetusage.md @@ -1,28 +1,28 @@ -# starting the softmodem with the telnet server +# starting the softmodem with the telnet server By default the embedded telnet server, which is implemented in a shared library, is not built. It can be built after compiling the softmodem executable using the `build_oai` script: ```bash - cd \<oai repository\>/openairinterface5g - source oaienv - cd cmake_targets - ./build_oai --build-telnetsrv + cd \<oai repository\>/openairinterface5g + source oaienv + cd cmake_targets + ./build_oai --build-telnetsrv ``` This will create the `libtelnetsrv.so` file in the `targets/bin` and `cmake_targets/lte_build_oai/build` sub directories of the oai repository. When starting the softmodem, you must specify the **_\-\-telnetsrv_** option to load and start the telnet server. The telnet server is loaded via the [oai shared library loader](loader). -# using the Command Line Interface -By default the telnet server listen on all the ip addresses configured on the system and on port 9090. This behavior can be changed using the `listenaddr` and `listenport` parameters. +# using the Command Line Interface +By default the telnet server listen on all the ip addresses configured on the system and on port 9090. This behavior can be changed using the `listenaddr` and `listenport` parameters. The telnet server includes a basic help, listing available commands and some commands also provide a specific detailed help sub-command. -Below are examples of telnet sessions: +Below are examples of telnet sessions: * [getting help](telnethelp.md) * [using the history](telnethist.md) * [using the get and set commands](telnetgetset.md) * [using the loop command](telnetloop.md) * [loader command](telnetloader.md) -* [log command](telnetlog.md) +* [log command](telnetlog.md) # telnet server parameters The telnet server is using the [oai configuration module](Config/Rtusage). Telnet parameters must be specified in the `telnetsrv` section. Some parameters can be modified via the telnet telnet server command, as specified in the last column of the following table. @@ -36,4 +36,4 @@ The telnet server is using the [oai configuration module](Config/Rtusage). Telne | `histfile` | `character string` | "oaitelnet.history" | file used for command history persistency | Y | | `histfsize` | `integer` | 50 | maximum number of commands saved in the history | Y | -[oai telnet server home](telnetsrv.md) \ No newline at end of file +[oai telnet server home](telnetsrv.md) diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 4e8e2c7c7fdbb48197698127685de7c45c23680c..7f8645be02a43ea422f6dc79c1111acde066ab9c 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -58,7 +58,7 @@ #include "telnetsrv_phycmd.h" #include "telnetsrv_proccmd.h" -static char *telnet_defstatmod[] = {"softmodem","phy","loader"}; +static char *telnet_defstatmod[] = {"softmodem","phy","loader","measur"}; static telnetsrv_params_t telnetparams; #define TELNETSRV_LISTENADDR 0 #define TELNETSRV_LISTENPORT 1 @@ -355,7 +355,7 @@ int setgetvar(int moduleindex,char getorset,char *params) { char varname[TELNET_CMD_MAXSIZE]; char *varval=NULL; memset(varname,0,sizeof(varname)); - n = sscanf(params,"%s %ms",varname,&varval); + n = sscanf(params,"%9s %ms",varname,&varval); for ( i=0 ; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL ; i++) { if ( strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,varname,strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0) { @@ -475,7 +475,7 @@ int process_command(char *buf) { memset(cmdb,0,sizeof(cmdb)); bufbck=strdup(buf); rt=CMDSTATUS_NOTFOUND; - j = sscanf(buf,"%9s %9s %[^\t\n]",modulename,cmd,cmdb); + j = sscanf(buf,"%9s %9s %9[^\t\n]",modulename,cmd,cmdb); if (telnetparams.telnetdbg > 0) printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb); @@ -500,23 +500,32 @@ int process_command(char *buf) { }/* else */ }/* strncmp: module name test */ else if (strncasecmp(modulename,"loop",4) == 0 ) { - int lc; int f = fcntl(telnetparams.new_socket,F_GETFL); - fcntl (telnetparams.new_socket, F_SETFL, O_NONBLOCK | f); + int f1=fcntl (telnetparams.new_socket, F_SETFL, O_NONBLOCK | f); - for(lc=0; lc<telnetparams.loopcount; lc++) { + if (f<0 || f1 <0) { + client_printf( " Loop won't be cancelable: %s\n",strerror(errno) ); + } + + for(int lc=0; lc<telnetparams.loopcount; lc++) { char dummybuff[20]; char tbuff[64]; - int rs; client_printf(CSI "1J" CSI "1;10H " STDFMT "%s %i/%i\n", get_time(tbuff,sizeof(tbuff)),lc,telnetparams.loopcount ); process_command(bufbck+strlen("loop")+1); - usleep(telnetparams.loopdelay * 1000); - rs = read(telnetparams.new_socket,dummybuff,sizeof(dummybuff)); + errno=0; + int rs = read(telnetparams.new_socket,dummybuff,sizeof(dummybuff)); - if ( rs > 0 ) { + if (telnetparams.telnetdbg > 0) + client_printf("Received \"%s\" status %d, errno %s while running loop\n",dummybuff,rs,strerror(errno)); + + if ( errno != EAGAIN && errno != EWOULDBLOCK) { + client_printf( STDFMT " Loop canceled, iteration %i/%i\n",lc,telnetparams.loopcount ); + lc=telnetparams.loopcount; break; } + + usleep(telnetparams.loopdelay * 1000); } fcntl (telnetparams.new_socket, F_SETFL, f); diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h index 2d3ef531aee8494ad080f00f42c9b42c1934eb50..89f6a8dda11bd3180790359ae666a9b638e2269f 100644 --- a/common/utils/telnetsrv/telnetsrv.h +++ b/common/utils/telnetsrv/telnetsrv.h @@ -69,7 +69,8 @@ typedef struct cmddef { #define TELNET_VARTYPE_INT64 3 #define TELNET_VARTYPE_STRING 4 #define TELNET_VARTYPE_DOUBLE 5 -//#define TELNET_VARTYPE_PTR 6 +#define TELNET_VARTYPE_INT8 6 +#define TELNET_VARTYPE_UINT 7 typedef struct variabledef { char varname[TELNET_CMD_MAXSIZE]; char vartype; diff --git a/common/utils/telnetsrv/telnetsrv_CMakeLists.txt b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt index 5dee7db4c41fef1d5c3f96b18eb770d64e044054..3a07632bfecf36a7306be40fcdd040397962a530 100644 --- a/common/utils/telnetsrv/telnetsrv_CMakeLists.txt +++ b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt @@ -9,6 +9,7 @@ set(TELNETSRV_SOURCE ${TELNETROOT}/telnetsrv_phycmd.c ${TELNETROOT}/telnetsrv_proccmd.c ${TELNETROOT}/telnetsrv_loader.c + ${TELNETROOT}/telnetsrv_measurements.c ) #set(TELNETSRV_ETHDEVCMD_SOURCE diff --git a/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h b/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h new file mode 100644 index 0000000000000000000000000000000000000000..89ced509a4504a8c9b742bdbb3e1e9344936ab61 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_cpumeasur_def.h @@ -0,0 +1,99 @@ +/* + * 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 common/utils/telnetsrv/telnetsrv_cpumeasur_def.h + * \brief: definitions of macro used to initialize the telnet_ltemeasurdef_t + * \ strucures arrays which are then used by the display functions + * \ in telnetsrv_measurements.c. + * \author Francois TABURET + * \date 2019 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + + +#define CPU_PHYENB_MEASURE \ +{ \ + {"phy_proc_tx", &(phyvars->phy_proc_tx),0},\ + {"phy_proc_rx", &(phyvars->phy_proc_rx),0},\ + {"rx_prach", &(phyvars->rx_prach),0},\ + {"ofdm_mod", &(phyvars->ofdm_mod_stats),0},\ + {"dlsch_common_and_dci", &(phyvars->dlsch_common_and_dci),0},\ + {"dlsch_ue_specific", &(phyvars->dlsch_ue_specific),0},\ + {"dlsch_encoding", &(phyvars->dlsch_encoding_stats),0},\ + {"dlsch_modulation", &(phyvars->dlsch_modulation_stats),0},\ + {"dlsch_scrambling", &(phyvars->dlsch_scrambling_stats),0},\ + {"dlsch_rate_matching", &(phyvars->dlsch_rate_matching_stats),0},\ + {"dlsch_turbo_encod_prep", &(phyvars->dlsch_turbo_encoding_preperation_stats),0},\ + {"dlsch_turbo_encod_segm", &(phyvars->dlsch_turbo_encoding_segmentation_stats),0},\ + {"dlsch_turbo_encod", &(phyvars->dlsch_turbo_encoding_stats),0},\ + {"dlsch_turbo_encod_waiting", &(phyvars->dlsch_turbo_encoding_waiting_stats),0},\ + {"dlsch_turbo_encod_signal", &(phyvars->dlsch_turbo_encoding_signal_stats),0},\ + {"dlsch_turbo_encod_main", &(phyvars->dlsch_turbo_encoding_main_stats),0},\ + {"dlsch_turbo_encod_wakeup0", &(phyvars->dlsch_turbo_encoding_wakeup_stats0),0},\ + {"dlsch_turbo_encod_wakeup1", &(phyvars->dlsch_turbo_encoding_wakeup_stats1),0},\ + {"dlsch_interleaving", &(phyvars->dlsch_interleaving_stats),0},\ + {"rx_dft", &(phyvars->rx_dft_stats),0},\ + {"ulsch_channel_estimation", &(phyvars->ulsch_channel_estimation_stats),0},\ + {"ulsch_freq_offset_estimation", &(phyvars->ulsch_freq_offset_estimation_stats),0},\ + {"ulsch_decoding", &(phyvars->ulsch_decoding_stats),0},\ + {"ulsch_demodulation", &(phyvars->ulsch_demodulation_stats),0},\ + {"ulsch_rate_unmatching", &(phyvars->ulsch_rate_unmatching_stats),0},\ + {"ulsch_turbo_decoding", &(phyvars->ulsch_turbo_decoding_stats),0},\ + {"ulsch_deinterleaving", &(phyvars->ulsch_deinterleaving_stats),0},\ + {"ulsch_demultiplexing", &(phyvars->ulsch_demultiplexing_stats),0},\ + {"ulsch_llr", &(phyvars->ulsch_llr_stats),0},\ + {"ulsch_tc_init", &(phyvars->ulsch_tc_init_stats),0},\ + {"ulsch_tc_alpha", &(phyvars->ulsch_tc_alpha_stats),0},\ + {"ulsch_tc_beta", &(phyvars->ulsch_tc_beta_stats),0},\ + {"ulsch_tc_gamma", &(phyvars->ulsch_tc_gamma_stats),0},\ + {"ulsch_tc_ext", &(phyvars->ulsch_tc_ext_stats),0},\ + {"ulsch_tc_intl1", &(phyvars->ulsch_tc_intl1_stats),0},\ + {"ulsch_tc_intl2", &(phyvars->ulsch_tc_intl2_stats),0},\ +} + +#define CPU_MACENB_MEASURE \ +{ \ + {"eNB_scheduler", &(macvars->eNB_scheduler),0},\ + {"schedule_si", &(macvars->schedule_si),0},\ + {"schedule_ra", &(macvars->schedule_ra),0},\ + {"schedule_ulsch", &(macvars->schedule_ulsch),0},\ + {"fill_DLSCH_dci", &(macvars->fill_DLSCH_dci),0},\ + {"schedule_dlsch_pre", &(macvars->schedule_dlsch_preprocessor),0},\ + {"schedule_dlsch", &(macvars->schedule_dlsch),0},\ + {"schedule_mch", &(macvars->schedule_mch),0},\ + {"rx_ulsch_sdu", &(macvars->rx_ulsch_sdu),0},\ + {"schedule_pch", &(macvars->schedule_pch),0},\ +} + +#define CPU_PDCPENB_MEASURE \ +{ \ + {"pdcp_run", &(pdcpvars->pdcp_run),0},\ + {"data_req", &(pdcpvars->data_req),0},\ + {"data_ind", &(pdcpvars->data_ind),0},\ + {"apply_security", &(pdcpvars->apply_security),0},\ + {"validate_security", &(pdcpvars->validate_security),0},\ + {"pdcp_ip", &(pdcpvars->pdcp_ip),0},\ + {"ip_pdcp", &(pdcpvars->ip_pdcp),0},\ +} diff --git a/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h new file mode 100644 index 0000000000000000000000000000000000000000..2f479d8ee6f9e5f59b06720e751df617d871e3bb --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h @@ -0,0 +1,127 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file common/utils/telnetsrv/telnetsrv_ltemeasur_def.h + * \brief: definitions of macro used to initialize the telnet_ltemeasurdef_t + * \ strucures arrays which are then used by the display functions + * \ in telnetsrv_measurements.c. + * \author Francois TABURET + * \date 2019 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + + +#define LTEMAC_MEASURE \ +{ \ + {"total_num_bcch_pdu", &(macstatptr->total_num_bcch_pdu),TELNET_VARTYPE_INT32,0},\ + {"bcch_buffer", &(macstatptr->bcch_buffer),TELNET_VARTYPE_INT32,0},\ + {"total_bcch_buffer", &(macstatptr->total_bcch_buffer),TELNET_VARTYPE_INT32,0},\ + {"bcch_mcs", &(macstatptr->bcch_mcs),TELNET_VARTYPE_INT32,0},\ + {"total_num_ccch_pdu", &(macstatptr->total_num_ccch_pdu),TELNET_VARTYPE_INT32,0},\ + {"ccch_buffer", &(macstatptr->ccch_buffer),TELNET_VARTYPE_INT32,0},\ + {"total_ccch_buffer", &(macstatptr->total_ccch_buffer),TELNET_VARTYPE_INT32,0},\ + {"ccch_mcs", &(macstatptr->ccch_mcs),TELNET_VARTYPE_INT32,0},\ + {"total_num_pcch_pdu", &(macstatptr->total_num_pcch_pdu),TELNET_VARTYPE_INT32,0},\ + {"pcch_buffer", &(macstatptr->pcch_buffer),TELNET_VARTYPE_INT32,0},\ + {"total_pcch_buffer", &(macstatptr->total_pcch_buffer),TELNET_VARTYPE_INT32,0},\ + {"pcch_mcs", &(macstatptr->pcch_mcs),TELNET_VARTYPE_INT32,0},\ + {"num_dlactive_UEs", &(macstatptr->num_dlactive_UEs),TELNET_VARTYPE_INT16,0},\ + {"available_prbs", &(macstatptr->available_prbs),TELNET_VARTYPE_INT16,0},\ + {"total_available_prbs", &(macstatptr->total_available_prbs),TELNET_VARTYPE_INT32,0},\ + {"available_ncces", &(macstatptr->available_ncces),TELNET_VARTYPE_INT16,0},\ + {"dlsch_bitrate", &(macstatptr->dlsch_bitrate),TELNET_VARTYPE_INT32,0},\ + {"dlsch_bytes_tx", &(macstatptr->dlsch_bytes_tx),TELNET_VARTYPE_INT32,0},\ + {"dlsch_pdus_tx", &(macstatptr->dlsch_pdus_tx),TELNET_VARTYPE_INT32,0},\ + {"total_dlsch_bitrate", &(macstatptr->total_dlsch_bitrate),TELNET_VARTYPE_INT32,0},\ + {"total_dlsch_bytes_tx", &(macstatptr->total_dlsch_bytes_tx),TELNET_VARTYPE_INT32,0},\ + {"total_dlsch_pdus_tx", &(macstatptr->total_dlsch_pdus_tx),TELNET_VARTYPE_INT32,0},\ + {"ulsch_bitrate", &(macstatptr->ulsch_bitrate),TELNET_VARTYPE_INT32,0},\ + {"ulsch_bytes_rx", &(macstatptr->ulsch_bytes_rx),TELNET_VARTYPE_INT32,0},\ + {"ulsch_pdus_rx", &(macstatptr->ulsch_pdus_rx),TELNET_VARTYPE_INT32,0},\ + {"total_ulsch_bitrate", &(macstatptr->total_ulsch_bitrate),TELNET_VARTYPE_INT32,0},\ + {"total_ulsch_bytes_rx", &(macstatptr->total_ulsch_bytes_rx),TELNET_VARTYPE_INT32,0},\ + {"total_ulsch_pdus_rx", &(macstatptr->total_ulsch_pdus_rx),TELNET_VARTYPE_INT32,0},\ + {"sched_decisions", &(macstatptr->sched_decisions),TELNET_VARTYPE_INT32,0},\ + {"missed_deadlines", &(macstatptr->missed_deadlines),TELNET_VARTYPE_INT32,0},\ +} + +#define LTEMAC_UEMEASURE \ +{ \ + {"dlsch_mcs1", &(macuestatptr->dlsch_mcs1),TELNET_VARTYPE_INT8,0},\ + {"dlsch_mcs2", &(macuestatptr->dlsch_mcs2),TELNET_VARTYPE_INT8,0},\ + {"rbs_used", &(macuestatptr->rbs_used),TELNET_VARTYPE_INT32,0},\ + {"rbs_used_retx", &(macuestatptr->rbs_used_retx),TELNET_VARTYPE_INT16,0},\ + {"total_rbs_used", &(macuestatptr->total_rbs_used),TELNET_VARTYPE_INT16,0},\ + {"ncce_used", &(macuestatptr->ncce_used),TELNET_VARTYPE_INT16,0},\ + {"ncce_used_retx", &(macuestatptr->ncce_used_retx),TELNET_VARTYPE_INT16,0},\ + {"TBS", &(macuestatptr->TBS),TELNET_VARTYPE_INT32,0},\ + {"total_pdu_bytes", &(macuestatptr->total_pdu_bytes),TELNET_VARTYPE_INT64,0},\ + {"total_num_pdus", &(macuestatptr->total_num_pdus),TELNET_VARTYPE_INT32,0},\ + {"overhead_bytes", &(macuestatptr->overhead_bytes),TELNET_VARTYPE_INT64,0},\ + {"crnti", &(macuestatptr->crnti),TELNET_VARTYPE_INT16,0},\ + {"normalized_rx_power", &(macuestatptr->normalized_rx_power),TELNET_VARTYPE_INT32,0},\ + {"target_rx_power", &(macuestatptr->target_rx_power),TELNET_VARTYPE_INT32,0},\ + {"ulsch_mcs1", &(macuestatptr->ulsch_mcs1),TELNET_VARTYPE_INT8,0},\ + {"ulsch_mcs2", &(macuestatptr->ulsch_mcs2),TELNET_VARTYPE_INT8,0},\ + {"rbs_used_rx", &(macuestatptr->rbs_used_rx),TELNET_VARTYPE_INT32,0},\ + {"rbs_used_retx_rx", &(macuestatptr->rbs_used_retx_rx),TELNET_VARTYPE_INT32,0},\ + {"total_rbs_used_rx", &(macuestatptr->total_rbs_used_rx),TELNET_VARTYPE_INT32,0},\ + {"ulsch_TBS", &(macuestatptr->ulsch_TBS),TELNET_VARTYPE_INT32,0},\ + {"total_pdu_bytes_rx", &(macuestatptr->total_pdu_bytes_rx),TELNET_VARTYPE_INT64,0},\ + {"total_num_pdus_rx", &(macuestatptr->total_num_pdus_rx),TELNET_VARTYPE_INT32,0},\ + {"num_errors_rx", &(macuestatptr->num_errors_rx),TELNET_VARTYPE_INT32,0},\ +} + +#define LTE_RLCMEASURE \ +{ \ + {"rlc_mode", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_pdcp_sdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_pdcp_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_pdcp_sdu_discarded", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_pdcp_bytes_discarded", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_data_pdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_data_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_retransmit_pdu_by_status", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_retransmit_bytes_by_status", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_retransmit_pdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_retransmit_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_control_pdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"tx_control_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_pdcp_sdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_pdcp_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_pdus_duplicate", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_bytes_duplicate", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_pdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_pdu_dropped", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_bytes_dropped", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_pdu_out_of_window", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_data_bytes_out_of_window", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_control_pdu", NULL, TELNET_VARTYPE_UINT, 0},\ + {"rx_control_bytes", NULL, TELNET_VARTYPE_UINT, 0},\ + {"timer_reorder_tout", NULL, TELNET_VARTYPE_UINT, 0},\ + {"timer_poll_retrans_tout", NULL, TELNET_VARTYPE_UINT, 0},\ + {"timer_status_prohibit_tout", NULL, TELNET_VARTYPE_UINT, 0},\ +} diff --git a/common/utils/telnetsrv/telnetsrv_measurements.c b/common/utils/telnetsrv/telnetsrv_measurements.c new file mode 100644 index 0000000000000000000000000000000000000000..7cfc6562254b0522f19cf1ba78d27a8fa956d557 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_measurements.c @@ -0,0 +1,316 @@ +/* + * 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 common/utils/telnetsrv/telnetsrv_measurements.c + * \brief: implementation of telnet commands related to measurments + * \author Francois TABURET + * \date 2019 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#define _GNU_SOURCE +#include <sys/types.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + + + + +#define TELNETSERVERCODE +#include "telnetsrv.h" +#define TELNETSRV_MEASURMENTS_MAIN +#include "common/utils/LOG/log.h" +#include "common/config/config_userapi.h" +#include "telnetsrv_measurements.h" +#include "telnetsrv_ltemeasur_def.h" +#include "telnetsrv_cpumeasur_def.h" +#include "openair2/LAYER2/MAC/mac.h" +#include "openair1/PHY/phy_extern.h" + +void measurcmd_display_macstats(telnet_printfunc_t prnt); +void measurcmd_display_macstats_ue(telnet_printfunc_t prnt); +void measurcmd_display_rlcstats(telnet_printfunc_t prnt); +void measurcmd_display_phycpu(telnet_printfunc_t prnt); +void measurcmd_display_maccpu(telnet_printfunc_t prnt); +void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt); + + +static telnet_measurgroupdef_t measurgroups[] = { + {"enb", GROUP_LTESTATS,0, measurcmd_display_macstats, {NULL}}, + {"enbues",GROUP_LTESTATS,0, measurcmd_display_macstats_ue,{NULL}}, + {"rlc", GROUP_LTESTATS,0, measurcmd_display_rlcstats, {NULL}}, + {"phycpu",GROUP_CPUSTATS,0, measurcmd_display_phycpu, {NULL}}, + {"maccpu",GROUP_CPUSTATS,0, measurcmd_display_maccpu, {NULL}}, + {"pdcpcpu",GROUP_CPUSTATS,0, measurcmd_display_pdcpcpu, {NULL}}, +}; +#define TELNET_NUM_MEASURGROUPS (sizeof(measurgroups)/sizeof(telnet_measurgroupdef_t)) + +static int eNB_id =0; +static char *grouptypes[] = {"ltestats","cpustats"}; +static double cpufreq; +#define TELNET_NUM_MEASURTYPES (sizeof(grouptypes)/sizeof(char *)) + +#define HDR "---------------------------------" + +void measurcmd_display_groups(telnet_printfunc_t prnt) { + prnt(" %*s %10s %s\n",TELNET_MAXMEASURNAME_LEN-1,"name","type","nombre de mesures"); + + for(int i=0; i<TELNET_NUM_MEASURGROUPS; i++) + prnt("%02d %*s %10s %i\n",i,TELNET_MAXMEASURNAME_LEN-1,measurgroups[i].groupname, + grouptypes[measurgroups[i].type], measurgroups[i].size); +} /* measurcmd_display_groups */ +/*----------------------------------------------------------------------------------------------------*/ +/* cpu measurements functions */ +void measurcmd_display_cpumeasures(telnet_printfunc_t prnt, telnet_cpumeasurdef_t *cpumeasure, int cpumeasure_size) { + for (int i=0; i<cpumeasure_size; i++) { + prnt("%02d %*s: %15.3f us; %15d %s",i,TELNET_MAXMEASURNAME_LEN-1,(cpumeasure+i)->statname, + ((cpumeasure+i)->astatptr->trials!=0)?(((cpumeasure+i)->astatptr->diff)/((cpumeasure+i)->astatptr->trials))/cpufreq/1000:0, + (cpumeasure+i)->astatptr->trials, ((i%2)==1)?"|\n":" | " ); + } + + prnt("\n\n"); +} /* measurcmd_display_measures */ + +#define PRINT_CPUMEAS_STATE ((cpumeas(CPUMEAS_GETSTATE))?"enabled":"disabled") +void measurcmd_display_phycpu(telnet_printfunc_t prnt) { + PHY_VARS_eNB *phyvars = RC.eNB[eNB_id][0]; + telnet_cpumeasurdef_t cpumeasur[]=CPU_PHYENB_MEASURE; + prnt("%s cpu (%1.1g GHz) measurements: PHY (cpustats %s) %s\n",HDR,cpufreq, + PRINT_CPUMEAS_STATE,HDR); + measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t)); +} + +void measurcmd_display_maccpu(telnet_printfunc_t prnt) { + eNB_MAC_INST *macvars = RC.mac[eNB_id]; + telnet_cpumeasurdef_t cpumeasur[]=CPU_MACENB_MEASURE; + prnt("%s cpu (%1.1g GHz) measurements: MAC (cpustats %s) %s\n",HDR,cpufreq, + PRINT_CPUMEAS_STATE,HDR); + measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t)); +} + +void measurcmd_display_pdcpcpu(telnet_printfunc_t prnt) { + pdcp_stats_t *pdcpvars = &(eNB_pdcp_stats[eNB_id]); + telnet_cpumeasurdef_t cpumeasur[]=CPU_PDCPENB_MEASURE; + prnt("%s cpu (%1.1g GHz) measurements: PDCP (cpustats %s) %s \n",HDR,cpufreq, + PRINT_CPUMEAS_STATE,HDR); + measurcmd_display_cpumeasures(prnt, cpumeasur, sizeof(cpumeasur)/sizeof(telnet_cpumeasurdef_t)); +} +/*----------------------------------------------------------------------------------------------------*/ +/* lte measurements functions */ +uint64_t measurcmd_getstatvalue(telnet_ltemeasurdef_t *measur,telnet_printfunc_t prnt) { + uint64_t val; + + switch(measur->vtyp) { + case TELNET_VARTYPE_INT64: + val = (uint64_t)(*((uint64_t *)(measur->vptr))); + break; + + case TELNET_VARTYPE_INT32: + val = (uint64_t)(*((uint32_t *)(measur->vptr))); + break; + + case TELNET_VARTYPE_INT16: + val = (uint64_t)(*((uint16_t *)(measur->vptr))); + break; + + case TELNET_VARTYPE_INT8: + val = (uint64_t)(*((uint8_t *)(measur->vptr))); + break; + + case TELNET_VARTYPE_UINT: + val = (uint64_t)(*((unsigned int *)(measur->vptr))); + break; + + default: + prnt("%s %i: unknown type \n",measur->statname,measur->vtyp); + val = (uint64_t)(*((uint64_t *)(measur->vptr))); + break; + } + + return val; +} /* measurcmd_getstatvalue */ + +void measurcmd_display_measures(telnet_printfunc_t prnt, telnet_ltemeasurdef_t *statsptr, int stats_size) { + for (int i=0; i<stats_size; i++) { + prnt("%*s = %15llu%s",TELNET_MAXMEASURNAME_LEN-1,statsptr[i].statname, + measurcmd_getstatvalue(&(statsptr[i]),prnt), ((i%3)==2)?"\n":" "); + } + + prnt("\n\n"); +} /* measurcmd_display_measures */ + +void measurcmd_display_macstats_ue(telnet_printfunc_t prnt) { + UE_list_t *UE_list = &(RC.mac[eNB_id]->UE_list); + + for (int UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + for (int i=0; i<UE_list->numactiveCCs[UE_id]; i++) { + int CC_id = UE_list->ordered_CCids[i][UE_id]; + prnt("%s UE %i Id %i CCid %i %s\n",HDR,i,UE_id,CC_id,HDR); + eNB_UE_STATS *macuestatptr = &(UE_list->eNB_UE_stats[CC_id][UE_id]); + telnet_ltemeasurdef_t statsptr[]=LTEMAC_UEMEASURE; + measurcmd_display_measures(prnt, statsptr, sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t)); + } + } +} /* measurcmd_display_macstats_ue */ + +void measurcmd_display_macstats(telnet_printfunc_t prnt) { + for (int CC_id=0 ; CC_id < MAX_NUM_CCs; CC_id++) { + eNB_STATS *macstatptr=&(RC.mac[eNB_id]->eNB_stats[CC_id]); + telnet_ltemeasurdef_t statsptr[]=LTEMAC_MEASURE; + prnt("%s eNB %i mac stats CC %i frame %u %s\n", + HDR, eNB_id, CC_id, RC.mac[eNB_id]->frame,HDR); + measurcmd_display_measures(prnt,statsptr,sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t)); + } +} /* measurcmd_display_macstats */ + + +void measurcmd_display_one_rlcstat(telnet_printfunc_t prnt, int UE_id, telnet_ltemeasurdef_t *statsptr, int num_rlcmeasure, unsigned int *rlcstats, + char *rbid_str, protocol_ctxt_t *ctxt, const srb_flag_t srb_flagP, const rb_id_t rb_idP) + +{ + int rlc_status = rlc_stat_req(ctxt,srb_flagP,rb_idP, + rlcstats, rlcstats+1, rlcstats+2, rlcstats+3, rlcstats+4, rlcstats+5, + rlcstats+6, rlcstats+7, rlcstats+8, rlcstats+9, rlcstats+10, rlcstats+11, + rlcstats+12, rlcstats+13, rlcstats+14, rlcstats+15, rlcstats+16, rlcstats+17, + rlcstats+18, rlcstats+19, rlcstats+20, rlcstats+21, rlcstats+22, rlcstats+23, + rlcstats+24, rlcstats+25, rlcstats+26, rlcstats+27); + + if (rlc_status == RLC_OP_STATUS_OK) { + prnt("%s UE %i RLC %s mode %s %s\n",HDR,UE_id, rbid_str, + (rlcstats[0]==RLC_MODE_AM)? "AM": (rlcstats[0]==RLC_MODE_UM)?"UM":"NONE",HDR); + measurcmd_display_measures(prnt, statsptr, num_rlcmeasure); + } +} /* status measurcmd_rlc_stat_req */ + + +void measurcmd_display_rlcstats(telnet_printfunc_t prnt) { + protocol_ctxt_t ctxt; + UE_list_t *UE_list = &(RC.mac[eNB_id]->UE_list); + telnet_ltemeasurdef_t statsptr[]=LTE_RLCMEASURE; + int num_rlcmeasure = sizeof(statsptr)/sizeof(telnet_ltemeasurdef_t ); + unsigned int *rlcstats = malloc(num_rlcmeasure*sizeof(unsigned int)); + eNB_MAC_INST *eNB = RC.mac[eNB_id]; + + for(int i=0; i <num_rlcmeasure ; i++) { + statsptr[i].vptr = rlcstats + i; + } + + for (int UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { +#define NB_eNB_INST 1 + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,eNB_id, ENB_FLAG_YES,UE_list->eNB_UE_stats[0][UE_id].crnti, + eNB->frame,eNB->subframe,eNB_id); + measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DCCH", &ctxt, SRB_FLAG_YES, DCCH); + measurcmd_display_one_rlcstat(prnt, UE_id, statsptr, num_rlcmeasure, rlcstats, "DTCH", &ctxt, SRB_FLAG_NO, DTCH-2); + } +} /* measurcmd_display_macstats_ue */ + +/*------------------------------------------------------------------------------------------------------------------------*/ +/* function called by the telnet server when measur command is entered */ +int measurcmd_show(char *buf, int debug, telnet_printfunc_t prnt) { + char *subcmd=NULL; + int idx1, idx2; + int badcmd=1; + + if (debug > 0) + prnt(" measurcmd_show received %s\n",buf); + + // char tmp[20480]; + // dump_eNB_l2_stats(tmp, 0); + // prnt("%s\n",tmp); + int s = sscanf(buf,"%ms %i-%i\n",&subcmd, &idx1,&idx2); + + if (s>0) { + if ( strcmp(subcmd,"groups") == 0) { + measurcmd_display_groups(prnt); + badcmd=0; + } else { + for (int i=0; i<TELNET_NUM_MEASURTYPES; i++) { + if(strcmp(subcmd,grouptypes[i]) == 0) { + for(int j=0; j<TELNET_NUM_MEASURGROUPS; j++) { + if(i == measurgroups[j].type) { + badcmd=0; + measurgroups[j].displayfunc(prnt); + } + } /* for j...*/ + } + }/* for i...*/ + + for (int i=0; i<TELNET_NUM_MEASURGROUPS; i++) { + if(strcmp(subcmd,measurgroups[i].groupname) == 0) { + measurgroups[i].displayfunc(prnt); + badcmd=0; + break; + } + } + } + + free(subcmd); + } /* s>0 */ + + if (badcmd) { + prnt("%s: unknown measur command\n",buf); + } + + return CMDSTATUS_FOUND; +} + + +int measurcmd_cpustats(char *buf, int debug, telnet_printfunc_t prnt) { + char *subcmd=NULL; + int idx1, idx2; + int badcmd=1; + + if (debug > 0) + prnt(" measurcmd_show received %s\n",buf); + + int s = sscanf(buf,"%ms %i-%i\n",&subcmd, &idx1,&idx2); + + if (s>0) { + if ( strcmp(subcmd,"enable") == 0) { + cpumeas(CPUMEAS_ENABLE); + badcmd=0; + } else if ( strcmp(subcmd,"disable") == 0) { + cpumeas(CPUMEAS_DISABLE); + badcmd=0; + } + } + + if (badcmd) { + prnt("Cpu measurments state: %s\n",PRINT_CPUMEAS_STATE); + } + + free(subcmd); + return CMDSTATUS_FOUND; +} +/*-------------------------------------------------------------------------------------*/ + +/* function called at telnet server init to add the measur command */ +void add_measur_cmds(void) { + add_telnetcmd("measur",measur_vardef,measur_cmdarray); + cpufreq = get_cpu_freq_GHz(); +} diff --git a/common/utils/telnetsrv/telnetsrv_measurements.h b/common/utils/telnetsrv/telnetsrv_measurements.h new file mode 100644 index 0000000000000000000000000000000000000000..46f25da4c52ddc3e17ce071501c0a98481b01eb7 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_measurements.h @@ -0,0 +1,88 @@ +/* + * 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 common/utils/telnetsrv/telnetsrv_measurements.h + * \brief: Include file defining constants, structures and function prototypes + * \ used to implement the measurements functionality of the telnet server + * \author Francois TABURET + * \date 2019 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#include <dlfcn.h> +#include "telnetsrv.h" +#include "openair1/PHY/defs_eNB.h" +#ifdef TELNETSRV_MEASURMENTS_MAIN + + +#define TELNET_MAXMEASURNAME_LEN 30 +#define TELNET_MAXMEASURGROUPS 10 + +telnetshell_vardef_t measur_vardef[] = { + {"",0,NULL} +}; + +typedef struct cpumeasurdef { + char statname[TELNET_MAXMEASURNAME_LEN]; + time_stats_t *astatptr; + unsigned int statemask; +} telnet_cpumeasurdef_t; + +typedef struct ltemeasurdef { + char statname[TELNET_MAXMEASURNAME_LEN]; + void *vptr; + char vtyp; + unsigned int statemask; +} telnet_ltemeasurdef_t; + +#define GROUP_LTESTATS 0 +#define GROUP_CPUSTATS 1 +typedef void(*measur_dislayfunc_t)(telnet_printfunc_t prnt); +typedef struct mesurgroupdef { + char groupname[TELNET_MAXMEASURNAME_LEN]; + unsigned char type; + unsigned char size; + measur_dislayfunc_t displayfunc; + union { + telnet_cpumeasurdef_t *cpustats; + telnet_ltemeasurdef_t *ltestats; + }; +} telnet_measurgroupdef_t; + +#define MACSTATS_NAME(valptr) #valptr +#define LTEMAC_MEASURGROUP_NAME "ltemac" +#define PHYCPU_MEASURGROUP_NAME "phycpu" + +int measurcmd_show(char *buf, int debug, telnet_printfunc_t prnt); +int measurcmd_cpustats(char *buf, int debug, telnet_printfunc_t prnt); +telnetshell_cmddef_t measur_cmdarray[] = { + {"show", "groups | <group name>" , measurcmd_show}, + {"cpustats","[enable | disable]",measurcmd_cpustats}, + {"","",NULL} +}; + +#else +extern void add_measur_cmds(void); +#endif /* TELNETSRV_MEASURCMD_MAIN */ diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c index 3b423bd4655e47d15e711e972c4b5d722dbcafec..9dd512091d73331c73940a4bf604018a50e56577 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.c +++ b/common/utils/telnetsrv/telnetsrv_proccmd.c @@ -183,7 +183,7 @@ struct dirent *entry; { if(entry->d_name[0] == '.') continue; - snprintf(aname, sizeof(aname), "/proc/%d/task/%s/stat", getpid(),entry->d_name); + snprintf(aname, sizeof(aname), "/proc/%d/task/%.*s/stat", getpid(),(int)(sizeof(aname)-24),entry->d_name); read_statfile(aname,debug,prnt); } /* while entry != NULL */ closedir(proc_dir); diff --git a/common/utils/threadPool/Makefile b/common/utils/threadPool/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..6f0e884886839933ee173e63c02042dde1d6cb23 --- /dev/null +++ b/common/utils/threadPool/Makefile @@ -0,0 +1,8 @@ +all: measurement_display thread-pool-test + +measurement_display: measurement_display.c thread-pool.h + gcc measurement_display.c -I /data/openairinterface5g.nr/common/utils/ -I. /data/openairinterface5g.nr/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o measurement_display + +thread-pool-test: thread-pool.c thread-pool.h + gcc -g thread-pool.c -I /data/openairinterface5g.nr/common/utils/ -I. /data/openairinterface5g.nr/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test + diff --git a/common/utils/threadPool/measurement_display.c b/common/utils/threadPool/measurement_display.c new file mode 100644 index 0000000000000000000000000000000000000000..ac7beca1fe00bac4b8d29d5906ded4cc5d7d1ea6 --- /dev/null +++ b/common/utils/threadPool/measurement_display.c @@ -0,0 +1,61 @@ +/* + Author: Laurent THOMAS, Open Cells + copyleft: OpenAirInterface Software Alliance and it's licence +*/ + +#define __USE_GNU +#define _GNU_SOURCE +#include <stdio.h> +#include <pthread.h> +#include <sched.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <string.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/time.h> +#include <stdint.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "thread-pool.h" + +#define SEP "\t" + +uint64_t cpuCyclesMicroSec; + +int main(int argc, char *argv[]) { + if(argc != 2) { + printf("Need one paramter: the trace Linux pipe (fifo)"); + exit(1); + } + + mkfifo(argv[1],0666); + int fd=open(argv[1], O_RDONLY); + + if ( fd == -1 ) { + perror("open read mode trace file:"); + exit(1); + } + + uint64_t deb=rdtsc(); + usleep(100000); + cpuCyclesMicroSec=(rdtsc()-deb)/100000; + printf("Cycles per µs: %lu\n",cpuCyclesMicroSec); + printf("Key" SEP "delay to process" SEP "processing time" SEP "delay to be read answer\n"); + notifiedFIFO_elt_t doneRequest; + + while ( 1 ) { + if ( read(fd,&doneRequest, sizeof(doneRequest)) == sizeof(doneRequest)) { + printf("%lu" SEP "%lu" SEP "%lu" SEP "%lu" "\n", + doneRequest.key, + (doneRequest.startProcessingTime-doneRequest.creationTime)/cpuCyclesMicroSec, + (doneRequest.endProcessingTime-doneRequest.startProcessingTime)/cpuCyclesMicroSec, + (doneRequest.returnTime-doneRequest.endProcessingTime)/cpuCyclesMicroSec + ); + } else { + printf("no measurements\n"); + sleep(1); + } + } +} diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c new file mode 100644 index 0000000000000000000000000000000000000000..4cc56fc9b8126f8a5f88d03ce8be780563b7d116 --- /dev/null +++ b/common/utils/threadPool/thread-pool.c @@ -0,0 +1,230 @@ +/* + Author: Laurent THOMAS, Open Cells + copyleft: OpenAirInterface Software Alliance and it's licence +*/ + +#define _GNU_SOURCE +#include <sched.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/sysinfo.h> +#include <threadPool/thread-pool.h> + +void displayList(notifiedFIFO_t *nf) { + int n=0; + notifiedFIFO_elt_t *ptr=nf->outF; + + while(ptr) { + printf("element: %d, key: %lu\n",++n,ptr->key); + ptr=ptr->next; + } + + printf("End of list: %d elements\n",n); +} + +static inline notifiedFIFO_elt_t *pullNotifiedFifoRemember( notifiedFIFO_t *nf, struct one_thread *thr) { + mutexlock(nf->lockF); + + while(!nf->outF) + condwait(nf->notifF, nf->lockF); + + notifiedFIFO_elt_t *ret=nf->outF; + nf->outF=nf->outF->next; + + if (nf->outF==NULL) + nf->inF=NULL; + + // For abort feature + thr->runningOnKey=ret->key; + thr->abortFlag=false; + mutexunlock(nf->lockF); + return ret; +} + +void *one_thread(void *arg) { + struct one_thread *myThread=(struct one_thread *) arg; + struct thread_pool *tp=myThread->pool; + + // configure the thread core assignment + // TBD: reserve the core for us exclusively + if ( myThread->coreID >= 0 && myThread->coreID < get_nprocs_conf()) { + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(myThread->coreID, &cpuset); + pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + } + + //Configure the thread scheduler policy for Linux + struct sched_param sparam= {0}; + sparam.sched_priority = sched_get_priority_max(SCHED_RR); + pthread_setschedparam(pthread_self(), SCHED_RR, &sparam); + // set the thread name for debugging + sprintf(myThread->name,"Tpool_%d",myThread->coreID); + pthread_setname_np(pthread_self(), myThread->name ); + + // Infinite loop to process requests + do { + notifiedFIFO_elt_t *elt=pullNotifiedFifoRemember(&tp->incomingFifo, myThread); + + if (tp->measurePerf) elt->startProcessingTime=rdtsc(); + + elt->processingFunc(NotifiedFifoData(elt)); + + if (tp->measurePerf) elt->endProcessingTime=rdtsc(); + + if (elt->reponseFifo) { + // Check if the job is still alive, else it has been aborted + mutexlock(tp->incomingFifo.lockF); + + if (myThread->abortFlag) + delNotifiedFIFO_elt(elt); + else + pushNotifiedFIFO(elt->reponseFifo, elt); + + mutexunlock(tp->incomingFifo.lockF); + } + } while (true); +} + +void initTpool(char *params,tpool_t *pool, bool performanceMeas) { + memset(pool,0,sizeof(*pool)); + char *measr=getenv("threadPoolMeasurements"); + pool->measurePerf=performanceMeas; + // force measurement if the output is defined + pool->measurePerf=measr!=NULL; + + if (measr) { + mkfifo(measr,0666); + AssertFatal(-1 != (pool->dummyTraceFd= + open(measr, O_RDONLY| O_NONBLOCK)),""); + AssertFatal(-1 != (pool->traceFd= + open(measr, O_WRONLY|O_APPEND|O_NOATIME|O_NONBLOCK)),""); + } else + pool->traceFd=-1; + + //Configure the thread scheduler policy for Linux + struct sched_param sparam= {0}; + sparam.sched_priority = sched_get_priority_max(SCHED_RR)-1; + pthread_setschedparam(pthread_self(), SCHED_RR, &sparam); + pool->activated=true; + initNotifiedFIFO(&pool->incomingFifo); + char *saveptr, * curptr; + pool->nbThreads=0; + pool->restrictRNTI=false; + curptr=strtok_r(params,",",&saveptr); + + while ( curptr!=NULL ) { + int c=toupper(curptr[0]); + + switch (c) { + case 'U': + pool->restrictRNTI=true; + break; + + case 'N': + pool->activated=false; + break; + + default: + pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread)); + pool->allthreads->next=pool->allthreads; + printf("create a thread for core %d\n", atoi(curptr)); + pool->allthreads->coreID=atoi(curptr); + pool->allthreads->id=pool->nbThreads; + pool->allthreads->pool=pool; + pthread_create(&pool->allthreads->threadID, NULL, one_thread, (void *)pool->allthreads); + pool->nbThreads++; + } + + curptr=strtok_r(NULL,",",&saveptr); + } + + if (pool->activated && pool->nbThreads==0) { + printf("No servers created in the thread pool, exit\n"); + exit(1); + } +} + +#ifdef TEST_THREAD_POOL + +struct testData { + int id; + char txt[30]; +}; + +void processing(void *arg) { + struct testData *in=(struct testData *)arg; + printf("doing: %d, %s, in thr %ld\n",in->id, in->txt,pthread_self() ); + sprintf(in->txt,"Done by %ld, job %d", pthread_self(), in->id); + usleep(rand()%100); + printf("done: %d, %s, in thr %ld\n",in->id, in->txt,pthread_self() ); +} + +int main() { + notifiedFIFO_t myFifo; + initNotifiedFIFO(&myFifo); + pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 1234,NULL,NULL)); + + for(int i=10; i>1; i--) { + pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 1000+i,NULL,NULL)); + } + + displayList(&myFifo); + notifiedFIFO_elt_t *tmp=pullNotifiedFIFO(&myFifo); + printf("pulled: %lu\n", tmp->key); + displayList(&myFifo); + tmp=pullNotifiedFIFO(&myFifo); + printf("pulled: %lu\n", tmp->key); + displayList(&myFifo); + abortNotifiedFIFO(&myFifo,1005); + printf("aborted 1005\n"); + displayList(&myFifo); + pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 12345678, NULL, NULL)); + displayList(&myFifo); + abortNotifiedFIFO(&myFifo,12345678); + printf("aborted 12345678\n"); + displayList(&myFifo); + + do { + tmp=pollNotifiedFIFO(&myFifo); + + if (tmp) { + printf("pulled: %lu\n", tmp->key); + displayList(&myFifo); + } else + printf("Empty list \n"); + } while(tmp); + + tpool_t pool; + char params[]="1,2,3,u"; + initTpool(params,&pool, true); + notifiedFIFO_t worker_back; + initNotifiedFIFO(&worker_back); + + for (int i=0; i <1000 ; i++) { + notifiedFIFO_elt_t *work=newNotifiedFIFO_elt(sizeof(struct testData), i, &worker_back, processing); + struct testData *x=(struct testData *)NotifiedFifoData(work); + x->id=i; + pushTpool(&pool, work); + } + + do { + tmp=pullTpool(&worker_back,&pool); + + if (tmp) { + struct testData *dd=NotifiedFifoData(tmp); + printf("Result: %s\n",dd->txt); + delNotifiedFIFO_elt(tmp); + } else + printf("Empty list \n"); + + abortTpool(&pool,510); + } while(tmp); + + return 0; +} +#endif diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h new file mode 100644 index 0000000000000000000000000000000000000000..6f34508c5a9023b23d3b15e4be9b036c09b2b06a --- /dev/null +++ b/common/utils/threadPool/thread-pool.h @@ -0,0 +1,244 @@ +/* + Author: Laurent THOMAS, Open Cells + copyleft: OpenAirInterface Software Alliance and it's licence +*/ + +#ifndef THREAD_POOL_H +#define THREAD_POOL_H +#include <stdbool.h> +#include <stdint.h> +#include <pthread.h> +#include <sys/syscall.h> +#include <assertions.h> +#include <LOG/log.h> + +#ifdef DEBUG + #define THREADINIT PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP +#else + #define THREADINIT PTHREAD_MUTEX_INITIALIZER +#endif +#define mutexinit(mutex) AssertFatal(pthread_mutex_init(&mutex,NULL)==0,""); +#define condinit(signal) AssertFatal(pthread_cond_init(&signal,NULL)==0,""); +#define mutexlock(mutex) AssertFatal(pthread_mutex_lock(&mutex)==0,""); +#define mutextrylock(mutex) pthread_mutex_trylock(&mutex) +#define mutexunlock(mutex) AssertFatal(pthread_mutex_unlock(&mutex)==0,""); +#define condwait(condition, mutex) AssertFatal(pthread_cond_wait(&condition, &mutex)==0,""); +#define condbroadcast(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,""); +#define condsignal(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,""); + +typedef struct notifiedFIFO_elt_s { + struct notifiedFIFO_elt_s *next; + uint64_t key; //To filter out elements + struct notifiedFIFO_s *reponseFifo; + void (*processingFunc)(void *); + bool malloced; + uint64_t creationTime; + uint64_t startProcessingTime; + uint64_t endProcessingTime; + uint64_t returnTime; + void *msgData; +} notifiedFIFO_elt_t; + +typedef struct notifiedFIFO_s { + notifiedFIFO_elt_t *outF; + notifiedFIFO_elt_t *inF; + pthread_mutex_t lockF; + pthread_cond_t notifF; +} notifiedFIFO_t; + +// You can use this allocator or use any piece of memory +static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size, + uint64_t key, + notifiedFIFO_t *reponseFifo, + void (*processingFunc)(void *)) { + notifiedFIFO_elt_t *ret; + AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) malloc(sizeof(notifiedFIFO_elt_t)+size+32)), ""); + ret->next=NULL; + ret->key=key; + ret->reponseFifo=reponseFifo; + ret->processingFunc=processingFunc; + // We set user data piece aligend 32 bytes to be able to process it with SIMD + ret->msgData=(void *)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32; + ret->malloced=true; + return ret; +} + +static inline void *NotifiedFifoData(notifiedFIFO_elt_t *elt) { + return elt->msgData; +} + +static inline void delNotifiedFIFO_elt(notifiedFIFO_elt_t *elt) { + if (elt->malloced) { + elt->malloced=false; + free(elt); + } else + printf("delNotifiedFIFO on something not allocated by newNotifiedFIFO\n"); + + //LOG_W(UTIL,"delNotifiedFIFO on something not allocated by newNotifiedFIFO\n"); +} + +static inline void initNotifiedFIFO(notifiedFIFO_t *nf) { + mutexinit(nf->lockF); + condinit (nf->notifF); + nf->inF=NULL; + nf->outF=NULL; + // No delete function: the creator has only to free the memory +} + +static inline void pushNotifiedFIFO(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg) { + mutexlock(nf->lockF); + msg->next=NULL; + + if (nf->outF == NULL) + nf->outF = msg; + + if (nf->inF) + nf->inF->next = msg; + + nf->inF = msg; + condbroadcast(nf->notifF); + mutexunlock(nf->lockF); +} + +static inline notifiedFIFO_elt_t *pullNotifiedFIFO(notifiedFIFO_t *nf) { + mutexlock(nf->lockF); + + while(!nf->outF) + condwait(nf->notifF, nf->lockF); + + notifiedFIFO_elt_t *ret=nf->outF; + nf->outF=nf->outF->next; + + if (nf->outF==NULL) + nf->inF=NULL; + + mutexunlock(nf->lockF); + return ret; +} + +static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) { + int tmp=mutextrylock(nf->lockF); + + if (tmp != 0 ) + return NULL; + + notifiedFIFO_elt_t *ret=nf->outF; + + if (ret!=NULL) + nf->outF=nf->outF->next; + + if (nf->outF==NULL) + nf->inF=NULL; + + mutexunlock(nf->lockF); + return ret; +} + +// This function aborts all messages matching the key +// If the queue is used in thread pools, it doesn't cancels already running processing +// because the message has already been picked +static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) { + mutexlock(nf->lockF); + notifiedFIFO_elt_t **start=&nf->outF; + + while(*start!=NULL) { + if ( (*start)->key == key ) { + notifiedFIFO_elt_t *request=*start; + *start=(*start)->next; + delNotifiedFIFO_elt(request); + } + + if (*start != NULL) + start=&(*start)->next; + } + + mutexunlock(nf->lockF); +} + +struct one_thread { + pthread_t threadID; + int id; + int coreID; + char name[256]; + uint64_t runningOnKey; + bool abortFlag; + struct thread_pool *pool; + struct one_thread *next; +}; + +typedef struct thread_pool { + int activated; + bool measurePerf; + int traceFd; + int dummyTraceFd; + uint64_t cpuCyclesMicroSec; + uint64_t startProcessingUE; + int nbThreads; + bool restrictRNTI; + notifiedFIFO_t incomingFifo; + struct one_thread *allthreads; +} tpool_t; + +static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) { + if (t->measurePerf) msg->creationTime=rdtsc(); + + pushNotifiedFIFO(&t->incomingFifo, msg); +} + +static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) { + notifiedFIFO_elt_t *msg= pullNotifiedFIFO(responseFifo); + + if (t->measurePerf) + msg->returnTime=rdtsc(); + + if (t->traceFd) + if(write(t->traceFd, msg, sizeof(*msg))); + + return msg; +} + +static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) { + notifiedFIFO_elt_t *msg= pollNotifiedFIFO(responseFifo); + + if (msg == NULL) + return NULL; + + if (t->measurePerf) + msg->returnTime=rdtsc(); + + if (t->traceFd) + if(write(t->traceFd, msg, sizeof(*msg))); + + return msg; +} + +static inline void abortTpool(tpool_t *t, uint64_t key) { + notifiedFIFO_t *nf=&t->incomingFifo; + mutexlock(nf->lockF); + notifiedFIFO_elt_t **start=&nf->outF; + + while(*start!=NULL) { + if ( (*start)->key == key ) { + notifiedFIFO_elt_t *request=*start; + *start=(*start)->next; + delNotifiedFIFO_elt(request); + } + + if (*start != NULL) + start=&(*start)->next; + } + + struct one_thread *ptr=t->allthreads; + + while(ptr!=NULL) { + if (ptr->runningOnKey==key) + ptr->abortFlag=true; + + ptr=ptr->next; + } + + mutexunlock(nf->lockF); +} +void initTpool(char *params,tpool_t *pool, bool performanceMeas); + +#endif diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md new file mode 100644 index 0000000000000000000000000000000000000000..2b6336fb6093e7789d82aeb5ccef6cd5815b5f27 --- /dev/null +++ b/common/utils/threadPool/thread-pool.md @@ -0,0 +1,71 @@ +# Thread pool + +The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores. + +Each worker loop on pick from the same input queue jobs to do. +When a job is done, the worker sends a return if a return is defined. + +A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless). + +All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter. + +## license +Author: Laurent Thomas, Open cells project +The owner share this piece code to Openairsoftware alliance as per OSA license terms + +# jobs + +A job is a message (notifiedFIFO_elt_t): +next: internal FIFO chain, do not set it +key: a long int that the client can use to identify a message or a group of messages +responseFifo: if the client defines a response FIFO, the message will be posted back after processing +processingFunc: any funtion (type void processingFunc(void *)) that the worker will launch +msgData: the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing +malloced: a boolean that enable internal free in these cases: no return Fifo or Abort feature + +The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. + +# Queues of jobs + +Queues are type of: notifiedFIFO_t that must be initialized by init_notifiedFIFO() +No delete function is required, the creator has only to free the data of type notifiedFIFO_t + +push_notifiedFIFO() add a job in the queue +pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking + +abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition) + +# Thread pools + +## initialization +The clients can create one or more thread pools with init_tpool() +the params string structure: describes a list of cores, separated by "," that run a worker thread + +If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core). + +The threads are all Linux real time scheduler, their name is set automatically is "Tpool_<core id>" + +## adding jobs +The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO()) + +If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job. + +## abort + +A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues. + +Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue. + +## Performance measurements + +A performance measurement is integrated: the pool will automacillay fill timestamps: + +* creationTime: time the request is push to the pool; +* startProcessingTime: time a worker start to run on the job +* endProcessingTime: time the worker finished the job +* returnTime: time the client reads the result + +if you set the environement variable: thread-pool-measurements to a valid file name +These measurements will be wrote to this Linux pipe. + +A tool to read the linux fifo and display it in ascii is provided: see the local directory Makefile for this tool and to compile the thread pool unitary tests. diff --git a/configuration/bladeRF/enb-band7-5mhz.conf b/configuration/bladeRF/enb-band7-5mhz.conf index 6e07b8d9499e8cfb2ca60f0d3da91d3dbb92348a..127c8654227d8e3a40b410fa7ea246bbbe440210 100644 --- a/configuration/bladeRF/enb-band7-5mhz.conf +++ b/configuration/bladeRF/enb-band7-5mhz.conf @@ -181,6 +181,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; diff --git a/doc/BUILD.md b/doc/BUILD.md new file mode 100644 index 0000000000000000000000000000000000000000..1f971b7776aaccefb6dcb7507925bb29e5f74741 --- /dev/null +++ b/doc/BUILD.md @@ -0,0 +1,134 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">OAI Build Procedures</font></b> + </td> + </tr> +</table> + +This page is valid on tags starting from **`2019.w09`**. + +# Soft Modem Build Script + +oai EPC is developed in a distinct project with it's own [documentation](https://github.com/OPENAIRINTERFACE/openair-cn/wiki) , it is not described here. + +OAI UE and eNodeB sources can be downloaded from the Eurecom [gitlab repository](./GET_SOURCES.md). + +Sources come with a build script [build_oai](../cmake_targets/build_oai) located at the root of the `openairinterface5g/cmake_targets` directory. This script is developed to build the oai binaries (executables,shared libraries) for different hardware platforms, and use cases. + +The main oai binaries, which are tested by the Continuous Integration process are: + +- The LTE UE: `lte-uesoftmodem` +- The LTE eNodeB: `lte-softmodem` +- The PHY simulators: `dlsim` and `ulsim` + +The build system for OAI uses [cmake](https://cmake.org/) which is a tool to generate makefiles. The `build_oai` script is a wrapper using cmake, make and standard linux shell commands to ease the oai build and use . The file describing how to build the executables from source files is the [CMakeLists.txt](../cmake_targets/CMakeLists.txt), it is used as input by cmake to generate the makefiles. + +The oai softmodem supports many use cases, and new ones are regularly added. Most of them are accessible using the configuration file or the command line options and continuous effort is done to avoid introducing build options as it makes tests and usage more complicated than run-time options. The following functionalities, originally requiring a specific build are now accessible by configuration or command line options: + +- s1, noS1 +- all simulators, with exception of PHY simulators, which are distinct executables. + + +Calling the `build_oai` script with the -h option gives the list of all available options, but a process to simplify and check the requirements of all these options is on-going. Check the + +[table]: BUILD.md "`build_oai` options" + +At the end of this page to know the status of `buid_oai` options which are not described hereafter. + +# Building PHY Simulators + +Detailed information about these simulators can be found [in this dedicated page](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/OpenAirLTEPhySimul) + +# Building UE and eNodeB Executables + +After downloading the source files, a single build command can be used to get the binaries supporting all the oai softmodem use cases (UE and eNodeB): + +``` +cd <your oai installation directory>/openairinterface5g/ +source oaienv +cd ../cmake_targets/ +./build_oai -I -w USRP --eNB --UE +``` + +- The `-I` option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed. +- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. +- `--eNB` is to build the `lte-softmodem` executable and all required shared libraries +- `--UE` is to build the `lte-uesoftmodem` executable and all required shared libraries + +You can build the eNodeB and the UE separately, you may not need both of them depending on your oai usage. + +After completing the build, the binaries are available in the `cmake_targets/lte_build_oai/build` directory. A copy is also available in the `target/bin` directory, with all binaries suffixed by the 3GPP release number, today .Rel14 by default. It must be noticed that the option for building for a specific 3GPP release number is not tested by the CI and may be removed in the future. + +# Building Optional Binaries + +## Telnet Server + +The telnet server can be built with the --build-telnet option, after building the softmodem or while building it. + +`./build_oai -I -w USRP --eNB --UE --build-telnetsrv` + +or + +`./build_oai --build-telnetsrv` + +## USRP record player + +The USRP record player today needs a specific build. Work to make it available as a run time option is under consideration + +# `build_oai` options + +| Option | Status | Description | +| ----------------------------------------------------------- | ------------------------------------------- | :----------------------------------------------------------- | +| -h | maintained | get help | +| -c | maintained | erase all previously built files for this target before starting the new build. | +| -C | maintained, needs improvement | erase all previously built files for any target before starting the new build. | +| --verbose-compile | maintained | | +| --cflags_processor | maintained | used to pass options to the compiler | +| --clean-kernel | unknown | no code in the script corresponding to this option | +| --install-system-files | maintained | install oai built binaries in linux system files repositories | +| -w | maintained and tested in CI for USRP device | build corresponding oai device and create the soft link to enforce this device usage at run-time | +| -t | maintained | build the specified transport library, which is used in some simulators and in non monolithic eNodeB deployments. Now of little interest as transport library build is enforced when building the eNodeB. | +| --phy_simulators | maintained, tested in CI | build all PHY simulators, a set of executables allowing unitary tests of LTE channel implementation within oai. | +| --core_simulators | | | +| -s | | | +| --run-group | | | +| -I | maintained, tested in CI | install external dependencies before starting the build | +| --install-optional-packages | maintained | install optional packages, useful for developing and testing. look at the | +| | | check_install_additional_tools function in cmake_targets/tools/build_helper script to get the list | +| -g | maintained | build binaries with gdb support. | +| --eNB | maintained and tested in CI | build `lte-softmodem` the LTE eNodeB | +| --UE | maintained and tested in CI | build `lte-uesoftmodem` the LTE UE | +| --usrp-recplay | maintained | build with support for the record player. Implementation will be soon reviewed to switch to a run-time option. | +| --build-telnet | maintained | build the telnet server shared library, which can then be loaded at run time via the --telnetsrv command line option. | +| --build-msc | unknown | build the msc shared library, which can then be loaded at run time via the --msc command line option. msc is a tracing utility which status is unknown. | +| --UE-conf-nvram | | | +| --UE-gen-nvram | | | +| -r | unknown, to be removed | specifies which 3GPP release to build for. Only the default (today rel14) is tested in CI and it is likely that future oai release will remove this option | +| -V | deprecated | Used to build with support for synchronization diagram utility. This is now available via the T-Tracer and is included if T-Tracer is not disabled. | +| -x | deprecated | Used to build with support for embedded signal analyzer. This is now available via the T-Tracer and is included if T-Tracer is not disabled. | +| --noS1 | deprecated, to be removed | build noS1 version of oai softmodem binaries. noS1 allows running oai eNodeB and UE without an LTE core network (EPC). This functionality is now available via a run-time option. | +| --build-doxygen | unknown | build doxygen documentation, many oai source files do not include doxygen comments | +| --disable-deadline --enable-deadline --disable-cpu-affinity | deprecated | These options were used to activate or de-activate specific code depending on the choice of a specific linux scheduling mode. This has not been tested for a while and should be implemented as configuration options | +| --disable-T-Tracer | maintained, to be tested | Remove T_Tracer and console LOG messages except error messages. | +| --disable-hardware-dependency | | | +| --ue-autotest-trace --ue-timing --ue-trace | deprecated | Were used to enable conditional code implementing debugging messages or debugging statistics. These functionalities are now either available from run-time options or not maintained. | +| --disable-log | deprecated, to be removed | Was used to disable LOG messages, replaced by `--disable-T-Tracer` build option to remove tracing code from the build or `--T-stdout 0` run time option to redirect LOG messages to T-Tracer client interface. | +| --ue-nas-use-tun | deprecated to be removed | Usage of tun in place of specific kernel modules is now a run time option. `--nokrnmod 0` option disable the default behavior which is to use tun to send or receive ip packets to/from the linux ip stack. | +| --build-eclipse | unknown | | +| --basic-simulator | deprecated tested in CI | builds the basic simulator device. Now of little interest as this device build is enforced when building the eNodeB and it can be used at run time with the `--basicsim` option. More over the rf simulator is an enhanced basic simulator. | +| --rfsimulator | maintained | builds the rf simulator device. Now of little interest as this device build is enforced when building the eNodeB and it can be used at run time with the `--rfsim` option. | +| | | | + +[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) + +[oai softmodem features](FEATURE_SET.md) + +[running the oai softmodem ](RUNMODEM.md) + diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index fef47d9c271aae7eaf53640715baa9a48fb2a972..deb4fec994fa4544a41beee69191a360114325c1 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -18,7 +18,7 @@ # OpenAirInterface Block diagram # - + # OpenAirInterface eNB Feature Set # @@ -43,22 +43,26 @@ The Physical layer implements **3GPP 36.211**, **36.212**, **36.213** and provid **Transmission Mode, Bandwidth** | **Expected Throughput** | **Measured Throughput** | **Measurement Conditions** -------------------------------- | ----------------------- | ------------------------| ----------------: FDD DL: 5 MHz, 25 PRBS/ MCS 28 | 16 - 17 Mbit/s | TM1: 17.0 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) -FDD DL: 10 MHz, 50 PRBS/ MCS 28 | 34 - 35 Mbit/s | TM1: 32.8 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +FDD DL: 10 MHz, 50 PRBS/ MCS 28 | 34 - 35 Mbit/s | TM1: 34.0 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) FDD DL: 20 MHz, 100 PRBS/ MCS 28 | 70 Mbit/s | TM1: 69.9 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) | | | FDD UL: 5 MHz, 25 PRBS/ MCS 20 | 9 Mbit/s | TM1: 8.28 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) -FDD UL: 10 MHz, 50 PRBS/ MCS 20 | 17 Mbit/s | TM1: 15.2 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +FDD UL: 10 MHz, 50 PRBS/ MCS 20 | 17 Mbit/s | TM1: 18.3 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) FDD UL: 20 MHz, 100 PRBS/ MCS 20 | 35 Mbit/s | TM1: 18.6 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) | | -TDD DL: 5 MHz, 25 PRBS/ MCS **XX** | **TBC** Mbit/s | 3.33 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) -TDD DL: 10 MHz, 50 PRBS/ MCS **XX** | **TBC** Mbit/s | 8.90 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) -TDD DL: 20 MHz, 100 PRBS/ MCS **XX** | **TBC** Mbit/s | N/A | COTS-UE Cat 4 (150/50 Mbps) +TDD DL: 5 MHz, 25 PRBS/ MCS **XX** | 6.5 Mbit/s | TM1: 6.71 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +TDD DL: 10 MHz, 50 PRBS/ MCS **XX** | 13.5 Mbit/s | TM1: 13.6 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +TDD DL: 20 MHz, 100 PRBS/ MCS **XX** | 28.0 Mbit/s | TM1: 27.2 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) | | | -TDD UL: 5 MHz, 25 PRBS/ MCS **XX** | **TBC** Mbit/s | 1.66 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) -TDD UL: 10 MHz, 50 PRBS/ MCS **XX** | **TBC** Mbit/s | 1.89 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) -TDD UL: 20 MHz, 100 PRBS/ MCS **XX** | **TBC** Mbit/s | N/A | COTS-UE Cat 4 (150/50 Mbps) +TDD UL: 5 MHz, 25 PRBS/ MCS **XX** | 2.0 Mbit/s | TM1: 3.31 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +TDD UL: 10 MHz, 50 PRBS/ MCS **XX** | 2.0 Mbit/s | TM1: 7.25 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +TDD UL: 20 MHz, 100 PRBS/ MCS **XX** | 3.0 Mbit/s | TM1: 4.21 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) -- Number of supported UEs: **To Be Completed** +### Number of supported UEs ### + +* 16 by default +* up to 256 when compiling with dedicated compile flag +* was tested with 40 COTS-UE ## eNB MAC Layer ## @@ -72,6 +76,7 @@ The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support - RLC interface (AM, UM) - UL power control - Link adaptation +- Connected DRX (CDRX) support for FDD LTE UE. Compatible with R13 from 3GPP. Support for Cat-M1 UE comming soon. ## eNB RLC Layer ## @@ -124,6 +129,12 @@ The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following - X2 Setup Request - X2 Setup Response + - X2 Setup Failure + - Handover Request + - Handover Request Acknowledge + - UE Context Release + - X2 timers (t_reloc_prep, tx2_reloc_overall) + - Handover Cancel ## eNB Advanced Features ## @@ -135,7 +146,7 @@ The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following - RAU: Radio-Access Unit - RRU: Remote Radio-Unit - + - IF4.5 / IF5 : similar to IEEE P1914.1 - FAPI (IF2) : specified by Small Cell Forum (open-nFAPI implementation) @@ -189,3 +200,10 @@ The NAS layer is based on **3GPP 24.301** and implements the following functions - EMM attach/detach, authentication, tracking area update, and more - ESM default/dedicated bearer, PDN connectivity, and more + +[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) + +[oai softmodem build procedure](BUILD.md) + +[running the oai softmodem ](RUNMODEM.md) + diff --git a/doc/GET_SOURCES.md b/doc/GET_SOURCES.md new file mode 100644 index 0000000000000000000000000000000000000000..e27e9dbb74bca76987335081fd9acea8f7a01145 --- /dev/null +++ b/doc/GET_SOURCES.md @@ -0,0 +1,109 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">The OpenAirInterface repository: the sources</font></b> + </td> + </tr> +</table> + +The OpenAirInterface software can be obtained from our gitLab +server. You will need a git client to get the sources. The repository +is currently used for main developments. + +# Prerequisites + +You need to install the subversion/git using the following commands: + +```shell +sudo apt-get update +sudo apt-get install subversion git +``` + +# Using EURECOM Gitlab + +The [openairinterface5g repository](https://gitlab.eurecom.fr/oai/openairinterface5g.git) +holds the source code for (eNB RAN + UE RAN). + +For legal issues (licenses), the core network (EPC) source code is now moved away from +the above openairinterface5g git repository. + +* A very old version of the EPC is located under the same GitLab Eurecom server (splitted into 2 Git repos): + * [openair-cn](https://gitlab.eurecom.fr/oai/openair-cn.git) with apache license + * [xtables-addons-oai](https://gitlab.eurecom.fr/oai/xtables-addons-oai.git) with GPL license + * **These repositories are no more maintained.** +* A more recent version is available under our GitHub domain: + * [OAI GitHub openair-cn](https://github.com/OPENAIRINTERFACE/openair-cn) + * Check its wiki pages for more details + +Configure git with your name/email address (only important if you are developer and want to contribute/push code to Git Repository): + +```shell +git config --global user.name "Your Name" +git config --global user.email "Your email address" +``` + +- Add a certificate from gitlab.eurecom.fr to your Ubuntu 14.04 installation: + +```shell +echo -n | openssl s_client -showcerts -connect gitlab.eurecom.fr:443 2>/dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt +``` + +- Disable certificate check completely if you do not have root access to /etc/ssl directory + +```shell +git config --global http.sslverify false +``` + +## In order to clone the Git repository (for OAI Users without login to gitlab server) + +Cloning RAN repository (eNB RAN + UE RAN): + +```shell +git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git +``` + +## In order to contribute to the Git RAN repository (for OAI Developers/admins with login to gitlab server) + +Please send email to [contact@openairinterface.org](mailto:contact@openairinterface.org) to be added to the repository +as a developer (only important for users who want to commit code to the repository). If +you do not have account on gitlab.eurecom.fr, please register yourself to gitlab.eurecom.fr and provide the identifiant in the email. + +* Clone with using ssh keys: + * You will need to put your ssh keys in https://gitlab.eurecom.fr/profile/keys + to access to the git repo. Once that is done, clone the git repository using: + * `git clone git@gitlab.eurecom.fr:oai/openairinterface5g.git` +* Clone with user name/password prompt: + * `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/openairinterface5g.git` + * `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/openair-cn.git` + * `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/xtables-addons-oai.git` (optional, openair-cn build script can do it for you) + +# Which branch to checkout? + +On the RAN side: + +* **master**: This branch is targeted for the user community. Since January 2019, it is also subject to a Continuous Integration process. The update frequency is about once every 2-3 months. We are also performing bug fixes on this branch. +* **develop**: This branch contains recent commits that are tested on our CI test bench. The update frequency is about once a week. + +Please see the work flow and policies page : + +https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/oai-policies-home + +you can find the latest stable tag release here : + +https://gitlab.eurecom.fr/oai/openairinterface5g/tags + +The tag naming conventions are : + +- On `master` branch: **v1.`x`.`y`** where + * `x` is the minor release number, incremented every 2-3 months when we are merging `develop` into `master` branch. + * `y` is the maintenance number, starting at 0 when we do a minor release and being incremented when a bug fix is incorporated into `master` branch. +- On `develop` branch **`yyyy`.w`xx`** + * `yyyy` is the calendar year + * `xx` the week number within the year + diff --git a/doc/L1SIM.md b/doc/L1SIM.md new file mode 100644 index 0000000000000000000000000000000000000000..d63c0e5a3400213aad3b961de2485dd68c28da18 --- /dev/null +++ b/doc/L1SIM.md @@ -0,0 +1,99 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">Open Air LTE Emulation</font></b> + </td> + </tr> +</table> + +This page is valid for the develop branch + +# Table of Contents: # + +* [How to build the eNB and the UE](#build) +* [How to run an eNB built with the noS1 option](#run-noS1-eNB) +* [How to run a UE built with the noS1 option](#run-noS1-UE) +* [Continuous Integration notes](#CInote) +* [How to ping an eNB from a UE and vice versa (with the noS1 option)](#noS1-pinging) + +The old oaisim is dead! Long live oaisim! :) + +If you are looking for a description of the old oaisim (which is still available in some branches/tags), please see [here](OpenAirLTEEmulation) and [here](how-to-run-oaisim-with-multiple-ue). + +oaisim has been scraped and replaced by the same programs that are used for the real-time operation, `lte-softmodem` and `lte-uesoftmodem`. The latter also now includes an optional channel model, just like oaisim did. + +# <a name="build">[How to build the eNB and the UE](BUILD.md)</a> + +The following paragraph explains how to run the L1 simulator in noS1 mode and using the oai kernel modules. + +# <a name="run-noS1-eNB">How to run an eNB with the noS1 option</a> + +Modify the configuration file for IF4p5 fronthaul, `/openairinterface5g/ci-scripts/conf_files/rcc.band7.nos1.simulator.conf`, and replace the loopback interface with a physical ethernet interface and the IP addresses to work on your network. Copy your modifications to a new file, let's call YYY.conf the resulting configuration file. + +Run lte-softmodem as usual with this configuration. + +```bash +$ source oaienv +$ cd cmake_targets/tools +$ sudo -E ./init_nas_nos1 eNB +$ cd ../lte_build_oai/build +$ sudo -E ./lte-softmodem -O YYY.conf --noS1 --nokrnmod 0 +``` + +# <a name="run-noS1-UE">How to run a UE with the noS1 option</a> + +Similarly modify the example configuration file in `/openairinterface5g/ci-scripts/conf_files/rru.band7.nos1.simulator.conf` and replace loopback interface and IP addresses. Copy your modifications to a new file, let's call XXX.conf the resulting configuration file. + +Run it like: + +```bash +$ source oaienv +$ cd cmake_targets/tools +$ sudo -E ./init_nas_nos1 UE +$ cd ../lte_build_oai/build +$ sudo ./lte-uesoftmodem -O XXX.conf -r 25 --siml1 --noS1 --nokrnmod 0 +``` + +That should give you equivalent functionality to what you had with oaisim including noise and RF channel emulation (path loss / fading, etc.). You should also be able to run multiple UEs. + +# <a name="CInote">Continuous Integration notes</a> +The CI currently tests the noS1 build option with one eNB and one UE in the following scenarios: +* pinging one UE from one eNB +* pinging one eNB from one UE +* iperf download between one eNB and one UE +* iperf upload between one eNB and one UE +* all the above tests are done in FDD 5Mhz mode. + +# <a name="noS1-pinging">How to ping an eNB from a UE and vice versa (with the noS1 option)</a> + +Once your eNB and UE (built with the noS1 option) are running and synchronised, you can ping the eNB from the UE with the following command: + +```bash +ping -I oai0 -c 20 $eNB_ip_addr +``` +where $eNB_ip_addr is the IP address of your eNB. + +Similarly, you can ping the UE from the eNB. + +The IP adresses of the eNB and the UE are set up by the init_nas_nos1 program and should have the following values: +* eNB_ip_addr set to 20 10.0.1.1 +* ue_ip_addr set to 20 10.0.1.2 + + + + + + + +[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) + +[oai softmodem features](FEATURE_SET.md) + +[oai softmodem build procedure](BUILD.md) + diff --git a/doc/L2NFAPI.md b/doc/L2NFAPI.md new file mode 100644 index 0000000000000000000000000000000000000000..4dcaaef3bcf8771a4ae8108b11dd31dcadedd79c --- /dev/null +++ b/doc/L2NFAPI.md @@ -0,0 +1,36 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">L2 nFAPI Simulator Usage</font></b> + </td> + </tr> +</table> + +This simulator allows to test L2 and above Layers using the nFAPI interface. + +**This simulator is available starting the `v1.0.0` release on the `master` branch.** + +Currently the only validated deployment by CI and developers is *with S1 interface and eNB / UEs are on the same machine*. + +Others deployments will be supported later after bug fixes and validation in the CI process. + +1. [With S1 -- eNB and UE on same machine](L2NFAPI_S1.md) + + + + + + + +[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) + +[oai softmodem features](FEATURE_SET.md) + +[oai softmodem build procedure](BUILD.md) + diff --git a/doc/L2NFAPI_S1.md b/doc/L2NFAPI_S1.md new file mode 100644 index 0000000000000000000000000000000000000000..c1c83211e19fedaa4e9c5b9ee8801053fb2ceeb0 --- /dev/null +++ b/doc/L2NFAPI_S1.md @@ -0,0 +1,304 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">L2 nFAPI Simulator (with S1 / same machine deployment)</font></b> + </td> + </tr> +</table> + +## Table of Contents ## + +1. [Environment](#1-environment) +2. [Prepare the EPC](#2-prepare-the-epc) +3. [Retrieve the OAI eNB-UE source code](#3-retrieve-the-oai-enb-ue-source-code) +4. [Setup of the USIM information in UE folder](#4-setup-of-the-usim-information-in-ue-folder) +5. [Setup of the Configuration files](#5-setup-of-the-configuration-files) + 1. [The eNB Configuration file](#51-the-enb-configuration-file) + 2. [The UE Configuration file](#52-the-ue-configuration-file) +6. [Bring Up a second loopback interface](#6-bring-up-a-second-loopback-interface) +7. [Build the eNB](#7-build-the-enb) +8. [Build the UE](#8-build-the-ue) +9. [Initialize the NAS UE Layer](#9-initialize-the-nas-ue-layer) +10. [Start the eNB](#10-start-the-enb) +11. [Start the UE](#11-start-the-ue) +12. [Test with ping](#12-test-with-ping) +13. [Limitations](#13-limitations) + +# 1. Environment # + +2 servers are used in this deployment. You can use Virtual Machines instead of each server; like it is done in the CI process. + +* Machine A contains the EPC. +* Machine B contains the OAI eNB and the OAI UE(s) + +Example of L2 nFAPI Simulator testing environment: + +<img src="../l2-nfapi-simulator/L2-sim-single-server-deployment.png" alt="" border=3> + +Note that the IP addresses are indicative and need to be adapted to your environment. + +# 2. Prepare the EPC # + +Create the environment for the EPC and register all **USIM** information into the **HSS** database. + +If you are using OAI-EPC ([see on GitHub](https://github.com/OPENAIRINTERFACE/openair-cn)), build **HSS/MME/SPGW** and create config files. + +# 3. Retrieve the OAI eNB-UE source code # + +The eNB and the UE executables will compiled into 2 separate folders on the same machine `B`. + +```bash +$ ssh sudousername@machineB +$ git clone https://gitlab.eurecom.fr/oai/openairinterface5g/ enb_folder +$ cd enb_folder +$ git checkout -f v1.0.0 +$ cd .. +$ cp -Rf enb_folder ue_folder +``` + +# 4. Setup of the USIM information in UE folder # + +```bash +$ ssh sudousername@machineB +$ cd ue_folder +# Edit openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf with your preferred editor +``` + +Edit the USIM information within this file in order to match the HSS database. They **HAVE TO** match: + +* PLMN+MSIN and IMSI of users table of HSS database **SHALL** be the same. +* OPC of this file and OPC of users table of HSS database **SHALL** be the same. +* USIM_API_K of this file and the key of users table of HSS database **SHALL** be the same. + +When testing multiple UEs, it is necessary to add other UEs information like described below for 2 Users. Only UE0 (first UE) information is written in the original file. + +``` +UE0: +{ + USER: { + IMEI="356113022094149"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="0000000001"; // <-- Modify here + USIM_API_K="8baf473f2f8fd09487cccbd7097c6862"; + OPC="e734f8734007d6c5ce7a0508809e7e9c"; + MSISDN="33611123456"; + }; +... +}; +// Copy the UE0 and edit +UE1: // <- Edit here +{ + USER: { + IMEI="356113022094149"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="0000000002"; // <-- Modify here + USIM_API_K="8baf473f2f8fd09487cccbd7097c6862"; + OPC="e734f8734007d6c5ce7a0508809e7e9c"; + MSISDN="33611123456"; + }; +... +}; +``` + +You can repeat the operation for as many users you want to test with. + +# 5. Setup of the Configuration files # + +**CAUTION: both proposed configuration files resides in the ci-scripts realm. You can copy them but you CANNOT push any modification on these 2 files as part of an MR without informing the CI team.** + +## 5.1. The eNB Configuration file ## + +```bash +$ ssh sudousername@machineB +$ cd enb_folder +# Edit ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf with your preferred editor +``` + +First verify the nFAPI interface setup on the 2nd loopback interface. + +``` +MACRLCs = ( + { + num_cc = 1; + local_s_if_name = "lo:"; // <-- HERE + remote_s_address = "127.0.0.1"; // <-- HERE + local_s_address = "127.0.0.2"; // <-- HERE + local_s_portc = 50001; + remote_s_portc = 50000; + local_s_portd = 50011; + remote_s_portd = 50010; + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + } +); +``` + +If you are testing more than 16 UEs, a proper setting on the RUs is necessary. **Note that this part is NOT present in the original configuration file**. + +``` +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 20 + att_rx = 0; + bands = [38]; + max_pdschReferenceSignalPower = -23; + max_rxgain = 116; + eNB_instances = [0]; + } +); +``` + +Last, the S1 interface shall be properly set. + +``` + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; // replace with 192.168.10.20 + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "ens3"; // replace with the proper interface name + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; // replace with 192.168.10.10 + ENB_INTERFACE_NAME_FOR_S1U = "ens3"; // replace with the proper interface name + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; // replace with 192.168.10.10 + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; // replace with 192.168.10.10 + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + + }; +``` + +## 5.2. The UE Configuration file ## + +```bash +$ ssh sudousername@machineB +$ cd ue_folder +# Edit ci-scripts/conf_files/ue.nfapi.conf with your preferred editor +``` + +Verify the nFAPI interface setup on the loopback interface. + +``` +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "lo"; // <- HERE + remote_n_address = "127.0.0.2"; // <- HERE + local_n_address = "127.0.0.1"; // <- HERE + local_n_portc = 50000; + remote_n_portc = 50001; + local_n_portd = 50010; + remote_n_portd = 50011; + } +); +``` + +# 6. Bring Up a second loopback interface # + +A second loopback interface is used to connect the eNB and the UEs. + +```bash +$ ssh sudousername@machineB +$ sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up +``` + +# 7. [Build OAI UE and eNodeB](BUILD.md) # + + + +# 8. Initialize the NAS UE Layer # + +Start the EPC on machine `A`. + +```bash +$ ssh sudousername@machineA +# Start the EPC +``` + +# 9. Start the eNB # + +In the first terminal (the one you used to build the eNB): + +```bash +$ ssh sudousername@machineB +$ cd enb_folder/cmake_targets +$ sudo -E ./lte_build_oai/build/lte-softmodem -O ../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf > enb.log 2>&1 +``` + +If you don't use redirection, you can test but many logs are printed on the console and this may affect performance of the L2-nFAPI simulator. + +We do recommend the redirection in steady mode once your setup is correct. + +# 10. Start the UE # + +In the second terminal (the one you used to build the UE): + +```bash +$ ssh sudousername@machineB +$ cd ue_folder/cmake_targets +# Test 64 UEs, 64 threads in FDD mode +$ sudo -E ./lte_build_oai/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums-ue-thread 64 > ue.log 2>&1 +# Test 64 UEs, 64 threads in TDD mode +$ sudo -E ./lte_build_oai/build/lte-uesoftmodem -O ../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 64 --nums-ue-thread 64 -T 1 > ue.log 2>&1 +# The "-T 1" option means TDD config +``` + +- The number of UEs can set by using `--num-ues` option and the maximum UE number is 255 (with the `--mu*` options, otherwise 16). +- The umber of threads can set with the `--nums-ue-thread`. This number **SHALL NOT** be greater than the number of UEs. +- How many UE that can be tested depends on hardware (server , PC, etc) performance in your environment. + +# 11. Test with ping # + +In a third terminal, after around 10 seconds, the UE(s) shall be connected to the eNB: + +```bash +$ ssh sudousername@machineA +# Ping UE0 IP address based on the EPC pool used: in this example: +$ ping -c 20 192.168.200.2 +# Ping UE1 IP address based on the EPC pool used: in this example: +$ ping -c 20 192.168.200.4 +``` + +# 12. Limitations # + +Testing on the CI process is currently limited at time of writing. Improvements will be made soon. + + + + + + + + + +[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) + +[oai softmodem features](FEATURE_SET.md) + +[oai softmodem build procedure](BUILD.md) + +[L2 nfapi simulator](L2NFAPI.md) diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md new file mode 100644 index 0000000000000000000000000000000000000000..314c2cc78bd7de484f3df3c68d5f39c7cc2683fb --- /dev/null +++ b/doc/RUNMODEM.md @@ -0,0 +1,67 @@ +<table style="border-collapse: collapse; border: none;"> + <tr style="border-collapse: collapse; border: none;"> + <td style="border-collapse: collapse; border: none;"> + <a href="http://www.openairinterface.org/"> + <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> + </img> + </a> + </td> + <td style="border-collapse: collapse; border: none; vertical-align: center;"> + <b><font size = "5">Running OAI Softmodem</font></b> + </td> + </tr> +</table> + +After you have [built the softmodem executables](BUILD.md) you can set your default directory to the build directory `cmake_targets/lte_build_oai/build/` and start testing some use cases. Below, the description of the different oai functionalities should help you choose the oai configuration that suits your need. + +# RF Simulator + +The rf simulator is a oai device replacing the radio heads (for example the USRP device). It allows connecting the oai UE and the oai eNodeB through a network interface carrying the time-domain samples, getting rid of over the air unpredictable perturbations. This is the ideal tool to check signal processing algorithms and protocols implementation. + +It is planned to enhance this simulator with the following functionalities: + +- Support for multiple UE connections,each UE being a `lte-uesoftmodem` instance. +- Support for multiple eNodeB for hand-over tests +- Support for channel modeling + + This is an easy use-case to setup and test, as no specific hardware is required. The [rfsimulator page](../targets/ARCH/rfsimulator/README.md ) contains the detailed documentation. + +# L2 nFAPI Simulator + +This simulator connects a eNodeB and UEs through a nfapi interface, short-cutting the L1 layer. The objective of this simulator is to allow multi UEs simulation, with a large number of UEs (ideally up to 255 ) .Here to ease the platform setup, UEs are simulated via a single `lte-uesoftmodem` instance. Today the CI tests just with one UE and architecture has to be reviewed to allow a number of UE above about 16. This work is on-going. + +As for the rf simulator, no specific hardware is required. The [L2 nfapi simlator page](L2NFAPI.md) contains the detailed documentation. + +# L1 Simulator + +The L1 simulator is using the ethernet fronthaul protocol, as used to connect a RRU and a RAU to connect UEs and a eNodeB. UEs are simulated in a single `lte-uesoftmodem` process, as for the nfapi simulator. + +The [L1 simulator page](L1SIM.md) contains the detailed documentation. + +## noS1 mode + +The noS1 mode is now available via the `--noS1`command line option. It can be used with simulators, described above, or when using oai with true RF boards. Only the oai UE can be connected to the oai eNodeB in noS1 mode. + +By default the noS1 mode is using linux tun interfaces to send or receive ip packets to/from the linux ip stack. using the `--nokrnmod 0`option you can enforce kernel modules instead of tun. + +noS1 code has been revisited, it has been tested with the rf simulator, and tun interfaces. More tests are on going and CI will soon include noS1 tests. + +# Running with a true radio head + +oai supports [number of deployment](FEATURE_SET.md) model, the following are tested in the CI: + +1. [Monolithic eNodeB](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/HowToConnectCOTSUEwithOAIeNBNew) where the whole signal processing is performed in a single process +2. if4p5 mode, where frequency domain samples are carried over ethernet, from the RRU which implement part of L1(FFT,IFFT,part of PRACH), to a RAU + + + + + + + +[oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) + +[oai softmodem features](FEATURE_SET.md) + +[oai softmodem build procedure](BUILD.md) + diff --git a/doc/images/L2-sim-single-server-deployment.png b/doc/images/L2-sim-single-server-deployment.png new file mode 100644 index 0000000000000000000000000000000000000000..d59efb73f3929e1710b3cd8c011733a3da4bbb8d Binary files /dev/null and b/doc/images/L2-sim-single-server-deployment.png differ diff --git a/doc/oai_enb_block_diagram.png b/doc/images/oai_enb_block_diagram.png similarity index 100% rename from doc/oai_enb_block_diagram.png rename to doc/images/oai_enb_block_diagram.png diff --git a/doc/images/oai_final_logo.png b/doc/images/oai_final_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d2cc79f71ff4dd6495c74011a3849b20f54f1927 Binary files /dev/null and b/doc/images/oai_final_logo.png differ diff --git a/doc/oai_lte_enb_func_split_arch.png b/doc/images/oai_lte_enb_func_split_arch.png similarity index 100% rename from doc/oai_lte_enb_func_split_arch.png rename to doc/images/oai_lte_enb_func_split_arch.png diff --git a/nfapi/oai_integration/nfapi.c b/nfapi/oai_integration/nfapi.c index 5a3bc804c1b7685ad1292413d71d3965a03339a1..4fc35fd951309bae126a53bf4818cfc7ccdf1352 100644 --- a/nfapi/oai_integration/nfapi.c +++ b/nfapi/oai_integration/nfapi.c @@ -21,31 +21,55 @@ #include <stdio.h> #include <pthread.h> +#include "nfapi/oai_integration/vendor_ext.h" +#include "common/utils/LOG/log.h" +static char nfapi_str_mode[6][24] = {"MONOLITHIC","PNF","VNF","UE_STUB_PNF","UE_STUB_OFFNET","<UNKNOWN NFAPI MODE>"}; -void set_thread_priority(int priority) -{ - //printf("%s(priority:%d)\n", __FUNCTION__, priority); +typedef struct { + nfapi_mode_t nfapi_mode; +} nfapi_params_t; - pthread_attr_t ptAttr; +static nfapi_params_t nfapi_params; +void set_thread_priority(int priority) { + //printf("%s(priority:%d)\n", __FUNCTION__, priority); + pthread_attr_t ptAttr; struct sched_param schedParam; schedParam.__sched_priority = priority; //79; - if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) - { + + if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) { printf("Failed to set scheduler to SCHED_RR\n"); } - if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) - { + if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) { printf("Failed to set pthread sched policy SCHED_RR\n"); } pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); - struct sched_param thread_params; thread_params.sched_priority = 20; - if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) - { + + if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) { printf("failed to set sched param\n"); } } + +char *nfapi_get_strmode(void) { + if (nfapi_params.nfapi_mode > NFAPI_MODE_UNKNOWN) + return nfapi_str_mode[NFAPI_MODE_UNKNOWN]; + + return nfapi_str_mode[nfapi_params.nfapi_mode]; +} + +void nfapi_logmode() { + LOG_I(ENB_APP,"nfapi running mode: %s\n",nfapi_get_strmode()); +} + +nfapi_mode_t nfapi_getmode(void) { + return nfapi_params.nfapi_mode; +} + +void nfapi_setmode(nfapi_mode_t nfapi_mode) { + nfapi_params.nfapi_mode = nfapi_mode; + nfapi_logmode(); +} diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 78c058ad007229b775a8558b3eb22c7f4ef00432..a4b83e613b3c5685ab574ce84c30aad521916c67 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -28,6 +28,7 @@ #include <unistd.h> #include "debug.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "nfapi_pnf_interface.h" #include "nfapi.h" #include "nfapi_pnf.h" @@ -57,7 +58,7 @@ extern RAN_CONTEXT_t RC; #define _GNU_SOURCE -extern void phy_init_RU(RU_t*); +extern void phy_init_RU(RU_t *); extern int config_sync_var; extern pthread_cond_t nfapi_sync_cond; @@ -76,9 +77,9 @@ extern void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame, int subfra extern void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); extern void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu); -extern uint8_t nfapi_mode; -nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10]; // [frame][subframe][max_num_pdus] + +nfapi_tx_request_pdu_t *tx_request_pdu[1023][10][10]; // [frame][subframe][max_num_pdus] uint8_t tx_pdus[32][8][4096]; @@ -90,11 +91,11 @@ nfapi_pnf_param_response_t g_pnf_param_resp; nfapi_pnf_p7_config_t *p7_config_g = NULL; -void* pnf_allocate(size_t size) { +void *pnf_allocate(size_t size) { return malloc(size); } -void pnf_deallocate(void* ptr) { +void pnf_deallocate(void *ptr) { free(ptr); } @@ -109,36 +110,36 @@ typedef struct { } udp_data; typedef struct { - uint16_t index; - uint16_t id; - uint8_t rfs[2]; - uint8_t excluded_rfs[2]; + uint16_t index; + uint16_t id; + uint8_t rfs[2]; + uint8_t excluded_rfs[2]; - udp_data udp; + udp_data udp; - char local_addr[80]; - int local_port; + char local_addr[80]; + int local_port; - char* remote_addr; - int remote_port; + char *remote_addr; + int remote_port; - uint8_t duplex_mode; - uint16_t dl_channel_bw_support; - uint16_t ul_channel_bw_support; - uint8_t num_dl_layers_supported; - uint8_t num_ul_layers_supported; - uint16_t release_supported; - uint8_t nmm_modes_supported; + uint8_t duplex_mode; + uint16_t dl_channel_bw_support; + uint16_t ul_channel_bw_support; + uint8_t num_dl_layers_supported; + uint8_t num_ul_layers_supported; + uint16_t release_supported; + uint8_t nmm_modes_supported; - uint8_t dl_ues_per_subframe; - uint8_t ul_ues_per_subframe; + uint8_t dl_ues_per_subframe; + uint8_t ul_ues_per_subframe; - uint8_t first_subframe_ind; + uint8_t first_subframe_ind; - // timing information recevied from the vnf - uint8_t timing_window; - uint8_t timing_info_mode; - uint8_t timing_info_period; + // timing information recevied from the vnf + uint8_t timing_window; + uint8_t timing_info_mode; + uint8_t timing_info_period; } phy_info; @@ -158,36 +159,36 @@ typedef struct { typedef struct { - int release; - phy_info phys[2]; - rf_info rfs[2]; - - uint8_t sync_mode; - uint8_t location_mode; - uint8_t location_coordinates[6]; - uint32_t dl_config_timing; - uint32_t ul_config_timing; - uint32_t tx_timing; - uint32_t hi_dci0_timing; - - uint16_t max_phys; - uint16_t max_total_bw; - uint16_t max_total_dl_layers; - uint16_t max_total_ul_layers; - uint8_t shared_bands; - uint8_t shared_pa; - int16_t max_total_power; - uint8_t oui; - - uint8_t wireshark_test_mode; + int release; + phy_info phys[2]; + rf_info rfs[2]; + + uint8_t sync_mode; + uint8_t location_mode; + uint8_t location_coordinates[6]; + uint32_t dl_config_timing; + uint32_t ul_config_timing; + uint32_t tx_timing; + uint32_t hi_dci0_timing; + + uint16_t max_phys; + uint16_t max_total_bw; + uint16_t max_total_dl_layers; + uint16_t max_total_ul_layers; + uint8_t shared_bands; + uint8_t shared_pa; + int16_t max_total_power; + uint8_t oui; + + uint8_t wireshark_test_mode; } pnf_info; typedef struct { uint16_t phy_id; - nfapi_pnf_config_t* config; - phy_info* phy; - nfapi_pnf_p7_config_t* p7_config; + nfapi_pnf_config_t *config; + phy_info *phy; + nfapi_pnf_p7_config_t *p7_config; } pnf_phy_user_data_t; static pnf_info pnf; @@ -195,32 +196,34 @@ static pthread_t pnf_start_pthread; int nfapitooai_level(int nfapi_level) { switch(nfapi_level) { - case NFAPI_TRACE_ERROR: - return LOG_ERR; - case NFAPI_TRACE_WARN: - return LOG_WARNING; + case NFAPI_TRACE_ERROR: + return LOG_ERR; + + case NFAPI_TRACE_WARN: + return LOG_WARNING; + case NFAPI_TRACE_NOTE: - return LOG_INFO; - case NFAPI_TRACE_INFO: - return LOG_DEBUG; - } + return LOG_INFO; + + case NFAPI_TRACE_INFO: + return LOG_DEBUG; + } + return LOG_ERR; } -void pnf_nfapi_trace(nfapi_trace_level_t nfapi_level, const char* message, ...) { +void pnf_nfapi_trace(nfapi_trace_level_t nfapi_level, const char *message, ...) { va_list args; - va_start(args, message); - nfapi_log("FILE>", "FUNC", 999, PHY, nfapitooai_level(nfapi_level), message, args); + VLOG( NFAPI_PNF, nfapitooai_level(nfapi_level), message, args); va_end(args); } void pnf_set_thread_priority(int priority) { - pthread_attr_t ptAttr; - struct sched_param schedParam; schedParam.__sched_priority = priority; + if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) { printf("failed to set SCHED_RR\n"); } @@ -230,36 +233,29 @@ void pnf_set_thread_priority(int priority) { } pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); - struct sched_param thread_params; thread_params.sched_priority = 20; + if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) { printf("failed to set sched param\n"); } } -void* pnf_p7_thread_start(void* ptr) { +void *pnf_p7_thread_start(void *ptr) { NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P7 THREAD %s\n", __FUNCTION__); - pnf_set_thread_priority(79); - - nfapi_pnf_p7_config_t* config = (nfapi_pnf_p7_config_t*)ptr; + nfapi_pnf_p7_config_t *config = (nfapi_pnf_p7_config_t *)ptr; nfapi_pnf_p7_start(config); - return 0; } -int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req) { - +int pnf_param_request(nfapi_pnf_config_t *config, nfapi_pnf_param_request_t *req) { printf("[PNF] pnf param request\n"); - nfapi_pnf_param_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE; resp.error_code = NFAPI_MSG_OK; - - pnf_info* pnf = (pnf_info*)(config->user_data); - + pnf_info *pnf = (pnf_info *)(config->user_data); resp.pnf_param_general.tl.tag = NFAPI_PNF_PARAM_GENERAL_TAG; resp.pnf_param_general.nfapi_sync_mode = pnf->sync_mode; resp.pnf_param_general.location_mode = pnf->location_mode; @@ -274,25 +270,25 @@ int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req resp.pnf_param_general.shared_bands = pnf->shared_bands; resp.pnf_param_general.shared_pa = pnf->shared_pa; resp.pnf_param_general.maximum_total_power = pnf->max_total_power; - resp.pnf_phy.tl.tag = NFAPI_PNF_PHY_TAG; resp.pnf_phy.number_of_phys = 1; for(int i = 0; i < 1; ++i) { - resp.pnf_phy.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy.phy[i].phy_config_index = pnf->phys[i].index; resp.pnf_phy.phy[i].downlink_channel_bandwidth_supported = pnf->phys[i].dl_channel_bw_support; resp.pnf_phy.phy[i].uplink_channel_bandwidth_supported = pnf->phys[i].ul_channel_bw_support; resp.pnf_phy.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported; resp.pnf_phy.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported; resp.pnf_phy.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported; resp.pnf_phy.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported; - resp.pnf_phy.phy[i].number_of_rfs = 2; + for(int j = 0; j < 1; ++j) { resp.pnf_phy.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j]; } resp.pnf_phy.phy[i].number_of_rf_exclusions = 0; + for(int j = 0; j < 0; ++j) { resp.pnf_phy.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j]; } @@ -302,9 +298,9 @@ int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req resp.pnf_rf.number_of_rfs = 2; for(int i = 0; i < 2; ++i) { - resp.pnf_rf.rf[i].rf_config_index = pnf->rfs[i].index; + resp.pnf_rf.rf[i].rf_config_index = pnf->rfs[i].index; resp.pnf_rf.rf[i].band = pnf->rfs[i].band; - resp.pnf_rf.rf[i].maximum_transmit_power = pnf->rfs[i].max_transmit_power; + resp.pnf_rf.rf[i].maximum_transmit_power = pnf->rfs[i].max_transmit_power; resp.pnf_rf.rf[i].minimum_transmit_power = pnf->rfs[i].min_transmit_power; resp.pnf_rf.rf[i].number_of_antennas_suppported = pnf->rfs[i].num_antennas_supported; resp.pnf_rf.rf[i].minimum_downlink_frequency = pnf->rfs[i].min_downlink_frequency; @@ -317,9 +313,8 @@ int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req resp.pnf_phy_rel10.tl.tag = NFAPI_PNF_PHY_REL10_TAG; resp.pnf_phy_rel10.number_of_phys = 1; - for(int i = 0; i < 1; ++i) - { - resp.pnf_phy_rel10.phy[i].phy_config_index = pnf->phys[i].index; + for(int i = 0; i < 1; ++i) { + resp.pnf_phy_rel10.phy[i].phy_config_index = pnf->phys[i].index; resp.pnf_phy_rel10.phy[i].transmission_mode_7_supported = 0; resp.pnf_phy_rel10.phy[i].transmission_mode_8_supported = 1; resp.pnf_phy_rel10.phy[i].two_antenna_ports_for_pucch = 0; @@ -334,7 +329,7 @@ int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req resp.pnf_phy_rel11.number_of_phys = 1; for(int i = 0; i < 1; ++i) { - resp.pnf_phy_rel11.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel11.phy[i].phy_config_index = pnf->phys[i].index; resp.pnf_phy_rel11.phy[i].edpcch_supported = 0; resp.pnf_phy_rel11.phy[i].multi_ack_csi_reporting = 1; resp.pnf_phy_rel11.phy[i].pucch_tx_diversity = 0; @@ -348,7 +343,7 @@ int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req resp.pnf_phy_rel12.number_of_phys = 1; for(int i = 0; i < 1; ++i) { - resp.pnf_phy_rel12.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel12.phy[i].phy_config_index = pnf->phys[i].index; resp.pnf_phy_rel12.phy[i].csi_subframe_set = 0; resp.pnf_phy_rel12.phy[i].enhanced_4tx_codebook = 2; resp.pnf_phy_rel12.phy[i].drs_supported = 0; @@ -363,7 +358,7 @@ int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req resp.pnf_phy_rel13.number_of_phys = 1; for(int i = 0; i < 1; ++i) { - resp.pnf_phy_rel13.phy[i].phy_config_index = pnf->phys[i].index; + resp.pnf_phy_rel13.phy[i].phy_config_index = pnf->phys[i].index; resp.pnf_phy_rel13.phy[i].pucch_format4_supported = 0; resp.pnf_phy_rel13.phy[i].pucch_format5_supported = 1; resp.pnf_phy_rel13.phy[i].more_than_5_ca_support = 0; @@ -380,14 +375,15 @@ int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req resp.pnf_phy_rel13_nb_iot.number_of_phys = 1; for(int i = 0; i < 1; ++i) { - resp.pnf_phy_rel13_nb_iot.phy[i].phy_config_index = pnf->phys[i].index; - + resp.pnf_phy_rel13_nb_iot.phy[i].phy_config_index = pnf->phys[i].index; resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rfs = 1; + for(int j = 0; j < 1; ++j) { resp.pnf_phy_rel13_nb_iot.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j]; } resp.pnf_phy_rel13_nb_iot.phy[i].number_of_rf_exclusions = 1; + for(int j = 0; j < 1; ++j) { resp.pnf_phy_rel13_nb_iot.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j]; } @@ -400,51 +396,39 @@ int pnf_param_request(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req } nfapi_pnf_pnf_param_resp(config, &resp); - return 0; } -int pnf_config_request(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req) { - +int pnf_config_request(nfapi_pnf_config_t *config, nfapi_pnf_config_request_t *req) { printf("[PNF] pnf config request\n"); - - pnf_info* pnf = (pnf_info*)(config->user_data); - + pnf_info *pnf = (pnf_info *)(config->user_data); phy_info *phy = pnf->phys; phy->id = req->pnf_phy_rf_config.phy_rf_config[0].phy_id; printf("[PNF] pnf config request assigned phy_id %d to phy_config_index %d\n", phy->id, req->pnf_phy_rf_config.phy_rf_config[0].phy_config_index); - nfapi_pnf_config_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; resp.error_code = NFAPI_MSG_OK; nfapi_pnf_pnf_config_resp(config, &resp); printf("[PNF] Sent pnf_config_resp\n"); - return 0; } -void nfapi_send_pnf_start_resp(nfapi_pnf_config_t* config, uint16_t phy_id) { - +void nfapi_send_pnf_start_resp(nfapi_pnf_config_t *config, uint16_t phy_id) { printf("Sending NFAPI_START_RESPONSE config:%p phy_id:%d\n", config, phy_id); - nfapi_start_response_t start_resp; memset(&start_resp, 0, sizeof(start_resp)); start_resp.header.message_id = NFAPI_START_RESPONSE; start_resp.header.phy_id = phy_id; start_resp.error_code = NFAPI_MSG_OK; - nfapi_pnf_start_resp(config, &start_resp); } -int pnf_start_request(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req) { - +int pnf_start_request(nfapi_pnf_config_t *config, nfapi_pnf_start_request_t *req) { printf("Received NFAPI_PNF_START_REQUEST\n"); - - pnf_info* pnf = (pnf_info*)(config->user_data); - + pnf_info *pnf = (pnf_info *)(config->user_data); // start all phys that have been configured - phy_info* phy = pnf->phys; + phy_info *phy = pnf->phys; if(phy->id != 0) { nfapi_pnf_start_response_t resp; @@ -454,79 +438,62 @@ int pnf_start_request(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req nfapi_pnf_pnf_start_resp(config, &resp); printf("[PNF] Sent NFAPI_PNF_START_RESP\n"); } + return 0; } -int pnf_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_stop_request_t* req) { - +int pnf_stop_request(nfapi_pnf_config_t *config, nfapi_pnf_stop_request_t *req) { printf("[PNF] Received NFAPI_PNF_STOP_REQ\n"); - nfapi_pnf_stop_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_PNF_STOP_RESPONSE; resp.error_code = NFAPI_MSG_OK; nfapi_pnf_pnf_stop_resp(config, &resp); printf("[PNF] Sent NFAPI_PNF_STOP_REQ\n"); - return 0; } -int param_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req) { - +int param_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_param_request_t *req) { printf("[PNF] Received NFAPI_PARAM_REQUEST phy_id:%d\n", req->header.phy_id); - //pnf_info* pnf = (pnf_info*)(config->user_data); - nfapi_param_response_t nfapi_resp; - - pnf_info* pnf = (pnf_info*)(config->user_data); - + pnf_info *pnf = (pnf_info *)(config->user_data); memset(&nfapi_resp, 0, sizeof(nfapi_resp)); nfapi_resp.header.message_id = NFAPI_PARAM_RESPONSE; nfapi_resp.header.phy_id = req->header.phy_id; nfapi_resp.error_code = 0; // DJP - what value??? - struct sockaddr_in pnf_p7_sockaddr; - pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(pnf->phys[0].local_addr); nfapi_resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_PNF_ADDRESS_IPV4_TAG; memcpy(nfapi_resp.nfapi_config.p7_pnf_address_ipv4.address, &pnf_p7_sockaddr.sin_addr.s_addr, 4); nfapi_resp.num_tlv++; - // P7 PNF Port nfapi_resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NFAPI_P7_PNF_PORT_TAG; nfapi_resp.nfapi_config.p7_pnf_port.value = 32123; // DJP - hard code alert!!!! FIXME TODO nfapi_resp.num_tlv++; - nfapi_pnf_param_resp(config, &nfapi_resp); - printf("[PNF] Sent NFAPI_PARAM_RESPONSE phy_id:%d number_of_tlvs:%u\n", req->header.phy_id, nfapi_resp.num_tlv); - printf("[PNF] param request .. exit\n"); - return 0; } -int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req) { - +int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_config_request_t *req) { printf("[PNF] Received NFAPI_CONFIG_REQ phy_id:%d\n", req->header.phy_id); - - pnf_info* pnf = (pnf_info*)(config->user_data); + pnf_info *pnf = (pnf_info *)(config->user_data); uint8_t num_tlv = 0; //struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - // In the case of nfapi_mode = 3 (UE = PNF) we should not have dependency on any eNB var. So we aim // to keep only the necessary just to keep the nfapi FSM rolling by sending a dummy response. LTE_DL_FRAME_PARMS *fp; - if (nfapi_mode!=3) { - struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - fp = &eNB->frame_parms; - } - else{ - fp = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS)); + + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; + fp = &eNB->frame_parms; + } else { + fp = (LTE_DL_FRAME_PARMS *) malloc(sizeof(LTE_DL_FRAME_PARMS)); } - phy_info* phy_info = pnf->phys; + phy_info *phy_info = pnf->phys; if(req->nfapi_config.timing_window.tl.tag == NFAPI_NFAPI_TIMING_WINDOW_TAG) { phy_info->timing_window = req->nfapi_config.timing_window.value; @@ -576,9 +543,8 @@ int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfap fp->dl_CarrierFreq = from_earfcn(fp->eutra_band, req->nfapi_config.earfcn.value); fp->ul_CarrierFreq = fp->dl_CarrierFreq - (get_uldl_offset(fp->eutra_band) * 1e5); num_tlv++; - - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() earfcn:%u dl_carrierFreq:%u ul_CarrierFreq:%u band:%u N_RB_DL:%u\n", - __FUNCTION__, req->nfapi_config.earfcn.value, fp->dl_CarrierFreq, fp->ul_CarrierFreq, pnf->rfs[0].band, fp->N_RB_DL); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() earfcn:%u dl_carrierFreq:%u ul_CarrierFreq:%u band:%u N_RB_DL:%u\n", + __FUNCTION__, req->nfapi_config.earfcn.value, fp->dl_CarrierFreq, fp->ul_CarrierFreq, pnf->rfs[0].band, fp->N_RB_DL); } if (req->subframe_config.duplex_mode.tl.tag == NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG) { @@ -682,29 +648,23 @@ int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfap num_tlv++; } - if(nfapi_mode!=3) { - printf("[PNF] CONFIG_REQUEST[num_tlv:%d] TLVs processed:%d\n", req->num_tlv, num_tlv); - - printf("[PNF] Simulating PHY CONFIG - DJP\n"); - PHY_Config_t phy_config; - phy_config.Mod_id = 0; - phy_config.CC_id=0; - phy_config.cfg = req; - - phy_config_request(&phy_config); - - dump_frame_parms(fp); + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + printf("[PNF] CONFIG_REQUEST[num_tlv:%d] TLVs processed:%d\n", req->num_tlv, num_tlv); + printf("[PNF] Simulating PHY CONFIG - DJP\n"); + PHY_Config_t phy_config; + phy_config.Mod_id = 0; + phy_config.CC_id=0; + phy_config.cfg = req; + phy_config_request(&phy_config); + dump_frame_parms(fp); } phy_info->remote_port = req->nfapi_config.p7_vnf_port.value; - struct sockaddr_in vnf_p7_sockaddr; memcpy(&vnf_p7_sockaddr.sin_addr.s_addr, &(req->nfapi_config.p7_vnf_address_ipv4.address[0]), 4); phy_info->remote_addr = inet_ntoa(vnf_p7_sockaddr.sin_addr); - - printf("[PNF] %d vnf p7 %s:%d timing %d %d %d\n", phy_info->id, phy_info->remote_addr, phy_info->remote_port, - phy_info->timing_window, phy_info->timing_info_mode, phy_info->timing_info_period); - + printf("[PNF] %d vnf p7 %s:%d timing %d %d %d\n", phy_info->id, phy_info->remote_addr, phy_info->remote_port, + phy_info->timing_window, phy_info->timing_info_mode, phy_info->timing_info_period); nfapi_config_response_t nfapi_resp; memset(&nfapi_resp, 0, sizeof(nfapi_resp)); nfapi_resp.header.message_id = NFAPI_CONFIG_RESPONSE; @@ -712,71 +672,54 @@ int config_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfap nfapi_resp.error_code = 0; // DJP - some value resp->error_code; nfapi_pnf_config_resp(config, &nfapi_resp); printf("[PNF] Sent NFAPI_CONFIG_RESPONSE phy_id:%d\n", phy_info->id); - if(nfapi_mode ==3) - free(fp); + + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) + free(fp); return 0; } -nfapi_p7_message_header_t* pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size) { - +nfapi_p7_message_header_t *pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size) { if(message_id == P7_VENDOR_EXT_REQ) { (*msg_size) = sizeof(vendor_ext_p7_req); - return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_req)); + return (nfapi_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_req)); } return 0; } -void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header) { - +void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) { free(header); } -int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req) { - +int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) { if (req->hi_dci0_request_body.number_of_dci == 0 && req->hi_dci0_request_body.number_of_hi == 0) LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi); //phy_info* phy = (phy_info*)(pnf_p7->user_data); - struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; L1_rxtx_proc_t *proc = &eNB->proc.L1_proc; for (int i=0; i<req->hi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++) { - //LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); - if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) { - //LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_DCI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); - nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu = &req->hi_dci0_request_body.hi_dci0_pdu_list[i]; - handle_nfapi_hi_dci0_dci_pdu(eNB,NFAPI_SFNSF2SFN(req->sfn_sf),NFAPI_SFNSF2SF(req->sfn_sf),proc,hi_dci0_req_pdu); - eNB->pdcch_vars[NFAPI_SFNSF2SF(req->sfn_sf)&1].num_dci++; - } else if (req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type == NFAPI_HI_DCI0_HI_PDU_TYPE) { - LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_HI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i); - nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu = &req->hi_dci0_request_body.hi_dci0_pdu_list[i]; - handle_nfapi_hi_dci0_hi_pdu(eNB, NFAPI_SFNSF2SFN(req->sfn_sf),NFAPI_SFNSF2SF(req->sfn_sf), proc, hi_dci0_req_pdu); - } else { - LOG_E(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), i, req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type); - } } return 0; } -int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req) { - +int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) { if (RC.ru == 0) { return -1; } @@ -789,65 +732,51 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request return -3; } - if (sync_var != 0) { + if (sync_var != 0) { NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy subframe?\n", __FUNCTION__); return -4; } int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); int sf = NFAPI_SFNSF2SF(req->sfn_sf); - struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; L1_rxtx_proc_t *proc = &eNB->proc.L1_proc; - nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list; + nfapi_dl_config_request_pdu_t *dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list; LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[sf&1]; - pdcch_vars->num_pdcch_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols; pdcch_vars->num_dci = 0; - if (req->dl_config_request_body.number_dci || + if (req->dl_config_request_body.number_dci || req->dl_config_request_body.number_pdu || req->dl_config_request_body.number_pdsch_rnti) - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d sfn_sf:%d pdcch:%u dl_cfg[dci:%u pdus:%d pdsch_rnti:%d] pcfich:%u\n", - __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, - NFAPI_SFNSF2DEC(req->sfn_sf), - req->dl_config_request_body.number_pdcch_ofdm_symbols, - req->dl_config_request_body.number_dci, - req->dl_config_request_body.number_pdu, - req->dl_config_request_body.number_pdsch_rnti, - req->dl_config_request_body.transmission_power_pcfich); - - for (int i=0;i<req->dl_config_request_body.number_pdu;i++) { - + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d sfn_sf:%d pdcch:%u dl_cfg[dci:%u pdus:%d pdsch_rnti:%d] pcfich:%u\n", + __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, + NFAPI_SFNSF2DEC(req->sfn_sf), + req->dl_config_request_body.number_pdcch_ofdm_symbols, + req->dl_config_request_body.number_dci, + req->dl_config_request_body.number_pdu, + req->dl_config_request_body.number_pdsch_rnti, + req->dl_config_request_body.transmission_power_pcfich); + + for (int i=0; i<req->dl_config_request_body.number_pdu; i++) { NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d pdcch_vars->num_dci:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size,pdcch_vars->num_dci); if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) { - handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(req->sfn_sf),NFAPI_SFNSF2SF(req->sfn_sf),proc,&dl_config_pdu_list[i]); - pdcch_vars->num_dci++; // Is actually number of DCI PDUs - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() pdcch_vars->num_dci:%d\n", __FUNCTION__, pdcch_vars->num_dci); - } else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) { - nfapi_dl_config_bch_pdu *bch_pdu = &dl_config_pdu_list[i].bch_pdu; uint16_t pdu_index = bch_pdu->bch_pdu_rel8.pdu_index; if (tx_request_pdu[sfn][sf][pdu_index] != NULL) { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PDU:%d BCH: pdu_index:%u pdu_length:%d sdu_length:%d BCH_SDU:%x,%x,%x\n", __FUNCTION__, i, pdu_index, bch_pdu->bch_pdu_rel8.length, tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_length, sdu[0], sdu[1], sdu[2]); - handle_nfapi_bch_pdu(eNB, proc, &dl_config_pdu_list[i], tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_data); - eNB->pbch_configured=1; - } else { - - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() BCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pdu_index); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() BCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pdu_index); } } else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) { - nfapi_dl_config_dlsch_pdu *dlsch_pdu = &dl_config_pdu_list[i].dlsch_pdu; nfapi_dl_config_dlsch_pdu_rel8_t *rel8_pdu = &dlsch_pdu->dlsch_pdu_rel8; nfapi_tx_request_pdu_t *tx_pdu = tx_request_pdu[sfn][sf][rel8_pdu->pdu_index]; @@ -859,23 +788,19 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[UE_id][0]; //LTE_eNB_DLSCH_t *dlsch1 = eNB->dlsch[UE_id][1]; int harq_pid = dlsch0->harq_ids[sfn%2][sf]; + if(harq_pid >= dlsch0->Mdlharq) { LOG_E(PHY,"pnf_phy_dl_config_req illegal harq_pid %d\n", harq_pid); return(-1); } + uint8_t *dlsch_sdu = tx_pdus[UE_id][harq_pid]; - memcpy(dlsch_sdu, tx_pdu->segments[0].segment_data, tx_pdu->segments[0].segment_length); - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols); - handle_nfapi_dlsch_pdu( eNB, sfn,sf, &eNB->proc.L1_proc, &dl_config_pdu_list[i], rel8_pdu->transport_blocks-1, dlsch_sdu); - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), rel8_pdu->pdu_index); } - } else { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_config_pdu_list[i].pdu_type); } @@ -887,8 +812,7 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request return 0; } -int pnf_phy_tx_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) { - +int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) { uint16_t sfn = NFAPI_SFNSF2SFN(req->sfn_sf); uint16_t sf = NFAPI_SFNSF2SF(req->sfn_sf); @@ -898,15 +822,14 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) { if (req->tx_request_body.tl.tag==NFAPI_TX_REQUEST_BODY_TAG) { for (int i=0; i<req->tx_request_body.number_of_pdus; i++) { LOG_D(PHY,"%s() SFN/SF:%d%d number_of_pdus:%d [PDU:%d] pdu_length:%d pdu_index:%d num_segments:%d\n", - __FUNCTION__, - sfn, sf, - req->tx_request_body.number_of_pdus, - i, - req->tx_request_body.tx_pdu_list[i].pdu_length, - req->tx_request_body.tx_pdu_list[i].pdu_index, - req->tx_request_body.tx_pdu_list[i].num_segments - ); - + __FUNCTION__, + sfn, sf, + req->tx_request_body.number_of_pdus, + i, + req->tx_request_body.tx_pdu_list[i].pdu_length, + req->tx_request_body.tx_pdu_list[i].pdu_index, + req->tx_request_body.tx_pdu_list[i].num_segments + ); tx_request_pdu[sfn][sf][i] = &req->tx_request_body.tx_pdu_list[i]; } } @@ -914,15 +837,14 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) { return 0; } -int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req) { - - if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n", - __FUNCTION__, - NFAPI_SFNSF2DEC(req->sfn_sf), - req->ul_config_request_body.number_of_pdus, - req->ul_config_request_body.rach_prach_frequency_resources, - req->ul_config_request_body.srs_present - ); +int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) { + if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(req->sfn_sf), + req->ul_config_request_body.number_of_pdus, + req->ul_config_request_body.rach_prach_frequency_resources, + req->ul_config_request_body.srs_present + ); if (RC.ru == 0) { return -1; @@ -936,32 +858,29 @@ int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request return -3; } - if (sync_var != 0) { + if (sync_var != 0) { NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy subframe?\n", __FUNCTION__); return -4; } uint16_t curr_sfn = NFAPI_SFNSF2SFN(req->sfn_sf); uint16_t curr_sf = NFAPI_SFNSF2SF(req->sfn_sf); - struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; L1_rxtx_proc_t *proc = &eNB->proc.L1_proc; - nfapi_ul_config_request_pdu_t* ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list; + nfapi_ul_config_request_pdu_t *ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list; - for (int i=0;i<req->ul_config_request_body.number_of_pdus;i++) { + for (int i=0; i<req->ul_config_request_body.number_of_pdus; i++) { //LOG_D(PHY, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, ul_config_pdu_list[i].pdu_size); - if ( - ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE || - ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE || - ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE || - ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE || - ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE || - ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE || - ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE - ) { + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE || + ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE + ) { //LOG_D(PHY, "%s() handle_nfapi_ul_pdu() for PDU:%d\n", __FUNCTION__, i); - handle_nfapi_ul_pdu(eNB,proc,&ul_config_pdu_list[i],curr_sfn,curr_sf,req->ul_config_request_body.srs_present); } else { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_config_pdu_list[i].pdu_type); @@ -971,54 +890,59 @@ int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request return 0; } -int pnf_phy_lbt_dl_config_req(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req) { +int pnf_phy_lbt_dl_config_req(nfapi_pnf_p7_config_t *config, nfapi_lbt_dl_config_request_t *req) { //printf("[PNF] lbt dl config request\n"); return 0; } -int pnf_phy_vendor_ext(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg) { +int pnf_phy_vendor_ext(nfapi_pnf_p7_config_t *config, nfapi_p7_message_header_t *msg) { if(msg->message_id == P7_VENDOR_EXT_REQ) { //vendor_ext_p7_req* req = (vendor_ext_p7_req*)msg; //printf("[PNF] vendor request (1:%d 2:%d)\n", req->dummy1, req->dummy2); } else { printf("[PNF] unknown vendor ext\n"); } + return 0; } -int pnf_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codex) { +int pnf_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codex) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); if(header->message_id == P7_VENDOR_EXT_IND) { - vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)(header); + vendor_ext_p7_ind *ind = (vendor_ext_p7_ind *)(header); + if(!push16(ind->error_code, ppWritePackedMsg, end)) return 0; return 1; } + return -1; } -int pnf_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* codec) { +int pnf_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t *codec) { if(header->message_id == P7_VENDOR_EXT_REQ) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); - vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header); + vendor_ext_p7_req *req = (vendor_ext_p7_req *)(header); + if(!(pull16(ppReadPackedMessage, &req->dummy1, end) && - pull16(ppReadPackedMessage, &req->dummy2, end))) + pull16(ppReadPackedMessage, &req->dummy2, end))) return 0; + return 1; } + return -1; } -int pnf_phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t* end, void** ve, nfapi_p7_codec_config_t* config) { +int pnf_phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p7_codec_config_t *config) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_phy_unpack_vendor_extension_tlv\n"); - - switch(tl->tag) - { + switch(tl->tag) { case VENDOR_EXT_TLV_1_TAG: *ve = malloc(sizeof(vendor_ext_tlv_1)); - if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_1*)(*ve))->dummy, end)) - return 0; + + if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_1 *)(*ve))->dummy, end)) + return 0; return 1; break; @@ -1027,22 +951,21 @@ int pnf_phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMe return -1; } -int pnf_phy_pack_vendor_extention_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p7_codec_config_t* config) { +int pnf_phy_pack_vendor_extention_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) { //printf("%s\n", __FUNCTION__); (void)ve; (void)ppWritePackedMsg; return -1; } -int pnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* config) { +int pnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p4_p5_codec_config_t *config) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_sim_unpack_vendor_extension_tlv\n"); - - switch(tl->tag) - { + switch(tl->tag) { case VENDOR_EXT_TLV_2_TAG: *ve = malloc(sizeof(vendor_ext_tlv_2)); - if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_2*)(*ve))->dummy, end)) - return 0; + + if(!pull32(ppReadPackedMessage, &((vendor_ext_tlv_2 *)(*ve))->dummy, end)) + return 0; return 1; break; @@ -1051,7 +974,7 @@ int pnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMe return -1; } -int pnf_sim_pack_vendor_extention_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { +int pnf_sim_pack_vendor_extention_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) { //printf("%s\n", __FUNCTION__); (void)ve; (void)ppWritePackedMsg; @@ -1063,41 +986,29 @@ nfapi_tx_request_t dummy_tx_req; nfapi_pnf_p7_subframe_buffer_t dummy_subframe; -int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req) { - +int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_start_request_t *req) { printf("[PNF] Received NFAPI_START_REQ phy_id:%d\n", req->header.phy_id); - nfapi_set_trace_level(NFAPI_TRACE_INFO); - - pnf_info* pnf = (pnf_info*)(config->user_data); - - phy_info* phy_info = pnf->phys; - - nfapi_pnf_p7_config_t* p7_config = nfapi_pnf_p7_config_create(); - + pnf_info *pnf = (pnf_info *)(config->user_data); + phy_info *phy_info = pnf->phys; + nfapi_pnf_p7_config_t *p7_config = nfapi_pnf_p7_config_create(); p7_config->phy_id = phy->phy_id; - p7_config->remote_p7_port = phy_info->remote_port; p7_config->remote_p7_addr = phy_info->remote_addr; p7_config->local_p7_port = 32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port; //DJP p7_config->local_p7_addr = (char*)phy_info->local_addr.c_str(); p7_config->local_p7_addr = phy_info->local_addr; - printf("[PNF] P7 remote:%s:%d local:%s:%d\n", p7_config->remote_p7_addr, p7_config->remote_p7_port, p7_config->local_p7_addr, p7_config->local_p7_port); - p7_config->user_data = phy_info; - p7_config->malloc = &pnf_allocate; p7_config->free = &pnf_deallocate; p7_config->codec_config.allocate = &pnf_allocate; p7_config->codec_config.deallocate = &pnf_deallocate; - p7_config->trace = &pnf_nfapi_trace; - phy->user_data = p7_config; - p7_config->subframe_buffer_size = phy_info->timing_window; printf("subframe_buffer_size configured using phy_info->timing_window:%d\n", phy_info->timing_window); + if(phy_info->timing_info_mode & 0x1) { p7_config->timing_info_mode_periodic = 1; p7_config->timing_info_period = phy_info->timing_info_period; @@ -1113,107 +1024,89 @@ int start_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi p7_config->tx_req = &pnf_phy_tx_req; p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; - if (nfapi_mode==3) { - p7_config->dl_config_req = &memcpy_dl_config_req; - p7_config->ul_config_req = &memcpy_ul_config_req; - p7_config->hi_dci0_req = &memcpy_hi_dci0_req; - p7_config->tx_req = &memcpy_tx_req; - } - else { - p7_config->dl_config_req = &pnf_phy_dl_config_req; - p7_config->ul_config_req = &pnf_phy_ul_config_req; - p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req; - p7_config->tx_req = &pnf_phy_tx_req; - } - p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; - - memset(&dummy_dl_config_req, 0, sizeof(dummy_dl_config_req)); - dummy_dl_config_req.dl_config_request_body.tl.tag=NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - dummy_dl_config_req.dl_config_request_body.number_pdcch_ofdm_symbols=1; - dummy_dl_config_req.dl_config_request_body.number_dci=0; - dummy_dl_config_req.dl_config_request_body.number_pdu=0; - dummy_dl_config_req.dl_config_request_body.number_pdsch_rnti=0; - dummy_dl_config_req.dl_config_request_body.transmission_power_pcfich=6000; - dummy_dl_config_req.dl_config_request_body.dl_config_pdu_list=0; - - memset(&dummy_tx_req, 0, sizeof(dummy_tx_req)); - dummy_tx_req.tx_request_body.number_of_pdus=0; - dummy_tx_req.tx_request_body.tl.tag=NFAPI_TX_REQUEST_BODY_TAG; - - dummy_subframe.dl_config_req = &dummy_dl_config_req; - dummy_subframe.tx_req = 0;//&dummy_tx_req; - - dummy_subframe.ul_config_req=0; - dummy_subframe.hi_dci0_req=0; - dummy_subframe.lbt_dl_config_req=0; - - p7_config->dummy_subframe = dummy_subframe; - - p7_config->vendor_ext = &pnf_phy_vendor_ext; - - p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext; - p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext; - - p7_config->codec_config.unpack_p7_vendor_extension = &pnf_phy_unpack_p7_vendor_extension; - p7_config->codec_config.pack_p7_vendor_extension = &pnf_phy_pack_p7_vendor_extension; - p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_phy_unpack_vendor_extension_tlv; - p7_config->codec_config.pack_vendor_extension_tlv = &pnf_phy_pack_vendor_extention_tlv; - - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating P7 thread %s\n", __FUNCTION__); - pthread_t p7_thread; - pthread_create(&p7_thread, NULL, &pnf_p7_thread_start, p7_config); - - //((pnf_phy_user_data_t*)(phy_info->fapi->user_data))->p7_config = p7_config; - - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Calling l1_north_init_eNB() %s\n", __FUNCTION__); - l1_north_init_eNB(); - - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] DJP - HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__); - p7_config_g = p7_config; - - // Need to wait for main thread to create RU structures - while(config_sync_var<0) - { - usleep(5000000); - printf("[PNF] waiting for OAI to be configured (eNB/RU)\n"); - } - printf("[PNF] OAI eNB/RU configured\n"); - - //printf("[PNF] About to call phy_init_RU() for RC.ru[0]:%p\n", RC.ru[0]); - //phy_init_RU(RC.ru[0]); - - printf("[PNF] About to call init_eNB_afterRU()\n"); - - if (nfapi_mode != 3) { - init_eNB_afterRU(); - } - - // Signal to main thread that it can carry on - otherwise RU will startup too quickly and it is not initialised - { - pthread_mutex_lock(&nfapi_sync_mutex); - nfapi_sync_var=0; - pthread_cond_broadcast(&nfapi_sync_cond); - pthread_mutex_unlock(&nfapi_sync_mutex); - } - - while(sync_var<0) - { - usleep(5000000); - printf("[PNF] waiting for OAI to be started\n"); - } + if (NFAPI_MODE==NFAPI_UE_STUB_PNF) { + p7_config->dl_config_req = &memcpy_dl_config_req; + p7_config->ul_config_req = &memcpy_ul_config_req; + p7_config->hi_dci0_req = &memcpy_hi_dci0_req; + p7_config->tx_req = &memcpy_tx_req; + } else { + p7_config->dl_config_req = &pnf_phy_dl_config_req; + p7_config->ul_config_req = &pnf_phy_ul_config_req; + p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req; + p7_config->tx_req = &pnf_phy_tx_req; + } - printf("[PNF] Sending PNF_START_RESP\n"); - nfapi_send_pnf_start_resp(config, p7_config->phy_id); + p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; + memset(&dummy_dl_config_req, 0, sizeof(dummy_dl_config_req)); + dummy_dl_config_req.dl_config_request_body.tl.tag=NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dummy_dl_config_req.dl_config_request_body.number_pdcch_ofdm_symbols=1; + dummy_dl_config_req.dl_config_request_body.number_dci=0; + dummy_dl_config_req.dl_config_request_body.number_pdu=0; + dummy_dl_config_req.dl_config_request_body.number_pdsch_rnti=0; + dummy_dl_config_req.dl_config_request_body.transmission_power_pcfich=6000; + dummy_dl_config_req.dl_config_request_body.dl_config_pdu_list=0; + memset(&dummy_tx_req, 0, sizeof(dummy_tx_req)); + dummy_tx_req.tx_request_body.number_of_pdus=0; + dummy_tx_req.tx_request_body.tl.tag=NFAPI_TX_REQUEST_BODY_TAG; + dummy_subframe.dl_config_req = &dummy_dl_config_req; + dummy_subframe.tx_req = 0;//&dummy_tx_req; + dummy_subframe.ul_config_req=0; + dummy_subframe.hi_dci0_req=0; + dummy_subframe.lbt_dl_config_req=0; + p7_config->dummy_subframe = dummy_subframe; + p7_config->vendor_ext = &pnf_phy_vendor_ext; + p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext; + p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext; + p7_config->codec_config.unpack_p7_vendor_extension = &pnf_phy_unpack_p7_vendor_extension; + p7_config->codec_config.pack_p7_vendor_extension = &pnf_phy_pack_p7_vendor_extension; + p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_phy_unpack_vendor_extension_tlv; + p7_config->codec_config.pack_vendor_extension_tlv = &pnf_phy_pack_vendor_extention_tlv; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating P7 thread %s\n", __FUNCTION__); + pthread_t p7_thread; + pthread_create(&p7_thread, NULL, &pnf_p7_thread_start, p7_config); + //((pnf_phy_user_data_t*)(phy_info->fapi->user_data))->p7_config = p7_config; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Calling l1_north_init_eNB() %s\n", __FUNCTION__); + l1_north_init_eNB(); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] DJP - HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__); + p7_config_g = p7_config; + + // Need to wait for main thread to create RU structures + while(config_sync_var<0) { + usleep(5000000); + printf("[PNF] waiting for OAI to be configured (eNB/RU)\n"); + } + + printf("[PNF] OAI eNB/RU configured\n"); + //printf("[PNF] About to call phy_init_RU() for RC.ru[0]:%p\n", RC.ru[0]); + //phy_init_RU(RC.ru[0]); + printf("[PNF] About to call init_eNB_afterRU()\n"); + + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + init_eNB_afterRU(); + } + + // Signal to main thread that it can carry on - otherwise RU will startup too quickly and it is not initialised + { + pthread_mutex_lock(&nfapi_sync_mutex); + nfapi_sync_var=0; + pthread_cond_broadcast(&nfapi_sync_cond); + pthread_mutex_unlock(&nfapi_sync_mutex); + } - printf("[PNF] Sending first P7 subframe ind\n"); - nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct??? - printf("[PNF] Sent first P7 subframe ind\n"); + while(sync_var<0) { + usleep(5000000); + printf("[PNF] waiting for OAI to be started\n"); + } + printf("[PNF] Sending PNF_START_RESP\n"); + nfapi_send_pnf_start_resp(config, p7_config->phy_id); + printf("[PNF] Sending first P7 subframe ind\n"); + nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct??? + printf("[PNF] Sent first P7 subframe ind\n"); return 0; } -int measurement_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_measurement_request_t* req) { - +int measurement_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_measurement_request_t *req) { nfapi_measurement_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_MEASUREMENT_RESPONSE; @@ -1223,15 +1116,13 @@ int measurement_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, return 0; } -int rssi_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_rssi_request_t* req) { - +int rssi_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_rssi_request_t *req) { nfapi_rssi_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_RSSI_RESPONSE; resp.header.phy_id = req->header.phy_id; resp.error_code = NFAPI_P4_MSG_OK; nfapi_pnf_rssi_resp(config, &resp); - nfapi_rssi_indication_t ind; memset(&ind, 0, sizeof(ind)); ind.header.message_id = NFAPI_RSSI_INDICATION; @@ -1241,19 +1132,16 @@ int rssi_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_ ind.rssi_indication_body.number_of_rssi = 1; ind.rssi_indication_body.rssi[0] = -42; nfapi_pnf_rssi_ind(config, &ind); - return 0; } -int cell_search_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_cell_search_request_t* req) { - +int cell_search_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_cell_search_request_t *req) { nfapi_cell_search_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_CELL_SEARCH_RESPONSE; resp.header.phy_id = req->header.phy_id; resp.error_code = NFAPI_P4_MSG_OK; nfapi_pnf_cell_search_resp(config, &resp); - nfapi_cell_search_indication_t ind; memset(&ind, 0, sizeof(ind)); ind.header.message_id = NFAPI_CELL_SEARCH_INDICATION; @@ -1269,160 +1157,135 @@ int cell_search_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, ind.lte_cell_search_indication.lte_found_cells[0].rsrq = 123; ind.lte_cell_search_indication.lte_found_cells[0].frequency_offset = 123; break; - case NFAPI_RAT_TYPE_UTRAN: - { - ind.utran_cell_search_indication.tl.tag = NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG; - ind.utran_cell_search_indication.number_of_utran_cells_found = 1; - ind.utran_cell_search_indication.utran_found_cells[0].psc = 89; - ind.utran_cell_search_indication.utran_found_cells[0].rscp = 89; - ind.utran_cell_search_indication.utran_found_cells[0].ecno = 89; - ind.utran_cell_search_indication.utran_found_cells[0].frequency_offset = -89; - } - break; - case NFAPI_RAT_TYPE_GERAN: - { - ind.geran_cell_search_indication.tl.tag = NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG; - ind.geran_cell_search_indication.number_of_gsm_cells_found = 1; - ind.geran_cell_search_indication.gsm_found_cells[0].bsic = 23; - ind.geran_cell_search_indication.gsm_found_cells[0].rxlev = 23; - ind.geran_cell_search_indication.gsm_found_cells[0].rxqual = 23; - ind.geran_cell_search_indication.gsm_found_cells[0].frequency_offset = -23; - ind.geran_cell_search_indication.gsm_found_cells[0].sfn_offset = 230; - - } - break; + case NFAPI_RAT_TYPE_UTRAN: { + ind.utran_cell_search_indication.tl.tag = NFAPI_UTRAN_CELL_SEARCH_INDICATION_TAG; + ind.utran_cell_search_indication.number_of_utran_cells_found = 1; + ind.utran_cell_search_indication.utran_found_cells[0].psc = 89; + ind.utran_cell_search_indication.utran_found_cells[0].rscp = 89; + ind.utran_cell_search_indication.utran_found_cells[0].ecno = 89; + ind.utran_cell_search_indication.utran_found_cells[0].frequency_offset = -89; + } + break; + + case NFAPI_RAT_TYPE_GERAN: { + ind.geran_cell_search_indication.tl.tag = NFAPI_GERAN_CELL_SEARCH_INDICATION_TAG; + ind.geran_cell_search_indication.number_of_gsm_cells_found = 1; + ind.geran_cell_search_indication.gsm_found_cells[0].bsic = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].rxlev = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].rxqual = 23; + ind.geran_cell_search_indication.gsm_found_cells[0].frequency_offset = -23; + ind.geran_cell_search_indication.gsm_found_cells[0].sfn_offset = 230; + } + break; } ind.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; ind.pnf_cell_search_state.length = 3; - - nfapi_pnf_cell_search_ind(config, &ind); - + nfapi_pnf_cell_search_ind(config, &ind); return 0; } -int broadcast_detect_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_broadcast_detect_request_t* req) -{ +int broadcast_detect_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_broadcast_detect_request_t *req) { nfapi_broadcast_detect_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_BROADCAST_DETECT_RESPONSE; resp.header.phy_id = req->header.phy_id; resp.error_code = NFAPI_P4_MSG_OK; nfapi_pnf_broadcast_detect_resp(config, &resp); - nfapi_broadcast_detect_indication_t ind; memset(&ind, 0, sizeof(ind)); ind.header.message_id = NFAPI_BROADCAST_DETECT_INDICATION; ind.header.phy_id = req->header.phy_id; ind.error_code = NFAPI_P4_MSG_OK; - switch(req->rat_type) - { - case NFAPI_RAT_TYPE_LTE: - { - ind.lte_broadcast_detect_indication.tl.tag = NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG; - ind.lte_broadcast_detect_indication.number_of_tx_antenna = 1; - ind.lte_broadcast_detect_indication.mib_length = 4; - //ind.lte_broadcast_detect_indication.mib... - ind.lte_broadcast_detect_indication.sfn_offset = 77; - - } - break; - case NFAPI_RAT_TYPE_UTRAN: - { - ind.utran_broadcast_detect_indication.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG; - ind.utran_broadcast_detect_indication.mib_length = 4; - //ind.utran_broadcast_detect_indication.mib... - // ind.utran_broadcast_detect_indication.sfn_offset; DJP - nonsense line + switch(req->rat_type) { + case NFAPI_RAT_TYPE_LTE: { + ind.lte_broadcast_detect_indication.tl.tag = NFAPI_LTE_BROADCAST_DETECT_INDICATION_TAG; + ind.lte_broadcast_detect_indication.number_of_tx_antenna = 1; + ind.lte_broadcast_detect_indication.mib_length = 4; + //ind.lte_broadcast_detect_indication.mib... + ind.lte_broadcast_detect_indication.sfn_offset = 77; + } + break; - } - break; + case NFAPI_RAT_TYPE_UTRAN: { + ind.utran_broadcast_detect_indication.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_INDICATION_TAG; + ind.utran_broadcast_detect_indication.mib_length = 4; + //ind.utran_broadcast_detect_indication.mib... + // ind.utran_broadcast_detect_indication.sfn_offset; DJP - nonsense line + } + break; } ind.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; ind.pnf_cell_broadcast_state.length = 3; - - nfapi_pnf_broadcast_detect_ind(config, &ind); - + nfapi_pnf_broadcast_detect_ind(config, &ind); return 0; } -int system_information_schedule_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_schedule_request_t* req) -{ +int system_information_schedule_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_system_information_schedule_request_t *req) { nfapi_system_information_schedule_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_RESPONSE; resp.header.phy_id = req->header.phy_id; resp.error_code = NFAPI_P4_MSG_OK; nfapi_pnf_system_information_schedule_resp(config, &resp); - nfapi_system_information_schedule_indication_t ind; memset(&ind, 0, sizeof(ind)); ind.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_INDICATION; ind.header.phy_id = req->header.phy_id; ind.error_code = NFAPI_P4_MSG_OK; - ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; ind.lte_system_information_indication.sib_type = 3; ind.lte_system_information_indication.sib_length = 5; //ind.lte_system_information_indication.sib... - - nfapi_pnf_system_information_schedule_ind(config, &ind); - + nfapi_pnf_system_information_schedule_ind(config, &ind); return 0; } -int system_information_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_request_t* req) -{ +int system_information_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_system_information_request_t *req) { nfapi_system_information_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_SYSTEM_INFORMATION_RESPONSE; resp.header.phy_id = req->header.phy_id; resp.error_code = NFAPI_P4_MSG_OK; nfapi_pnf_system_information_resp(config, &resp); - nfapi_system_information_indication_t ind; memset(&ind, 0, sizeof(ind)); ind.header.message_id = NFAPI_SYSTEM_INFORMATION_INDICATION; ind.header.phy_id = req->header.phy_id; ind.error_code = NFAPI_P4_MSG_OK; - switch(req->rat_type) - { - case NFAPI_RAT_TYPE_LTE: - { - ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; - ind.lte_system_information_indication.sib_type = 1; - ind.lte_system_information_indication.sib_length = 3; - //ind.lte_system_information_indication.sib... - } - break; - case NFAPI_RAT_TYPE_UTRAN: - { - ind.utran_system_information_indication.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG; - ind.utran_system_information_indication.sib_length = 3; - //ind.utran_system_information_indication.sib... + switch(req->rat_type) { + case NFAPI_RAT_TYPE_LTE: { + ind.lte_system_information_indication.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_INDICATION_TAG; + ind.lte_system_information_indication.sib_type = 1; + ind.lte_system_information_indication.sib_length = 3; + //ind.lte_system_information_indication.sib... + } + break; - } - break; - case NFAPI_RAT_TYPE_GERAN: - { - ind.geran_system_information_indication.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG; - ind.geran_system_information_indication.si_length = 3; - //ind.geran_system_information_indication.si... + case NFAPI_RAT_TYPE_UTRAN: { + ind.utran_system_information_indication.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_INDICATION_TAG; + ind.utran_system_information_indication.sib_length = 3; + //ind.utran_system_information_indication.sib... + } + break; - } - break; + case NFAPI_RAT_TYPE_GERAN: { + ind.geran_system_information_indication.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_INDICATION_TAG; + ind.geran_system_information_indication.si_length = 3; + //ind.geran_system_information_indication.si... + } + break; } - nfapi_pnf_system_information_ind(config, &ind); - + nfapi_pnf_system_information_ind(config, &ind); return 0; } -int nmm_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nmm_stop_request_t* req) -{ +int nmm_stop_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_nmm_stop_request_t *req) { nfapi_nmm_stop_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_NMM_STOP_RESPONSE; @@ -1432,108 +1295,94 @@ int nmm_stop_request(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nf return 0; } -int vendor_ext(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg) -{ +int vendor_ext(nfapi_pnf_config_t *config, nfapi_p4_p5_message_header_t *msg) { NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 %s %p\n", __FUNCTION__, msg); - switch(msg->message_id) - { - case P5_VENDOR_EXT_REQ: - { - vendor_ext_p5_req* req = (vendor_ext_p5_req*)msg; - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 Vendor Ext Req (%d %d)\n", req->dummy1, req->dummy2); - // send back the P5_VENDOR_EXT_RSP - vendor_ext_p5_rsp rsp; - memset(&rsp, 0, sizeof(rsp)); - rsp.header.message_id = P5_VENDOR_EXT_RSP; - rsp.error_code = NFAPI_MSG_OK; - nfapi_pnf_vendor_extension(config, &rsp.header, sizeof(vendor_ext_p5_rsp)); - } - break; + switch(msg->message_id) { + case P5_VENDOR_EXT_REQ: { + vendor_ext_p5_req *req = (vendor_ext_p5_req *)msg; + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 Vendor Ext Req (%d %d)\n", req->dummy1, req->dummy2); + // send back the P5_VENDOR_EXT_RSP + vendor_ext_p5_rsp rsp; + memset(&rsp, 0, sizeof(rsp)); + rsp.header.message_id = P5_VENDOR_EXT_RSP; + rsp.error_code = NFAPI_MSG_OK; + nfapi_pnf_vendor_extension(config, &rsp.header, sizeof(vendor_ext_p5_rsp)); + } + break; } return 0; } -nfapi_p4_p5_message_header_t* pnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size) { - +nfapi_p4_p5_message_header_t *pnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size) { if(message_id == P5_VENDOR_EXT_REQ) { (*msg_size) = sizeof(vendor_ext_p5_req); - return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_req)); + return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_req)); } return 0; } -void pnf_sim_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header) { +void pnf_sim_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header) { free(header); } -int pnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config) { +int pnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); if(header->message_id == P5_VENDOR_EXT_RSP) { - vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)(header); + vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)(header); return (!push16(rsp->error_code, ppWritePackedMsg, end)); } + return 0; } -int pnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) { +int pnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); if(header->message_id == P5_VENDOR_EXT_REQ) { - vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header); + vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header); return (!(pull16(ppReadPackedMessage, &req->dummy1, end) && - pull16(ppReadPackedMessage, &req->dummy2, end))); - + pull16(ppReadPackedMessage, &req->dummy2, end))); //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s (%d %d)\n", __FUNCTION__, req->dummy1, req->dummy2); } + return 0; } /*------------------------------------------------------------------------------*/ -void* pnf_start_thread(void* ptr) { - +void *pnf_start_thread(void *ptr) { NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] IN PNF NFAPI start thread %s\n", __FUNCTION__); - - nfapi_pnf_config_t *config = (nfapi_pnf_config_t*)ptr; - + nfapi_pnf_config_t *config = (nfapi_pnf_config_t *)ptr; struct sched_param sp; sp.sched_priority = 20; pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp); - nfapi_pnf_start(config); - - return (void*)0; + return (void *)0; } void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { - printf("%s() PNF\n\n\n\n\n\n", __FUNCTION__); - if(nfapi_mode!=3) { - nfapi_mode = 1; // PNF! + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + nfapi_setmode(NFAPI_PNF); // PNF! } - nfapi_pnf_config_t* config = nfapi_pnf_config_create(); - + nfapi_pnf_config_t *config = nfapi_pnf_config_create(); config->vnf_ip_addr = vnf_ip_addr; config->vnf_p5_port = vnf_p5_port; - pnf.phys[0].udp.enabled = 1; pnf.phys[0].udp.rx_port = pnf_p7_port; pnf.phys[0].udp.tx_port = vnf_p7_port; strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr); - strcpy(pnf.phys[0].local_addr, pnf_ip_addr); - - printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n", - __FUNCTION__, - config->vnf_ip_addr, config->vnf_p5_port, - pnf.phys[0].local_addr, - pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port, - pnf.phys[0].udp.rx_port); - + printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n", + __FUNCTION__, + config->vnf_ip_addr, config->vnf_p5_port, + pnf.phys[0].local_addr, + pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port, + pnf.phys[0].udp.rx_port); config->pnf_param_req = &pnf_param_request; config->pnf_config_req = &pnf_config_request; config->pnf_start_req = &pnf_start_request; @@ -1541,7 +1390,6 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, config->param_req = ¶m_request; config->config_req = &config_request; config->start_req = &start_request; - config->measurement_req = &measurement_request; config->rssi_req = &rssi_request; config->cell_search_req = &cell_search_request; @@ -1549,45 +1397,31 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, config->system_information_schedule_req = &system_information_schedule_request; config->system_information_req = &system_information_request; config->nmm_stop_req = &nmm_stop_request; - config->vendor_ext = &vendor_ext; - config->trace = &pnf_nfapi_trace; - config->user_data = &pnf; - // To allow custom vendor extentions to be added to nfapi config->codec_config.unpack_vendor_extension_tlv = &pnf_sim_unpack_vendor_extension_tlv; config->codec_config.pack_vendor_extension_tlv = &pnf_sim_pack_vendor_extention_tlv; - config->allocate_p4_p5_vendor_ext = &pnf_sim_allocate_p4_p5_vendor_ext; config->deallocate_p4_p5_vendor_ext = &pnf_sim_deallocate_p4_p5_vendor_ext; - config->codec_config.unpack_p4_p5_vendor_extension = &pnf_sim_unpack_p4_p5_vendor_extension; config->codec_config.pack_p4_p5_vendor_extension = &pnf_sim_pack_p4_p5_vendor_extension; - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating PNF NFAPI start thread %s\n", __FUNCTION__); pthread_create(&pnf_start_pthread, NULL, &pnf_start_thread, config); - pthread_setname_np(pnf_start_pthread, "NFAPI_PNF"); } void oai_subframe_ind(uint16_t sfn, uint16_t sf) { - //LOG_D(PHY,"%s(sfn:%d, sf:%d)\n", __FUNCTION__, sfn, sf); - //TODO FIXME - HACK - DJP - using a global to bodge it in - + //TODO FIXME - HACK - DJP - using a global to bodge it in if (p7_config_g != NULL && sync_var==0) { - uint16_t sfn_sf_tx = sfn<<4 | sf; - if ((sfn % 100 == 0) && sf==0) - { + if ((sfn % 100 == 0) && sf==0) { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u sf:%u) SFN/SF(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, sf, NFAPI_SFNSF2DEC(sfn_sf_tx)); } @@ -1603,21 +1437,15 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf) { } int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) { - rach_ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! - LOG_D(PHY, "%s() sfn_sf:%d preambles:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(rach_ind->sfn_sf), rach_ind->rach_indication_body.number_of_preambles); - return nfapi_pnf_p7_rach_ind(p7_config_g, rach_ind); } int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind) { - harq_ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! harq_ind->header.message_id = NFAPI_HARQ_INDICATION; - LOG_D(PHY, "%s() sfn_sf:%d number_of_harqs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(harq_ind->sfn_sf), harq_ind->harq_indication_body.number_of_harqs); - int retval = nfapi_pnf_p7_harq_ind(p7_config_g, harq_ind); if (retval != 0) @@ -1627,48 +1455,32 @@ int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind) { } int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind) { - crc_ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! crc_ind->header.message_id = NFAPI_CRC_INDICATION; - //LOG_D(PHY, "%s() sfn_sf:%d number_of_crcs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(crc_ind->sfn_sf), crc_ind->crc_indication_body.number_of_crcs); - return nfapi_pnf_p7_crc_ind(p7_config_g, crc_ind); } int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *ind) { - ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! ind->header.message_id = NFAPI_RX_CQI_INDICATION; - //LOG_D(PHY, "%s() sfn_sf:%d number_of_cqis:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->cqi_indication_body.number_of_cqis); - return nfapi_pnf_p7_cqi_ind(p7_config_g, ind); } int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind) { - ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! ind->header.message_id = NFAPI_RX_ULSCH_INDICATION; - int retval = nfapi_pnf_p7_rx_ind(p7_config_g, ind); - //LOG_D(PHY,"%s() SFN/SF:%d pdus:%d retval:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, retval); - //free(ind.rx_indication_body.rx_pdu_list); - return retval; } int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind) { - ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! - int retval = nfapi_pnf_p7_sr_ind(p7_config_g, ind); - //LOG_D(PHY,"%s() SFN/SF:%d srs:%d retval:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->sr_indication_body.number_of_srs, retval); - //free(ind.rx_indication_body.rx_pdu_list); - return retval; } diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 3da2059ba7174e5b15b72860d050c4bf4ba5e03e..2752df3435d37090e4ddc3f2347e8a45896869ba 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -61,7 +61,7 @@ typedef struct { char local_addr[80]; int local_port; - char* remote_addr; + char *remote_addr; int remote_port; uint8_t duplex_mode; @@ -127,12 +127,12 @@ typedef struct mac mac_t; typedef struct mac { - void* user_data; + void *user_data; - void (*dl_config_req)(mac_t* mac, nfapi_dl_config_request_t* req); - void (*ul_config_req)(mac_t* mac, nfapi_ul_config_request_t* req); - void (*hi_dci0_req)(mac_t* mac, nfapi_hi_dci0_request_t* req); - void (*tx_req)(mac_t* mac, nfapi_tx_request_t* req); + void (*dl_config_req)(mac_t *mac, nfapi_dl_config_request_t *req); + void (*ul_config_req)(mac_t *mac, nfapi_ul_config_request_t *req); + void (*hi_dci0_req)(mac_t *mac, nfapi_hi_dci0_request_t *req); + void (*tx_req)(mac_t *mac, nfapi_tx_request_t *req); } mac_t; typedef struct { @@ -145,15 +145,15 @@ typedef struct { unsigned aperiodic_timing_enabled; unsigned periodic_timing_period; - // This is not really the right place if we have multiple PHY, + // This is not really the right place if we have multiple PHY, // should be part of the phy struct udp_data udp; uint8_t thread_started; - nfapi_vnf_p7_config_t* config; + nfapi_vnf_p7_config_t *config; - mac_t* mac; + mac_t *mac; } vnf_p7_info; @@ -165,24 +165,27 @@ typedef struct { } vnf_info; -int vnf_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) { +int vnf_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "vnf_pack_vendor_extension_tlv\n"); - nfapi_tl_t* tlv = (nfapi_tl_t*)ve; + nfapi_tl_t *tlv = (nfapi_tl_t *)ve; + switch(tlv->tag) { - case VENDOR_EXT_TLV_2_TAG: - { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_2\n"); - vendor_ext_tlv_2* ve = (vendor_ext_tlv_2*)tlv; - if(!push32(ve->dummy, ppWritePackedMsg, end)) - return 0; - return 1; - } - break; + case VENDOR_EXT_TLV_2_TAG: { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_2\n"); + vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)tlv; + + if(!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; + + return 1; + } + break; } + return -1; } -int vnf_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* codec) { +int vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p4_p5_codec_config_t *codec) { return -1; } @@ -192,17 +195,14 @@ extern void init_eNB_afterRU(void); extern uint16_t sf_ahead; void oai_create_enb(void) { - int bodge_counter=0; PHY_VARS_eNB *eNB = RC.eNB[0][0]; - - printf("[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d nb_CC[0]:%d abstraction_flag:%d single_thread_flag:%d if_inst:%p\n", eNB->Mod_id, eNB->CC_id, RC.nb_CC[0], eNB->abstraction_flag, eNB->single_thread_flag, eNB->if_inst); - + printf("[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d nb_CC[0]:%d abstraction_flag:%d single_thread_flag:%d if_inst:%p\n", eNB->Mod_id, eNB->CC_id, RC.nb_CC[0], eNB->abstraction_flag, + eNB->single_thread_flag, eNB->if_inst); eNB->Mod_id = bodge_counter; eNB->CC_id = bodge_counter; eNB->abstraction_flag = 0; eNB->single_thread_flag = 0;//single_thread_flag; - RC.nb_CC[bodge_counter] = 1; if (eNB->if_inst==0) { @@ -213,7 +213,6 @@ void oai_create_enb(void) { // that will result in eNB->configured being set to TRUE. // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values if (RC.eNB[0][0]->if_inst==0 || RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0) { - printf("RC.eNB[0][0]->if_inst->PHY_config_req is not installed - install it\n"); install_schedule_handlers(RC.eNB[0][0]->if_inst); } @@ -227,17 +226,13 @@ void oai_create_enb(void) { } void oai_enb_init(void) { - printf("%s() About to call init_eNB_afterRU()\n", __FUNCTION__); init_eNB_afterRU(); } -int pnf_connection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) { - +int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { printf("[VNF] pnf connection indication idx:%d\n", p5_idx); - oai_create_enb(); - nfapi_pnf_param_request_t req; memset(&req, 0, sizeof(req)); req.header.message_id = NFAPI_PNF_PARAM_REQUEST; @@ -245,40 +240,29 @@ int pnf_connection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) { return 0; } -int pnf_disconnection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) { +int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { printf("[VNF] pnf disconnection indication idx:%d\n", p5_idx); - - vnf_info* vnf = (vnf_info*)(config->user_data); - + vnf_info *vnf = (vnf_info *)(config->user_data); pnf_info *pnf = vnf->pnfs; phy_info *phy = pnf->phys; - - vnf_p7_info* p7_vnf = vnf->p7_vnfs; + vnf_p7_info *p7_vnf = vnf->p7_vnfs; nfapi_vnf_p7_del_pnf((p7_vnf->config), phy->id); - return 0; } -int pnf_param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp) { - +int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_response_t *resp) { printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); - - vnf_info* vnf = (vnf_info*)(config->user_data); - + vnf_info *vnf = (vnf_info *)(config->user_data); pnf_info *pnf = vnf->pnfs; - for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) - { + for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) { phy_info phy; memset(&phy,0,sizeof(phy)); phy.index = resp->pnf_phy.phy[i].phy_config_index; - printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); - nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id)); - for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) - { + for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) { printf("[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index; } @@ -290,16 +274,13 @@ int pnf_param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_re rf_info rf; memset(&rf,0,sizeof(rf)); rf.index = resp->pnf_rf.rf[i].rf_config_index; - printf("[VNF] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index); - pnf->rfs[0] = rf; } nfapi_pnf_config_request_t req; memset(&req, 0, sizeof(req)); req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; - req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size(); printf("DJP:Hard coded num phy rf to 2\n"); @@ -311,25 +292,22 @@ int pnf_param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_re } nfapi_vnf_pnf_config_req(config, p5_idx, &req); - return 0; } -int pnf_config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp) { - +int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_response_t *resp) { printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length); if(1) { - nfapi_pnf_start_request_t req; - memset(&req, 0, sizeof(req)); - req.header.phy_id = resp->header.phy_id; - req.header.message_id = NFAPI_PNF_START_REQUEST; - nfapi_vnf_pnf_start_req(config, p5_idx, &req); + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.phy_id = resp->header.phy_id; + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); } else { // Rather than send the pnf_start_request we will demonstrate // sending a vendor extention message. The start request will be - // send when the vendor extension response is received - + // send when the vendor extension response is received //vnf_info* vnf = (vnf_info*)(config->user_data); vendor_ext_p5_req req; memset(&req, 0, sizeof(req)); @@ -338,22 +316,17 @@ int pnf_config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_ req.dummy2 = 1977; nfapi_vnf_vendor_extension(config, p5_idx, &req.header); } + return 0; } int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { - L1_proc_t *proc=&eNB->proc; - L1_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx; - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - //printf("%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf); - //int i; struct timespec wait; - wait.tv_sec=0; wait.tv_nsec=5000000L; @@ -368,10 +341,8 @@ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { { static uint16_t old_sf = 0; static uint16_t old_sfn = 0; - proc->subframe_rx = old_sf; proc->frame_rx = old_sfn; - // Try to be 1 frame back old_sf = sf; old_sfn = sfn; @@ -380,9 +351,7 @@ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { } ++L1_proc->instance_cnt; - //LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx); - // We have just received and processed the common part of a subframe, say n. // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired // transmitted timestamp of the next TX slot (first). @@ -407,7 +376,6 @@ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { //LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__); pthread_mutex_unlock( &L1_proc->mutex ); //LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__); - return(0); } @@ -415,12 +383,10 @@ extern pthread_cond_t nfapi_sync_cond; extern pthread_mutex_t nfapi_sync_mutex; extern int nfapi_sync_var; -int phy_sync_indication(struct nfapi_vnf_p7_config* config, uint8_t sync) { - +int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) { printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST"); - - if (sync==1 && nfapi_sync_var!=0) { + if (sync==1 && nfapi_sync_var!=0) { printf("[VNF] Signal to OAI main code that it can go\n"); pthread_mutex_lock(&nfapi_sync_mutex); nfapi_sync_var=0; @@ -431,9 +397,9 @@ int phy_sync_indication(struct nfapi_vnf_p7_config* config, uint8_t sync) { return(0); } -int phy_subframe_indication(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf) { - +int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn_sf) { static uint8_t first_time = 1; + if (first_time) { printf("[VNF] subframe indication %d\n", NFAPI_SFNSF2DEC(sfn_sf)); first_time = 0; @@ -442,40 +408,33 @@ int phy_subframe_indication(struct nfapi_vnf_p7_config* config, uint16_t phy_id, if (RC.eNB && RC.eNB[0][0]->configured) { uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf); uint16_t sf = NFAPI_SFNSF2SF(sfn_sf); - //LOG_D(PHY,"[VNF] subframe indication sfn_sf:%d sfn:%d sf:%d\n", sfn_sf, sfn, sf); - wake_eNB_rxtx(RC.eNB[0][0], sfn, sf); } else { printf("[VNF] %s() RC.eNB:%p\n", __FUNCTION__, RC.eNB); + if (RC.eNB) printf("RC.eNB[0][0]->configured:%d\n", RC.eNB[0][0]->configured); } return 0; } -int phy_rach_indication(struct nfapi_vnf_p7_config* config, nfapi_rach_indication_t* ind) { - +int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indication_t *ind) { LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_preambles:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rach_indication_body.number_of_preambles); - struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - printf("[VNF] RACH_IND eNB:%p sfn_sf:%d number_of_preambles:%d\n", eNB, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rach_indication_body.number_of_preambles); - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rach_ind = *ind; eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = eNB->preamble_list; - for (int i=0;i<ind->rach_indication_body.number_of_preambles;i++) { + for (int i=0; i<ind->rach_indication_body.number_of_preambles; i++) { if (ind->rach_indication_body.preamble_list[i].preamble_rel8.tl.tag == NFAPI_PREAMBLE_REL8_TAG) { - - printf("preamble[%d]: rnti:%02x preamble:%d timing_advance:%d\n", - i, - ind->rach_indication_body.preamble_list[i].preamble_rel8.rnti, - ind->rach_indication_body.preamble_list[i].preamble_rel8.preamble, - ind->rach_indication_body.preamble_list[i].preamble_rel8.timing_advance - ); + printf("preamble[%d]: rnti:%02x preamble:%d timing_advance:%d\n", + i, + ind->rach_indication_body.preamble_list[i].preamble_rel8.rnti, + ind->rach_indication_body.preamble_list[i].preamble_rel8.preamble, + ind->rach_indication_body.preamble_list[i].preamble_rel8.timing_advance + ); } if(ind->rach_indication_body.preamble_list[i].preamble_rel13.tl.tag == NFAPI_PREAMBLE_REL13_TAG) { @@ -484,21 +443,17 @@ int phy_rach_indication(struct nfapi_vnf_p7_config* config, nfapi_rach_indicatio eNB->preamble_list[i] = ind->rach_indication_body.preamble_list[i]; } - pthread_mutex_unlock(&eNB->UL_INFO_mutex); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_rach_ind(p7_vnf->mac, ind); return 1; } -int phy_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_harq_indication_t* ind) { - +int phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind) { struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_harqs:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->harq_indication_body.number_of_harqs); - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.harq_ind = *ind; eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; @@ -507,51 +462,41 @@ int phy_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_harq_indicatio } pthread_mutex_unlock(&eNB->UL_INFO_mutex); - // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_harq_ind(p7_vnf->mac, ind); - return 1; } -int phy_crc_indication(struct nfapi_vnf_p7_config* config, nfapi_crc_indication_t* ind) { - +int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_t *ind) { struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.crc_ind = *ind; - nfapi_crc_indication_t *dest_ind = &eNB->UL_INFO.crc_ind; nfapi_crc_indication_pdu_t *dest_pdu_list = eNB->crc_pdu_list; - *dest_ind = *ind; dest_ind->crc_indication_body.crc_pdu_list = dest_pdu_list; if (ind->crc_indication_body.number_of_crcs==0) - LOG_D(MAC, "%s() NFAPI SFN/SF:%d IND:number_of_crcs:%u UL_INFO:crcs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs, eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs); + LOG_D(MAC, "%s() NFAPI SFN/SF:%d IND:number_of_crcs:%u UL_INFO:crcs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs, + eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs); for (int i=0; i<ind->crc_indication_body.number_of_crcs; i++) { memcpy(&dest_ind->crc_indication_body.crc_pdu_list[i], &ind->crc_indication_body.crc_pdu_list[i], sizeof(ind->crc_indication_body.crc_pdu_list[0])); - - LOG_D(MAC, "%s() NFAPI SFN/SF:%d CRC_IND:number_of_crcs:%u UL_INFO:crcs:%d PDU[%d] rnti:%04x UL_INFO:rnti:%04x\n", - __FUNCTION__, - NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs, eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, - i, - ind->crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti, - eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti); + LOG_D(MAC, "%s() NFAPI SFN/SF:%d CRC_IND:number_of_crcs:%u UL_INFO:crcs:%d PDU[%d] rnti:%04x UL_INFO:rnti:%04x\n", + __FUNCTION__, + NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs, eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, + i, + ind->crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti, + eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti); } pthread_mutex_unlock(&eNB->UL_INFO_mutex); - // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_crc_ind(p7_vnf->mac, ind); - return 1; } -int phy_rx_indication(struct nfapi_vnf_p7_config* config, nfapi_rx_indication_t* ind) { - +int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t *ind) { struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; if (ind->rx_indication_body.number_of_pdus==0) { @@ -559,198 +504,170 @@ int phy_rx_indication(struct nfapi_vnf_p7_config* config, nfapi_rx_indication_t* } pthread_mutex_lock(&eNB->UL_INFO_mutex); - nfapi_rx_indication_t *dest_ind = &eNB->UL_INFO.rx_ind; nfapi_rx_indication_pdu_t *dest_pdu_list = eNB->rx_pdu_list; - *dest_ind = *ind; dest_ind->rx_indication_body.rx_pdu_list = dest_pdu_list; for(int i=0; i<ind->rx_indication_body.number_of_pdus; i++) { nfapi_rx_indication_pdu_t *dest_pdu = &dest_ind->rx_indication_body.rx_pdu_list[i]; nfapi_rx_indication_pdu_t *src_pdu = &ind->rx_indication_body.rx_pdu_list[i]; - memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); - // DJP - TODO FIXME - intentional memory leak dest_pdu->data = malloc(dest_pdu->rx_indication_rel8.length); - memcpy(dest_pdu->data, src_pdu->data, dest_pdu->rx_indication_rel8.length); - LOG_D(PHY, "%s() NFAPI SFN/SF:%d PDUs:%d [PDU:%d] handle:%d rnti:%04x length:%d offset:%d ul_cqi:%d ta:%d data:%p\n", - __FUNCTION__, - NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, i, - dest_pdu->rx_ue_information.handle, - dest_pdu->rx_ue_information.rnti, - dest_pdu->rx_indication_rel8.length, - dest_pdu->rx_indication_rel8.offset, - dest_pdu->rx_indication_rel8.ul_cqi, - dest_pdu->rx_indication_rel8.timing_advance, - dest_pdu->data - ); + __FUNCTION__, + NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, i, + dest_pdu->rx_ue_information.handle, + dest_pdu->rx_ue_information.rnti, + dest_pdu->rx_indication_rel8.length, + dest_pdu->rx_indication_rel8.offset, + dest_pdu->rx_indication_rel8.ul_cqi, + dest_pdu->rx_indication_rel8.timing_advance, + dest_pdu->data + ); } pthread_mutex_unlock(&eNB->UL_INFO_mutex); - // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_rx_ind(p7_vnf->mac, ind); return 1; } -int phy_srs_indication(struct nfapi_vnf_p7_config* config, nfapi_srs_indication_t* ind) { +int phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind) { // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_srs_ind(p7_vnf->mac, ind); return 1; } -int phy_sr_indication(struct nfapi_vnf_p7_config* config, nfapi_sr_indication_t* ind) { - +int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind) { struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - LOG_D(MAC, "%s() NFAPI SFN/SF:%d srs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->sr_indication_body.number_of_srs); - pthread_mutex_lock(&eNB->UL_INFO_mutex); - nfapi_sr_indication_t *dest_ind = &eNB->UL_INFO.sr_ind; nfapi_sr_indication_pdu_t *dest_pdu_list = eNB->sr_pdu_list; - *dest_ind = *ind; dest_ind->sr_indication_body.sr_pdu_list = dest_pdu_list; - LOG_D(MAC,"%s() eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs:%d\n", __FUNCTION__, eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs); - for (int i=0;i<eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs;i++) { + for (int i=0; i<eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs; i++) { nfapi_sr_indication_pdu_t *dest_pdu = &dest_ind->sr_indication_body.sr_pdu_list[i]; nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i]; - LOG_D(MAC, "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti, src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel); - memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); } pthread_mutex_unlock(&eNB->UL_INFO_mutex); - // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_sr_ind(p7_vnf->mac, ind); - return 1; } -int phy_cqi_indication(struct nfapi_vnf_p7_config* config, nfapi_cqi_indication_t* ind) { - +int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind) { // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_cqi_ind(p7_vnf->mac, ind); struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_cqis:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->cqi_indication_body.number_of_cqis); - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.cqi_ind = ind->cqi_indication_body; - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - return 1; } -int phy_lbt_dl_indication(struct nfapi_vnf_p7_config* config, nfapi_lbt_dl_indication_t* ind) { +int phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind) { // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_lbt_dl_ind(p7_vnf->mac, ind); return 1; } -int phy_nb_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_nb_harq_indication_t* ind) { +int phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind) { // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_nb_harq_ind(p7_vnf->mac, ind); return 1; } -int phy_nrach_indication(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind) { +int phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind) { // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_nrach_ind(p7_vnf->mac, ind); return 1; } -void* vnf_allocate(size_t size) { +void *vnf_allocate(size_t size) { //return (void*)memory_pool::allocate(size); - return (void*)malloc(size); + return (void *)malloc(size); } -void vnf_deallocate(void* ptr) { +void vnf_deallocate(void *ptr) { //memory_pool::deallocate((uint8_t*)ptr); free(ptr); } -void vnf_trace(nfapi_trace_level_t nfapi_level, const char* message, ...) { - +void vnf_trace(nfapi_trace_level_t nfapi_level, const char *message, ...) { va_list args; - va_start(args, message); - nfapi_log("FILE>", "FUNC", 999, PHY, nfapitooai_level(nfapi_level), message, args); + VLOG( NFAPI_VNF, nfapitooai_level(nfapi_level), message, args); va_end(args); } -int phy_vendor_ext(struct nfapi_vnf_p7_config* config, nfapi_p7_message_header_t* msg) { - - if(msg->message_id == P7_VENDOR_EXT_IND) - { +int phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg) { + if(msg->message_id == P7_VENDOR_EXT_IND) { //vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg; //printf("[VNF] vendor_ext (error_code:%d)\n", ind->error_code); - } - else - { + } else { printf("[VNF] unknown %02x\n", msg->message_id); } + return 0; } -nfapi_p7_message_header_t* phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size) { - if(message_id == P7_VENDOR_EXT_IND) - { +nfapi_p7_message_header_t *phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size) { + if(message_id == P7_VENDOR_EXT_IND) { *msg_size = sizeof(vendor_ext_p7_ind); - return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_ind)); + return (nfapi_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_ind)); } + return 0; } -void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header) { +void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) { free(header); } -int phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p7_codec_config_t* codec) { - +int phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p7_codec_config_t *codec) { (void)tl; (void)ppReadPackedMessage; (void)ve; return -1; } -int phy_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codec) { - +int phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n"); + nfapi_tl_t *tlv = (nfapi_tl_t *)ve; - nfapi_tl_t* tlv = (nfapi_tl_t*)ve; switch(tlv->tag) { - case VENDOR_EXT_TLV_1_TAG: - { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n"); - vendor_ext_tlv_1* ve = (vendor_ext_tlv_1*)tlv; - if(!push32(ve->dummy, ppWritePackedMsg, end)) - return 0; - return 1; - } - break; + case VENDOR_EXT_TLV_1_TAG: { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n"); + vendor_ext_tlv_1 *ve = (vendor_ext_tlv_1 *)tlv; + + if(!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; + + return 1; + } + break; + default: return -1; break; } } -int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* config) { - +int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t *config) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); if(header->message_id == P7_VENDOR_EXT_IND) { - vendor_ext_p7_ind* req = (vendor_ext_p7_ind*)(header); + vendor_ext_p7_ind *req = (vendor_ext_p7_ind *)(header); + if(!pull16(ppReadPackedMessage, &req->error_code, end)) return 0; } @@ -758,54 +675,48 @@ int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** return 1; } -int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) { +int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); if(header->message_id == P7_VENDOR_EXT_REQ) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); - vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header); + vendor_ext_p7_req *req = (vendor_ext_p7_req *)(header); + if(!(push16(req->dummy1, ppWritePackedMsg, end) && - push16(req->dummy2, ppWritePackedMsg, end))) + push16(req->dummy2, ppWritePackedMsg, end))) return 0; } + return 1; } -int vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) { - +int vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); if(header->message_id == P5_VENDOR_EXT_REQ) { - vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header); + vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header); //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2); return (!(push16(req->dummy1, ppWritePackedMsg, end) && - push16(req->dummy2, ppWritePackedMsg, end))); + push16(req->dummy2, ppWritePackedMsg, end))); } + return 0; } static pthread_t vnf_start_pthread; static pthread_t vnf_p7_start_pthread; -void* vnf_p7_start_thread(void *ptr) { - +void *vnf_p7_start_thread(void *ptr) { printf("%s()\n", __FUNCTION__); - pthread_setname_np(pthread_self(), "VNF_P7"); - - nfapi_vnf_p7_config_t* config = (nfapi_vnf_p7_config_t*)ptr; - + nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr; nfapi_vnf_p7_start(config); - return config; } void set_thread_priority(int priority); -void* vnf_p7_thread_start(void* ptr) { - +void *vnf_p7_thread_start(void *ptr) { set_thread_priority(79); - - vnf_p7_info* p7_vnf = (vnf_p7_info*)ptr; - + vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr; p7_vnf->config->port = p7_vnf->local_port; p7_vnf->config->sync_indication = &phy_sync_indication; p7_vnf->config->subframe_indication = &phy_subframe_indication; @@ -821,117 +732,87 @@ void* vnf_p7_thread_start(void* ptr) { p7_vnf->config->nrach_indication = &phy_nrach_indication; p7_vnf->config->malloc = &vnf_allocate; p7_vnf->config->free = &vnf_deallocate; - p7_vnf->config->trace = &vnf_trace; - p7_vnf->config->vendor_ext = &phy_vendor_ext; p7_vnf->config->user_data = p7_vnf; - p7_vnf->mac->user_data = p7_vnf; - p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension; p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension; p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv; p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv; p7_vnf->config->codec_config.allocate = &vnf_allocate; p7_vnf->config->codec_config.deallocate = &vnf_deallocate; - p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext; p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext; - NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config); - return 0; } -int pnf_start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp) { - - vnf_info* vnf = (vnf_info*)(config->user_data); +int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_response_t *resp) { + vnf_info *vnf = (vnf_info *)(config->user_data); vnf_p7_info *p7_vnf = vnf->p7_vnfs; pnf_info *pnf = vnf->pnfs; nfapi_param_request_t req; - printf("[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started); if(p7_vnf->thread_started == 0) { - pthread_t vnf_p7_thread; pthread_create(&vnf_p7_thread, NULL, &vnf_p7_thread_start, p7_vnf); p7_vnf->thread_started = 1; - } - else - { - // P7 thread already running. + } else { + // P7 thread already running. } // start all the phys in the pnf. printf("[VNF] Sending NFAPI_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); - memset(&req, 0, sizeof(req)); req.header.message_id = NFAPI_PARAM_REQUEST; req.header.phy_id = pnf->phys[0].id; - nfapi_vnf_param_req(config, p5_idx, &req); - return 0; } extern uint32_t to_earfcn(int eutra_bandP,uint32_t dl_CarrierFreq,uint32_t bw); -int param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* resp) { - +int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t *resp) { printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); - - vnf_info* vnf = (vnf_info*)(config->user_data); + vnf_info *vnf = (vnf_info *)(config->user_data); vnf_p7_info *p7_vnf = vnf->p7_vnfs; - pnf_info *pnf = vnf->pnfs; phy_info *phy = pnf->phys; struct sockaddr_in pnf_p7_sockaddr; nfapi_config_request_t *req = &RC.mac[0]->config[0]; - phy->remote_port = resp->nfapi_config.p7_pnf_port.value; - memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4); - phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr); - // for now just 1 - - printf("[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, p7_vnf->periodic_timing_period); - + printf("[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, + p7_vnf->periodic_timing_period); req->header.message_id = NFAPI_CONFIG_REQUEST; req->header.phy_id = phy->id; - printf("[VNF] Send NFAPI_CONFIG_REQUEST\n"); - req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NFAPI_P7_VNF_PORT_TAG; req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port; req->num_tlv++; - printf("[VNF] DJP local_port:%d\n", p7_vnf->local_port); - req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; struct sockaddr_in vnf_p7_sockaddr; vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr); memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4); req->num_tlv++; printf("[VNF] DJP local_addr:%s\n", p7_vnf->local_addr); - req->nfapi_config.timing_window.tl.tag = NFAPI_NFAPI_TIMING_WINDOW_TAG; req->nfapi_config.timing_window.value = p7_vnf->timing_window; printf("[VNF] Timing window:%u\n", p7_vnf->timing_window); req->num_tlv++; if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) { - req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NFAPI_TIMING_INFO_MODE_TAG; req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled); req->num_tlv++; if(p7_vnf->periodic_timing_enabled) { - req->nfapi_config.timing_info_period.tl.tag = NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG; req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period; req->num_tlv++; @@ -943,142 +824,110 @@ int param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t ve2.tl.tag = VENDOR_EXT_TLV_2_TAG; ve2.dummy = 2016; req->vendor_extension = &ve2.tl; - nfapi_vnf_config_req(config, p5_idx, req); printf("[VNF] Sent NFAPI_CONFIG_REQ num_tlv:%u\n",req->num_tlv); - return 0; } -int config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp) { - +int config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_config_response_t *resp) { nfapi_start_request_t req; - printf("[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); - printf("[VNF] Calling oai_enb_init()\n"); oai_enb_init(); - memset(&req, 0, sizeof(req)); req.header.message_id = NFAPI_START_REQUEST; req.header.phy_id = resp->header.phy_id; nfapi_vnf_start_req(config, p5_idx, &req); - printf("[VNF] Send NFAPI_START_REQUEST idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); - return 0; } -int start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp) { - +int start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_start_response_t *resp) { printf("[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); - - vnf_info* vnf = (vnf_info*)(config->user_data); - + vnf_info *vnf = (vnf_info *)(config->user_data); pnf_info *pnf = vnf->pnfs; phy_info *phy = pnf->phys; vnf_p7_info *p7_vnf = vnf->p7_vnfs; nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id); - return 0; } -int vendor_ext_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg) { - +int vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg) { printf("[VNF] %s\n", __FUNCTION__); switch(msg->message_id) { - case P5_VENDOR_EXT_RSP: - { - vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)msg; - printf("[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code); - - // send the start request - - nfapi_pnf_start_request_t req; - memset(&req, 0, sizeof(req)); - req.header.message_id = NFAPI_PNF_START_REQUEST; - nfapi_vnf_pnf_start_req(config, p5_idx, &req); - } - break; + case P5_VENDOR_EXT_RSP: { + vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg; + printf("[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code); + // send the start request + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); + } + break; } return 0; } -int vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) { - +int vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) { //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); - if(header->message_id == P5_VENDOR_EXT_RSP) - { - vendor_ext_p5_rsp* req = (vendor_ext_p5_rsp*)(header); + if(header->message_id == P5_VENDOR_EXT_RSP) { + vendor_ext_p5_rsp *req = (vendor_ext_p5_rsp *)(header); return(!pull16(ppReadPackedMessage, &req->error_code, end)); } + return 0; } -nfapi_p4_p5_message_header_t* vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size) { - +nfapi_p4_p5_message_header_t *vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size) { if(message_id == P5_VENDOR_EXT_RSP) { *msg_size = sizeof(vendor_ext_p5_rsp); - return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_rsp)); + return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_rsp)); } + return 0; } -void vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header) { +void vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header) { free(header); } nfapi_vnf_config_t *config = 0; -void vnf_start_thread(void* ptr) { - +void vnf_start_thread(void *ptr) { NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] VNF NFAPI thread - nfapi_vnf_start()%s\n", __FUNCTION__); - pthread_setname_np(pthread_self(), "VNF"); - - config = (nfapi_vnf_config_t*)ptr; - + config = (nfapi_vnf_config_t *)ptr; nfapi_vnf_start(config); } static vnf_info vnf; -extern uint8_t nfapi_mode; -/*------------------------------------------------------------------------------*/ -void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) -{ - nfapi_mode = 2; +/*------------------------------------------------------------------------------*/ +void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { + nfapi_setmode(NFAPI_MODE_VNF); memset(&vnf, 0, sizeof(vnf)); - memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs)); - vnf.p7_vnfs[0].timing_window = 32; vnf.p7_vnfs[0].periodic_timing_enabled = 1; vnf.p7_vnfs[0].aperiodic_timing_enabled = 0; vnf.p7_vnfs[0].periodic_timing_period = 10; - vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create(); NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port); - strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr); vnf.p7_vnfs[0].local_port = 50001; - vnf.p7_vnfs[0].mac = (mac_t*)malloc(sizeof(mac_t)); - - nfapi_vnf_config_t* config = nfapi_vnf_config_create(); - + vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t)); + nfapi_vnf_config_t *config = nfapi_vnf_config_create(); config->malloc = malloc; config->free = free; config->trace = &vnf_trace; - config->vnf_p5_port = vnf_p5_port; config->vnf_ipv4 = 1; config->vnf_ipv6 = 0; - config->pnf_list = 0; config->phy_list = 0; - config->pnf_connection_indication = &pnf_connection_indication_cb; config->pnf_disconnect_indication = &pnf_disconnection_indication_cb; config->pnf_param_resp = &pnf_param_resp_cb; @@ -1088,33 +937,26 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) config->config_resp = &config_resp_cb; config->start_resp = &start_resp_cb; config->vendor_ext = &vendor_ext_cb; - config->user_data = &vnf; - // To allow custom vendor extentions to be added to nfapi config->codec_config.unpack_vendor_extension_tlv = &vnf_unpack_vendor_extension_tlv; config->codec_config.pack_vendor_extension_tlv = &vnf_pack_vendor_extension_tlv; - config->codec_config.unpack_p4_p5_vendor_extension = &vnf_unpack_p4_p5_vendor_extension; config->codec_config.pack_p4_p5_vendor_extension = &vnf_pack_p4_p5_vendor_extension; config->allocate_p4_p5_vendor_ext = &vnf_allocate_p4_p5_vendor_ext; config->deallocate_p4_p5_vendor_ext = &vnf_deallocate_p4_p5_vendor_ext; config->codec_config.allocate = &vnf_allocate; config->codec_config.deallocate = &vnf_deallocate; - NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); - pthread_create(&vnf_start_pthread, NULL, (void*)&vnf_start_thread, config); + pthread_create(&vnf_start_pthread, NULL, (void *)&vnf_start_thread, config); NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__); } -int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) -{ +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; - dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! dl_config_req->header.message_id = NFAPI_DL_CONFIG_REQUEST; int retval = nfapi_vnf_p7_dl_config_req(p7_config, dl_config_req); - dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = 1; dl_config_req->dl_config_request_body.number_dci = 0; dl_config_req->dl_config_request_body.number_pdu = 0; @@ -1123,35 +965,31 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) if (retval!=0) { LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); } + return retval; } -int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) -{ +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; - tx_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! tx_req->header.message_id = NFAPI_TX_REQUEST; //LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_req->sfn_sf), tx_req->tx_request_body.number_of_pdus); - int retval = nfapi_vnf_p7_tx_req(p7_config, tx_req); - if (retval!=0) { LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval); } else { tx_req->tx_request_body.number_of_pdus = 0; } + return retval; } int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; - hi_dci0_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; //LOG_D(PHY, "[VNF] %s() HI_DCI0_REQ sfn_sf:%d dci:%d hi:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req->hi_dci0_request_body.number_of_dci, hi_dci0_req->hi_dci0_request_body.number_of_hi); - int retval = nfapi_vnf_p7_hi_dci0_req(p7_config, hi_dci0_req); if (retval!=0) { @@ -1160,19 +998,16 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { hi_dci0_req->hi_dci0_request_body.number_of_hi = 0; hi_dci0_req->hi_dci0_request_body.number_of_dci = 0; } + return retval; } int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { - nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; - ul_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! ul_config_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; //LOG_D(PHY, "[VNF] %s() header message_id:%02x\n", __FUNCTION__, ul_config_req->header.message_id); - //LOG_D(PHY, "[VNF] %s() UL_CONFIG sfn_sf:%d PDUs:%d rach_prach_frequency_resources:%d srs_present:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ul_config_req->sfn_sf), ul_config_req->ul_config_request_body.number_of_pdus, ul_config_req->ul_config_request_body.rach_prach_frequency_resources, ul_config_req->ul_config_request_body.srs_present); - int retval = nfapi_vnf_p7_ul_config_req(p7_config, ul_config_req); if (retval!=0) { @@ -1183,5 +1018,6 @@ int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { ul_config_req->ul_config_request_body.rach_prach_frequency_resources = 0; ul_config_req->ul_config_request_body.srs_present = 0; } + return retval; } diff --git a/nfapi/oai_integration/vendor_ext.h b/nfapi/oai_integration/vendor_ext.h index 0622432260060dc7ef3f4fc4d76f889a7e3860d8..f25aa703ccdb5a5f3eac99225585c6595309066d 100644 --- a/nfapi/oai_integration/vendor_ext.h +++ b/nfapi/oai_integration/vendor_ext.h @@ -1,12 +1,12 @@ /* * Copyright 2017 Cisco Systems, Inc. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,48 +20,62 @@ #include "nfapi_interface.h" typedef enum { - P5_VENDOR_EXT_REQ = NFAPI_VENDOR_EXT_MSG_MIN, - P5_VENDOR_EXT_RSP, + P5_VENDOR_EXT_REQ = NFAPI_VENDOR_EXT_MSG_MIN, + P5_VENDOR_EXT_RSP, - P7_VENDOR_EXT_REQ, - P7_VENDOR_EXT_IND + P7_VENDOR_EXT_REQ, + P7_VENDOR_EXT_IND } vendor_ext_message_id_e; typedef struct { - nfapi_p4_p5_message_header_t header; - uint16_t dummy1; - uint16_t dummy2; + nfapi_p4_p5_message_header_t header; + uint16_t dummy1; + uint16_t dummy2; } vendor_ext_p5_req; typedef struct { - nfapi_p4_p5_message_header_t header; - uint16_t error_code; + nfapi_p4_p5_message_header_t header; + uint16_t error_code; } vendor_ext_p5_rsp; typedef struct { - nfapi_p7_message_header_t header; - uint16_t dummy1; - uint16_t dummy2; + nfapi_p7_message_header_t header; + uint16_t dummy1; + uint16_t dummy2; } vendor_ext_p7_req; typedef struct { - nfapi_p7_message_header_t header; - uint16_t error_code; + nfapi_p7_message_header_t header; + uint16_t error_code; } vendor_ext_p7_ind; typedef struct { - nfapi_tl_t tl; - uint32_t dummy; + nfapi_tl_t tl; + uint32_t dummy; } vendor_ext_tlv_1; #define VENDOR_EXT_TLV_1_TAG 0xF001 typedef struct { - nfapi_tl_t tl; - uint32_t dummy; + nfapi_tl_t tl; + uint32_t dummy; } vendor_ext_tlv_2; #define VENDOR_EXT_TLV_2_TAG 0xF002 +typedef enum { + NFAPI_MONOLITHIC=0, + NFAPI_MODE_PNF, + NFAPI_MODE_VNF, + NFAPI_UE_STUB_PNF, + NFAPI_UE_STUB_OFFNET, + NFAPI_MODE_UNKNOWN +} nfapi_mode_t; + +char *nfapi_get_strmode(void); +void nfapi_logmode(void); +nfapi_mode_t nfapi_getmode(void); +void nfapi_setmode(nfapi_mode_t nfapi_mode); +#define NFAPI_MODE (nfapi_getmode()) #endif // _VENDOR_EXT_ diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index c180b5b0f9cfa24ae620950e19548d2b99387f3b..2daf1450c852c9bbb7b5ff1003e308903b494ba4 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -1545,7 +1545,7 @@ static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, // DJP - if(pusharray8(pdu->segments[j].segment_data, (uint32_t)(-1), pdu->segments[j].segment_length, ppWritePackedMsg, end) == 0) int push_ret = pusharray8(pdu->segments[j].segment_data, 65535, pdu->segments[j].segment_length, ppWritePackedMsg, end); - if (0 && pdu->segments[j].segment_length == 3) + if (pdu->segments[j].segment_length == 3) { NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, pdu->segments[j].segment_data[0], @@ -4429,40 +4429,43 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void * for(i = 0; i < totalNumPdus; ++i) { nfapi_tx_request_pdu_t* pdu = &(pNfapiMsg->tx_request_body.tx_pdu_list[i]); + if (pdu) { + uint16_t length = 0; + uint16_t index = 0; - uint16_t length = 0; - uint16_t index = 0; - - if(!(pull16(ppReadPackedMsg, &length, end) && + if(!(pull16(ppReadPackedMsg, &length, end) && pull16(ppReadPackedMsg, &index, end))) - return 0; + return 0; - pdu->pdu_length = length; - pdu->pdu_index = index; + pdu->pdu_length = length; + pdu->pdu_index = index; // TODO : May need to rethink this bit - pdu->num_segments = 1; - pdu->segments[0].segment_length = pdu->pdu_length; - pdu->segments[0].segment_data = nfapi_p7_allocate(pdu->pdu_length, config); + pdu->num_segments = 1; + pdu->segments[0].segment_length = pdu->pdu_length; + pdu->segments[0].segment_data = nfapi_p7_allocate(pdu->pdu_length, config); - if(pdu->segments[0].segment_data) - { - if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end)) + if(pdu->segments[0].segment_data) + { + if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end)) return 0; - if (0 && pdu->segments[0].segment_length == 3) - { + if (pdu->segments[0].segment_length == 3) + { NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__, pdu->segments[0].segment_data[0], pdu->segments[0].segment_data[1], pdu->segments[0].segment_data[2] ); - } - } - else - { + } + } + else + { NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request: Failed to allocate pdu (len:%d) %d/%d %d\n", pdu->pdu_length, totalNumPdus, i, pdu->pdu_index); - } + } + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n"); + } } } break; diff --git a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp index df0ca12305f6ca954c9f02f1874e31c46637022e..1c2f0bef8078a072d7abd9eab6de65cbe3b5568d 100644 --- a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp +++ b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp @@ -1,12 +1,12 @@ /* * Copyright 2017 Cisco Systems, Inc. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -34,609 +34,510 @@ #include <queue> #include <list> -struct phy_pdu -{ - phy_pdu() : buffer_len(1500), buffer(0), len(0) - { - buffer = (char*) malloc(buffer_len); - } - - virtual ~phy_pdu() - { - free(buffer); - } - - - unsigned buffer_len; - char* buffer; - unsigned len; +struct phy_pdu { + phy_pdu() : buffer_len(1500), buffer(0), len(0) { + buffer = (char *) malloc(buffer_len); + } + + virtual ~phy_pdu() { + free(buffer); + } + + + unsigned buffer_len; + char *buffer; + unsigned len; }; -class fapi_private -{ - std::mutex mutex; - std::queue<phy_pdu*> rx_buffer; - - std::queue<phy_pdu*> free_store; - public: - - fapi_private() - : byte_count(0), tick(0), first_dl_config(false) - { - } - - phy_pdu* allocate_phy_pdu() - { - phy_pdu* pdu = 0; - mutex.lock(); - if(free_store.empty()) - { - pdu = new phy_pdu(); - } - else - { - pdu = free_store.front(); - free_store.pop(); - } - mutex.unlock(); - return pdu; - } - - void release_phy_pdu(phy_pdu* pdu) - { - mutex.lock(); - free_store.push(pdu); - mutex.unlock(); - } - - bool rx_buffer_empty() - { - bool empty; - mutex.lock(); - empty = rx_buffer.empty(); - mutex.unlock(); - - return empty; - } - - - void push_rx_buffer(phy_pdu* buff) - { - mutex.lock(); - rx_buffer.push(buff); - mutex.unlock(); - } - - phy_pdu* pop_rx_buffer() - { - phy_pdu* buff = 0; - mutex.lock(); - if(!rx_buffer.empty()) - { - buff = rx_buffer.front(); - rx_buffer.pop(); - } - mutex.unlock(); - return buff; - } - - uint32_t byte_count; - uint32_t tick; - bool first_dl_config; +class fapi_private { + std::mutex mutex; + std::queue<phy_pdu *> rx_buffer; + + std::queue<phy_pdu *> free_store; + public: + + fapi_private() + : byte_count(0), tick(0), first_dl_config(false) { + } + + phy_pdu *allocate_phy_pdu() { + phy_pdu *pdu = 0; + mutex.lock(); + + if(free_store.empty()) { + pdu = new phy_pdu(); + } else { + pdu = free_store.front(); + free_store.pop(); + } + + mutex.unlock(); + return pdu; + } + + void release_phy_pdu(phy_pdu *pdu) { + mutex.lock(); + free_store.push(pdu); + mutex.unlock(); + } + + bool rx_buffer_empty() { + bool empty; + mutex.lock(); + empty = rx_buffer.empty(); + mutex.unlock(); + return empty; + } + + + void push_rx_buffer(phy_pdu *buff) { + mutex.lock(); + rx_buffer.push(buff); + mutex.unlock(); + } + + phy_pdu *pop_rx_buffer() { + phy_pdu *buff = 0; + mutex.lock(); + + if(!rx_buffer.empty()) { + buff = rx_buffer.front(); + rx_buffer.pop(); + } + + mutex.unlock(); + return buff; + } + + uint32_t byte_count; + uint32_t tick; + bool first_dl_config; }; extern "C" { - typedef struct fapi_internal - { - fapi_t _public; + typedef struct fapi_internal { + fapi_t _public; - fapi_cb_t callbacks; + fapi_cb_t callbacks; - uint8_t state; - fapi_config_t config; + uint8_t state; + fapi_config_t config; - int rx_sock; - int tx_sock; - struct sockaddr_in tx_addr; + int rx_sock; + int tx_sock; + struct sockaddr_in tx_addr; - uint32_t tx_byte_count; - uint32_t tick; - - fapi_private* fapi; + uint32_t tx_byte_count; + uint32_t tick; - } fapi_internal_t; + fapi_private *fapi; + + } fapi_internal_t; } extern void set_thread_priority(int); /* { - pthread_attr_t ptAttr; - - struct sched_param schedParam; - schedParam.__sched_priority = 79; - sched_setscheduler(0, SCHED_RR, &schedParam); + pthread_attr_t ptAttr; + + struct sched_param schedParam; + schedParam.__sched_priority = 79; + sched_setscheduler(0, SCHED_RR, &schedParam); - pthread_attr_setschedpolicy(&ptAttr, SCHED_RR); + pthread_attr_setschedpolicy(&ptAttr, SCHED_RR); - pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); - struct sched_param thread_params; - thread_params.sched_priority = 20; - pthread_attr_setschedparam(&ptAttr, &thread_params); + struct sched_param thread_params; + thread_params.sched_priority = 20; + pthread_attr_setschedparam(&ptAttr, &thread_params); } */ -void send_uplink_indications(fapi_internal_t* instance, uint16_t sfn_sf) -{ - fapi_harq_ind_t harq_ind; - (instance->callbacks.fapi_harq_ind)(&(instance->_public), &harq_ind); - - fapi_crc_ind_t crc_ind; - crc_ind.header.message_id = FAPI_CRC_INDICATION; - crc_ind.header.length = 0; //??; - crc_ind.sfn_sf = sfn_sf; - crc_ind.body.number_of_crcs = 1; - crc_ind.body.pdus[0].rx_ue_info.handle = 0; //?? - crc_ind.body.pdus[0].rx_ue_info.rnti = 0; //?? - crc_ind.body.pdus[0].rel8_pdu.crc_flag = 1; - - (instance->callbacks.fapi_crc_ind)(&(instance->_public), &crc_ind); - - if(!instance->fapi->rx_buffer_empty()) - { - fapi_rx_ulsch_ind_t rx_ind; - memset(&rx_ind, 0, sizeof(rx_ind)); - rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION; - rx_ind.sfn_sf = sfn_sf; - - - phy_pdu* buff = 0; - int i = 0; - std::list<phy_pdu*> free_list; - do - { - buff = instance->fapi->pop_rx_buffer(); - if(buff != 0) - { - if(buff->len == 0) - { - printf("[FAPI] Buffer length = 0\n"); - } - - rx_ind.body.pdus[i].rx_ue_info.handle = 0xDEADBEEF; - rx_ind.body.pdus[i].rx_ue_info.rnti = 0x4242; - - rx_ind.body.pdus[i].rel8_pdu.length = buff->len; - //rx_ind.pdus[i].rel8_pdu.data_offset; - //rx_ind.pdus[i].rel8_pdu.ul_cqi; - //rx_ind.pdus[i].rel8_pdu.timing_advance; - - rx_ind.body.data[i] = buff->buffer; - - rx_ind.body.number_of_pdus++; - i++; - - instance->fapi->byte_count += buff->len; - - free_list.push_back(buff); - } - }while(buff != 0 && i < 8); - - (instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind); - - for(phy_pdu* pdu : free_list) - { - instance->fapi->release_phy_pdu(pdu); - //free(tx_req.tx_request_body.tx_pdu_list[j].segments[0].segment_data); - } - } - else - { - fapi_rx_ulsch_ind_t rx_ind; - memset(&rx_ind, 0, sizeof(rx_ind)); - rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION; - rx_ind.sfn_sf = sfn_sf; - (instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind); - } - - - fapi_rx_cqi_ind_t cqi_ind; - cqi_ind.sfn_sf = sfn_sf; - (instance->callbacks.fapi_rx_cqi_ind)(&(instance->_public), &cqi_ind); - - fapi_rx_sr_ind_t sr_ind; - sr_ind.sfn_sf = sfn_sf; - (instance->callbacks.fapi_rx_sr_ind)(&(instance->_public), &sr_ind); - - fapi_rach_ind_t rach_ind; - rach_ind.sfn_sf = sfn_sf; - (instance->callbacks.fapi_rach_ind)(&(instance->_public), &rach_ind); - - fapi_srs_ind_t srs_ind; - srs_ind.sfn_sf = sfn_sf; - (instance->callbacks.fapi_srs_ind)(&(instance->_public), &srs_ind); - /* - nfapi_lbt_dl_indication_t lbt_ind; - memset(&lbt_ind, 0, sizeof(lbt_ind)); - lbt_ind.header.message_id = NFAPI_LBT_DL_INDICATION; - lbt_ind.header.phy_id = config->phy_id; - lbt_ind.sfn_sf = sfn_sf; - nfapi_pnf_p7_lbt_dl_ind(config, &lbt_ind); - - vendor_ext_p7_ind ve_p7_ind; - memset(&ve_p7_ind, 0, sizeof(ve_p7_ind)); - ve_p7_ind.header.message_id = P7_VENDOR_EXT_IND; - ve_p7_ind.header.phy_id = config->phy_id; - ve_p7_ind.error_code = NFAPI_MSG_OK; - nfapi_pnf_p7_vendor_extension(config, &(ve_p7_ind.header)); - */ - - fapi_nb_harq_ind_t nb_harq_ind; - nb_harq_ind.sfn_sf = sfn_sf; - (instance->callbacks.fapi_nb_harq_ind)(&(instance->_public), &nb_harq_ind); - - fapi_nrach_ind_t nrach_ind; - nrach_ind.sfn_sf = sfn_sf; - (instance->callbacks.fapi_nrach_ind)(&(instance->_public), &nrach_ind); - +void send_uplink_indications(fapi_internal_t *instance, uint16_t sfn_sf) { + fapi_harq_ind_t harq_ind; + (instance->callbacks.fapi_harq_ind)(&(instance->_public), &harq_ind); + fapi_crc_ind_t crc_ind; + crc_ind.header.message_id = FAPI_CRC_INDICATION; + crc_ind.header.length = 0; //??; + crc_ind.sfn_sf = sfn_sf; + crc_ind.body.number_of_crcs = 1; + crc_ind.body.pdus[0].rx_ue_info.handle = 0; //?? + crc_ind.body.pdus[0].rx_ue_info.rnti = 0; //?? + crc_ind.body.pdus[0].rel8_pdu.crc_flag = 1; + (instance->callbacks.fapi_crc_ind)(&(instance->_public), &crc_ind); + + if(!instance->fapi->rx_buffer_empty()) { + fapi_rx_ulsch_ind_t rx_ind; + memset(&rx_ind, 0, sizeof(rx_ind)); + rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION; + rx_ind.sfn_sf = sfn_sf; + phy_pdu *buff = 0; + int i = 0; + std::list<phy_pdu *> free_list; + + do { + buff = instance->fapi->pop_rx_buffer(); + + if(buff != 0) { + if(buff->len == 0) { + printf("[FAPI] Buffer length = 0\n"); + } + + rx_ind.body.pdus[i].rx_ue_info.handle = 0xDEADBEEF; + rx_ind.body.pdus[i].rx_ue_info.rnti = 0x4242; + rx_ind.body.pdus[i].rel8_pdu.length = buff->len; + //rx_ind.pdus[i].rel8_pdu.data_offset; + //rx_ind.pdus[i].rel8_pdu.ul_cqi; + //rx_ind.pdus[i].rel8_pdu.timing_advance; + rx_ind.body.data[i] = buff->buffer; + rx_ind.body.number_of_pdus++; + i++; + instance->fapi->byte_count += buff->len; + free_list.push_back(buff); + } + } while(buff != 0 && i < 8); + + (instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind); + + for(phy_pdu *pdu : free_list) { + instance->fapi->release_phy_pdu(pdu); + //free(tx_req.tx_request_body.tx_pdu_list[j].segments[0].segment_data); + } + } else { + fapi_rx_ulsch_ind_t rx_ind; + memset(&rx_ind, 0, sizeof(rx_ind)); + rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION; + rx_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind); + } + + fapi_rx_cqi_ind_t cqi_ind; + cqi_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rx_cqi_ind)(&(instance->_public), &cqi_ind); + fapi_rx_sr_ind_t sr_ind; + sr_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rx_sr_ind)(&(instance->_public), &sr_ind); + fapi_rach_ind_t rach_ind; + rach_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_rach_ind)(&(instance->_public), &rach_ind); + fapi_srs_ind_t srs_ind; + srs_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_srs_ind)(&(instance->_public), &srs_ind); + /* + nfapi_lbt_dl_indication_t lbt_ind; + memset(&lbt_ind, 0, sizeof(lbt_ind)); + lbt_ind.header.message_id = NFAPI_LBT_DL_INDICATION; + lbt_ind.header.phy_id = config->phy_id; + lbt_ind.sfn_sf = sfn_sf; + nfapi_pnf_p7_lbt_dl_ind(config, &lbt_ind); + + vendor_ext_p7_ind ve_p7_ind; + memset(&ve_p7_ind, 0, sizeof(ve_p7_ind)); + ve_p7_ind.header.message_id = P7_VENDOR_EXT_IND; + ve_p7_ind.header.phy_id = config->phy_id; + ve_p7_ind.error_code = NFAPI_MSG_OK; + nfapi_pnf_p7_vendor_extension(config, &(ve_p7_ind.header)); + */ + fapi_nb_harq_ind_t nb_harq_ind; + nb_harq_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_nb_harq_ind)(&(instance->_public), &nb_harq_ind); + fapi_nrach_ind_t nrach_ind; + nrach_ind.sfn_sf = sfn_sf; + (instance->callbacks.fapi_nrach_ind)(&(instance->_public), &nrach_ind); } -void* fapi_thread_start(void* ptr) -{ - set_thread_priority(81); - - fapi_internal_t* instance = (fapi_internal_t*)ptr; - uint16_t sfn_sf_dec = 0; - uint32_t last_tv_usec = 0; - uint32_t last_tv_sec = 0; - - uint32_t millisec; - uint32_t last_millisec = -1; - uint16_t catchup = 0; - - while(1) - { - // get the time - struct timeval sf_start; - (void)gettimeofday(&sf_start, NULL); - - uint16_t sfn_sf = ((((sfn_sf_dec) / 10) << 4) | (((sfn_sf_dec) - (((sfn_sf_dec) / 10) * 10)) & 0xF)); - // increment the sfn/sf - for the next subframe - sfn_sf_dec++; - if(sfn_sf_dec > 10239) - sfn_sf_dec = 0; - - - fapi_subframe_ind_t ind; - ind.sfn_sf = sfn_sf; - - if(instance->fapi->first_dl_config) - send_uplink_indications(instance, sfn_sf); - - if(instance->tick == 1000) - { - if(instance->tx_byte_count > 0) - { - printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count); - instance->tx_byte_count = 0; - } - - instance->tick = 0; - } - - instance->tick++; - - (instance->callbacks.fapi_subframe_ind)(&(instance->_public), &ind); - - { - phy_pdu* pdu = instance->fapi->allocate_phy_pdu(); - int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, MSG_DONTWAIT, 0, 0); - if(len > 0) - { - pdu->len = len; - instance->fapi->push_rx_buffer(pdu); - } - else - { - instance->fapi->release_phy_pdu(pdu); - } - } - - - if(catchup) - { - catchup--; - } - else - { - struct timespec now_ts; - struct timespec sleep_ts; - struct timespec sleep_rem_ts; - - // get the current time - clock_gettime(CLOCK_MONOTONIC, &now_ts); - - - // determine how long to sleep before the start of the next 1ms - sleep_ts.tv_sec = 0; - sleep_ts.tv_nsec = 1e6 - (now_ts.tv_nsec % 1000000); - - int nanosleep_result = nanosleep(&sleep_ts, &sleep_rem_ts); - - if(nanosleep_result != 0) - printf("*** nanosleep failed or was interrupted\n"); - - - clock_gettime(CLOCK_MONOTONIC, &now_ts); - millisec = now_ts.tv_nsec / 1e6; - - if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) - { - printf("*** missing millisec %d %d\n", last_millisec, millisec); - catchup = millisec - last_millisec - 1; - } - - last_millisec = millisec; - } - } +void *fapi_thread_start(void *ptr) { + set_thread_priority(81); + fapi_internal_t *instance = (fapi_internal_t *)ptr; + uint16_t sfn_sf_dec = 0; + uint32_t last_tv_usec = 0; + uint32_t last_tv_sec = 0; + uint32_t millisec; + uint32_t last_millisec = -1; + uint16_t catchup = 0; + + while(1) { + // get the time + struct timeval sf_start; + (void)gettimeofday(&sf_start, NULL); + uint16_t sfn_sf = ((((sfn_sf_dec) / 10) << 4) | (((sfn_sf_dec) - (((sfn_sf_dec) / 10) * 10)) & 0xF)); + // increment the sfn/sf - for the next subframe + sfn_sf_dec++; + + if(sfn_sf_dec > 10239) + sfn_sf_dec = 0; + + fapi_subframe_ind_t ind; + ind.sfn_sf = sfn_sf; + + if(instance->fapi->first_dl_config) + send_uplink_indications(instance, sfn_sf); + + if(instance->tick == 1000) { + if(instance->tx_byte_count > 0) { + printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count); + instance->tx_byte_count = 0; + } + + instance->tick = 0; + } + + instance->tick++; + (instance->callbacks.fapi_subframe_ind)(&(instance->_public), &ind); + { + phy_pdu *pdu = instance->fapi->allocate_phy_pdu(); + int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, MSG_DONTWAIT, 0, 0); + + if(len > 0) { + pdu->len = len; + instance->fapi->push_rx_buffer(pdu); + } else { + instance->fapi->release_phy_pdu(pdu); + } + } + + if(catchup) { + catchup--; + } else { + struct timespec now_ts; + struct timespec sleep_ts; + struct timespec sleep_rem_ts; + // get the current time + clock_gettime(CLOCK_MONOTONIC, &now_ts); + // determine how long to sleep before the start of the next 1ms + sleep_ts.tv_sec = 0; + sleep_ts.tv_nsec = 1e6 - (now_ts.tv_nsec % 1000000); + int nanosleep_result = nanosleep(&sleep_ts, &sleep_rem_ts); + + if(nanosleep_result != 0) + printf("*** nanosleep failed or was interrupted\n"); + + clock_gettime(CLOCK_MONOTONIC, &now_ts); + millisec = now_ts.tv_nsec / 1e6; + + if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) { + printf("*** missing millisec %d %d\n", last_millisec, millisec); + catchup = millisec - last_millisec - 1; + } + + last_millisec = millisec; + } + } } extern "C" { - fapi_t* fapi_create(fapi_cb_t* callbacks, fapi_config_t* config) - { - fapi_internal_t* instance = (fapi_internal*)calloc(1, sizeof(fapi_internal_t)); - instance->callbacks = *callbacks; - instance->config = *config; - instance->state = 0; - - instance->fapi = new fapi_private(); - - return (fapi_t*)instance; - } - - void fapi_destroy(fapi_t* fapi) - { - fapi_internal_t* instance = (fapi_internal_t*)fapi; - - delete instance->fapi; - free(instance); - } - - void* fapi_rx_thread_start(void* ptr) - { - set_thread_priority(60); - - fapi_internal_t* instance = (fapi_internal_t*)ptr; - - while(1) - { - phy_pdu* pdu = instance->fapi->allocate_phy_pdu(); - int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, 0, 0, 0); - if(len > 0) - { - pdu->len = len; - instance->fapi->push_rx_buffer(pdu); - } - else - { - instance->fapi->release_phy_pdu(pdu); - } - - } - } - - void fapi_start_data(fapi_t* fapi, unsigned rx_port, const char* tx_address, unsigned tx_port) - { - fapi_internal_t* instance = (fapi_internal_t*)fapi; - - printf("[FAPI] Rx Data from %d\n", rx_port); - printf("[FAPI] Tx Data to %s:%d\n", tx_address, tx_port); - - instance->rx_sock = socket(AF_INET, SOCK_DGRAM, 0); - - if(instance->rx_sock < 0) - { - printf("[FAPI] Failed to create socket\n"); - return; - } - - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(rx_port); - addr.sin_addr.s_addr = INADDR_ANY; - - int bind_result = bind(instance->rx_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); - - if(bind_result == -1) - { - printf("[FAPI] Failed to bind to port %d\n", rx_port); - close(instance->rx_sock); - return ; - } - - instance->tx_sock = socket(AF_INET, SOCK_DGRAM, 0); - instance->tx_addr.sin_family = AF_INET; - instance->tx_addr.sin_port = htons(tx_port); - instance->tx_addr.sin_addr.s_addr = inet_addr(tx_address); - - } - - - void fill_tlv(fapi_tlv_t tlvs[], uint8_t count, uint8_t tag, uint8_t len, uint16_t value) - { - tlvs[count].tag = tag; - tlvs[count].value = value; - tlvs[count].length = len; - - } - - int fapi_param_request(fapi_t* fapi, fapi_param_req_t* req) - { - fapi_internal_t* instance = (fapi_internal_t*)fapi; - - fapi_param_resp_t resp; - resp.header.message_id = FAPI_PARAM_RESPONSE; - - resp.error_code = FAPI_MSG_OK; - - resp.number_of_tlvs = 0; - fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_STATE_TAG, 2, instance->state); - - - if(instance->state == 0) - { - if(instance->config.duplex_mode == 0) - { - // -- TDD - // Downlink Bandwidth Support - // Uplink Bandwidth Support - // Downlink Modulation Support - // Uplink Modulation Support - // PHY Antenna Capability - // Release Capability - // MBSFN Capability - } - else if(instance->config.duplex_mode == 1) - { - // -- FDD - // Downlink Bandwidth Support - fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.dl_channel_bw_support); - // Uplink Bandwidth Support - fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.ul_channel_bw_support); - // Downlink Modulation Support - // Uplink Modulation Support - // PHY Antenna Capability - // Release Capability - // MBSFN Capability - // LAA Capability - } - } - else - { - if(instance->config.duplex_mode == 0) - { - // -- TDD - // Downlink Bandwidth Support - // Uplink Bandwidth Support - // Downlink Modulation Support - // Uplink Modulation Support - // PHY Antenna Capability - // Release Capability - // MBSFN Capability - // Duplexing Mode - // PCFICH Power Offset - // P-B - // DL Cyclic Prefix Type - // UL Cyclic Prefix Type - // RF Config - // PHICH Config - // SCH Config - // PRACH Config - // PUSCH Config - // PUCCH Config - // SRS Config - // Uplink Reference Signal Config - // TDD Frame Structure Config - // Data Report Mode - } - else if(instance->config.duplex_mode == 1) - { - // FDD - // Downlink Bandwidth Support - // Uplink Bandwidth Support - // Downlink Modulation Support - // Uplink Modulation Support - // PHY Antenna Capability - // Release Capability - // MBSFN Capability - // LAA Capability - // Duplexing Mode - // PCFICH Power Offset - // P-B - // DL Cyclic Prefix Type - // UL Cyclic Prefix Type - // RF Config - // PHICH Config - // SCH Config - // PRACH Config - // PUSCH Config - // PUCCH Config - // SRS Config - // Uplink Reference Signal Config - // Data Report Mode - } - } - - - //todo fill - (instance->callbacks.fapi_param_response)(fapi, &resp); - - return 0; - } - - int fapi_config_request(fapi_t* fapi, fapi_config_req_t* req) - { - fapi_internal_t* instance = (fapi_internal_t*)fapi; - - fapi_config_resp_t resp; - resp.header.message_id = FAPI_CONFIG_RESPONSE; - resp.error_code = FAPI_MSG_OK; - - (instance->callbacks.fapi_config_response)(fapi, &resp); - return 0; - } - - int fapi_start_request(fapi_t* fapi, fapi_start_req_t* req) - { - fapi_internal_t* instance = (fapi_internal_t*)fapi; - - pthread_t fapi_thread; - pthread_create(&fapi_thread, NULL, &fapi_thread_start, instance); - - return 0; - } - - int fapi_dl_config_request(fapi_t* fapi, fapi_dl_config_req_t* req) - { - fapi_internal_t* instance = (fapi_internal_t*)fapi; - instance->fapi->first_dl_config = true; - return 0; - } - int fapi_ul_config_request(fapi_t* fapi, fapi_ul_config_req_t* req) - { - fapi_internal_t* instance = (fapi_internal_t*)fapi; - return 0; - } - int fapi_hi_dci0_request(fapi_t* fapi, fapi_hi_dci0_req_t* req) - { - fapi_internal_t* instance = (fapi_internal_t*)fapi; - return 0; - } - int fapi_tx_request(fapi_t* fapi, fapi_tx_req_t* req) - { - fapi_internal_t* instance = (fapi_internal_t*)fapi; - - for(int i = 0; i < req->body.number_of_pdus; ++i) - { - uint16_t len = req->body.pdus[i].pdu_length; - uint32_t* data = req->body.pdus[i].tlvs[0].value; - //printf("[FAPI] sfnsf:%d len:%d\n", req->sfn_sf,len); - // - instance->tx_byte_count += len; - - int sendto_result = sendto(instance->tx_sock, data, len, 0, (struct sockaddr*)&(instance->tx_addr), sizeof(instance->tx_addr)); - - if(sendto_result == -1) - { - // error - } - } - - return 0; - } + fapi_t *fapi_create(fapi_cb_t *callbacks, fapi_config_t *config) { + fapi_internal_t *instance = (fapi_internal *)calloc(1, sizeof(fapi_internal_t)); + instance->callbacks = *callbacks; + instance->config = *config; + instance->state = 0; + instance->fapi = new fapi_private(); + return (fapi_t *)instance; + } + + void fapi_destroy(fapi_t *fapi) { + fapi_internal_t *instance = (fapi_internal_t *)fapi; + delete instance->fapi; + free(instance); + } + + void *fapi_rx_thread_start(void *ptr) { + set_thread_priority(60); + fapi_internal_t *instance = (fapi_internal_t *)ptr; + + while(1) { + phy_pdu *pdu = instance->fapi->allocate_phy_pdu(); + int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, 0, 0, 0); + + if(len > 0) { + pdu->len = len; + instance->fapi->push_rx_buffer(pdu); + } else { + instance->fapi->release_phy_pdu(pdu); + } + } + } + + void fapi_start_data(fapi_t *fapi, unsigned rx_port, const char *tx_address, unsigned tx_port) { + fapi_internal_t *instance = (fapi_internal_t *)fapi; + printf("[FAPI] Rx Data from %u\n", rx_port); + printf("[FAPI] Tx Data to %s:%u\n", tx_address, tx_port); + instance->rx_sock = socket(AF_INET, SOCK_DGRAM, 0); + + if(instance->rx_sock < 0) { + printf("[FAPI] Failed to create socket\n"); + return; + } + + struct sockaddr_in addr; + + memset(&addr, 0, sizeof(addr)); + + addr.sin_family = AF_INET; + + addr.sin_port = htons(rx_port); + + addr.sin_addr.s_addr = INADDR_ANY; + + int bind_result = bind(instance->rx_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); + + if(bind_result == -1) { + printf("[FAPI] Failed to bind to port %u\n", rx_port); + close(instance->rx_sock); + return ; + } + + instance->tx_sock = socket(AF_INET, SOCK_DGRAM, 0); + instance->tx_addr.sin_family = AF_INET; + instance->tx_addr.sin_port = htons(tx_port); + instance->tx_addr.sin_addr.s_addr = inet_addr(tx_address); + } + + + void fill_tlv(fapi_tlv_t tlvs[], uint8_t count, uint8_t tag, uint8_t len, uint16_t value) { + tlvs[count].tag = tag; + tlvs[count].value = value; + tlvs[count].length = len; + } + + int fapi_param_request(fapi_t *fapi, fapi_param_req_t *req) { + fapi_internal_t *instance = (fapi_internal_t *)fapi; + fapi_param_resp_t resp; + resp.header.message_id = FAPI_PARAM_RESPONSE; + resp.error_code = FAPI_MSG_OK; + resp.number_of_tlvs = 0; + fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_STATE_TAG, 2, instance->state); + + if(instance->state == 0) { + if(instance->config.duplex_mode == 0) { + // -- TDD + // Downlink Bandwidth Support + // Uplink Bandwidth Support + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + } else if(instance->config.duplex_mode == 1) { + // -- FDD + // Downlink Bandwidth Support + fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.dl_channel_bw_support); + // Uplink Bandwidth Support + fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.ul_channel_bw_support); + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + // LAA Capability + } + } else { + if(instance->config.duplex_mode == 0) { + // -- TDD + // Downlink Bandwidth Support + // Uplink Bandwidth Support + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + // Duplexing Mode + // PCFICH Power Offset + // P-B + // DL Cyclic Prefix Type + // UL Cyclic Prefix Type + // RF Config + // PHICH Config + // SCH Config + // PRACH Config + // PUSCH Config + // PUCCH Config + // SRS Config + // Uplink Reference Signal Config + // TDD Frame Structure Config + // Data Report Mode + } else if(instance->config.duplex_mode == 1) { + // FDD + // Downlink Bandwidth Support + // Uplink Bandwidth Support + // Downlink Modulation Support + // Uplink Modulation Support + // PHY Antenna Capability + // Release Capability + // MBSFN Capability + // LAA Capability + // Duplexing Mode + // PCFICH Power Offset + // P-B + // DL Cyclic Prefix Type + // UL Cyclic Prefix Type + // RF Config + // PHICH Config + // SCH Config + // PRACH Config + // PUSCH Config + // PUCCH Config + // SRS Config + // Uplink Reference Signal Config + // Data Report Mode + } + } + + //todo fill + (instance->callbacks.fapi_param_response)(fapi, &resp); + return 0; + } + + int fapi_config_request(fapi_t *fapi, fapi_config_req_t *req) { + fapi_internal_t *instance = (fapi_internal_t *)fapi; + fapi_config_resp_t resp; + resp.header.message_id = FAPI_CONFIG_RESPONSE; + resp.error_code = FAPI_MSG_OK; + (instance->callbacks.fapi_config_response)(fapi, &resp); + return 0; + } + + int fapi_start_request(fapi_t *fapi, fapi_start_req_t *req) { + fapi_internal_t *instance = (fapi_internal_t *)fapi; + pthread_t fapi_thread; + pthread_create(&fapi_thread, NULL, &fapi_thread_start, instance); + return 0; + } + + int fapi_dl_config_request(fapi_t *fapi, fapi_dl_config_req_t *req) { + fapi_internal_t *instance = (fapi_internal_t *)fapi; + instance->fapi->first_dl_config = true; + return 0; + } + int fapi_ul_config_request(fapi_t *fapi, fapi_ul_config_req_t *req) { + fapi_internal_t *instance = (fapi_internal_t *)fapi; + return 0; + } + int fapi_hi_dci0_request(fapi_t *fapi, fapi_hi_dci0_req_t *req) { + fapi_internal_t *instance = (fapi_internal_t *)fapi; + return 0; + } + int fapi_tx_request(fapi_t *fapi, fapi_tx_req_t *req) { + fapi_internal_t *instance = (fapi_internal_t *)fapi; + + for(int i = 0; i < req->body.number_of_pdus; ++i) { + uint16_t len = req->body.pdus[i].pdu_length; + uint32_t *data = req->body.pdus[i].tlvs[0].value; + //printf("[FAPI] sfnsf:%d len:%d\n", req->sfn_sf,len); + // + instance->tx_byte_count += len; + int sendto_result = sendto(instance->tx_sock, data, len, 0, (struct sockaddr *)&(instance->tx_addr), sizeof(instance->tx_addr)); + + if(sendto_result == -1) { + // error + } + } + + return 0; + } } diff --git a/nfapi/open-nFAPI/pnf_sim/src/main.cpp b/nfapi/open-nFAPI/pnf_sim/src/main.cpp index e2622cf3c3636f1021633e1570c8949d31088f8c..251e2a48cbdd2156b61e84d83c26adc2858c780e 100644 --- a/nfapi/open-nFAPI/pnf_sim/src/main.cpp +++ b/nfapi/open-nFAPI/pnf_sim/src/main.cpp @@ -101,7 +101,7 @@ class phy_info { index = 0; id = 0; - + udp = 0; local_port = 0; remote_addr = 0; remote_port = 0; @@ -178,6 +178,7 @@ class pnf_info sync_mode = 0; location_mode = 0; + location_coordinates = 0; dl_config_timing = 0; ul_config_timing = 0; tx_timing = 0; diff --git a/nfapi/open-nFAPI/vnf_sim/src/mac.cpp b/nfapi/open-nFAPI/vnf_sim/src/mac.cpp index fa6f487be8e2274d55ac10c69b238070abfea6f6..88898afc744133966b9eb079235b4537d2be453d 100644 --- a/nfapi/open-nFAPI/vnf_sim/src/mac.cpp +++ b/nfapi/open-nFAPI/vnf_sim/src/mac.cpp @@ -1,12 +1,12 @@ /* * Copyright 2017 Cisco Systems, Inc. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -31,1297 +31,1130 @@ #include <queue> #include <list> -uint32_t rand_range(uint32_t min, uint32_t max) -{ - return ((rand() % (max + 1 - min)) + min); +uint32_t rand_range(uint32_t min, uint32_t max) { + return ((rand() % (max + 1 - min)) + min); } -struct mac_pdu -{ - mac_pdu() : buffer_len(1500), buffer(0), len(0) - { - buffer = (char*) malloc(buffer_len); - } - - virtual ~mac_pdu() - { - free(buffer); - } - - unsigned buffer_len; - char* buffer; - unsigned len; +struct mac_pdu { + mac_pdu() : buffer_len(1500), buffer(0), len(0) { + buffer = (char *) malloc(buffer_len); + } + + virtual ~mac_pdu() { + free(buffer); + } + + unsigned buffer_len; + char *buffer; + unsigned len; }; -class mac_private -{ - std::mutex mutex; - std::queue<mac_pdu*> rx_buffer; - - std::queue<mac_pdu*> free_store; - public: - - mac_private(bool _wireshark_test_mode) - : byte_count(0), tick(0), wireshark_test_mode(_wireshark_test_mode) - { - - } - - mac_pdu* allocate_mac_pdu() - { - mac_pdu* pdu = 0; - mutex.lock(); - if(free_store.empty()) - { - pdu = new mac_pdu(); - } - else - { - pdu = free_store.front(); - free_store.pop(); - } - mutex.unlock(); - return pdu; - } - - void release_mac_pdu(mac_pdu* pdu) - { - mutex.lock(); - free_store.push(pdu); - mutex.unlock(); - } - - - - void push_rx_buffer(mac_pdu* buff) - { - mutex.lock(); - rx_buffer.push(buff); - mutex.unlock(); - } - - mac_pdu* pop_rx_buffer() - { - mac_pdu* buff = 0; - mutex.lock(); - if(!rx_buffer.empty()) - { - buff = rx_buffer.front(); - rx_buffer.pop(); - } - mutex.unlock(); - return buff; - } - - uint32_t byte_count; - uint32_t tick; - - bool wireshark_test_mode; +class mac_private { + std::mutex mutex; + std::queue<mac_pdu *> rx_buffer; + + std::queue<mac_pdu *> free_store; + public: + + mac_private(bool _wireshark_test_mode) + : byte_count(0), tick(0), wireshark_test_mode(_wireshark_test_mode) { + } + + mac_pdu *allocate_mac_pdu() { + mac_pdu *pdu = 0; + mutex.lock(); + + if(free_store.empty()) { + pdu = new mac_pdu(); + } else { + pdu = free_store.front(); + free_store.pop(); + } + + mutex.unlock(); + return pdu; + } + + void release_mac_pdu(mac_pdu *pdu) { + mutex.lock(); + free_store.push(pdu); + mutex.unlock(); + } + + + + void push_rx_buffer(mac_pdu *buff) { + mutex.lock(); + rx_buffer.push(buff); + mutex.unlock(); + } + + mac_pdu *pop_rx_buffer() { + mac_pdu *buff = 0; + mutex.lock(); + + if(!rx_buffer.empty()) { + buff = rx_buffer.front(); + rx_buffer.pop(); + } + + mutex.unlock(); + return buff; + } + + uint32_t byte_count; + uint32_t tick; + + bool wireshark_test_mode; }; extern "C" { - typedef struct { - mac_t _public; - - int rx_sock; - int tx_sock; - struct sockaddr_in tx_addr; - - uint32_t tx_byte_count; - - mac_private* mac; - - } mac_internal_t; - - mac_t* mac_create(uint8_t wireshark_test_mode) - { - mac_internal_t* instance = (mac_internal_t*)malloc(sizeof(mac_internal_t)); - instance->mac = new mac_private((wireshark_test_mode >= 1)); - return (mac_t*)instance; - } - - void mac_destroy(mac_t* mac) - { - mac_internal_t* instance = (mac_internal_t*)mac; - delete instance->mac; - free(instance); - } - - void* mac_rx_thread_start(void* ptr) - { - mac_internal_t* instance = (mac_internal_t*)ptr; - - while(1) - { - mac_pdu* pdu = instance->mac->allocate_mac_pdu(); - int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, 0, 0, 0); - if(len > 0) - { - pdu->len = len; - instance->mac->push_rx_buffer(pdu); - } - else - { - instance->mac->release_mac_pdu(pdu); - } - } - return 0; - } - - void mac_start_data(mac_t* mac, unsigned rx_port, const char* tx_address, unsigned tx_port) - { - mac_internal_t* instance = (mac_internal_t*)mac; - - printf("[MAC] Rx Data from %d\n", rx_port); - printf("[MAC] Tx Data to %s.%d\n", tx_address, tx_port); - - instance->rx_sock = socket(AF_INET, SOCK_DGRAM, 0); - - if(instance->rx_sock < 0) - { - printf("[MAC] Failed to create socket\n"); - return; - } - - struct sockaddr_in addr; - memset(&addr, 0, sizeof(0)); - addr.sin_family = AF_INET; - addr.sin_port = htons(rx_port); - addr.sin_addr.s_addr = INADDR_ANY; - - if(bind(instance->rx_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) - { - printf("[MAC] Failed to bind to %d\n", rx_port); - close(instance->rx_sock); - return; - } - - pthread_t mac_rx_thread; - pthread_create(&mac_rx_thread, NULL, &mac_rx_thread_start, instance); - - instance->tx_sock = socket(AF_INET, SOCK_DGRAM, 0); - instance->tx_addr.sin_family = AF_INET; - instance->tx_addr.sin_port = htons(tx_port); - instance->tx_addr.sin_addr.s_addr = inet_addr(tx_address); - } - - - - void generate_test_subframe(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf) - { - //mac_internal_t* instance = (mac_internal_t*)mac; - - uint8_t max_num_dl_pdus = 50; - nfapi_dl_config_request_pdu_t dl_config_pdus[max_num_dl_pdus]; - memset(&dl_config_pdus, 0, sizeof(dl_config_pdus)); - - nfapi_dl_config_request_t dl_config_req; - memset(&dl_config_req, 0, sizeof(dl_config_req)); - dl_config_req.header.message_id = NFAPI_DL_CONFIG_REQUEST; - dl_config_req.header.phy_id = phy_id; - dl_config_req.sfn_sf = sfn_sf; - dl_config_req.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - dl_config_req.dl_config_request_body.number_pdu = rand_range(4, max_num_dl_pdus); - - uint16_t i = 0; - for(i = 0; i < dl_config_req.dl_config_request_body.number_pdu; ++i) - { - dl_config_pdus[i].pdu_type = rand_range(0, 11); - - switch(dl_config_pdus[i].pdu_type) - { - case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: - { - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.dci_format = rand_range(0, 9); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = rand_range(0, 255); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = rand_range(0, 32); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti = rand_range(0, (uint16_t)-1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = rand_range(0, 320000); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = rand_range(0, 31); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rand_range(0, 3); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = rand_range(0, 31); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = rand_range(0, 31); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_2 = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.harq_process = rand_range(0, 31); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tpmi = rand_range(0, 15); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.pmi = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.precoding_information = rand_range(0, 63); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tpc = rand_range(0, 3); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = rand_range(0, 15); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.ngap = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transport_block_size_index = rand_range(0, 31); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.downlink_power_offset = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.allocate_prach_flag = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.preamble_index = rand_range(0, 63); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.prach_mask_index = rand_range(0, 15); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = rand_range(0, 3); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = rand_range(0, 10000); - - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG; - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.mcch_flag = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.mcch_change_notification = rand_range(0, 255); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.scrambling_identity = rand_range(0, 1); - - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG; - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.carrier_indicator = rand_range(0, 7); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.srs_flag = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.srs_request = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.antenna_ports_scrambling_and_layers = rand_range(0, 15); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.n_dl_rb = rand_range(0, 100); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG; - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.harq_ack_resource_offset = rand_range(0, 3); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.pdsch_re_mapping_quasi_co_location_indicator = rand_range(0, 3); - - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG; - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.primary_cell_type = rand_range(0, 2); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_flag = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.number_ul_dl_configurations = 2; - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_indication[0] = rand_range(1, 5); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_indication[1] = rand_range(1, 5); - - - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG; - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.laa_end_partial_sf_flag = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.laa_end_partial_sf_configuration = rand_range(0, 255); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.initial_lbt_sf = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.codebook_size_determination = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.drms_table_flag = rand_range(0, 1); - - // if the tpm extention is present of not. - if(rand_range(0, 1)) - { - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm_struct_flag = rand_range(0, 1); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_prb_per_subband = rand_range(0, 8); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.number_of_subbands = rand_range(0, 13); - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_antennas = 1; // rand_range(0, 8); - - for(int j = 0; j < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.number_of_subbands; ++j) - { - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].subband_index = j; - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].scheduled_ues = 1; //rand_range(1, 4); - - for(int k = 0; k < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_antennas; ++k) - for(int l = 0; l < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].scheduled_ues; ++l) - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].precoding_value[k][l] = rand_range(0, 65535); - } - } - else - { - dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm_struct_flag = 0; - } - - } - break; - - case NFAPI_DL_CONFIG_BCH_PDU_TYPE: - { - dl_config_pdus[i].bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; - dl_config_pdus[i].bch_pdu.bch_pdu_rel8.length = rand_range(0, 42); - dl_config_pdus[i].bch_pdu.bch_pdu_rel8.pdu_index = rand_range(0, 65535); - dl_config_pdus[i].bch_pdu.bch_pdu_rel8.transmission_power = rand_range(0, 10000); - } - break; - - case NFAPI_DL_CONFIG_MCH_PDU_TYPE: - { - dl_config_pdus[i].mch_pdu.mch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG; - dl_config_pdus[i].mch_pdu.mch_pdu_rel8.length = rand_range(0, 42); - dl_config_pdus[i].mch_pdu.mch_pdu_rel8.pdu_index = rand_range(0, 65535); - dl_config_pdus[i].mch_pdu.mch_pdu_rel8.rnti = 0xFFFD; - dl_config_pdus[i].mch_pdu.mch_pdu_rel8.resource_allocation_type = 0; - dl_config_pdus[i].mch_pdu.mch_pdu_rel8.resource_block_coding = 0; - dl_config_pdus[i].mch_pdu.mch_pdu_rel8.modulation = rand_range(0, 8); - dl_config_pdus[i].mch_pdu.mch_pdu_rel8.transmission_power = rand_range(0, 10000); - dl_config_pdus[i].mch_pdu.mch_pdu_rel8.mbsfn_area_id = rand_range(0, 255); - } - break; - - case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: - { - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.length = rand_range(0, 42); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.pdu_index = rand_range(0, 65535); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.rnti = rand_range(1, 65535); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = rand_range(0, 5); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = rand_range(0, 32000); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.modulation = rand_range(2, 8); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rand_range(0, 3); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transport_blocks = rand_range(1, 2); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = rand_range(0, 13); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.number_of_layers = rand_range(1, 8); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 2; //rand_range(0, 13); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.codebook_index[0] = rand_range(0, 15); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.codebook_index[1] = rand_range(0, 15); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = rand_range(0, 14); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.pa = rand_range(0, 7); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.ngap = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.nprb = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transmission_mode = rand_range(1, 10); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 2; //rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 2; //rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].subband_index = rand_range(0, 4); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].num_antennas = 1; - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].bf_value[0] = rand_range(0, 128); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].subband_index = rand_range(0, 4); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].num_antennas = 1; - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].bf_value[0] = rand_range(0, 128); - - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG; - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel9.nscid = rand_range(0, 1); - - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_flag = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_resource_config_r10 = 0; - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_zero_tx_power_resource_config_bitmap_r10 = rand_range(0, 65535); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_number_nzp_configuration = 1; - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_resource_config[0] = rand_range(0, 31); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.pdsch_start = rand_range(0, 4); - - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG; - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.drms_config_flag = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.drms_scrambling = rand_range(0, 503); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.csi_config_flag = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.csi_scrambling = rand_range(0, 503); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_flag = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_atenna_ports = rand_range(1,4); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_freq_shift = rand_range(0, 5); - - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG; - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.altcqi_table_r12 = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.maxlayers = rand_range(1, 8); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.n_dl_harq = rand_range(0, 255); - - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.dwpts_symbols = rand_range(3, 14); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.initial_lbt_sf = rand_range(0, 1); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.ue_type = rand_range(0, 2); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = rand_range(0, 2); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); - dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = rand_range(0, 1); - } - break; - - case NFAPI_DL_CONFIG_PCH_PDU_TYPE: - { - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG; - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.length = rand_range(0, 42); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.pdu_index = rand_range(0, 65535); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.p_rnti = 0xFFFE; - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.resource_allocation_type = rand_range(2, 6); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.resource_block_coding = rand_range(0, 34000); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.mcs = 0; - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.redundancy_version = 0; - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.number_of_transport_blocks = 1; - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transmission_scheme = rand_range(1, 6); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.number_of_layers = rand_range(1, 4); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.codebook_index = 0; - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.ue_category_capacity = rand_range(0, 14); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.pa = rand_range(0, 7); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transmission_power = rand_range(0, 10000); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.nprb = rand_range(0, 1); - dl_config_pdus[i].pch_pdu.pch_pdu_rel8.ngap = rand_range(0, 1); - dl_config_pdus[i].pch_pdu.pch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG; - dl_config_pdus[i].pch_pdu.pch_pdu_rel13.ue_mode = rand_range(0, 1); - dl_config_pdus[i].pch_pdu.pch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); - } - break; - - case NFAPI_DL_CONFIG_PRS_PDU_TYPE: - { - dl_config_pdus[i].prs_pdu.prs_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG; - dl_config_pdus[i].prs_pdu.prs_pdu_rel9.transmission_power = rand_range(0, 10000); - dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_bandwidth = rand_range(6, 100); - dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_cyclic_prefix_type = rand_range(0, 1); - dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_muting = rand_range(0, 1); - } - break; - - case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: - { - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG; - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_antenna_port_count_r10 = rand_range(1, 16); - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config_r10 = 0; - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.transmission_power = rand_range(0, 10000); - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_zero_tx_power_resource_config_bitmap_r10 = rand_range(0, 8); - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_number_of_nzp_configuration = 2; - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config[0] = rand_range(0, 31); - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config[1] = rand_range(0, 31); - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG; - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.csi_rs_class = rand_range(0, 2); - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.cdm_type = rand_range(0, 1); - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.num_bf_vector = 0; // set to zero as not clear how to handle bf value array - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.bf_vector[0].csi_rs_resource_index = rand_range(0, 7); - dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.bf_vector[0].bf_value[0] = 42; - } - break; - - case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: - { - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG; - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.dci_format = rand_range(0, 9); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.cce_idx = rand_range(0, 255); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.aggregation_level = rand_range(0, 32); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.rnti = rand_range(0, (uint16_t)-1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.resource_allocation_type = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.resource_block_coding = rand_range(0, 320000); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.mcs_1 = rand_range(0, 31); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.redundancy_version_1 = rand_range(0, 3); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.new_data_indicator_1 = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.mcs_2 = rand_range(0, 31); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.redundancy_version_2 = rand_range(0, 31); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.new_data_indicator_2 = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.harq_process = rand_range(0, 31); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tpmi = rand_range(0, 15); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.pmi = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.precoding_information = rand_range(0, 63); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tpc = rand_range(0, 3); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.downlink_assignment_index = rand_range(0, 15); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.ngap = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transport_block_size_index = rand_range(0, 31); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.downlink_power_offset = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.allocate_prach_flag = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.preamble_index = rand_range(0, 63); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.prach_mask_index = rand_range(0, 15); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.rnti_type = rand_range(0, 3); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transmission_power = rand_range(0, 10000); - - - - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG; - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.mcch_flag = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.mcch_change_notification = rand_range(0, 255); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.scrambling_identity = rand_range(0, 1); - - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG; - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.carrier_indicator = rand_range(0, 7); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.srs_flag = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.srs_request = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.antenna_ports_scrambling_and_layers = rand_range(0, 15); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.n_dl_rb = rand_range(0, 100); - - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG; - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.harq_ack_resource_offset = rand_range(0, 3); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.pdsch_re_mapping_quasi_co_location_indicator = rand_range(0, 3); - - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG; - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.primary_cell_type = rand_range(0, 2); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_flag = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.number_ul_dl_configurations = 2; - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_indication[0] = rand_range(1, 5); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_indication[1] = rand_range(1, 5); - - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG; - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.laa_end_partial_sf_flag = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.laa_end_partial_sf_configuration = rand_range(0, 255); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.initial_lbt_sf = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.codebook_size_determination = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.drms_table_flag = rand_range(0, 1); - - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG; - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_resource_assignment_flag = rand_range(0, 1); - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_id = rand_range(0, 503); - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_start_symbol = rand_range(1, 4); - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb = rand_range(2, 8); - for(int j = 0; j < dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb; ++j) - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_prb_index[j] = rand_range(0, 99); - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.subband_index = rand_range(0, 25); - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.num_antennas= rand_range(1, 4); - for(int j = 0; j < dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb; ++j) - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.bf_value[j] = rand_range(0, 65535); - - - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG; - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.dwpts_symbols = rand_range(3, 14); - dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.initial_lbt_sf = rand_range(0, 1); - } - break; - - case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: - { - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = rand_range(0, 15); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = rand_range(2, 6); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = rand_range(0, 14); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = rand_range(0, 1); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = rand_range(1, 4); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = rand_range(0, 22); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = rand_range(2, 24); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = rand_range(0, 4); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.rnti = rand_range(1, 65535); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = rand_range(1, 2); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = rand_range(0, 503); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = rand_range(0, 10000); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.dci_format = rand_range(10, 12); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = rand_range(0, 0xFFFF); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mcs = rand_range(0, 15); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = rand_range(1, 8); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = rand_range(0, 3); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = rand_range(0, 1); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.harq_process = rand_range(0, 15); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = rand_range(0, 4); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpmi = rand_range(0, 15); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = rand_range(0, 1); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pmi = rand_range(0, 1); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = rand_range(0, 3); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rand_range(1, 4); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpc = rand_range(0, 3); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = rand_range(0, 4); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = rand_range(0, 15); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = rand_range(0, 63); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = rand_range(0, 15); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = rand_range(0, 3); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = rand_range(0, 1); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.srs_request = rand_range(0, 1); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = rand_range(0, 1); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = rand_range(0, 3); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = rand_range(0, 1); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = rand_range(0, 1); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = rand_range(0, 255); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = rand_range(0, 1); - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = rand_range(0, 8); - for(int j = 0 ; j < dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports; ++j) - dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.precoding_value[j] = rand_range(0, 65535); - } - break; - - case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: - { - dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG; - dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.length = rand_range(0, 5555); - dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.pdu_index = rand_range(0, 65535); - dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.transmission_power = rand_range(0, 10000); - dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.hyper_sfn_2_lsbs = rand_range(0, 3); - } - break; - - case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: - { - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG; - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.length = rand_range(0, 5555); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.pdu_index = rand_range(0, 65535); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.ncce_index = rand_range(0, 1); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.aggregation_level = rand_range(1, 2); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.start_symbol = rand_range(0, 4); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.rnti_type = rand_range(0, 3); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.rnti = rand_range(1, 65535); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.scrambling_reinitialization_batch_index = rand_range(1, 4); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.dci_format = rand_range(0, 1); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.scheduling_delay = rand_range(0, 7); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.resource_assignment = rand_range(0, 7); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.repetition_number = rand_range(0, 15); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.mcs = rand_range(0, 13); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.new_data_indicator = rand_range(0, 1); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.harq_ack_resource = rand_range(0, 15); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.npdcch_order_indication = rand_range(0, 1); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.starting_number_of_nprach_repetitions = rand_range(0, 3); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.subcarrier_indication_of_nprach = rand_range(0, 63); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.paging_direct_indication_differentation_flag = rand_range(0, 1); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.direct_indication = rand_range(0, 255); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.dci_subframe_repetition_number = rand_range(0, 7); - dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.total_dci_length_including_padding = rand_range(0, 255); - } - break; - - case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: - { - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG; - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.length = rand_range(0, 5555); - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.pdu_index = rand_range(0, 65535); - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.start_symbol = rand_range(0, 4); - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.rnti_type = rand_range(0, 1); - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.rnti = rand_range(1, 65535); - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.resource_assignment = rand_range(0, 7); - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.repetition_number = rand_range(0, 15); - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.modulation = 2; - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.number_of_subframes_for_resource_assignment = rand_range(1, 10); - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.scrambling_sequence_initialization_cinit = rand_range(0, 65535); - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.sf_idx = rand_range(1, 10240); - dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2); - } - break; - - }; - } - - - dl_config_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdus; - mac->dl_config_req(mac, &dl_config_req); - - uint8_t num_ul_pdus = 18; - nfapi_ul_config_request_pdu_t ul_config_pdus[num_ul_pdus]; - memset(&ul_config_pdus, 0, sizeof(ul_config_pdus)); - - nfapi_ul_config_request_t ul_config_req; - memset(&ul_config_req, 0, sizeof(ul_config_req)); - ul_config_req.header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_config_req.header.phy_id = phy_id; - ul_config_req.sfn_sf = sfn_sf; - ul_config_req.ul_config_request_body.tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_config_req.ul_config_request_body.number_of_pdus = num_ul_pdus; - ul_config_req.ul_config_request_body.rach_prach_frequency_resources = rand_range(0, 255); - ul_config_req.ul_config_request_body.srs_present = rand_range(0, 1); - - auto ul_config_ulsch_pdu_test_gen = [](nfapi_ul_config_ulsch_pdu& ulsch_pdu) - { - ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; - ulsch_pdu.ulsch_pdu_rel8.handle = rand_range(0, 50000); - ulsch_pdu.ulsch_pdu_rel8.size = rand_range(0, 32000); - ulsch_pdu.ulsch_pdu_rel8.rnti = rand_range(1, 65535); - ulsch_pdu.ulsch_pdu_rel8.resource_block_start = rand_range(0, 99); - ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = rand_range(1, 100); - ulsch_pdu.ulsch_pdu_rel8.modulation_type = rand_range(2, 6); - ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); - ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1); - ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = rand_range(0, 3); - ulsch_pdu.ulsch_pdu_rel8.new_data_indication = rand_range(0, 1); - ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rand_range(0, 3); - ulsch_pdu.ulsch_pdu_rel8.harq_process_number = rand_range(0, 15); - ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = rand_range(0, 1); - ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = rand_range(0, 5); - ulsch_pdu.ulsch_pdu_rel8.n_srs = rand_range(0, 1); - ulsch_pdu.ulsch_pdu_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG; - ulsch_pdu.ulsch_pdu_rel10.resource_allocation_type = rand_range(0, 1); - ulsch_pdu.ulsch_pdu_rel10.resource_block_coding = rand_range(0, 35000); - ulsch_pdu.ulsch_pdu_rel10.transport_blocks = rand_range(1, 2); - ulsch_pdu.ulsch_pdu_rel10.transmission_scheme = rand_range(0, 1); - ulsch_pdu.ulsch_pdu_rel10.number_of_layers = rand_range(1, 4); - ulsch_pdu.ulsch_pdu_rel10.codebook_index = rand_range(0, 23); - ulsch_pdu.ulsch_pdu_rel10.disable_sequence_hopping_flag = rand_range(0, 1); - ulsch_pdu.ulsch_pdu_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG; - ulsch_pdu.ulsch_pdu_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1); - ulsch_pdu.ulsch_pdu_rel11.npusch_identity = rand_range(0, 509); - ulsch_pdu.ulsch_pdu_rel11.dmrs_config_flag = rand_range(0, 1); - ulsch_pdu.ulsch_pdu_rel11.ndmrs_csh_identity = rand_range(0, 509); - ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; - ulsch_pdu.ulsch_pdu_rel13.ue_type = rand_range(0, 2); - ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = rand_range(1, 2048); - ulsch_pdu.ulsch_pdu_rel13.repetition_number = rand_range(1, 2048); - ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); - ulsch_pdu.ulsch_pdu_rel13.empty_symbols_due_to_re_tunning = rand_range(0, 8); - }; - - auto ul_config_cqi_ri_info_test_gen = [](nfapi_ul_config_cqi_ri_information& cqi_ri_information) - { - cqi_ri_information.cqi_ri_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG; - cqi_ri_information.cqi_ri_information_rel8.dl_cqi_pmi_size_rank_1 = rand_range(0, 255); - cqi_ri_information.cqi_ri_information_rel8.dl_cqi_pmi_size_rank_greater_1 = rand_range(0, 255); - cqi_ri_information.cqi_ri_information_rel8.ri_size = rand_range(0, 3); - cqi_ri_information.cqi_ri_information_rel8.delta_offset_cqi = rand_range(0, 15); - cqi_ri_information.cqi_ri_information_rel8.delta_offset_ri = rand_range(0, 15); - - cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; - cqi_ri_information.cqi_ri_information_rel9.report_type = 1; // rand_range(0, 1); - cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = rand_range(0, 15); - cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = rand_range(0, 15); - - if(cqi_ri_information.cqi_ri_information_rel9.report_type == 0) - { - cqi_ri_information.cqi_ri_information_rel9.periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size = rand_range(0, 255); - cqi_ri_information.cqi_ri_information_rel9.periodic_cqi_pmi_ri_report.control_type = rand_range(0, 1); - } - else - { - cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; - cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = rand_range(0, 3); - cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0] = rand_range(0, 255); - } - - cqi_ri_information.cqi_ri_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG; - cqi_ri_information.cqi_ri_information_rel13.report_type = rand_range(0, 1); - - if(cqi_ri_information.cqi_ri_information_rel13.report_type == 0) - { - cqi_ri_information.cqi_ri_information_rel13.periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2 = rand_range(255, 10000); - } - }; - - auto ul_config_init_tx_params_test_gen = [](nfapi_ul_config_initial_transmission_parameters& initial_transmission_parameters) - { - initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = rand_range(0, 1); - initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rand_range(1, 100); - }; - - auto ul_config_harqinfo_test_gen = [](nfapi_ul_config_ulsch_harq_information& harq_information) - { - harq_information.harq_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG; - harq_information.harq_information_rel10.harq_size = rand_range(0, 21); - harq_information.harq_information_rel10.delta_offset_harq = rand_range(0, 15); - harq_information.harq_information_rel10.ack_nack_mode = rand_range(0, 5); - harq_information.harq_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG; - harq_information.harq_information_rel13.harq_size_2 = rand_range(0, 21); - harq_information.harq_information_rel13.delta_offset_harq_2 = rand_range(0, 15); - }; - - auto ul_config_sr_info_test_gen = [](nfapi_ul_config_sr_information& sr_info) - { - sr_info.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; - sr_info.sr_information_rel8.pucch_index = rand_range(0, 2047); - sr_info.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; - sr_info.sr_information_rel10.number_of_pucch_resources = rand_range(1, 2); - sr_info.sr_information_rel10.pucch_index_p1 = rand_range(0, 2047); - }; - - auto ul_config_ue_info_test_gen = [](nfapi_ul_config_ue_information& ue_information) - { - ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ue_information.ue_information_rel8.handle = rand_range(0, 99999); - ue_information.ue_information_rel8.rnti = rand_range(1, 65535); - ue_information.ue_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG; - ue_information.ue_information_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1); - ue_information.ue_information_rel11.npusch_identity = rand_range(0, 503); - ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG; - ue_information.ue_information_rel13.ue_type = rand_range(0, 2); - ue_information.ue_information_rel13.empty_symbols = rand_range(0, 2); - ue_information.ue_information_rel13.total_number_of_repetitions = rand_range(1, 32); - ue_information.ue_information_rel13.repetition_number = rand_range(1, 32); - }; - - auto ul_config_cqi_info_test_gen = [](nfapi_ul_config_cqi_information& cqi_information) - { - cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; - cqi_information.cqi_information_rel8.pucch_index = rand_range(0, 1184); - cqi_information.cqi_information_rel8.dl_cqi_pmi_size = rand_range(0, 255); - cqi_information.cqi_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG; - cqi_information.cqi_information_rel10.number_of_pucch_resource = rand_range(1, 2); - cqi_information.cqi_information_rel10.pucch_index_p1 = rand_range(0, 1184); - cqi_information.cqi_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG; - cqi_information.cqi_information_rel13.csi_mode = rand_range(0, 2); - cqi_information.cqi_information_rel13.dl_cqi_pmi_size_2 = rand_range(0, 999); - cqi_information.cqi_information_rel13.starting_prb = rand_range(0, 109); - cqi_information.cqi_information_rel13.n_prb = rand_range(0, 7); - cqi_information.cqi_information_rel13.cdm_index = rand_range(0, 1); - cqi_information.cqi_information_rel13.n_srs = rand_range(0, 1); - }; - - auto ul_config_harq_info_test_gen = [](nfapi_ul_config_harq_information& harq_information) - { - harq_information.harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; - harq_information.harq_information_rel10_tdd.harq_size = rand_range(0, 21); - harq_information.harq_information_rel10_tdd.ack_nack_mode = rand_range(0, 5); - harq_information.harq_information_rel10_tdd.number_of_pucch_resources = rand_range(0, 4); - harq_information.harq_information_rel10_tdd.n_pucch_1_0 = rand_range(0, 2047); - harq_information.harq_information_rel10_tdd.n_pucch_1_1 = rand_range(0, 2047); - harq_information.harq_information_rel10_tdd.n_pucch_1_2 = rand_range(0, 2047); - harq_information.harq_information_rel10_tdd.n_pucch_1_3 = rand_range(0, 2047); - harq_information.harq_information_rel8_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG; - harq_information.harq_information_rel8_fdd.n_pucch_1_0 = rand_range(0, 2047); - harq_information.harq_information_rel8_fdd.harq_size = rand_range(1, 2); - harq_information.harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; - harq_information.harq_information_rel9_fdd.harq_size = rand_range(1, 10); - harq_information.harq_information_rel9_fdd.ack_nack_mode = rand_range(0, 4); - harq_information.harq_information_rel9_fdd.number_of_pucch_resources = rand_range(0, 4); - harq_information.harq_information_rel9_fdd.n_pucch_1_0 = rand_range(0, 2047); - harq_information.harq_information_rel9_fdd.n_pucch_1_1 = rand_range(0, 2047); - harq_information.harq_information_rel9_fdd.n_pucch_1_2 = rand_range(0, 2047); - harq_information.harq_information_rel9_fdd.n_pucch_1_3 = rand_range(0, 2047); - harq_information.harq_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG; - harq_information.harq_information_rel11.num_ant_ports = rand_range(1, 2); - harq_information.harq_information_rel11.n_pucch_2_0 = rand_range(0, 2047); - harq_information.harq_information_rel11.n_pucch_2_1 = rand_range(0, 2047); - harq_information.harq_information_rel11.n_pucch_2_2 = rand_range(0, 2047); - harq_information.harq_information_rel11.n_pucch_2_3 = rand_range(0, 2047); - harq_information.harq_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG; - harq_information.harq_information_rel13.harq_size_2 = rand_range(0, 999); - harq_information.harq_information_rel13.starting_prb = rand_range(0, 109); - harq_information.harq_information_rel13.n_prb = rand_range(0, 7); - harq_information.harq_information_rel13.cdm_index = rand_range(0, 1); - harq_information.harq_information_rel13.n_srs = rand_range(0, 1); - }; - - - ul_config_pdus[0].pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_ulsch_pdu_test_gen(ul_config_pdus[0].ulsch_pdu); - - ul_config_pdus[1].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; - ul_config_ulsch_pdu_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.ulsch_pdu); - ul_config_cqi_ri_info_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.cqi_ri_information); - ul_config_init_tx_params_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.initial_transmission_parameters); - - ul_config_pdus[2].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ul_config_ulsch_pdu_test_gen(ul_config_pdus[2].ulsch_harq_pdu.ulsch_pdu); - ul_config_harqinfo_test_gen(ul_config_pdus[2].ulsch_harq_pdu.harq_information); - ul_config_init_tx_params_test_gen(ul_config_pdus[2].ulsch_harq_pdu.initial_transmission_parameters); - - ul_config_pdus[3].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - ul_config_ulsch_pdu_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.ulsch_pdu); - ul_config_cqi_ri_info_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.cqi_ri_information); - ul_config_harqinfo_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.harq_information); - ul_config_init_tx_params_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters); - - - ul_config_pdus[4].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; - ul_config_ue_info_test_gen(ul_config_pdus[4].uci_cqi_pdu.ue_information); - ul_config_cqi_info_test_gen(ul_config_pdus[4].uci_cqi_pdu.cqi_information); - - ul_config_pdus[5].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; - ul_config_ue_info_test_gen(ul_config_pdus[5].uci_sr_pdu.ue_information); - ul_config_sr_info_test_gen(ul_config_pdus[5].uci_sr_pdu.sr_information); - - - ul_config_pdus[6].pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; - ul_config_ue_info_test_gen(ul_config_pdus[6].uci_harq_pdu.ue_information); - ul_config_harq_info_test_gen(ul_config_pdus[6].uci_harq_pdu.harq_information); - - - ul_config_pdus[7].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; - ul_config_ue_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.ue_information); - ul_config_sr_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.sr_information); - ul_config_harq_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.harq_information); - - ul_config_pdus[8].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE; - ul_config_ue_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.ue_information); - ul_config_cqi_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.cqi_information); - ul_config_harq_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.harq_information); - - ul_config_pdus[9].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE; - ul_config_ue_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.ue_information); - ul_config_cqi_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.cqi_information); - ul_config_sr_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.sr_information); - - ul_config_pdus[10].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE; - ul_config_ue_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.ue_information); - ul_config_cqi_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.cqi_information); - ul_config_sr_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.sr_information); - ul_config_harq_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.harq_information); - - ul_config_pdus[11].pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; - ul_config_pdus[11].srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG; - ul_config_pdus[11].srs_pdu.srs_pdu_rel8.handle = rand_range(0, 9999); - ul_config_pdus[11].srs_pdu.srs_pdu_rel8.size = rand_range(1, 999); - ul_config_pdus[11].srs_pdu.srs_pdu_rel8.rnti = rand_range(1, 65535); - ul_config_pdus[11].srs_pdu.srs_pdu_rel8.srs_bandwidth = rand_range(0, 3); - ul_config_pdus[11].srs_pdu.srs_pdu_rel8.frequency_domain_position = rand_range(0, 23); - ul_config_pdus[11].srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = rand_range(0, 3); - ul_config_pdus[11].srs_pdu.srs_pdu_rel8.transmission_comb = rand_range(0, 3); - ul_config_pdus[11].srs_pdu.srs_pdu_rel8.i_srs = rand_range(0, 1023); - ul_config_pdus[11].srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = rand_range(0, 11); - ul_config_pdus[11].srs_pdu.srs_pdu_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG; - ul_config_pdus[11].srs_pdu.srs_pdu_rel10.antenna_port = rand_range(0, 2); - ul_config_pdus[11].srs_pdu.srs_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG; - ul_config_pdus[11].srs_pdu.srs_pdu_rel13.number_of_combs = rand_range(0, 1); - - ul_config_pdus[12].pdu_type = NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE; - ul_config_ue_info_test_gen(ul_config_pdus[12].harq_buffer_pdu.ue_information); - - ul_config_pdus[13].pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE; - ul_config_ulsch_pdu_test_gen(ul_config_pdus[13].ulsch_uci_csi_pdu.ulsch_pdu); - ul_config_cqi_info_test_gen(ul_config_pdus[13].ulsch_uci_csi_pdu.csi_information); - - ul_config_pdus[14].pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE; - ul_config_ulsch_pdu_test_gen(ul_config_pdus[14].ulsch_uci_harq_pdu.ulsch_pdu); - ul_config_harq_info_test_gen(ul_config_pdus[14].ulsch_uci_harq_pdu.harq_information); - - ul_config_pdus[15].pdu_type = NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE; - ul_config_ulsch_pdu_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.ulsch_pdu); - ul_config_cqi_info_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.csi_information); - ul_config_harq_info_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.harq_information); - - ul_config_pdus[16].pdu_type = NFAPI_UL_CONFIG_NULSCH_PDU_TYPE; - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG; - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nulsch_format = rand_range(0, 1); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.handle = rand_range(0, 0xFFFF); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.size = rand_range(0, 65535); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.rnti = rand_range(1, 65535); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.subcarrier_indication = rand_range(0, 47); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.resource_assignment = rand_range(0, 7); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.mcs = rand_range(0, 12); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.redudancy_version = rand_range(0, 1); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.repetition_number = rand_range(0, 7); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.new_data_indication = rand_range(0, 1); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.n_srs = rand_range(0, 1); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.scrambling_sequence_initialization_cinit = rand_range(0, 65535); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.sf_idx = rand_range(0, 40960); - - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.handle = rand_range(0, 0xFF); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.rnti = rand_range(1, 65535); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG; - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.npusch_identity = rand_range(0, 503); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG; - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.ue_type = rand_range(0, 2); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.empty_symbols = rand_range(0, 0x3); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.total_number_of_repetitions = rand_range(1, 32); - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.repetition_number = rand_range(1, 32); - - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nb_harq_information.nb_harq_information_rel13_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG; - ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource = rand_range(0, 15); - - ul_config_pdus[17].pdu_type = NFAPI_UL_CONFIG_NRACH_PDU_TYPE; - ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG; - ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_0 = rand_range(0, 1); - ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_1 = rand_range(0, 1); - ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_2 = rand_range(0, 1); - - ul_config_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdus; - mac->ul_config_req(mac, &ul_config_req); - - - uint8_t num_dci_pdus = 4; - uint8_t num_hi_pdus = 1; - nfapi_hi_dci0_request_pdu_t hi_dci0_pdus[num_dci_pdus + num_hi_pdus]; - memset(&hi_dci0_pdus, 0, sizeof(hi_dci0_pdus)); - - nfapi_hi_dci0_request_t hi_dci0_req; - memset(&hi_dci0_req, 0, sizeof(hi_dci0_req)); - hi_dci0_req.header.message_id = NFAPI_HI_DCI0_REQUEST; - hi_dci0_req.header.phy_id = phy_id; - hi_dci0_req.sfn_sf = sfn_sf; - - hi_dci0_req.hi_dci0_request_body.tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req.hi_dci0_request_body.sfnsf = sfn_sf; - hi_dci0_req.hi_dci0_request_body.number_of_dci = num_dci_pdus; - hi_dci0_req.hi_dci0_request_body.number_of_hi = num_hi_pdus; - - hi_dci0_pdus[0].pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; - hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.resource_block_start = rand_range(0, 100); - hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); - hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.hi_value = rand_range(0, 1); - hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.i_phich = rand_range(0, 1); - hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.transmission_power = rand_range(0, 10000); - hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG; - hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.flag_tb2 = rand_range(0, 1); - hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.hi_value_2 = rand_range(0, 1); - - hi_dci0_pdus[1].pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.dci_format = rand_range(0, 4); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cce_index = rand_range(0, 88); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.aggregation_level = rand_range(1, 8); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.rnti = rand_range(1, 65535); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.resource_block_start = rand_range(0, 100); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.number_of_resource_block = rand_range(0, 100); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.mcs_1 = rand_range(0, 31); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.frequency_hopping_bits = rand_range(0, 3); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.new_data_indication_1 = rand_range(0, 1); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.ue_tx_antenna_seleciton = rand_range(0, 2); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tpc = rand_range(0, 3); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cqi_csi_request = rand_range(0, 7); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.ul_index = rand_range(0, 3); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.dl_assignment_index = rand_range(1, 4); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tpc_bitmap = rand_range(0, 9999); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.transmission_power = rand_range(0, 10000); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG; - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.carrier_indicator = rand_range(0, 7); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.size_of_cqi_csi_feild = rand_range(0, 2); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.srs_flag = rand_range(0, 1); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.srs_request = rand_range(0, 1); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_allocation_flag = rand_range(0, 1); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_allocation_type = rand_range(0, 1); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_block_coding = rand_range(0, 9999); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.mcs_2 = rand_range(0, 31); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.new_data_indication_2 = rand_range(0, 1); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.number_of_antenna_ports = rand_range(0, 2); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.tpmi = rand_range(0, 63); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.n_ul_rb = rand_range(6, 100); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG; - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.pscch_resource = rand_range(0, 16); - hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.time_resource_pattern = rand_range(0, 32); - - - hi_dci0_pdus[2].pdu_type = NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE; - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG; - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.dci_format = rand_range(0, 4); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cce_index = rand_range(0, 88); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.aggregation_level = rand_range(1, 8); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.rnti = rand_range(1, 65535); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.resource_block_start = rand_range(0, 100); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.number_of_resource_block = rand_range(0, 100); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.mcs_1 = rand_range(0, 31); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.frequency_hopping_bits = rand_range(0, 3); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.new_data_indication_1 = rand_range(0, 1); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.ue_tx_antenna_seleciton = rand_range(0, 2); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tpc = rand_range(0, 3); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cqi_csi_request = rand_range(0, 7); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.ul_index = rand_range(0, 3); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.dl_assignment_index = rand_range(1, 4); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tpc_bitmap = rand_range(0, 9999); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.transmission_power = rand_range(0, 10000); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG; - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.carrier_indicator = rand_range(0, 7); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.size_of_cqi_csi_feild = rand_range(0, 2); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.srs_flag = rand_range(0, 1); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.srs_request = rand_range(0, 1); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_allocation_flag = rand_range(0, 1); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_allocation_type = rand_range(0, 1); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_block_coding = rand_range(0, 9999); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.mcs_2 = rand_range(0, 31); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.new_data_indication_2 = rand_range(0, 1); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.number_of_antenna_ports = rand_range(0, 2); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.tpmi = rand_range(0, 63); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.n_ul_rb = rand_range(6, 100); - hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_parameters_rel11.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG; - - hi_dci0_pdus[3].pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; - hi_dci0_pdus[3].mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tl.tag = NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG; - - hi_dci0_pdus[4].pdu_type = NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE; - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.tl.tag = NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG; - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.ncce_index = rand_range(0, 1); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.aggregation_level = rand_range(1, 2); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.start_symbol = rand_range(0, 4); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.rnti = rand_range(1, 65535); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.scrambling_reinitialization_batch_index = rand_range(1, 4); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.subcarrier_indication = rand_range(0, 63); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.resource_assignment = rand_range(0, 7); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.scheduling_delay = rand_range(0, 3); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.mcs = rand_range(0, 12); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.redudancy_version = rand_range(0, 1); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.repetition_number = rand_range(0, 7); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.new_data_indicator = rand_range(0, 1); - hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.dci_subframe_repetition_number = rand_range(0, 3); - - hi_dci0_req.hi_dci0_request_body.hi_dci0_pdu_list = hi_dci0_pdus; - mac->hi_dci0_req(mac, &hi_dci0_req); - - uint8_t num_tx_pdus = 2; - nfapi_tx_request_pdu_t tx_pdus[num_tx_pdus]; - memset(&tx_pdus, 0, sizeof(tx_pdus)); - - nfapi_tx_request_t tx_req; - memset(&tx_req, 0, sizeof(tx_req)); - tx_req.header.message_id = NFAPI_TX_REQUEST; - tx_req.header.phy_id = phy_id; - tx_req.sfn_sf = sfn_sf; - - tx_req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - tx_req.tx_request_body.number_of_pdus = num_tx_pdus; - - uint32_t data[2]; - data[0] = 0x11223344; - data[1] = 0x55667788; - - tx_pdus[0].pdu_length = 8; - tx_pdus[0].pdu_index = 1; - tx_pdus[0].num_segments = 2; - tx_pdus[0].segments[0].segment_length = 4; - tx_pdus[0].segments[0].segment_data = (uint8_t*)&data[0]; - tx_pdus[0].segments[1].segment_length = 4; - tx_pdus[0].segments[1].segment_data = (uint8_t*)&data[1]; - - tx_pdus[1].pdu_length = 8; - tx_pdus[1].pdu_index = 2; - tx_pdus[1].num_segments = 2; - tx_pdus[1].segments[0].segment_length = 4; - tx_pdus[1].segments[0].segment_data = (uint8_t*)&data[0]; - tx_pdus[1].segments[1].segment_length = 4; - tx_pdus[1].segments[1].segment_data = (uint8_t*)&data[1]; - - - tx_req.tx_request_body.tx_pdu_list = tx_pdus; - mac->tx_req(mac, &tx_req); - } - - void generate_subframe(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf) - { - mac_internal_t* instance = (mac_internal_t*)mac; - - nfapi_dl_config_request_t dl_config_req; - memset(&dl_config_req, 0, sizeof(dl_config_req)); - dl_config_req.header.message_id = NFAPI_DL_CONFIG_REQUEST; - dl_config_req.header.phy_id = phy_id; - dl_config_req.sfn_sf = sfn_sf; - - dl_config_req.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - dl_config_req.dl_config_request_body.number_pdu = 8; - - nfapi_dl_config_request_pdu_t pdus[8]; - memset(&pdus, 0, sizeof(pdus)); - for(int i = 0; i < 8; i++) - { - pdus[i].pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE; - - pdus[i].bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; - pdus[i].bch_pdu.bch_pdu_rel8.length = 42; - pdus[i].bch_pdu.bch_pdu_rel8.pdu_index = i; - pdus[i].bch_pdu.bch_pdu_rel8.transmission_power = 56; - - } - - dl_config_req.dl_config_request_body.dl_config_pdu_list = pdus; - - /* - vendor_ext_tlv_1 ve; - ve.tl.tag = VENDOR_EXT_TLV_1_TAG; - ve.dummy = 999; - dl_config_req.vendor_extension = &ve.tl; - */ - - mac->dl_config_req(mac, &dl_config_req); - - - nfapi_ul_config_request_t ul_config_req; - memset(&ul_config_req, 0, sizeof(ul_config_req)); - ul_config_req.header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_config_req.header.phy_id = phy_id; - ul_config_req.sfn_sf = sfn_sf; - mac->ul_config_req(mac, &ul_config_req); - - nfapi_hi_dci0_request_t hi_dci0_req; - memset(&hi_dci0_req, 0, sizeof(hi_dci0_req)); - hi_dci0_req.header.message_id = NFAPI_HI_DCI0_REQUEST; - hi_dci0_req.header.phy_id = phy_id; - hi_dci0_req.sfn_sf = sfn_sf; - mac->hi_dci0_req(mac, &hi_dci0_req); - - - - nfapi_tx_request_t tx_req; - memset(&tx_req, 0, sizeof(tx_req)); - tx_req.header.message_id = NFAPI_TX_REQUEST; - tx_req.header.phy_id = phy_id; - tx_req.sfn_sf = sfn_sf; - - nfapi_tx_request_pdu_t tx_pdus[8]; - - tx_req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - tx_req.tx_request_body.number_of_pdus = 0; - tx_req.tx_request_body.tx_pdu_list = &tx_pdus[0]; - - mac_pdu* buff = 0; - int i = 0; - std::list<mac_pdu*> free_list; - do - { - buff = instance->mac->pop_rx_buffer(); - if(buff != 0) - { - if(buff->len == 0) - { - printf("[MAC] Buffer length = 0\n"); - } - - tx_req.tx_request_body.tx_pdu_list[i].pdu_length = buff->len; - tx_req.tx_request_body.tx_pdu_list[i].pdu_index = i; - tx_req.tx_request_body.tx_pdu_list[i].num_segments = 1; - tx_req.tx_request_body.tx_pdu_list[i].segments[0].segment_length = buff->len; - tx_req.tx_request_body.tx_pdu_list[i].segments[0].segment_data = (uint8_t*)buff->buffer; - - tx_req.tx_request_body.number_of_pdus++; - i++; - - instance->mac->byte_count += buff->len; - - free_list.push_back(buff); - } - }while(buff != 0 && i < 8); - - mac->tx_req(mac, &tx_req); - - //for(int j = 0; j < tx_req.tx_request_body.number_of_pdus; ++j) - for(mac_pdu* pdu : free_list) - { - instance->mac->release_mac_pdu(pdu); - //free(tx_req.tx_request_body.tx_pdu_list[j].segments[0].segment_data); - } - } - - void mac_subframe_ind(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf) - { - - - //printf("[MAC] subframe indication phyid:%d sfnsf:%d\n", phy_id, sfn_sf); - mac_internal_t* instance = (mac_internal_t*)mac; - - if(instance->mac->tick == 1000) - { - if(instance->mac->byte_count > 0) - { - printf("[MAC] Rx rate %d bytes/sec\n", instance->mac->byte_count); - instance->mac->byte_count = 0; - } - instance->mac->tick = 0; - } - instance->mac->tick++; - - if(instance->mac->wireshark_test_mode) - { - generate_test_subframe(mac, phy_id, sfn_sf); - } - else - { - generate_subframe(mac, phy_id, sfn_sf); - } - } - - void mac_harq_ind(mac_t* mac, nfapi_harq_indication_t* ind) - { - } - void mac_crc_ind(mac_t* mac, nfapi_crc_indication_t* ind) - { - } - void mac_rx_ind(mac_t* mac, nfapi_rx_indication_t* ind) - { - mac_internal_t* instance = (mac_internal_t*)mac; - - for(int i = 0; i < ind->rx_indication_body.number_of_pdus; ++i) - { - uint16_t len = ind->rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length; - uint8_t* data = ind->rx_indication_body.rx_pdu_list[i].data; - //printf("[MAC] sfnsf:%d len:%d\n", ind->sfn_sf,len); - // - instance->tx_byte_count += len; - - int sendto_result = sendto(instance->tx_sock, data, len, 0, (struct sockaddr*)&(instance->tx_addr), sizeof(instance->tx_addr)); - - if(sendto_result < 0) - { - // error - } - } - - } - void mac_rach_ind(mac_t* mac, nfapi_rach_indication_t* ind) - { - } - void mac_srs_ind(mac_t* mac, nfapi_srs_indication_t* ind) - { - } - void mac_sr_ind(mac_t* mac, nfapi_sr_indication_t* ind) - { - } - void mac_cqi_ind(mac_t* mac, nfapi_cqi_indication_t* ind) - { - } - void mac_lbt_dl_ind(mac_t* mac, nfapi_lbt_dl_indication_t* ind) - { - } - void mac_nb_harq_ind(mac_t* mac, nfapi_nb_harq_indication_t* ind) - { - } - void mac_nrach_ind(mac_t* mac, nfapi_nrach_indication_t* ind) - { - } + typedef struct { + mac_t _public; + + int rx_sock; + int tx_sock; + struct sockaddr_in tx_addr; + + uint32_t tx_byte_count; + + mac_private *mac; + + } mac_internal_t; + + mac_t *mac_create(uint8_t wireshark_test_mode) { + mac_internal_t *instance = (mac_internal_t *)malloc(sizeof(mac_internal_t)); + instance->mac = new mac_private((wireshark_test_mode >= 1)); + return (mac_t *)instance; + } + + void mac_destroy(mac_t *mac) { + mac_internal_t *instance = (mac_internal_t *)mac; + delete instance->mac; + free(instance); + } + + void *mac_rx_thread_start(void *ptr) { + mac_internal_t *instance = (mac_internal_t *)ptr; + + while(1) { + mac_pdu *pdu = instance->mac->allocate_mac_pdu(); + int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, 0, 0, 0); + + if(len > 0) { + pdu->len = len; + instance->mac->push_rx_buffer(pdu); + } else { + instance->mac->release_mac_pdu(pdu); + } + } + + return 0; + } + + void mac_start_data(mac_t *mac, unsigned rx_port, const char *tx_address, unsigned tx_port) { + mac_internal_t *instance = (mac_internal_t *)mac; + printf("[MAC] Rx Data from %u\n", rx_port); + printf("[MAC] Tx Data to %s.%u\n", tx_address, tx_port); + instance->rx_sock = socket(AF_INET, SOCK_DGRAM, 0); + + if(instance->rx_sock < 0) { + printf("[MAC] Failed to create socket\n"); + return; + } + + struct sockaddr_in addr; + + memset(&addr, 0, sizeof(sockaddr_in)); + + addr.sin_family = AF_INET; + + addr.sin_port = htons(rx_port); + + addr.sin_addr.s_addr = INADDR_ANY; + + if(bind(instance->rx_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { + printf("[MAC] Failed to bind to %u\n", rx_port); + close(instance->rx_sock); + return; + } + + pthread_t mac_rx_thread; + pthread_create(&mac_rx_thread, NULL, &mac_rx_thread_start, instance); + instance->tx_sock = socket(AF_INET, SOCK_DGRAM, 0); + instance->tx_addr.sin_family = AF_INET; + instance->tx_addr.sin_port = htons(tx_port); + instance->tx_addr.sin_addr.s_addr = inet_addr(tx_address); + } + + + + void generate_test_subframe(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf) { + //mac_internal_t* instance = (mac_internal_t*)mac; + uint8_t max_num_dl_pdus = 50; + nfapi_dl_config_request_pdu_t dl_config_pdus[max_num_dl_pdus]; + memset(&dl_config_pdus, 0, sizeof(dl_config_pdus)); + nfapi_dl_config_request_t dl_config_req; + memset(&dl_config_req, 0, sizeof(dl_config_req)); + dl_config_req.header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_req.header.phy_id = phy_id; + dl_config_req.sfn_sf = sfn_sf; + dl_config_req.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dl_config_req.dl_config_request_body.number_pdu = rand_range(4, max_num_dl_pdus); + uint16_t i = 0; + + for(i = 0; i < dl_config_req.dl_config_request_body.number_pdu; ++i) { + dl_config_pdus[i].pdu_type = rand_range(0, 11); + + switch(dl_config_pdus[i].pdu_type) { + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: { + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.dci_format = rand_range(0, 9); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = rand_range(0, 255); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = rand_range(0, 32); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti = rand_range(0, (uint16_t)-1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = rand_range(0, 320000); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = rand_range(0, 31); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rand_range(0, 3); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = rand_range(0, 31); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = rand_range(0, 31); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_2 = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.harq_process = rand_range(0, 31); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tpmi = rand_range(0, 15); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.pmi = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.precoding_information = rand_range(0, 63); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.tpc = rand_range(0, 3); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = rand_range(0, 15); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.ngap = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transport_block_size_index = rand_range(0, 31); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.downlink_power_offset = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.allocate_prach_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.preamble_index = rand_range(0, 63); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.prach_mask_index = rand_range(0, 15); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = rand_range(0, 3); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL9_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.mcch_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.mcch_change_notification = rand_range(0, 255); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel9.scrambling_identity = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL10_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.carrier_indicator = rand_range(0, 7); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.srs_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.srs_request = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.antenna_ports_scrambling_and_layers = rand_range(0, 15); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel10.n_dl_rb = rand_range(0, 100); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL11_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.harq_ack_resource_offset = rand_range(0, 3); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel11.pdsch_re_mapping_quasi_co_location_indicator = rand_range(0, 3); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL12_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.primary_cell_type = rand_range(0, 2); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.number_ul_dl_configurations = 2; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_indication[0] = rand_range(1, 5); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel12.ul_dl_configuration_indication[1] = rand_range(1, 5); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL13_TAG; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.laa_end_partial_sf_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.laa_end_partial_sf_configuration = rand_range(0, 255); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.initial_lbt_sf = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.codebook_size_determination = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.drms_table_flag = rand_range(0, 1); + + // if the tpm extention is present of not. + if(rand_range(0, 1)) { + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm_struct_flag = rand_range(0, 1); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_prb_per_subband = rand_range(0, 8); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.number_of_subbands = rand_range(0, 13); + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_antennas = 1; // rand_range(0, 8); + + for(int j = 0; j < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.number_of_subbands; ++j) { + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].subband_index = j; + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].scheduled_ues = 1; //rand_range(1, 4); + + for(int k = 0; k < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.num_antennas; ++k) + for(int l = 0; l < dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].scheduled_ues; ++l) + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm.subband_info[j].precoding_value[k][l] = rand_range(0, 65535); + } + } else { + dl_config_pdus[i].dci_dl_pdu.dci_dl_pdu_rel13.tpm_struct_flag = 0; + } + } + break; + + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: { + dl_config_pdus[i].bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; + dl_config_pdus[i].bch_pdu.bch_pdu_rel8.length = rand_range(0, 42); + dl_config_pdus[i].bch_pdu.bch_pdu_rel8.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].bch_pdu.bch_pdu_rel8.transmission_power = rand_range(0, 10000); + } + break; + + case NFAPI_DL_CONFIG_MCH_PDU_TYPE: { + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG; + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.length = rand_range(0, 42); + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.rnti = 0xFFFD; + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.resource_allocation_type = 0; + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.resource_block_coding = 0; + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.modulation = rand_range(0, 8); + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].mch_pdu.mch_pdu_rel8.mbsfn_area_id = rand_range(0, 255); + } + break; + + case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: { + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.length = rand_range(0, 42); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.rnti = rand_range(1, 65535); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = rand_range(0, 5); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = rand_range(0, 32000); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.modulation = rand_range(2, 8); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rand_range(0, 3); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transport_blocks = rand_range(1, 2); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = rand_range(0, 13); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.number_of_layers = rand_range(1, 8); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 2; //rand_range(0, 13); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.codebook_index[0] = rand_range(0, 15); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.codebook_index[1] = rand_range(0, 15); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = rand_range(0, 14); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.pa = rand_range(0, 7); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.ngap = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.nprb = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.transmission_mode = rand_range(1, 10); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 2; //rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 2; //rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].subband_index = rand_range(0, 4); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].num_antennas = 1; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[0].bf_value[0] = rand_range(0, 128); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].subband_index = rand_range(0, 4); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].num_antennas = 1; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel8.bf_vector[1].bf_value[0] = rand_range(0, 128); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL9_TAG; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel9.nscid = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_resource_config_r10 = 0; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_zero_tx_power_resource_config_bitmap_r10 = rand_range(0, 65535); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_number_nzp_configuration = 1; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.csi_rs_resource_config[0] = rand_range(0, 31); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel10.pdsch_start = rand_range(0, 4); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL11_TAG; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.drms_config_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.drms_scrambling = rand_range(0, 503); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.csi_config_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.csi_scrambling = rand_range(0, 503); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_flag = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_atenna_ports = rand_range(1,4); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel11.pdsch_re_mapping_freq_shift = rand_range(0, 5); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL12_TAG; + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.altcqi_table_r12 = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.maxlayers = rand_range(1, 8); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel12.n_dl_harq = rand_range(0, 255); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.dwpts_symbols = rand_range(3, 14); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.initial_lbt_sf = rand_range(0, 1); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.ue_type = rand_range(0, 2); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = rand_range(0, 2); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); + dl_config_pdus[i].dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = rand_range(0, 1); + } + break; + + case NFAPI_DL_CONFIG_PCH_PDU_TYPE: { + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL8_TAG; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.length = rand_range(0, 42); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.p_rnti = 0xFFFE; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.resource_allocation_type = rand_range(2, 6); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.resource_block_coding = rand_range(0, 34000); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.mcs = 0; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.redundancy_version = 0; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.number_of_transport_blocks = 1; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transmission_scheme = rand_range(1, 6); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.number_of_layers = rand_range(1, 4); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.codebook_index = 0; + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.ue_category_capacity = rand_range(0, 14); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.pa = rand_range(0, 7); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.nprb = rand_range(0, 1); + dl_config_pdus[i].pch_pdu.pch_pdu_rel8.ngap = rand_range(0, 1); + dl_config_pdus[i].pch_pdu.pch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_PCH_PDU_REL13_TAG; + dl_config_pdus[i].pch_pdu.pch_pdu_rel13.ue_mode = rand_range(0, 1); + dl_config_pdus[i].pch_pdu.pch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); + } + break; + + case NFAPI_DL_CONFIG_PRS_PDU_TYPE: { + dl_config_pdus[i].prs_pdu.prs_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_PRS_PDU_REL9_TAG; + dl_config_pdus[i].prs_pdu.prs_pdu_rel9.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_bandwidth = rand_range(6, 100); + dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_cyclic_prefix_type = rand_range(0, 1); + dl_config_pdus[i].prs_pdu.prs_pdu_rel9.prs_muting = rand_range(0, 1); + } + break; + + case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: { + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL10_TAG; + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_antenna_port_count_r10 = rand_range(1, 16); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config_r10 = 0; + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_zero_tx_power_resource_config_bitmap_r10 = rand_range(0, 8); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_number_of_nzp_configuration = 2; + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config[0] = rand_range(0, 31); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel10.csi_rs_resource_config[1] = rand_range(0, 31); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_CSI_RS_PDU_REL13_TAG; + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.csi_rs_class = rand_range(0, 2); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.cdm_type = rand_range(0, 1); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.num_bf_vector = 0; // set to zero as not clear how to handle bf value array + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.bf_vector[0].csi_rs_resource_index = rand_range(0, 7); + dl_config_pdus[i].csi_rs_pdu.csi_rs_pdu_rel13.bf_vector[0].bf_value[0] = 42; + } + break; + + case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: { + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL8_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.dci_format = rand_range(0, 9); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.cce_idx = rand_range(0, 255); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.aggregation_level = rand_range(0, 32); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.rnti = rand_range(0, (uint16_t)-1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.resource_allocation_type = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.virtual_resource_block_assignment_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.resource_block_coding = rand_range(0, 320000); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.mcs_1 = rand_range(0, 31); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.redundancy_version_1 = rand_range(0, 3); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.new_data_indicator_1 = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transport_block_to_codeword_swap_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.mcs_2 = rand_range(0, 31); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.redundancy_version_2 = rand_range(0, 31); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.new_data_indicator_2 = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.harq_process = rand_range(0, 31); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tpmi = rand_range(0, 15); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.pmi = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.precoding_information = rand_range(0, 63); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.tpc = rand_range(0, 3); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.downlink_assignment_index = rand_range(0, 15); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.ngap = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transport_block_size_index = rand_range(0, 31); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.downlink_power_offset = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.allocate_prach_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.preamble_index = rand_range(0, 63); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.prach_mask_index = rand_range(0, 15); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.rnti_type = rand_range(0, 3); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel8.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL9_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.mcch_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.mcch_change_notification = rand_range(0, 255); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel9.scrambling_identity = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL10_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.carrier_indicator = rand_range(0, 7); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.srs_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.srs_request = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.antenna_ports_scrambling_and_layers = rand_range(0, 15); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel10.n_dl_rb = rand_range(0, 100); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL11_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.harq_ack_resource_offset = rand_range(0, 3); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel11.pdsch_re_mapping_quasi_co_location_indicator = rand_range(0, 3); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL12_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.primary_cell_type = rand_range(0, 2); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.number_ul_dl_configurations = 2; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_indication[0] = rand_range(1, 5); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel12.ul_dl_configuration_indication[1] = rand_range(1, 5); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PDU_REL13_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.laa_end_partial_sf_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.laa_end_partial_sf_configuration = rand_range(0, 255); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.initial_lbt_sf = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.codebook_size_determination = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_pdu_rel13.drms_table_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL11_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_resource_assignment_flag = rand_range(0, 1); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_id = rand_range(0, 503); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_start_symbol = rand_range(1, 4); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb = rand_range(2, 8); + + for(int j = 0; j < dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb; ++j) + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_prb_index[j] = rand_range(0, 99); + + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.subband_index = rand_range(0, 25); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.num_antennas= rand_range(1, 4); + + for(int j = 0; j < dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.epdcch_num_prb; ++j) + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel11.bf_vector.bf_value[j] = rand_range(0, 65535); + + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_EPDCCH_PARAM_REL13_TAG; + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.dwpts_symbols = rand_range(3, 14); + dl_config_pdus[i].epdcch_pdu.epdcch_params_rel13.initial_lbt_sf = rand_range(0, 1); + } + break; + + case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: { + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_MPDCCH_PDU_REL13_TAG; + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = rand_range(2, 6); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = rand_range(0, 14); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = rand_range(1, 4); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = rand_range(0, 22); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = rand_range(2, 24); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = rand_range(0, 4); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.rnti = rand_range(1, 65535); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = rand_range(1, 2); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = rand_range(0, 503); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.dci_format = rand_range(10, 12); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = rand_range(0, 0xFFFF); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.mcs = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = rand_range(1, 8); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = rand_range(0, 3); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.harq_process = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = rand_range(0, 4); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpmi = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.pmi = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = rand_range(0, 3); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rand_range(1, 4); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.tpc = rand_range(0, 3); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = rand_range(0, 4); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = rand_range(0, 63); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = rand_range(0, 15); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = rand_range(0, 3); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.srs_request = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = rand_range(0, 3); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = rand_range(0, 255); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = rand_range(0, 1); + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = rand_range(0, 8); + + for(int j = 0 ; j < dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports; ++j) + dl_config_pdus[i].mpdcch_pdu.mpdcch_pdu_rel13.precoding_value[j] = rand_range(0, 65535); + } + break; + + case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: { + dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NBCH_PDU_REL13_TAG; + dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.length = rand_range(0, 5555); + dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.transmission_power = rand_range(0, 10000); + dl_config_pdus[i].nbch_pdu.nbch_pdu_rel13.hyper_sfn_2_lsbs = rand_range(0, 3); + } + break; + + case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: { + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NPDCCH_PDU_REL13_TAG; + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.length = rand_range(0, 5555); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.ncce_index = rand_range(0, 1); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.aggregation_level = rand_range(1, 2); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.start_symbol = rand_range(0, 4); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.rnti_type = rand_range(0, 3); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.rnti = rand_range(1, 65535); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.scrambling_reinitialization_batch_index = rand_range(1, 4); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.dci_format = rand_range(0, 1); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.scheduling_delay = rand_range(0, 7); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.resource_assignment = rand_range(0, 7); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.repetition_number = rand_range(0, 15); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.mcs = rand_range(0, 13); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.new_data_indicator = rand_range(0, 1); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.harq_ack_resource = rand_range(0, 15); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.npdcch_order_indication = rand_range(0, 1); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.starting_number_of_nprach_repetitions = rand_range(0, 3); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.subcarrier_indication_of_nprach = rand_range(0, 63); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.paging_direct_indication_differentation_flag = rand_range(0, 1); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.direct_indication = rand_range(0, 255); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.dci_subframe_repetition_number = rand_range(0, 7); + dl_config_pdus[i].npdcch_pdu.npdcch_pdu_rel13.total_dci_length_including_padding = rand_range(0, 255); + } + break; + + case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: { + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_NDLSCH_PDU_REL13_TAG; + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.length = rand_range(0, 5555); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.pdu_index = rand_range(0, 65535); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.start_symbol = rand_range(0, 4); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.rnti_type = rand_range(0, 1); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.rnti = rand_range(1, 65535); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.resource_assignment = rand_range(0, 7); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.repetition_number = rand_range(0, 15); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.modulation = 2; + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.number_of_subframes_for_resource_assignment = rand_range(1, 10); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.scrambling_sequence_initialization_cinit = rand_range(0, 65535); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.sf_idx = rand_range(1, 10240); + dl_config_pdus[i].ndlsch_pdu.ndlsch_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2); + } + break; + }; + } + + dl_config_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdus; + mac->dl_config_req(mac, &dl_config_req); + uint8_t num_ul_pdus = 18; + nfapi_ul_config_request_pdu_t ul_config_pdus[num_ul_pdus]; + memset(&ul_config_pdus, 0, sizeof(ul_config_pdus)); + nfapi_ul_config_request_t ul_config_req; + memset(&ul_config_req, 0, sizeof(ul_config_req)); + ul_config_req.header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_config_req.header.phy_id = phy_id; + ul_config_req.sfn_sf = sfn_sf; + ul_config_req.ul_config_request_body.tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_config_req.ul_config_request_body.number_of_pdus = num_ul_pdus; + ul_config_req.ul_config_request_body.rach_prach_frequency_resources = rand_range(0, 255); + ul_config_req.ul_config_request_body.srs_present = rand_range(0, 1); + auto ul_config_ulsch_pdu_test_gen = [](nfapi_ul_config_ulsch_pdu& ulsch_pdu) { + ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ulsch_pdu.ulsch_pdu_rel8.handle = rand_range(0, 50000); + ulsch_pdu.ulsch_pdu_rel8.size = rand_range(0, 32000); + ulsch_pdu.ulsch_pdu_rel8.rnti = rand_range(1, 65535); + ulsch_pdu.ulsch_pdu_rel8.resource_block_start = rand_range(0, 99); + ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = rand_range(1, 100); + ulsch_pdu.ulsch_pdu_rel8.modulation_type = rand_range(2, 6); + ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); + ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = rand_range(0, 3); + ulsch_pdu.ulsch_pdu_rel8.new_data_indication = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rand_range(0, 3); + ulsch_pdu.ulsch_pdu_rel8.harq_process_number = rand_range(0, 15); + ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = rand_range(0, 5); + ulsch_pdu.ulsch_pdu_rel8.n_srs = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG; + ulsch_pdu.ulsch_pdu_rel10.resource_allocation_type = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel10.resource_block_coding = rand_range(0, 35000); + ulsch_pdu.ulsch_pdu_rel10.transport_blocks = rand_range(1, 2); + ulsch_pdu.ulsch_pdu_rel10.transmission_scheme = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel10.number_of_layers = rand_range(1, 4); + ulsch_pdu.ulsch_pdu_rel10.codebook_index = rand_range(0, 23); + ulsch_pdu.ulsch_pdu_rel10.disable_sequence_hopping_flag = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL11_TAG; + ulsch_pdu.ulsch_pdu_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel11.npusch_identity = rand_range(0, 509); + ulsch_pdu.ulsch_pdu_rel11.dmrs_config_flag = rand_range(0, 1); + ulsch_pdu.ulsch_pdu_rel11.ndmrs_csh_identity = rand_range(0, 509); + ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; + ulsch_pdu.ulsch_pdu_rel13.ue_type = rand_range(0, 2); + ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = rand_range(1, 2048); + ulsch_pdu.ulsch_pdu_rel13.repetition_number = rand_range(1, 2048); + ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = rand_range(0, 10239); + ulsch_pdu.ulsch_pdu_rel13.empty_symbols_due_to_re_tunning = rand_range(0, 8); + }; + auto ul_config_cqi_ri_info_test_gen = [](nfapi_ul_config_cqi_ri_information& cqi_ri_information) { + cqi_ri_information.cqi_ri_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL8_TAG; + cqi_ri_information.cqi_ri_information_rel8.dl_cqi_pmi_size_rank_1 = rand_range(0, 255); + cqi_ri_information.cqi_ri_information_rel8.dl_cqi_pmi_size_rank_greater_1 = rand_range(0, 255); + cqi_ri_information.cqi_ri_information_rel8.ri_size = rand_range(0, 3); + cqi_ri_information.cqi_ri_information_rel8.delta_offset_cqi = rand_range(0, 15); + cqi_ri_information.cqi_ri_information_rel8.delta_offset_ri = rand_range(0, 15); + cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; + cqi_ri_information.cqi_ri_information_rel9.report_type = 1; // rand_range(0, 1); + cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = rand_range(0, 15); + cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = rand_range(0, 15); + + if(cqi_ri_information.cqi_ri_information_rel9.report_type == 0) { + cqi_ri_information.cqi_ri_information_rel9.periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size = rand_range(0, 255); + cqi_ri_information.cqi_ri_information_rel9.periodic_cqi_pmi_ri_report.control_type = rand_range(0, 1); + } else { + cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; + cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = rand_range(0, 3); + cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0] = rand_range(0, 255); + } + + cqi_ri_information.cqi_ri_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL13_TAG; + cqi_ri_information.cqi_ri_information_rel13.report_type = rand_range(0, 1); + + if(cqi_ri_information.cqi_ri_information_rel13.report_type == 0) { + cqi_ri_information.cqi_ri_information_rel13.periodic_cqi_pmi_ri_report.dl_cqi_pmi_ri_size_2 = rand_range(255, 10000); + } + }; + auto ul_config_init_tx_params_test_gen = [](nfapi_ul_config_initial_transmission_parameters& initial_transmission_parameters) { + initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = rand_range(0, 1); + initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rand_range(1, 100); + }; + auto ul_config_harqinfo_test_gen = [](nfapi_ul_config_ulsch_harq_information& harq_information) { + harq_information.harq_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG; + harq_information.harq_information_rel10.harq_size = rand_range(0, 21); + harq_information.harq_information_rel10.delta_offset_harq = rand_range(0, 15); + harq_information.harq_information_rel10.ack_nack_mode = rand_range(0, 5); + harq_information.harq_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL13_TAG; + harq_information.harq_information_rel13.harq_size_2 = rand_range(0, 21); + harq_information.harq_information_rel13.delta_offset_harq_2 = rand_range(0, 15); + }; + auto ul_config_sr_info_test_gen = [](nfapi_ul_config_sr_information& sr_info) { + sr_info.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; + sr_info.sr_information_rel8.pucch_index = rand_range(0, 2047); + sr_info.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; + sr_info.sr_information_rel10.number_of_pucch_resources = rand_range(1, 2); + sr_info.sr_information_rel10.pucch_index_p1 = rand_range(0, 2047); + }; + auto ul_config_ue_info_test_gen = [](nfapi_ul_config_ue_information& ue_information) { + ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ue_information.ue_information_rel8.handle = rand_range(0, 99999); + ue_information.ue_information_rel8.rnti = rand_range(1, 65535); + ue_information.ue_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG; + ue_information.ue_information_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1); + ue_information.ue_information_rel11.npusch_identity = rand_range(0, 503); + ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG; + ue_information.ue_information_rel13.ue_type = rand_range(0, 2); + ue_information.ue_information_rel13.empty_symbols = rand_range(0, 2); + ue_information.ue_information_rel13.total_number_of_repetitions = rand_range(1, 32); + ue_information.ue_information_rel13.repetition_number = rand_range(1, 32); + }; + auto ul_config_cqi_info_test_gen = [](nfapi_ul_config_cqi_information& cqi_information) { + cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; + cqi_information.cqi_information_rel8.pucch_index = rand_range(0, 1184); + cqi_information.cqi_information_rel8.dl_cqi_pmi_size = rand_range(0, 255); + cqi_information.cqi_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL10_TAG; + cqi_information.cqi_information_rel10.number_of_pucch_resource = rand_range(1, 2); + cqi_information.cqi_information_rel10.pucch_index_p1 = rand_range(0, 1184); + cqi_information.cqi_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL13_TAG; + cqi_information.cqi_information_rel13.csi_mode = rand_range(0, 2); + cqi_information.cqi_information_rel13.dl_cqi_pmi_size_2 = rand_range(0, 999); + cqi_information.cqi_information_rel13.starting_prb = rand_range(0, 109); + cqi_information.cqi_information_rel13.n_prb = rand_range(0, 7); + cqi_information.cqi_information_rel13.cdm_index = rand_range(0, 1); + cqi_information.cqi_information_rel13.n_srs = rand_range(0, 1); + }; + auto ul_config_harq_info_test_gen = [](nfapi_ul_config_harq_information& harq_information) { + harq_information.harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; + harq_information.harq_information_rel10_tdd.harq_size = rand_range(0, 21); + harq_information.harq_information_rel10_tdd.ack_nack_mode = rand_range(0, 5); + harq_information.harq_information_rel10_tdd.number_of_pucch_resources = rand_range(0, 4); + harq_information.harq_information_rel10_tdd.n_pucch_1_0 = rand_range(0, 2047); + harq_information.harq_information_rel10_tdd.n_pucch_1_1 = rand_range(0, 2047); + harq_information.harq_information_rel10_tdd.n_pucch_1_2 = rand_range(0, 2047); + harq_information.harq_information_rel10_tdd.n_pucch_1_3 = rand_range(0, 2047); + harq_information.harq_information_rel8_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL8_FDD_TAG; + harq_information.harq_information_rel8_fdd.n_pucch_1_0 = rand_range(0, 2047); + harq_information.harq_information_rel8_fdd.harq_size = rand_range(1, 2); + harq_information.harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; + harq_information.harq_information_rel9_fdd.harq_size = rand_range(1, 10); + harq_information.harq_information_rel9_fdd.ack_nack_mode = rand_range(0, 4); + harq_information.harq_information_rel9_fdd.number_of_pucch_resources = rand_range(0, 4); + harq_information.harq_information_rel9_fdd.n_pucch_1_0 = rand_range(0, 2047); + harq_information.harq_information_rel9_fdd.n_pucch_1_1 = rand_range(0, 2047); + harq_information.harq_information_rel9_fdd.n_pucch_1_2 = rand_range(0, 2047); + harq_information.harq_information_rel9_fdd.n_pucch_1_3 = rand_range(0, 2047); + harq_information.harq_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG; + harq_information.harq_information_rel11.num_ant_ports = rand_range(1, 2); + harq_information.harq_information_rel11.n_pucch_2_0 = rand_range(0, 2047); + harq_information.harq_information_rel11.n_pucch_2_1 = rand_range(0, 2047); + harq_information.harq_information_rel11.n_pucch_2_2 = rand_range(0, 2047); + harq_information.harq_information_rel11.n_pucch_2_3 = rand_range(0, 2047); + harq_information.harq_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL13_TAG; + harq_information.harq_information_rel13.harq_size_2 = rand_range(0, 999); + harq_information.harq_information_rel13.starting_prb = rand_range(0, 109); + harq_information.harq_information_rel13.n_prb = rand_range(0, 7); + harq_information.harq_information_rel13.cdm_index = rand_range(0, 1); + harq_information.harq_information_rel13.n_srs = rand_range(0, 1); + }; + ul_config_pdus[0].pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[0].ulsch_pdu); + ul_config_pdus[1].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.ulsch_pdu); + ul_config_cqi_ri_info_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.cqi_ri_information); + ul_config_init_tx_params_test_gen(ul_config_pdus[1].ulsch_cqi_ri_pdu.initial_transmission_parameters); + ul_config_pdus[2].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[2].ulsch_harq_pdu.ulsch_pdu); + ul_config_harqinfo_test_gen(ul_config_pdus[2].ulsch_harq_pdu.harq_information); + ul_config_init_tx_params_test_gen(ul_config_pdus[2].ulsch_harq_pdu.initial_transmission_parameters); + ul_config_pdus[3].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.ulsch_pdu); + ul_config_cqi_ri_info_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.cqi_ri_information); + ul_config_harqinfo_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.harq_information); + ul_config_init_tx_params_test_gen(ul_config_pdus[3].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters); + ul_config_pdus[4].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[4].uci_cqi_pdu.ue_information); + ul_config_cqi_info_test_gen(ul_config_pdus[4].uci_cqi_pdu.cqi_information); + ul_config_pdus[5].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[5].uci_sr_pdu.ue_information); + ul_config_sr_info_test_gen(ul_config_pdus[5].uci_sr_pdu.sr_information); + ul_config_pdus[6].pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[6].uci_harq_pdu.ue_information); + ul_config_harq_info_test_gen(ul_config_pdus[6].uci_harq_pdu.harq_information); + ul_config_pdus[7].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.ue_information); + ul_config_sr_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.sr_information); + ul_config_harq_info_test_gen(ul_config_pdus[7].uci_sr_harq_pdu.harq_information); + ul_config_pdus[8].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.ue_information); + ul_config_cqi_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.cqi_information); + ul_config_harq_info_test_gen(ul_config_pdus[8].uci_cqi_harq_pdu.harq_information); + ul_config_pdus[9].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.ue_information); + ul_config_cqi_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.cqi_information); + ul_config_sr_info_test_gen(ul_config_pdus[9].uci_cqi_sr_pdu.sr_information); + ul_config_pdus[10].pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.ue_information); + ul_config_cqi_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.cqi_information); + ul_config_sr_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.sr_information); + ul_config_harq_info_test_gen(ul_config_pdus[10].uci_cqi_sr_harq_pdu.harq_information); + ul_config_pdus[11].pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG; + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.handle = rand_range(0, 9999); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.size = rand_range(1, 999); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.rnti = rand_range(1, 65535); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.srs_bandwidth = rand_range(0, 3); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.frequency_domain_position = rand_range(0, 23); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = rand_range(0, 3); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.transmission_comb = rand_range(0, 3); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.i_srs = rand_range(0, 1023); + ul_config_pdus[11].srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = rand_range(0, 11); + ul_config_pdus[11].srs_pdu.srs_pdu_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL10_TAG; + ul_config_pdus[11].srs_pdu.srs_pdu_rel10.antenna_port = rand_range(0, 2); + ul_config_pdus[11].srs_pdu.srs_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL13_TAG; + ul_config_pdus[11].srs_pdu.srs_pdu_rel13.number_of_combs = rand_range(0, 1); + ul_config_pdus[12].pdu_type = NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE; + ul_config_ue_info_test_gen(ul_config_pdus[12].harq_buffer_pdu.ue_information); + ul_config_pdus[13].pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[13].ulsch_uci_csi_pdu.ulsch_pdu); + ul_config_cqi_info_test_gen(ul_config_pdus[13].ulsch_uci_csi_pdu.csi_information); + ul_config_pdus[14].pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[14].ulsch_uci_harq_pdu.ulsch_pdu); + ul_config_harq_info_test_gen(ul_config_pdus[14].ulsch_uci_harq_pdu.harq_information); + ul_config_pdus[15].pdu_type = NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE; + ul_config_ulsch_pdu_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.ulsch_pdu); + ul_config_cqi_info_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.csi_information); + ul_config_harq_info_test_gen(ul_config_pdus[15].ulsch_csi_uci_harq_pdu.harq_information); + ul_config_pdus[16].pdu_type = NFAPI_UL_CONFIG_NULSCH_PDU_TYPE; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_NULSCH_PDU_REL13_TAG; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nulsch_format = rand_range(0, 1); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.handle = rand_range(0, 0xFFFF); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.size = rand_range(0, 65535); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.rnti = rand_range(1, 65535); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.subcarrier_indication = rand_range(0, 47); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.resource_assignment = rand_range(0, 7); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.mcs = rand_range(0, 12); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.redudancy_version = rand_range(0, 1); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.repetition_number = rand_range(0, 7); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.new_data_indication = rand_range(0, 1); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.n_srs = rand_range(0, 1); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.scrambling_sequence_initialization_cinit = rand_range(0, 65535); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.sf_idx = rand_range(0, 40960); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.handle = rand_range(0, 0xFF); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel8.rnti = rand_range(1, 65535); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL11_TAG; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.virtual_cell_id_enabled_flag = rand_range(0, 1); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel11.npusch_identity = rand_range(0, 503); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.ue_type = rand_range(0, 2); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.empty_symbols = rand_range(0, 0x3); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.total_number_of_repetitions = rand_range(1, 32); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.ue_information.ue_information_rel13.repetition_number = rand_range(1, 32); + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nb_harq_information.nb_harq_information_rel13_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_NB_HARQ_INFORMATION_REL13_FDD_TAG; + ul_config_pdus[16].nulsch_pdu.nulsch_pdu_rel13.nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource = rand_range(0, 15); + ul_config_pdus[17].pdu_type = NFAPI_UL_CONFIG_NRACH_PDU_TYPE; + ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_NRACH_PDU_REL13_TAG; + ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_0 = rand_range(0, 1); + ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_1 = rand_range(0, 1); + ul_config_pdus[17].nrach_pdu.nrach_pdu_rel13.nprach_config_2 = rand_range(0, 1); + ul_config_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdus; + mac->ul_config_req(mac, &ul_config_req); + uint8_t num_dci_pdus = 4; + uint8_t num_hi_pdus = 1; + nfapi_hi_dci0_request_pdu_t hi_dci0_pdus[num_dci_pdus + num_hi_pdus]; + memset(&hi_dci0_pdus, 0, sizeof(hi_dci0_pdus)); + nfapi_hi_dci0_request_t hi_dci0_req; + memset(&hi_dci0_req, 0, sizeof(hi_dci0_req)); + hi_dci0_req.header.message_id = NFAPI_HI_DCI0_REQUEST; + hi_dci0_req.header.phy_id = phy_id; + hi_dci0_req.sfn_sf = sfn_sf; + hi_dci0_req.hi_dci0_request_body.tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req.hi_dci0_request_body.sfnsf = sfn_sf; + hi_dci0_req.hi_dci0_request_body.number_of_dci = num_dci_pdus; + hi_dci0_req.hi_dci0_request_body.number_of_hi = num_hi_pdus; + hi_dci0_pdus[0].pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.resource_block_start = rand_range(0, 100); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.hi_value = rand_range(0, 1); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.i_phich = rand_range(0, 1); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel8.transmission_power = rand_range(0, 10000); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL10_TAG; + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.flag_tb2 = rand_range(0, 1); + hi_dci0_pdus[0].hi_pdu.hi_pdu_rel10.hi_value_2 = rand_range(0, 1); + hi_dci0_pdus[1].pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.dci_format = rand_range(0, 4); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cce_index = rand_range(0, 88); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.aggregation_level = rand_range(1, 8); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.rnti = rand_range(1, 65535); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.resource_block_start = rand_range(0, 100); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.number_of_resource_block = rand_range(0, 100); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.mcs_1 = rand_range(0, 31); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.frequency_hopping_bits = rand_range(0, 3); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.new_data_indication_1 = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.ue_tx_antenna_seleciton = rand_range(0, 2); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tpc = rand_range(0, 3); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.cqi_csi_request = rand_range(0, 7); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.ul_index = rand_range(0, 3); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.dl_assignment_index = rand_range(1, 4); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.tpc_bitmap = rand_range(0, 9999); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel8.transmission_power = rand_range(0, 10000); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL10_TAG; + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.carrier_indicator = rand_range(0, 7); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.size_of_cqi_csi_feild = rand_range(0, 2); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.srs_flag = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.srs_request = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_allocation_flag = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_allocation_type = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.resource_block_coding = rand_range(0, 9999); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.mcs_2 = rand_range(0, 31); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.new_data_indication_2 = rand_range(0, 1); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.number_of_antenna_ports = rand_range(0, 2); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.tpmi = rand_range(0, 63); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel10.n_ul_rb = rand_range(6, 100); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL12_TAG; + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.pscch_resource = rand_range(0, 16); + hi_dci0_pdus[1].dci_pdu.dci_pdu_rel12.time_resource_pattern = rand_range(0, 32); + hi_dci0_pdus[2].pdu_type = NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE; + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL8_TAG; + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.dci_format = rand_range(0, 4); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cce_index = rand_range(0, 88); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.aggregation_level = rand_range(1, 8); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.rnti = rand_range(1, 65535); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.resource_block_start = rand_range(0, 100); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.number_of_resource_block = rand_range(0, 100); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.mcs_1 = rand_range(0, 31); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cyclic_shift_2_for_drms = rand_range(0, 7); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.frequency_hopping_enabled_flag = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.frequency_hopping_bits = rand_range(0, 3); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.new_data_indication_1 = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.ue_tx_antenna_seleciton = rand_range(0, 2); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tpc = rand_range(0, 3); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.cqi_csi_request = rand_range(0, 7); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.ul_index = rand_range(0, 3); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.dl_assignment_index = rand_range(1, 4); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.tpc_bitmap = rand_range(0, 9999); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel8.transmission_power = rand_range(0, 10000); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_DCI_PDU_REL10_TAG; + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.cross_carrier_scheduling_flag = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.carrier_indicator = rand_range(0, 7); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.size_of_cqi_csi_feild = rand_range(0, 2); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.srs_flag = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.srs_request = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_allocation_flag = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_allocation_type = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.resource_block_coding = rand_range(0, 9999); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.mcs_2 = rand_range(0, 31); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.new_data_indication_2 = rand_range(0, 1); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.number_of_antenna_ports = rand_range(0, 2); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.tpmi = rand_range(0, 63); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.total_dci_length_including_padding = rand_range(0, 255); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_dci_pdu_rel10.n_ul_rb = rand_range(6, 100); + hi_dci0_pdus[2].epdcch_dci_pdu.epdcch_parameters_rel11.tl.tag = NFAPI_HI_DCI0_REQUEST_EPDCCH_PARAMETERS_REL11_TAG; + hi_dci0_pdus[3].pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; + hi_dci0_pdus[3].mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tl.tag = NFAPI_HI_DCI0_REQUEST_MPDCCH_DCI_PDU_REL13_TAG; + hi_dci0_pdus[4].pdu_type = NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE; + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.tl.tag = NFAPI_HI_DCI0_REQUEST_NPDCCH_DCI_PDU_REL13_TAG; + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.ncce_index = rand_range(0, 1); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.aggregation_level = rand_range(1, 2); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.start_symbol = rand_range(0, 4); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.rnti = rand_range(1, 65535); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.scrambling_reinitialization_batch_index = rand_range(1, 4); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.nrs_antenna_ports_assumed_by_the_ue = rand_range(1, 2); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.subcarrier_indication = rand_range(0, 63); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.resource_assignment = rand_range(0, 7); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.scheduling_delay = rand_range(0, 3); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.mcs = rand_range(0, 12); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.redudancy_version = rand_range(0, 1); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.repetition_number = rand_range(0, 7); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.new_data_indicator = rand_range(0, 1); + hi_dci0_pdus[4].npdcch_dci_pdu.npdcch_dci_pdu_rel13.dci_subframe_repetition_number = rand_range(0, 3); + hi_dci0_req.hi_dci0_request_body.hi_dci0_pdu_list = hi_dci0_pdus; + mac->hi_dci0_req(mac, &hi_dci0_req); + uint8_t num_tx_pdus = 2; + nfapi_tx_request_pdu_t tx_pdus[num_tx_pdus]; + memset(&tx_pdus, 0, sizeof(tx_pdus)); + nfapi_tx_request_t tx_req; + memset(&tx_req, 0, sizeof(tx_req)); + tx_req.header.message_id = NFAPI_TX_REQUEST; + tx_req.header.phy_id = phy_id; + tx_req.sfn_sf = sfn_sf; + tx_req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + tx_req.tx_request_body.number_of_pdus = num_tx_pdus; + uint32_t data[2]; + data[0] = 0x11223344; + data[1] = 0x55667788; + tx_pdus[0].pdu_length = 8; + tx_pdus[0].pdu_index = 1; + tx_pdus[0].num_segments = 2; + tx_pdus[0].segments[0].segment_length = 4; + tx_pdus[0].segments[0].segment_data = (uint8_t *)&data[0]; + tx_pdus[0].segments[1].segment_length = 4; + tx_pdus[0].segments[1].segment_data = (uint8_t *)&data[1]; + tx_pdus[1].pdu_length = 8; + tx_pdus[1].pdu_index = 2; + tx_pdus[1].num_segments = 2; + tx_pdus[1].segments[0].segment_length = 4; + tx_pdus[1].segments[0].segment_data = (uint8_t *)&data[0]; + tx_pdus[1].segments[1].segment_length = 4; + tx_pdus[1].segments[1].segment_data = (uint8_t *)&data[1]; + tx_req.tx_request_body.tx_pdu_list = tx_pdus; + mac->tx_req(mac, &tx_req); + } + + void generate_subframe(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf) { + mac_internal_t *instance = (mac_internal_t *)mac; + nfapi_dl_config_request_t dl_config_req; + memset(&dl_config_req, 0, sizeof(dl_config_req)); + dl_config_req.header.message_id = NFAPI_DL_CONFIG_REQUEST; + dl_config_req.header.phy_id = phy_id; + dl_config_req.sfn_sf = sfn_sf; + dl_config_req.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + dl_config_req.dl_config_request_body.number_pdu = 8; + nfapi_dl_config_request_pdu_t pdus[8]; + memset(&pdus, 0, sizeof(pdus)); + + for(int i = 0; i < 8; i++) { + pdus[i].pdu_type = NFAPI_DL_CONFIG_BCH_PDU_TYPE; + pdus[i].bch_pdu.bch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG; + pdus[i].bch_pdu.bch_pdu_rel8.length = 42; + pdus[i].bch_pdu.bch_pdu_rel8.pdu_index = i; + pdus[i].bch_pdu.bch_pdu_rel8.transmission_power = 56; + } + + dl_config_req.dl_config_request_body.dl_config_pdu_list = pdus; + /* + vendor_ext_tlv_1 ve; + ve.tl.tag = VENDOR_EXT_TLV_1_TAG; + ve.dummy = 999; + dl_config_req.vendor_extension = &ve.tl; + */ + mac->dl_config_req(mac, &dl_config_req); + nfapi_ul_config_request_t ul_config_req; + memset(&ul_config_req, 0, sizeof(ul_config_req)); + ul_config_req.header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_config_req.header.phy_id = phy_id; + ul_config_req.sfn_sf = sfn_sf; + mac->ul_config_req(mac, &ul_config_req); + nfapi_hi_dci0_request_t hi_dci0_req; + memset(&hi_dci0_req, 0, sizeof(hi_dci0_req)); + hi_dci0_req.header.message_id = NFAPI_HI_DCI0_REQUEST; + hi_dci0_req.header.phy_id = phy_id; + hi_dci0_req.sfn_sf = sfn_sf; + mac->hi_dci0_req(mac, &hi_dci0_req); + nfapi_tx_request_t tx_req; + memset(&tx_req, 0, sizeof(tx_req)); + tx_req.header.message_id = NFAPI_TX_REQUEST; + tx_req.header.phy_id = phy_id; + tx_req.sfn_sf = sfn_sf; + nfapi_tx_request_pdu_t tx_pdus[8]; + tx_req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + tx_req.tx_request_body.number_of_pdus = 0; + tx_req.tx_request_body.tx_pdu_list = &tx_pdus[0]; + mac_pdu *buff = 0; + int i = 0; + std::list<mac_pdu *> free_list; + + do { + buff = instance->mac->pop_rx_buffer(); + + if(buff != 0) { + if(buff->len == 0) { + printf("[MAC] Buffer length = 0\n"); + } + + tx_req.tx_request_body.tx_pdu_list[i].pdu_length = buff->len; + tx_req.tx_request_body.tx_pdu_list[i].pdu_index = i; + tx_req.tx_request_body.tx_pdu_list[i].num_segments = 1; + tx_req.tx_request_body.tx_pdu_list[i].segments[0].segment_length = buff->len; + tx_req.tx_request_body.tx_pdu_list[i].segments[0].segment_data = (uint8_t *)buff->buffer; + tx_req.tx_request_body.number_of_pdus++; + i++; + instance->mac->byte_count += buff->len; + free_list.push_back(buff); + } + } while(buff != 0 && i < 8); + + mac->tx_req(mac, &tx_req); + + //for(int j = 0; j < tx_req.tx_request_body.number_of_pdus; ++j) + for(mac_pdu *pdu : free_list) { + instance->mac->release_mac_pdu(pdu); + //free(tx_req.tx_request_body.tx_pdu_list[j].segments[0].segment_data); + } + } + + void mac_subframe_ind(mac_t *mac, uint16_t phy_id, uint16_t sfn_sf) { + //printf("[MAC] subframe indication phyid:%d sfnsf:%d\n", phy_id, sfn_sf); + mac_internal_t *instance = (mac_internal_t *)mac; + + if(instance->mac->tick == 1000) { + if(instance->mac->byte_count > 0) { + printf("[MAC] Rx rate %d bytes/sec\n", instance->mac->byte_count); + instance->mac->byte_count = 0; + } + + instance->mac->tick = 0; + } + + instance->mac->tick++; + + if(instance->mac->wireshark_test_mode) { + generate_test_subframe(mac, phy_id, sfn_sf); + } else { + generate_subframe(mac, phy_id, sfn_sf); + } + } + + void mac_harq_ind(mac_t *mac, nfapi_harq_indication_t *ind) { + } + void mac_crc_ind(mac_t *mac, nfapi_crc_indication_t *ind) { + } + void mac_rx_ind(mac_t *mac, nfapi_rx_indication_t *ind) { + mac_internal_t *instance = (mac_internal_t *)mac; + + for(int i = 0; i < ind->rx_indication_body.number_of_pdus; ++i) { + uint16_t len = ind->rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length; + uint8_t *data = ind->rx_indication_body.rx_pdu_list[i].data; + //printf("[MAC] sfnsf:%d len:%d\n", ind->sfn_sf,len); + // + instance->tx_byte_count += len; + int sendto_result = sendto(instance->tx_sock, data, len, 0, (struct sockaddr *)&(instance->tx_addr), sizeof(instance->tx_addr)); + + if(sendto_result < 0) { + // error + } + } + } + void mac_rach_ind(mac_t *mac, nfapi_rach_indication_t *ind) { + } + void mac_srs_ind(mac_t *mac, nfapi_srs_indication_t *ind) { + } + void mac_sr_ind(mac_t *mac, nfapi_sr_indication_t *ind) { + } + void mac_cqi_ind(mac_t *mac, nfapi_cqi_indication_t *ind) { + } + void mac_lbt_dl_ind(mac_t *mac, nfapi_lbt_dl_indication_t *ind) { + } + void mac_nb_harq_ind(mac_t *mac, nfapi_nb_harq_indication_t *ind) { + } + void mac_nrach_ind(mac_t *mac, nfapi_nrach_indication_t *ind) { + } } diff --git a/nfapi/open-nFAPI/vnf_sim/src/main.cpp b/nfapi/open-nFAPI/vnf_sim/src/main.cpp index 5dc7161157defe8b5c6e3b8d5b10c445cf79a25d..dedf06174f43b435fd1ddf97ec6cc30af9815767 100644 --- a/nfapi/open-nFAPI/vnf_sim/src/main.cpp +++ b/nfapi/open-nFAPI/vnf_sim/src/main.cpp @@ -1,12 +1,12 @@ /* * Copyright 2017 Cisco Systems, Inc. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -38,8 +38,8 @@ #include <boost/foreach.hpp> #include <boost/property_tree/xml_parser.hpp> #include <boost/property_tree/ptree.hpp> -#include <boost/exception/diagnostic_information.hpp> -#include <boost/exception_ptr.hpp> +#include <boost/exception/diagnostic_information.hpp> +#include <boost/exception_ptr.hpp> extern "C" { #include <nfapi_vnf_interface.h> @@ -48,606 +48,486 @@ extern "C" { #include <vendor_ext.h> -//int vnf_main(int iPortP5, int, int); -int start_simulated_mac(int*, int*); -int read_xml(const char *xml_file); + //int vnf_main(int iPortP5, int, int); + int start_simulated_mac(int *, int *); + int read_xml(const char *xml_file); } -static uint32_t rand_range(uint32_t min, uint32_t max) -{ - return ((rand() % (max + 1 - min)) + min); +static uint32_t rand_range(uint32_t min, uint32_t max) { + return ((rand() % (max + 1 - min)) + min); } -void* vnf_allocate(size_t size) -{ - return (void*)memory_pool::allocate(size); +void *vnf_allocate(size_t size) { + return (void *)memory_pool::allocate(size); } -void vnf_deallocate(void* ptr) -{ - memory_pool::deallocate((uint8_t*)ptr); +void vnf_deallocate(void *ptr) { + memory_pool::deallocate((uint8_t *)ptr); } -class udp_data -{ - public: - bool enabled; - uint32_t rx_port; - uint32_t tx_port; - std::string tx_addr; +class udp_data { + public: + bool enabled; + uint32_t rx_port; + uint32_t tx_port; + std::string tx_addr; }; -class phy_info -{ - public: +class phy_info { + public: - uint16_t index; - uint16_t id; + uint16_t index; + uint16_t id; - std::vector<uint16_t> rfs; - std::vector<uint16_t> excluded_rfs; + std::vector<uint16_t> rfs; + std::vector<uint16_t> excluded_rfs; - int remote_port; - std::string remote_addr; + int remote_port; + std::string remote_addr; - uint16_t earfcn; + uint16_t earfcn; }; -class rf_info -{ - public: +class rf_info { + public: - uint16_t index; - uint16_t band; + uint16_t index; + uint16_t band; }; -class pnf_info -{ - public: +class pnf_info { + public: - std::vector<phy_info> phys; - std::vector<rf_info> rfs; + std::vector<phy_info> phys; + std::vector<rf_info> rfs; }; -class vnf_p7_info -{ - public: - vnf_p7_info() - : thread_started(false), - config(nfapi_vnf_p7_config_create(), - [] (nfapi_vnf_p7_config_t* f) { nfapi_vnf_p7_config_destory(f); }), - mac(0) - { - local_port = 0; - - timing_window = 0; - periodic_timing_enabled = 0; - aperiodic_timing_enabled = 0; - periodic_timing_period = 0; - - //config = nfapi_vnf_p7_config_create(); - } - - vnf_p7_info(const vnf_p7_info& other) = default; - - vnf_p7_info(vnf_p7_info&& other) = default; - - vnf_p7_info& operator=(const vnf_p7_info&) = default; - - vnf_p7_info& operator=(vnf_p7_info&&) = default; - - - - virtual ~vnf_p7_info() - { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "*** vnf_p7_info delete ***\n"); - - //nfapi_vnf_p7_config_destory(config); - - // should we delete the mac? - } - +class vnf_p7_info { + public: + + vnf_p7_info() + : thread_started(false), + config(nfapi_vnf_p7_config_create(), + [] (nfapi_vnf_p7_config_t *f) { + nfapi_vnf_p7_config_destory(f); + }), + mac(0) { + local_port = 0; + udp=0; + timing_window = 0; + periodic_timing_enabled = 0; + aperiodic_timing_enabled = 0; + periodic_timing_period = 0; + //config = nfapi_vnf_p7_config_create(); + } + + vnf_p7_info(const vnf_p7_info &other) = default; + + vnf_p7_info(vnf_p7_info &&other) = default; + + vnf_p7_info &operator=(const vnf_p7_info &) = default; + + vnf_p7_info &operator=(vnf_p7_info &&) = default; - int local_port; - std::string local_addr; - unsigned timing_window; - unsigned periodic_timing_enabled; - unsigned aperiodic_timing_enabled; - unsigned periodic_timing_period; - // This is not really the right place if we have multiple PHY, - // should be part of the phy struct - udp_data udp; + virtual ~vnf_p7_info() { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "*** vnf_p7_info delete ***\n"); + //nfapi_vnf_p7_config_destory(config); + // should we delete the mac? + } - bool thread_started; - //nfapi_vnf_p7_config_t* config; - std::shared_ptr<nfapi_vnf_p7_config_t> config; + int local_port; + std::string local_addr; - mac_t* mac; + unsigned timing_window; + unsigned periodic_timing_enabled; + unsigned aperiodic_timing_enabled; + unsigned periodic_timing_period; + // This is not really the right place if we have multiple PHY, + // should be part of the phy struct + udp_data udp; + + bool thread_started; + + //nfapi_vnf_p7_config_t* config; + std::shared_ptr<nfapi_vnf_p7_config_t> config; + + mac_t *mac; }; -class vnf_info -{ - public: - - uint8_t wireshark_test_mode; +class vnf_info { + public: - std::map<uint16_t, pnf_info> pnfs; + uint8_t wireshark_test_mode; + + std::map<uint16_t, pnf_info> pnfs; + + std::vector<vnf_p7_info> p7_vnfs; - std::vector<vnf_p7_info> p7_vnfs; - }; /// maybe these should be in the mac file... -int phy_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p7_codec_config_t* codec) -{ - (void)tl; - (void)ppReadPackedMessage; - (void)ve; - return -1; +int phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p7_codec_config_t *codec) { + (void)tl; + (void)ppReadPackedMessage; + (void)ve; + return -1; } -int phy_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* codec) -{ - //NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n"); +int phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n"); + nfapi_tl_t *tlv = (nfapi_tl_t *)ve; - nfapi_tl_t* tlv = (nfapi_tl_t*)ve; - switch(tlv->tag) - { - case VENDOR_EXT_TLV_1_TAG: - { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n"); - vendor_ext_tlv_1* ve = (vendor_ext_tlv_1*)tlv; - if(!push32(ve->dummy, ppWritePackedMsg, end)) - return 0; - return 1; - } - break; - default: - return -1; - break; - } -} + switch(tlv->tag) { + case VENDOR_EXT_TLV_1_TAG: { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n"); + vendor_ext_tlv_1 *ve = (vendor_ext_tlv_1 *)tlv; -int vnf_sim_pack_vendor_extension_tlv(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) -{ - //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_sim_pack_vendor_extension_tlv\n"); - nfapi_tl_t* tlv = (nfapi_tl_t*)ve; - switch(tlv->tag) - { - case VENDOR_EXT_TLV_2_TAG: - { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_2\n"); - vendor_ext_tlv_2* ve = (vendor_ext_tlv_2*)tlv; - if(!push32(ve->dummy, ppWritePackedMsg, end)) - return 0; - return 1; - } - break; - } - return -1; -} + if(!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; -int vnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t* tl, uint8_t **ppReadPackedMessage, uint8_t *end, void** ve, nfapi_p4_p5_codec_config_t* codec) -{ - return -1; + return 1; + } + break; + + default: + return -1; + break; + } } +int vnf_sim_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_sim_pack_vendor_extension_tlv\n"); + nfapi_tl_t *tlv = (nfapi_tl_t *)ve; + switch(tlv->tag) { + case VENDOR_EXT_TLV_2_TAG: { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_2\n"); + vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)tlv; + if(!push32(ve->dummy, ppWritePackedMsg, end)) + return 0; -int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); - if(header->message_id == P7_VENDOR_EXT_IND) - { - vendor_ext_p7_ind* req = (vendor_ext_p7_ind*)(header); - if(!pull16(ppReadPackedMessage, &req->error_code, end)) - return 0; - } - return 1; -} + return 1; + } + break; + } -int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) -{ - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); - if(header->message_id == P7_VENDOR_EXT_REQ) - { - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); - vendor_ext_p7_req* req = (vendor_ext_p7_req*)(header); - if(!(push16(req->dummy1, ppWritePackedMsg, end) && - push16(req->dummy2, ppWritePackedMsg, end))) - return 0; - } - return 1; + return -1; } -int vnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) -{ - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); - if(header->message_id == P5_VENDOR_EXT_RSP) - { - vendor_ext_p5_rsp* req = (vendor_ext_p5_rsp*)(header); - return(!pull16(ppReadPackedMessage, &req->error_code, end)); - } - return 0; +int vnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p4_p5_codec_config_t *codec) { + return -1; } -int vnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t* header, uint8_t** ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* codec) -{ - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); - if(header->message_id == P5_VENDOR_EXT_REQ) - { - vendor_ext_p5_req* req = (vendor_ext_p5_req*)(header); - //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2); - return (!(push16(req->dummy1, ppWritePackedMsg, end) && - push16(req->dummy2, ppWritePackedMsg, end))); - } - return 0; + + + +int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t *config) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_IND) { + vendor_ext_p7_ind *req = (vendor_ext_p7_ind *)(header); + + if(!pull16(ppReadPackedMessage, &req->error_code, end)) + return 0; + } + + return 1; } -void vnf_sim_trace(nfapi_trace_level_t level, const char* message, ...) -{ - va_list args; - va_start(args, message); - vprintf(message, args); - va_end(args); +int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P7_VENDOR_EXT_REQ) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + vendor_ext_p7_req *req = (vendor_ext_p7_req *)(header); + + if(!(push16(req->dummy1, ppWritePackedMsg, end) && + push16(req->dummy2, ppWritePackedMsg, end))) + return 0; + } + + return 1; } -void mac_dl_config_req(mac_t* mac, nfapi_dl_config_request_t* req) -{ - vnf_p7_info* info = (vnf_p7_info*)(mac->user_data); +int vnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_RSP) { + vendor_ext_p5_rsp *req = (vendor_ext_p5_rsp *)(header); + return(!pull16(ppReadPackedMessage, &req->error_code, end)); + } - nfapi_vnf_p7_dl_config_req(info->config.get(), req); + return 0; } -void mac_ul_config_req(mac_t* mac, nfapi_ul_config_request_t* req) -{ - vnf_p7_info* info = (vnf_p7_info*)(mac->user_data); +int vnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) { + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); + if(header->message_id == P5_VENDOR_EXT_REQ) { + vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2); + return (!(push16(req->dummy1, ppWritePackedMsg, end) && + push16(req->dummy2, ppWritePackedMsg, end))); + } - nfapi_vnf_p7_ul_config_req(info->config.get(), req); + return 0; } -void mac_hi_dci0_req(mac_t* mac, nfapi_hi_dci0_request_t* req) -{ - vnf_p7_info* info = (vnf_p7_info*)(mac->user_data); +void vnf_sim_trace(nfapi_trace_level_t level, const char *message, ...) { + va_list args; + va_start(args, message); + vprintf(message, args); + va_end(args); +} - nfapi_vnf_p7_hi_dci0_req(info->config.get(), req); +void mac_dl_config_req(mac_t *mac, nfapi_dl_config_request_t *req) { + vnf_p7_info *info = (vnf_p7_info *)(mac->user_data); + nfapi_vnf_p7_dl_config_req(info->config.get(), req); } -void mac_tx_req(mac_t* mac, nfapi_tx_request_t* req) -{ - vnf_p7_info* info = (vnf_p7_info*)(mac->user_data); +void mac_ul_config_req(mac_t *mac, nfapi_ul_config_request_t *req) { + vnf_p7_info *info = (vnf_p7_info *)(mac->user_data); + nfapi_vnf_p7_ul_config_req(info->config.get(), req); +} - nfapi_vnf_p7_tx_req(info->config.get(), req); +void mac_hi_dci0_req(mac_t *mac, nfapi_hi_dci0_request_t *req) { + vnf_p7_info *info = (vnf_p7_info *)(mac->user_data); + nfapi_vnf_p7_hi_dci0_req(info->config.get(), req); } -int phy_subframe_indication(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf) -{ - //printf("[VNF_SIM] subframe indication %d\n", sfn_sf); - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_subframe_ind(p7_vnf->mac, phy_id, sfn_sf); - return 0; +void mac_tx_req(mac_t *mac, nfapi_tx_request_t *req) { + vnf_p7_info *info = (vnf_p7_info *)(mac->user_data); + nfapi_vnf_p7_tx_req(info->config.get(), req); } -int phy_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_harq_indication_t* ind) -{ - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_harq_ind(p7_vnf->mac, ind); - return 1; + +int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn_sf) { + //printf("[VNF_SIM] subframe indication %d\n", sfn_sf); + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_subframe_ind(p7_vnf->mac, phy_id, sfn_sf); + return 0; } -int phy_crc_indication(struct nfapi_vnf_p7_config* config, nfapi_crc_indication_t* ind) -{ - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_crc_ind(p7_vnf->mac, ind); - return 1; +int phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind) { + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_harq_ind(p7_vnf->mac, ind); + return 1; } -int phy_rx_indication(struct nfapi_vnf_p7_config* config, nfapi_rx_indication_t* ind) -{ - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_rx_ind(p7_vnf->mac, ind); - return 1; +int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_t *ind) { + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_crc_ind(p7_vnf->mac, ind); + return 1; } -int phy_rach_indication(struct nfapi_vnf_p7_config* config, nfapi_rach_indication_t* ind) -{ - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_rach_ind(p7_vnf->mac, ind); - return 1; +int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t *ind) { + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_rx_ind(p7_vnf->mac, ind); + return 1; } -int phy_srs_indication(struct nfapi_vnf_p7_config* config, nfapi_srs_indication_t* ind) -{ - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_srs_ind(p7_vnf->mac, ind); - return 1; +int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indication_t *ind) { + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_rach_ind(p7_vnf->mac, ind); + return 1; } -int phy_sr_indication(struct nfapi_vnf_p7_config* config, nfapi_sr_indication_t* ind) -{ - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_sr_ind(p7_vnf->mac, ind); - return 1; +int phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind) { + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_srs_ind(p7_vnf->mac, ind); + return 1; } -int phy_cqi_indication(struct nfapi_vnf_p7_config* config, nfapi_cqi_indication_t* ind) -{ - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_cqi_ind(p7_vnf->mac, ind); - return 1; +int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind) { + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_sr_ind(p7_vnf->mac, ind); + return 1; } -int phy_lbt_dl_indication(struct nfapi_vnf_p7_config* config, nfapi_lbt_dl_indication_t* ind) -{ - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_lbt_dl_ind(p7_vnf->mac, ind); - return 1; +int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind) { + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_cqi_ind(p7_vnf->mac, ind); + return 1; } -int phy_nb_harq_indication(struct nfapi_vnf_p7_config* config, nfapi_nb_harq_indication_t* ind) -{ - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_nb_harq_ind(p7_vnf->mac, ind); - return 1; +int phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind) { + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_lbt_dl_ind(p7_vnf->mac, ind); + return 1; } -int phy_nrach_indication(struct nfapi_vnf_p7_config* config, nfapi_nrach_indication_t* ind) -{ - vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); - mac_nrach_ind(p7_vnf->mac, ind); - return 1; +int phy_nb_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_nb_harq_indication_t *ind) { + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_nb_harq_ind(p7_vnf->mac, ind); + return 1; } -int phy_vendor_ext(struct nfapi_vnf_p7_config* config, nfapi_p7_message_header_t* msg) -{ - if(msg->message_id == P7_VENDOR_EXT_IND) - { - //vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg; - //printf("[VNF_SIM] vendor_ext (error_code:%d)\n", ind->error_code); - } - else - { - printf("[VNF_SIM] unknown %d\n", msg->message_id); - } - return 0; +int phy_nrach_indication(struct nfapi_vnf_p7_config *config, nfapi_nrach_indication_t *ind) { + vnf_p7_info *p7_vnf = (vnf_p7_info *)(config->user_data); + mac_nrach_ind(p7_vnf->mac, ind); + return 1; } -nfapi_p7_message_header_t* phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t* msg_size) -{ - if(message_id == P7_VENDOR_EXT_IND) - { - *msg_size = sizeof(vendor_ext_p7_ind); - return (nfapi_p7_message_header_t*)malloc(sizeof(vendor_ext_p7_ind)); - } - return 0; +int phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg) { + if(msg->message_id == P7_VENDOR_EXT_IND) { + //vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg; + //printf("[VNF_SIM] vendor_ext (error_code:%d)\n", ind->error_code); + } else { + printf("[VNF_SIM] unknown %d\n", msg->message_id); + } + + return 0; } -void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t* header) -{ - free(header); +nfapi_p7_message_header_t *phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size) { + if(message_id == P7_VENDOR_EXT_IND) { + *msg_size = sizeof(vendor_ext_p7_ind); + return (nfapi_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_ind)); + } + + return 0; +} +void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) { + free(header); } //static pthread_t vnf_start_pthread; static pthread_t vnf_p7_start_pthread; -void* vnf_p7_start_thread(void *ptr) -{ +void *vnf_p7_start_thread(void *ptr) { printf("%s()\n", __FUNCTION__); - //std::shared_ptr<nfapi_vnf_p7_config> config = std::shared_ptr<nfapi_vnf_p7_config>(ptr); nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr; - nfapi_vnf_p7_start(config); - return 0; } -void set_thread_priority(int priority) -{ - //printf("%s(priority:%d)\n", __FUNCTION__, priority); - - pthread_attr_t ptAttr; - - struct sched_param schedParam; - schedParam.__sched_priority = priority; //79; - if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) - { - printf("Failed to set scheduler to SCHED_RR\n"); - } - - if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) - { - printf("Failed to set pthread sched policy SCHED_RR\n"); - } - - pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); - - struct sched_param thread_params; - thread_params.sched_priority = 20; - if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) - { - printf("failed to set sched param\n"); - } -} - -void* vnf_p7_thread_start(void* ptr) -{ - printf("%s()\n", __FUNCTION__); - - set_thread_priority(79); - - vnf_p7_info* p7_vnf = (vnf_p7_info*)ptr; - - p7_vnf->config->port = p7_vnf->local_port; - p7_vnf->config->subframe_indication = &phy_subframe_indication; - p7_vnf->config->harq_indication = &phy_harq_indication; - p7_vnf->config->crc_indication = &phy_crc_indication; - p7_vnf->config->rx_indication = &phy_rx_indication; - p7_vnf->config->rach_indication = &phy_rach_indication; - p7_vnf->config->srs_indication = &phy_srs_indication; - p7_vnf->config->sr_indication = &phy_sr_indication; - p7_vnf->config->cqi_indication = &phy_cqi_indication; - p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication; - p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication; - p7_vnf->config->nrach_indication = &phy_nrach_indication; - p7_vnf->config->malloc = &vnf_allocate; - p7_vnf->config->free = &vnf_deallocate; - - p7_vnf->config->trace = &vnf_sim_trace; +void set_thread_priority(int priority) { + //printf("%s(priority:%d)\n", __FUNCTION__, priority); + pthread_attr_t ptAttr; + struct sched_param schedParam; + schedParam.__sched_priority = priority; //79; - p7_vnf->config->vendor_ext = &phy_vendor_ext; - p7_vnf->config->user_data = p7_vnf; + if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) { + printf("Failed to set scheduler to SCHED_RR\n"); + } - p7_vnf->mac->user_data = p7_vnf; + if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) { + printf("Failed to set pthread sched policy SCHED_RR\n"); + } - p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension; - p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension; - p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv; - p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv; - p7_vnf->config->codec_config.allocate = &vnf_allocate; - p7_vnf->config->codec_config.deallocate = &vnf_deallocate; + pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); + struct sched_param thread_params; + thread_params.sched_priority = 20; - p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext; - p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext; - - printf("[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); - pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config.get()); - - return 0; + if(pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) { + printf("failed to set sched param\n"); + } } -int pnf_connection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) -{ - printf("[VNF_SIM] pnf connection indication idx:%d\n", p5_idx); - - pnf_info pnf; - vnf_info* vnf = (vnf_info*)(config->user_data); - vnf->pnfs.insert(std::pair<uint16_t, pnf_info>(p5_idx, pnf)); - - nfapi_pnf_param_request_t req; - memset(&req, 0, sizeof(req)); - req.header.message_id = NFAPI_PNF_PARAM_REQUEST; - nfapi_vnf_pnf_param_req(config, p5_idx, &req); - return 0; +void *vnf_p7_thread_start(void *ptr) { + printf("%s()\n", __FUNCTION__); + set_thread_priority(79); + vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr; + p7_vnf->config->port = p7_vnf->local_port; + p7_vnf->config->subframe_indication = &phy_subframe_indication; + p7_vnf->config->harq_indication = &phy_harq_indication; + p7_vnf->config->crc_indication = &phy_crc_indication; + p7_vnf->config->rx_indication = &phy_rx_indication; + p7_vnf->config->rach_indication = &phy_rach_indication; + p7_vnf->config->srs_indication = &phy_srs_indication; + p7_vnf->config->sr_indication = &phy_sr_indication; + p7_vnf->config->cqi_indication = &phy_cqi_indication; + p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication; + p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication; + p7_vnf->config->nrach_indication = &phy_nrach_indication; + p7_vnf->config->malloc = &vnf_allocate; + p7_vnf->config->free = &vnf_deallocate; + p7_vnf->config->trace = &vnf_sim_trace; + p7_vnf->config->vendor_ext = &phy_vendor_ext; + p7_vnf->config->user_data = p7_vnf; + p7_vnf->mac->user_data = p7_vnf; + p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension; + p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension; + p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv; + p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv; + p7_vnf->config->codec_config.allocate = &vnf_allocate; + p7_vnf->config->codec_config.deallocate = &vnf_deallocate; + p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext; + p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext; + printf("[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__); + pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config.get()); + return 0; } -int pnf_disconnection_indication_cb(nfapi_vnf_config_t* config, int p5_idx) -{ - printf("[VNF_SIM] pnf disconnection indication idx:%d\n", p5_idx); - - - vnf_info* vnf = (vnf_info*)(config->user_data); - auto find_result = vnf->pnfs.find(p5_idx); - - if(find_result != vnf->pnfs.end()) - { - pnf_info& pnf = find_result->second; - - for(phy_info& phy : pnf.phys) - { - vnf_p7_info& p7_vnf = vnf->p7_vnfs[0]; - nfapi_vnf_p7_del_pnf((p7_vnf.config.get()), phy.id); - } - } - return 0; +int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { + printf("[VNF_SIM] pnf connection indication idx:%d\n", p5_idx); + pnf_info pnf; + vnf_info *vnf = (vnf_info *)(config->user_data); + vnf->pnfs.insert(std::pair<uint16_t, pnf_info>(p5_idx, pnf)); + nfapi_pnf_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_PARAM_REQUEST; + nfapi_vnf_pnf_param_req(config, p5_idx, &req); + return 0; } +int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { + printf("[VNF_SIM] pnf disconnection indication idx:%d\n", p5_idx); + vnf_info *vnf = (vnf_info *)(config->user_data); + auto find_result = vnf->pnfs.find(p5_idx); -int pnf_param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp) -{ - printf("[VNF_SIM] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); - - vnf_info* vnf = (vnf_info*)(config->user_data); - - auto find_result = vnf->pnfs.find(p5_idx); - if(find_result != vnf->pnfs.end()) - { - pnf_info& pnf = find_result->second; - - for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) - { - phy_info phy; - phy.index = resp->pnf_phy.phy[i].phy_config_index; - - printf("[VNF_SIM] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); - - nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id)); - - - - for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) - { - printf("[VNF_SIM] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); - phy.rfs.push_back(resp->pnf_phy.phy[i].rf_config[j].rf_config_index); - } - - - pnf.phys.push_back(phy); - } - for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i) - { - rf_info rf; - rf.index = resp->pnf_rf.rf[i].rf_config_index; - - printf("[VNF_SIM] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index); - - pnf.rfs.push_back(rf); - } - - nfapi_pnf_config_request_t req; - memset(&req, 0, sizeof(req)); - req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; - - req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; - req.pnf_phy_rf_config.number_phy_rf_config_info = pnf.phys.size(); + if(find_result != vnf->pnfs.end()) { + pnf_info &pnf = find_result->second; - for(unsigned i = 0; i < pnf.phys.size(); ++i) - { - req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf.phys[i].id; - req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf.phys[i].index; - req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf.phys[i].rfs[0]; - } + for(phy_info &phy : pnf.phys) { + vnf_p7_info &p7_vnf = vnf->p7_vnfs[0]; + nfapi_vnf_p7_del_pnf((p7_vnf.config.get()), phy.id); + } + } - - nfapi_vnf_pnf_config_req(config, p5_idx, &req); - } - return 0; + return 0; } -int pnf_config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp) -{ - printf("[VNF_SIM] pnf config response idx:%d\n", p5_idx); - - if(1) - { - vnf_info* vnf = (vnf_info*)(config->user_data); - auto find_result = vnf->pnfs.find(p5_idx); - if(find_result != vnf->pnfs.end()) - { - //pnf_info& pnf = find_result->second; - - nfapi_pnf_start_request_t req; - memset(&req, 0, sizeof(req)); - req.header.message_id = NFAPI_PNF_START_REQUEST; - nfapi_vnf_pnf_start_req(config, p5_idx, &req); - } - } - else - { - // Rather than send the pnf_start_request we will demonstrate - // sending a vendor extention message. The start request will be - // send when the vendor extension response is received - - //vnf_info* vnf = (vnf_info*)(config->user_data); - vendor_ext_p5_req req; - memset(&req, 0, sizeof(req)); - req.header.message_id = P5_VENDOR_EXT_REQ; - req.dummy1 = 45; - req.dummy2 = 1977; - nfapi_vnf_vendor_extension(config, p5_idx, &req.header); - } - return 0; +int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_response_t *resp) { + printf("[VNF_SIM] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); + vnf_info *vnf = (vnf_info *)(config->user_data); + auto find_result = vnf->pnfs.find(p5_idx); + + if(find_result != vnf->pnfs.end()) { + pnf_info &pnf = find_result->second; + + for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) { + phy_info phy; + phy.index = resp->pnf_phy.phy[i].phy_config_index; + printf("[VNF_SIM] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); + nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id)); + + for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) { + printf("[VNF_SIM] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); + phy.rfs.push_back(resp->pnf_phy.phy[i].rf_config[j].rf_config_index); + } + + pnf.phys.push_back(phy); + } + + for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i) { + rf_info rf; + rf.index = resp->pnf_rf.rf[i].rf_config_index; + printf("[VNF_SIM] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index); + pnf.rfs.push_back(rf); + } + + nfapi_pnf_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; + req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; + req.pnf_phy_rf_config.number_phy_rf_config_info = pnf.phys.size(); + + for(unsigned i = 0; i < pnf.phys.size(); ++i) { + req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf.phys[i].id; + req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf.phys[i].index; + req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf.phys[i].rfs[0]; + } + + nfapi_vnf_pnf_config_req(config, p5_idx, &req); + } } - int pnf_start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp) { printf("[VNF_SIM] pnf start response idx:%d\n", p5_idx); @@ -716,7 +596,7 @@ int param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t // for now just 1 vnf_p7_info& p7_vnf = vnf->p7_vnfs[0]; - printf("[VNF_SIM] %d.%d pnf p7 %s:%d timing %d %d %d %d\n", p5_idx, phy.id, phy.remote_addr.c_str(), phy.remote_port, p7_vnf.timing_window, p7_vnf.periodic_timing_period, p7_vnf.aperiodic_timing_enabled, p7_vnf.periodic_timing_period); + printf("[VNF_SIM] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy.id, phy.remote_addr.c_str(), phy.remote_port, p7_vnf.timing_window, p7_vnf.periodic_timing_period, p7_vnf.aperiodic_timing_enabled, p7_vnf.periodic_timing_period); nfapi_config_request_t req; @@ -1065,461 +945,768 @@ int param_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t return 0; } -int config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp) -{ - printf("[VNF_SIM] config response idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); +int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_response_t *resp) { + printf("[VNF_SIM] pnf config response idx:%d\n", p5_idx); + + if(1) { + vnf_info *vnf = (vnf_info *)(config->user_data); + auto find_result = vnf->pnfs.find(p5_idx); + + if(find_result != vnf->pnfs.end()) { + //pnf_info& pnf = find_result->second; + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); + } + } else { + // Rather than send the pnf_start_request we will demonstrate + // sending a vendor extention message. The start request will be + // send when the vendor extension response is received + //vnf_info* vnf = (vnf_info*)(config->user_data); + vendor_ext_p5_req req; + memset(&req, 0, sizeof(req)); + req.header.message_id = P5_VENDOR_EXT_REQ; + req.dummy1 = 45; + req.dummy2 = 1977; + nfapi_vnf_vendor_extension(config, p5_idx, &req.header); + } + return 0; +} - nfapi_start_request_t req; - memset(&req, 0, sizeof(req)); - req.header.message_id = NFAPI_START_REQUEST; - req.header.phy_id = resp->header.phy_id; - nfapi_vnf_start_req(config, p5_idx, &req); +int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_response_t *resp) { + printf("[VNF_SIM] pnf start response idx:%d\n", p5_idx); + vnf_info *vnf = (vnf_info *)(config->user_data); + vnf_p7_info &p7_vnf = vnf->p7_vnfs[0]; + + if(p7_vnf.thread_started == false) { + pthread_t vnf_p7_thread; + pthread_create(&vnf_p7_thread, NULL, &vnf_p7_thread_start, &p7_vnf); + p7_vnf.thread_started = true; + } else { + // P7 thread already running. + } + + // start all the phys in the pnf. + auto find_result = vnf->pnfs.find(p5_idx); + + if(find_result != vnf->pnfs.end()) { + pnf_info &pnf = find_result->second; + + for(unsigned i = 0; i < pnf.phys.size(); ++i) { + pnf_info &pnf = find_result->second; + nfapi_param_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PARAM_REQUEST; + req.header.phy_id = pnf.phys[i].id; + nfapi_vnf_param_req(config, p5_idx, &req); + } + } - return 0; + return 0; } +int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t *resp) { + printf("[VNF_SIM] param response idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + vnf_info *vnf = (vnf_info *)(config->user_data); + auto find_result = vnf->pnfs.find(p5_idx); + + if(find_result != vnf->pnfs.end()) { + pnf_info &pnf = find_result->second; + auto found = std::find_if(pnf.phys.begin(), pnf.phys.end(), [&](phy_info& item) { + return item.id == resp->header.phy_id; + }); + + if(found != pnf.phys.end()) { + phy_info &phy = (*found); + phy.remote_port = resp->nfapi_config.p7_pnf_port.value; + struct sockaddr_in pnf_p7_sockaddr; + memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4); + phy.remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr); + // for now just 1 + vnf_p7_info &p7_vnf = vnf->p7_vnfs[0]; + printf("[VNF_SIM] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy.id, phy.remote_addr.c_str(), phy.remote_port, p7_vnf.timing_window, p7_vnf.periodic_timing_period, + p7_vnf.aperiodic_timing_enabled, p7_vnf.periodic_timing_period); + nfapi_config_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_CONFIG_REQUEST; + req.header.phy_id = phy.id; + req.nfapi_config.p7_vnf_port.tl.tag = NFAPI_NFAPI_P7_VNF_PORT_TAG; + req.nfapi_config.p7_vnf_port.value = p7_vnf.local_port; + req.num_tlv++; + req.nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; + struct sockaddr_in vnf_p7_sockaddr; + vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf.local_addr.c_str()); + memcpy(&(req.nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4); + req.num_tlv++; + req.nfapi_config.timing_window.tl.tag = NFAPI_NFAPI_TIMING_WINDOW_TAG; + req.nfapi_config.timing_window.value = p7_vnf.timing_window; + req.num_tlv++; + + if(p7_vnf.periodic_timing_enabled || p7_vnf.aperiodic_timing_enabled) { + req.nfapi_config.timing_info_mode.tl.tag = NFAPI_NFAPI_TIMING_INFO_MODE_TAG; + req.nfapi_config.timing_info_mode.value = (p7_vnf.aperiodic_timing_enabled << 1) | (p7_vnf.periodic_timing_enabled); + req.num_tlv++; + + if(p7_vnf.periodic_timing_enabled) { + req.nfapi_config.timing_info_period.tl.tag = NFAPI_NFAPI_TIMING_INFO_PERIOD_TAG; + req.nfapi_config.timing_info_period.value = p7_vnf.periodic_timing_period; + req.num_tlv++; + } + } + + req.nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG; + req.nfapi_config.earfcn.value = phy.earfcn; + req.num_tlv++; + + if(1) { + // Poplate all tlv for wireshark testing + req.subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; + req.num_tlv++; + req.subframe_config.pcfich_power_offset.tl.tag = NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG; + req.num_tlv++; + req.subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG; + req.num_tlv++; + req.subframe_config.dl_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG; + req.num_tlv++; + req.subframe_config.ul_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG; + req.num_tlv++; + req.rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; + req.num_tlv++; + req.rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; + req.num_tlv++; + req.rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG; + req.num_tlv++; + req.rf_config.tx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG; + req.num_tlv++; + req.rf_config.rx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG; + req.num_tlv++; + req.phich_config.phich_resource.tl.tag = NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG; + req.num_tlv++; + req.phich_config.phich_duration.tl.tag = NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG; + req.num_tlv++; + req.phich_config.phich_power_offset.tl.tag = NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG; + req.num_tlv++; + req.sch_config.primary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; + req.num_tlv++; + req.sch_config.secondary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; + req.num_tlv++; + req.sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG; + req.num_tlv++; + req.prach_config.configuration_index.tl.tag = NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG; + req.num_tlv++; + req.prach_config.root_sequence_index.tl.tag = NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG; + req.num_tlv++; + req.prach_config.zero_correlation_zone_configuration.tl.tag = NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + req.num_tlv++; + req.prach_config.high_speed_flag.tl.tag = NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG; + req.num_tlv++; + req.prach_config.frequency_offset.tl.tag = NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG; + req.num_tlv++; + req.pusch_config.hopping_mode.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG; + req.num_tlv++; + req.pusch_config.hopping_offset.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG; + req.num_tlv++; + req.pusch_config.number_of_subbands.tl.tag = NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG; + req.num_tlv++; + req.pucch_config.delta_pucch_shift.tl.tag = NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG; + req.num_tlv++; + req.pucch_config.n_cqi_rb.tl.tag = NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG; + req.num_tlv++; + req.pucch_config.n_an_cs.tl.tag = NFAPI_PUCCH_CONFIG_N_AN_CS_TAG; + req.num_tlv++; + req.pucch_config.n1_pucch_an.tl.tag = NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG; + req.num_tlv++; + req.srs_config.bandwidth_configuration.tl.tag = NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG; + req.num_tlv++; + req.srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG; + req.num_tlv++; + req.srs_config.srs_subframe_configuration.tl.tag = NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG; + req.num_tlv++; + req.srs_config.srs_acknack_srs_simultaneous_transmission.tl.tag = NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG; + req.num_tlv++; + req.uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG; + req.num_tlv++; + req.uplink_reference_signal_config.group_assignment.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG; + req.num_tlv++; + req.uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG; + req.num_tlv++; + req.laa_config.ed_threshold_lbt_pdsch.tl.tag = NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_PDSCH_TAG; + req.num_tlv++; + req.laa_config.ed_threshold_lbt_drs.tl.tag = NFAPI_LAA_CONFIG_ED_THRESHOLD_FOR_LBT_FOR_DRS_TAG; + req.num_tlv++; + req.laa_config.pd_threshold.tl.tag = NFAPI_LAA_CONFIG_PD_THRESHOLD_TAG; + req.num_tlv++; + req.laa_config.multi_carrier_type.tl.tag = NFAPI_LAA_CONFIG_MULTI_CARRIER_TYPE_TAG; + req.num_tlv++; + req.laa_config.multi_carrier_tx.tl.tag = NFAPI_LAA_CONFIG_MULTI_CARRIER_TX_TAG; + req.num_tlv++; + req.laa_config.multi_carrier_freeze.tl.tag = NFAPI_LAA_CONFIG_MULTI_CARRIER_FREEZE_TAG; + req.num_tlv++; + req.laa_config.tx_antenna_ports_drs.tl.tag = NFAPI_LAA_CONFIG_TX_ANTENNA_PORTS_FOR_DRS_TAG; + req.num_tlv++; + req.laa_config.tx_power_drs.tl.tag = NFAPI_LAA_CONFIG_TRANSMISSION_POWER_FOR_DRS_TAG; + req.num_tlv++; + req.emtc_config.pbch_repetitions_enable_r13.tl.tag = NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG; + req.num_tlv++; + req.emtc_config.prach_catm_root_sequence_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG; + req.num_tlv++; + req.emtc_config.prach_catm_zero_correlation_zone_configuration.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; + req.num_tlv++; + req.emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG; + req.num_tlv++; + req.emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG; + req.num_tlv++; + req.emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + req.num_tlv++; + req.emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + req.num_tlv++; + req.nb_iot_config.operating_mode.tl.tag = NFAPI_NB_IOT_CONFIG_OPERATING_MODE_TAG; + req.nb_iot_config.operating_mode.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.anchor.tl.tag = NFAPI_NB_IOT_CONFIG_ANCHOR_TAG; + req.nb_iot_config.anchor.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.prb_index.tl.tag = NFAPI_NB_IOT_CONFIG_PRB_INDEX_TAG; + req.nb_iot_config.prb_index.value = rand_range(0, 0x1F); + req.num_tlv++; + req.nb_iot_config.control_region_size.tl.tag = NFAPI_NB_IOT_CONFIG_CONTROL_REGION_SIZE_TAG; + req.nb_iot_config.control_region_size.value = rand_range(1, 4); + req.num_tlv++; + req.nb_iot_config.assumed_crs_aps.tl.tag = NFAPI_NB_IOT_CONFIG_ASSUMED_CRS_APS_TAG; + req.nb_iot_config.assumed_crs_aps.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_enabled.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_ENABLED_TAG; + req.nb_iot_config.nprach_config_0_enabled.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_sf_periodicity.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_SF_PERIODICITY_TAG; + req.nb_iot_config.nprach_config_0_sf_periodicity.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_start_time.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_START_TIME_TAG; + req.nb_iot_config.nprach_config_0_start_time.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_subcarrier_offset.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_SUBCARRIER_OFFSET_TAG; + req.nb_iot_config.nprach_config_0_subcarrier_offset.value = rand_range(0, 6); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_number_of_subcarriers.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_NUMBER_OF_SUBCARRIERS_TAG; + req.nb_iot_config.nprach_config_0_number_of_subcarriers.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_cp_length.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_CP_LENGTH_TAG; + req.nb_iot_config.nprach_config_0_cp_length.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.nb_iot_config.nprach_config_0_number_of_repetitions_per_attempt.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_enabled.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_ENABLED_TAG; + req.nb_iot_config.nprach_config_1_enabled.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_sf_periodicity.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_SF_PERIODICITY_TAG; + req.nb_iot_config.nprach_config_1_sf_periodicity.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_start_time.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_START_TIME_TAG; + req.nb_iot_config.nprach_config_1_start_time.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_subcarrier_offset.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_SUBCARRIER_OFFSET_TAG; + req.nb_iot_config.nprach_config_1_subcarrier_offset.value = rand_range(0, 6); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_number_of_subcarriers.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_NUMBER_OF_SUBCARRIERS_TAG; + req.nb_iot_config.nprach_config_1_number_of_subcarriers.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_cp_length.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_CP_LENGTH_TAG; + req.nb_iot_config.nprach_config_1_cp_length.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.nb_iot_config.nprach_config_1_number_of_repetitions_per_attempt.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_enabled.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_ENABLED_TAG; + req.nb_iot_config.nprach_config_2_enabled.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_sf_periodicity.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_SF_PERIODICITY_TAG; + req.nb_iot_config.nprach_config_2_sf_periodicity.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_start_time.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_START_TIME_TAG; + req.nb_iot_config.nprach_config_2_start_time.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_subcarrier_offset.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_SUBCARRIER_OFFSET_TAG; + req.nb_iot_config.nprach_config_2_subcarrier_offset.value = rand_range(0, 6); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_number_of_subcarriers.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_NUMBER_OF_SUBCARRIERS_TAG; + req.nb_iot_config.nprach_config_2_number_of_subcarriers.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_cp_length.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_CP_LENGTH_TAG; + req.nb_iot_config.nprach_config_2_cp_length.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.nprach_config_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_NB_IOT_CONFIG_NPRACH_CONFIG_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; + req.nb_iot_config.nprach_config_2_number_of_repetitions_per_attempt.value = rand_range(0, 7); + req.num_tlv++; + req.nb_iot_config.three_tone_base_sequence.tl.tag = NFAPI_NB_IOT_CONFIG_THREE_TONE_BASE_SEQUENCE_TAG; + req.nb_iot_config.three_tone_base_sequence.value = rand_range(0, 0x0F); + req.num_tlv++; + req.nb_iot_config.six_tone_base_sequence.tl.tag = NFAPI_NB_IOT_CONFIG_SIX_TONE_BASE_SEQUENCE_TAG; + req.nb_iot_config.six_tone_base_sequence.value = rand_range(0, 0x03); + req.num_tlv++; + req.nb_iot_config.twelve_tone_base_sequence.tl.tag = NFAPI_NB_IOT_CONFIG_TWELVE_TONE_BASE_SEQUENCE_TAG; + req.nb_iot_config.twelve_tone_base_sequence.value = rand_range(0, 0x1F); + req.num_tlv++; + req.nb_iot_config.three_tone_cyclic_shift.tl.tag = NFAPI_NB_IOT_CONFIG_THREE_TONE_CYCLIC_SHIFT_TAG; + req.nb_iot_config.three_tone_cyclic_shift.value = rand_range(0, 5); // what is the max + req.num_tlv++; + req.nb_iot_config.six_tone_cyclic_shift.tl.tag = NFAPI_NB_IOT_CONFIG_SIX_TONE_CYCLIC_SHIFT_TAG; + req.nb_iot_config.six_tone_cyclic_shift.value = rand_range(0, 5); // what is the max + req.num_tlv++; + req.nb_iot_config.dl_gap_config_enable.tl.tag = NFAPI_NB_IOT_CONFIG_DL_GAP_CONFIG_ENABLE_TAG; + req.nb_iot_config.dl_gap_config_enable.value = rand_range(0, 1); + req.num_tlv++; + req.nb_iot_config.dl_gap_threshold.tl.tag = NFAPI_NB_IOT_CONFIG_DL_GAP_THRESHOLD_TAG; + req.nb_iot_config.dl_gap_threshold.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.dl_gap_periodicity.tl.tag = NFAPI_NB_IOT_CONFIG_DL_GAP_PERIODICITY_TAG; + req.nb_iot_config.dl_gap_periodicity.value = rand_range(0, 3); + req.num_tlv++; + req.nb_iot_config.dl_gap_duration_coefficient.tl.tag = NFAPI_NB_IOT_CONFIG_DL_GAP_DURATION_COEFFICIENT_TAG; + req.nb_iot_config.dl_gap_duration_coefficient.value = rand_range(0, 3); + req.num_tlv++; + req.tdd_frame_structure_config.subframe_assignment.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG; + req.num_tlv++; + req.tdd_frame_structure_config.special_subframe_patterns.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG; + req.num_tlv++; + req.l23_config.data_report_mode.tl.tag = NFAPI_L23_CONFIG_DATA_REPORT_MODE_TAG; + req.num_tlv++; + req.l23_config.sfnsf.tl.tag = NFAPI_L23_CONFIG_SFNSF_TAG; + req.num_tlv++; + } + + vendor_ext_tlv_2 ve2; + memset(&ve2, 0, sizeof(ve2)); + ve2.tl.tag = VENDOR_EXT_TLV_2_TAG; + ve2.dummy = 2016; + req.vendor_extension = &ve2.tl; + nfapi_vnf_config_req(config, p5_idx, &req); + } else { + printf("[VNF_SIM] param response failed to find pnf %d phy %d\n", p5_idx, resp->header.phy_id); + } + } else { + printf("[VNF_SIM] param response failed to find pnf %d\n", p5_idx); + } -void test_p4_requests(nfapi_vnf_config_t* config, int p5_idx, int phy_id) -{ - { - nfapi_measurement_request_t req; - memset(&req, 0, sizeof(req)); - req.header.message_id = NFAPI_MEASUREMENT_REQUEST; - req.header.phy_id = phy_id; - - req.dl_rs_tx_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG; - req.dl_rs_tx_power.value = 42; - req.received_interference_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG; - req.received_interference_power.value = 42; - req.thermal_noise_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG; - req.thermal_noise_power.value = 42; - - nfapi_vnf_measurement_req(config, p5_idx, &req); - } - { - nfapi_rssi_request_t lte_req; - memset(<e_req, 0, sizeof(lte_req)); - lte_req.header.message_id = NFAPI_RSSI_REQUEST; - lte_req.header.phy_id = phy_id; - - lte_req.rat_type = NFAPI_RAT_TYPE_LTE; - lte_req.lte_rssi_request.tl.tag = NFAPI_LTE_RSSI_REQUEST_TAG; - lte_req.lte_rssi_request.frequency_band_indicator = 2; - lte_req.lte_rssi_request.measurement_period = 1000; - lte_req.lte_rssi_request.bandwidth = 50; - lte_req.lte_rssi_request.timeout = 0; - lte_req.lte_rssi_request.number_of_earfcns = 2; - lte_req.lte_rssi_request.earfcn[0] = 389; - lte_req.lte_rssi_request.earfcn[1] = 123; - - nfapi_vnf_rssi_request(config, p5_idx, <e_req); - - nfapi_rssi_request_t utran_req; - memset(&utran_req, 0, sizeof(utran_req)); - utran_req.header.message_id = NFAPI_RSSI_REQUEST; - utran_req.header.phy_id = phy_id; - - utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; - utran_req.utran_rssi_request.tl.tag = NFAPI_UTRAN_RSSI_REQUEST_TAG; - utran_req.utran_rssi_request.frequency_band_indicator = 2; - utran_req.utran_rssi_request.measurement_period = 1000; - utran_req.utran_rssi_request.timeout = 0; - utran_req.utran_rssi_request.number_of_uarfcns = 2; - utran_req.utran_rssi_request.uarfcn[0] = 2348; - utran_req.utran_rssi_request.uarfcn[1] = 52; - - nfapi_vnf_rssi_request(config, p5_idx, &utran_req); - - - nfapi_rssi_request_t geran_req; - memset(&geran_req, 0, sizeof(geran_req)); - geran_req.header.message_id = NFAPI_RSSI_REQUEST; - geran_req.header.phy_id = phy_id; - - geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; - geran_req.geran_rssi_request.tl.tag = NFAPI_GERAN_RSSI_REQUEST_TAG; - geran_req.geran_rssi_request.frequency_band_indicator = 2; - geran_req.geran_rssi_request.measurement_period = 1000; - geran_req.geran_rssi_request.timeout = 0; - geran_req.geran_rssi_request.number_of_arfcns = 1; - geran_req.geran_rssi_request.arfcn[0].arfcn = 34; - geran_req.geran_rssi_request.arfcn[0].direction = 0; - - nfapi_vnf_rssi_request(config, p5_idx, &geran_req); - } - { - nfapi_cell_search_request_t lte_req; - memset(<e_req, 0, sizeof(lte_req)); - lte_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; - lte_req.header.phy_id = phy_id; - - lte_req.rat_type = NFAPI_RAT_TYPE_LTE; - lte_req.lte_cell_search_request.tl.tag = NFAPI_LTE_CELL_SEARCH_REQUEST_TAG; - lte_req.lte_cell_search_request.earfcn = 1234; - lte_req.lte_cell_search_request.measurement_bandwidth = 50; - lte_req.lte_cell_search_request.exhaustive_search = 1; - lte_req.lte_cell_search_request.timeout = 1000; - lte_req.lte_cell_search_request.number_of_pci = 1; - lte_req.lte_cell_search_request.pci[0] = 234; - - nfapi_vnf_cell_search_request(config, p5_idx, <e_req); - - nfapi_cell_search_request_t utran_req; - memset(&utran_req, 0, sizeof(utran_req)); - utran_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; - utran_req.header.phy_id = phy_id; - - utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; - utran_req.utran_cell_search_request.tl.tag = NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG; - utran_req.utran_cell_search_request.uarfcn = 1234; - utran_req.utran_cell_search_request.exhaustive_search = 0; - utran_req.utran_cell_search_request.timeout = 1000; - utran_req.utran_cell_search_request.number_of_psc = 1; - utran_req.utran_cell_search_request.psc[0] = 234; - - nfapi_vnf_cell_search_request(config, p5_idx, &utran_req); - - nfapi_cell_search_request_t geran_req; - memset(&geran_req, 0, sizeof(geran_req)); - geran_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; - geran_req.header.phy_id = phy_id; - - geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; - geran_req.geran_cell_search_request.tl.tag = NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG; - geran_req.geran_cell_search_request.timeout = 1000; - geran_req.geran_cell_search_request.number_of_arfcn = 1; - geran_req.geran_cell_search_request.arfcn[0] = 8765; - - nfapi_vnf_cell_search_request(config, p5_idx, &geran_req); - } - { - nfapi_broadcast_detect_request_t lte_req; - memset(<e_req, 0, sizeof(lte_req)); - lte_req.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; - lte_req.header.phy_id = phy_id; - - lte_req.rat_type = NFAPI_RAT_TYPE_LTE; - lte_req.lte_broadcast_detect_request.tl.tag = NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG; - lte_req.lte_broadcast_detect_request.earfcn = 1234; - lte_req.lte_broadcast_detect_request.pci = 50; - lte_req.lte_broadcast_detect_request.timeout = 1000; - - lte_req.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; - lte_req.pnf_cell_search_state.length = 3; - - nfapi_vnf_broadcast_detect_request(config, p5_idx, <e_req); - - nfapi_broadcast_detect_request_t utran_req; - memset(&utran_req, 0, sizeof(utran_req)); - utran_req.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; - utran_req.header.phy_id = phy_id; - - utran_req.rat_type = NFAPI_RAT_TYPE_LTE; - utran_req.utran_broadcast_detect_request.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG; - utran_req.utran_broadcast_detect_request.uarfcn = 1234; - utran_req.utran_broadcast_detect_request.psc = 50; - utran_req.utran_broadcast_detect_request.timeout = 1000; - - utran_req.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; - utran_req.pnf_cell_search_state.length = 3; - - nfapi_vnf_broadcast_detect_request(config, p5_idx, &utran_req); - } - { - nfapi_system_information_schedule_request_t lte_req; - memset(<e_req, 0, sizeof(lte_req)); - lte_req.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST; - lte_req.header.phy_id = phy_id; - - lte_req.rat_type = NFAPI_RAT_TYPE_LTE; - lte_req.lte_system_information_schedule_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG; - lte_req.lte_system_information_schedule_request.earfcn = 1234; - lte_req.lte_system_information_schedule_request.pci = 50; - lte_req.lte_system_information_schedule_request.downlink_channel_bandwidth = 100; - lte_req.lte_system_information_schedule_request.phich_configuration = 3; - lte_req.lte_system_information_schedule_request.number_of_tx_antenna = 2; - lte_req.lte_system_information_schedule_request.retry_count = 4; - lte_req.lte_system_information_schedule_request.timeout = 1000; - - lte_req.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; - lte_req.pnf_cell_broadcast_state.length = 3; - - nfapi_vnf_system_information_schedule_request(config, p5_idx, <e_req); - } - { - nfapi_system_information_request_t lte_req; - memset(<e_req, 0, sizeof(lte_req)); - lte_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; - lte_req.header.phy_id = phy_id; - - lte_req.rat_type = NFAPI_RAT_TYPE_LTE; - lte_req.lte_system_information_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG; - lte_req.lte_system_information_request.earfcn = 1234; - lte_req.lte_system_information_request.pci= 456; - lte_req.lte_system_information_request.downlink_channel_bandwidth = 5; - lte_req.lte_system_information_request.phich_configuration = 2; - lte_req.lte_system_information_request.number_of_tx_antenna = 2; - lte_req.lte_system_information_request.number_of_si_periodicity = 1; - lte_req.lte_system_information_request.si_periodicity[0].si_periodicity = 3; - lte_req.lte_system_information_request.si_periodicity[0].si_index = 3; - lte_req.lte_system_information_request.si_window_length = 15; - lte_req.lte_system_information_request.timeout = 1000; - - nfapi_vnf_system_information_request(config, p5_idx, <e_req); - - nfapi_system_information_request_t utran_req; - memset(&utran_req, 0, sizeof(utran_req)); - utran_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; - utran_req.header.phy_id = phy_id; - - utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; - utran_req.utran_system_information_request.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG; - utran_req.utran_system_information_request.uarfcn = 1234; - utran_req.utran_system_information_request.psc = 456; - utran_req.utran_system_information_request.timeout = 1000; - - nfapi_vnf_system_information_request(config, p5_idx, &utran_req); - - nfapi_system_information_request_t geran_req; - memset(&geran_req, 0, sizeof(geran_req)); - geran_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; - geran_req.header.phy_id = phy_id; - - geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; - geran_req.geran_system_information_request.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG; - geran_req.geran_system_information_request.arfcn = 1234; - geran_req.geran_system_information_request.bsic = 21; - geran_req.geran_system_information_request.timeout = 1000; - - nfapi_vnf_system_information_request(config, p5_idx, &geran_req); - } - { - nfapi_nmm_stop_request_t req; - memset(&req, 0, sizeof(req)); - req.header.message_id = NFAPI_NMM_STOP_REQUEST; - req.header.phy_id = phy_id; - nfapi_vnf_nmm_stop_request(config, p5_idx, &req); - } + return 0; } +int config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_config_response_t *resp) { + printf("[VNF_SIM] config response idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + nfapi_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_START_REQUEST; + req.header.phy_id = resp->header.phy_id; + nfapi_vnf_start_req(config, p5_idx, &req); + return 0; +} -int start_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp) -{ - printf("[VNF_SIM] start response idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); - - vnf_info* vnf = (vnf_info*)(config->user_data); - - if(vnf->wireshark_test_mode) - test_p4_requests(config, p5_idx, resp->header.phy_id); +void test_p4_requests(nfapi_vnf_config_t *config, int p5_idx, int phy_id) { + { + nfapi_measurement_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_MEASUREMENT_REQUEST; + req.header.phy_id = phy_id; + req.dl_rs_tx_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_DL_RS_XTX_POWER_TAG; + req.dl_rs_tx_power.value = 42; + req.received_interference_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_RECEIVED_INTERFERENCE_POWER_TAG; + req.received_interference_power.value = 42; + req.thermal_noise_power.tl.tag = NFAPI_MEASUREMENT_REQUEST_THERMAL_NOISE_POWER_TAG; + req.thermal_noise_power.value = 42; + nfapi_vnf_measurement_req(config, p5_idx, &req); + } + { + nfapi_rssi_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_RSSI_REQUEST; + lte_req.header.phy_id = phy_id; + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_rssi_request.tl.tag = NFAPI_LTE_RSSI_REQUEST_TAG; + lte_req.lte_rssi_request.frequency_band_indicator = 2; + lte_req.lte_rssi_request.measurement_period = 1000; + lte_req.lte_rssi_request.bandwidth = 50; + lte_req.lte_rssi_request.timeout = 0; + lte_req.lte_rssi_request.number_of_earfcns = 2; + lte_req.lte_rssi_request.earfcn[0] = 389; + lte_req.lte_rssi_request.earfcn[1] = 123; + nfapi_vnf_rssi_request(config, p5_idx, <e_req); + nfapi_rssi_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_RSSI_REQUEST; + utran_req.header.phy_id = phy_id; + utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; + utran_req.utran_rssi_request.tl.tag = NFAPI_UTRAN_RSSI_REQUEST_TAG; + utran_req.utran_rssi_request.frequency_band_indicator = 2; + utran_req.utran_rssi_request.measurement_period = 1000; + utran_req.utran_rssi_request.timeout = 0; + utran_req.utran_rssi_request.number_of_uarfcns = 2; + utran_req.utran_rssi_request.uarfcn[0] = 2348; + utran_req.utran_rssi_request.uarfcn[1] = 52; + nfapi_vnf_rssi_request(config, p5_idx, &utran_req); + nfapi_rssi_request_t geran_req; + memset(&geran_req, 0, sizeof(geran_req)); + geran_req.header.message_id = NFAPI_RSSI_REQUEST; + geran_req.header.phy_id = phy_id; + geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; + geran_req.geran_rssi_request.tl.tag = NFAPI_GERAN_RSSI_REQUEST_TAG; + geran_req.geran_rssi_request.frequency_band_indicator = 2; + geran_req.geran_rssi_request.measurement_period = 1000; + geran_req.geran_rssi_request.timeout = 0; + geran_req.geran_rssi_request.number_of_arfcns = 1; + geran_req.geran_rssi_request.arfcn[0].arfcn = 34; + geran_req.geran_rssi_request.arfcn[0].direction = 0; + nfapi_vnf_rssi_request(config, p5_idx, &geran_req); + } + { + nfapi_cell_search_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + lte_req.header.phy_id = phy_id; + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_cell_search_request.tl.tag = NFAPI_LTE_CELL_SEARCH_REQUEST_TAG; + lte_req.lte_cell_search_request.earfcn = 1234; + lte_req.lte_cell_search_request.measurement_bandwidth = 50; + lte_req.lte_cell_search_request.exhaustive_search = 1; + lte_req.lte_cell_search_request.timeout = 1000; + lte_req.lte_cell_search_request.number_of_pci = 1; + lte_req.lte_cell_search_request.pci[0] = 234; + nfapi_vnf_cell_search_request(config, p5_idx, <e_req); + nfapi_cell_search_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + utran_req.header.phy_id = phy_id; + utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; + utran_req.utran_cell_search_request.tl.tag = NFAPI_UTRAN_CELL_SEARCH_REQUEST_TAG; + utran_req.utran_cell_search_request.uarfcn = 1234; + utran_req.utran_cell_search_request.exhaustive_search = 0; + utran_req.utran_cell_search_request.timeout = 1000; + utran_req.utran_cell_search_request.number_of_psc = 1; + utran_req.utran_cell_search_request.psc[0] = 234; + nfapi_vnf_cell_search_request(config, p5_idx, &utran_req); + nfapi_cell_search_request_t geran_req; + memset(&geran_req, 0, sizeof(geran_req)); + geran_req.header.message_id = NFAPI_CELL_SEARCH_REQUEST; + geran_req.header.phy_id = phy_id; + geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; + geran_req.geran_cell_search_request.tl.tag = NFAPI_GERAN_CELL_SEARCH_REQUEST_TAG; + geran_req.geran_cell_search_request.timeout = 1000; + geran_req.geran_cell_search_request.number_of_arfcn = 1; + geran_req.geran_cell_search_request.arfcn[0] = 8765; + nfapi_vnf_cell_search_request(config, p5_idx, &geran_req); + } + { + nfapi_broadcast_detect_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; + lte_req.header.phy_id = phy_id; + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_broadcast_detect_request.tl.tag = NFAPI_LTE_BROADCAST_DETECT_REQUEST_TAG; + lte_req.lte_broadcast_detect_request.earfcn = 1234; + lte_req.lte_broadcast_detect_request.pci = 50; + lte_req.lte_broadcast_detect_request.timeout = 1000; + lte_req.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + lte_req.pnf_cell_search_state.length = 3; + nfapi_vnf_broadcast_detect_request(config, p5_idx, <e_req); + nfapi_broadcast_detect_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_BROADCAST_DETECT_REQUEST; + utran_req.header.phy_id = phy_id; + utran_req.rat_type = NFAPI_RAT_TYPE_LTE; + utran_req.utran_broadcast_detect_request.tl.tag = NFAPI_UTRAN_BROADCAST_DETECT_REQUEST_TAG; + utran_req.utran_broadcast_detect_request.uarfcn = 1234; + utran_req.utran_broadcast_detect_request.psc = 50; + utran_req.utran_broadcast_detect_request.timeout = 1000; + utran_req.pnf_cell_search_state.tl.tag = NFAPI_PNF_CELL_SEARCH_STATE_TAG; + utran_req.pnf_cell_search_state.length = 3; + nfapi_vnf_broadcast_detect_request(config, p5_idx, &utran_req); + } + { + nfapi_system_information_schedule_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST; + lte_req.header.phy_id = phy_id; + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_system_information_schedule_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_SCHEDULE_REQUEST_TAG; + lte_req.lte_system_information_schedule_request.earfcn = 1234; + lte_req.lte_system_information_schedule_request.pci = 50; + lte_req.lte_system_information_schedule_request.downlink_channel_bandwidth = 100; + lte_req.lte_system_information_schedule_request.phich_configuration = 3; + lte_req.lte_system_information_schedule_request.number_of_tx_antenna = 2; + lte_req.lte_system_information_schedule_request.retry_count = 4; + lte_req.lte_system_information_schedule_request.timeout = 1000; + lte_req.pnf_cell_broadcast_state.tl.tag = NFAPI_PNF_CELL_BROADCAST_STATE_TAG; + lte_req.pnf_cell_broadcast_state.length = 3; + nfapi_vnf_system_information_schedule_request(config, p5_idx, <e_req); + } + { + nfapi_system_information_request_t lte_req; + memset(<e_req, 0, sizeof(lte_req)); + lte_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + lte_req.header.phy_id = phy_id; + lte_req.rat_type = NFAPI_RAT_TYPE_LTE; + lte_req.lte_system_information_request.tl.tag = NFAPI_LTE_SYSTEM_INFORMATION_REQUEST_TAG; + lte_req.lte_system_information_request.earfcn = 1234; + lte_req.lte_system_information_request.pci= 456; + lte_req.lte_system_information_request.downlink_channel_bandwidth = 5; + lte_req.lte_system_information_request.phich_configuration = 2; + lte_req.lte_system_information_request.number_of_tx_antenna = 2; + lte_req.lte_system_information_request.number_of_si_periodicity = 1; + lte_req.lte_system_information_request.si_periodicity[0].si_periodicity = 3; + lte_req.lte_system_information_request.si_periodicity[0].si_index = 3; + lte_req.lte_system_information_request.si_window_length = 15; + lte_req.lte_system_information_request.timeout = 1000; + nfapi_vnf_system_information_request(config, p5_idx, <e_req); + nfapi_system_information_request_t utran_req; + memset(&utran_req, 0, sizeof(utran_req)); + utran_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + utran_req.header.phy_id = phy_id; + utran_req.rat_type = NFAPI_RAT_TYPE_UTRAN; + utran_req.utran_system_information_request.tl.tag = NFAPI_UTRAN_SYSTEM_INFORMATION_REQUEST_TAG; + utran_req.utran_system_information_request.uarfcn = 1234; + utran_req.utran_system_information_request.psc = 456; + utran_req.utran_system_information_request.timeout = 1000; + nfapi_vnf_system_information_request(config, p5_idx, &utran_req); + nfapi_system_information_request_t geran_req; + memset(&geran_req, 0, sizeof(geran_req)); + geran_req.header.message_id = NFAPI_SYSTEM_INFORMATION_REQUEST; + geran_req.header.phy_id = phy_id; + geran_req.rat_type = NFAPI_RAT_TYPE_GERAN; + geran_req.geran_system_information_request.tl.tag = NFAPI_GERAN_SYSTEM_INFORMATION_REQUEST_TAG; + geran_req.geran_system_information_request.arfcn = 1234; + geran_req.geran_system_information_request.bsic = 21; + geran_req.geran_system_information_request.timeout = 1000; + nfapi_vnf_system_information_request(config, p5_idx, &geran_req); + } + { + nfapi_nmm_stop_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_NMM_STOP_REQUEST; + req.header.phy_id = phy_id; + nfapi_vnf_nmm_stop_request(config, p5_idx, &req); + } +} - auto find_result = vnf->pnfs.find(p5_idx); - if(find_result != vnf->pnfs.end()) - { - pnf_info& pnf = find_result->second; - - - auto found = std::find_if(pnf.phys.begin(), pnf.phys.end(), [&](phy_info& item) - { return item.id == resp->header.phy_id; }); - if(found != pnf.phys.end()) - { - phy_info& phy = (*found); +int start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_start_response_t *resp) { + printf("[VNF_SIM] start response idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + vnf_info *vnf = (vnf_info *)(config->user_data); - vnf_p7_info& p7_vnf = vnf->p7_vnfs[0]; + if(vnf->wireshark_test_mode) + test_p4_requests(config, p5_idx, resp->header.phy_id); - nfapi_vnf_p7_add_pnf((p7_vnf.config.get()), phy.remote_addr.c_str(), phy.remote_port, phy.id); - + auto find_result = vnf->pnfs.find(p5_idx); - } + if(find_result != vnf->pnfs.end()) { + pnf_info &pnf = find_result->second; + auto found = std::find_if(pnf.phys.begin(), pnf.phys.end(), [&](phy_info& item) { + return item.id == resp->header.phy_id; + }); + if(found != pnf.phys.end()) { + phy_info &phy = (*found); + vnf_p7_info &p7_vnf = vnf->p7_vnfs[0]; + nfapi_vnf_p7_add_pnf((p7_vnf.config.get()), phy.remote_addr.c_str(), phy.remote_port, phy.id); + } + } - } - return 0; + return 0; } -nfapi_p4_p5_message_header_t* vnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t* msg_size) -{ - if(message_id == P5_VENDOR_EXT_RSP) - { - *msg_size = sizeof(vendor_ext_p5_rsp); - return (nfapi_p4_p5_message_header_t*)malloc(sizeof(vendor_ext_p5_rsp)); - } - return 0; +nfapi_p4_p5_message_header_t *vnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size) { + if(message_id == P5_VENDOR_EXT_RSP) { + *msg_size = sizeof(vendor_ext_p5_rsp); + return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_rsp)); + } + + return 0; } -void vnf_sim_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t* header) -{ - free(header); +void vnf_sim_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header) { + free(header); } -int vendor_ext_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg) -{ - printf("[VNF_SIM] %s\n", __FUNCTION__); - - switch(msg->message_id) - { - case P5_VENDOR_EXT_RSP: - { - vendor_ext_p5_rsp* rsp = (vendor_ext_p5_rsp*)msg; - printf("[VNF_SIM] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code); - - // send the start request - - nfapi_pnf_start_request_t req; - memset(&req, 0, sizeof(req)); - req.header.message_id = NFAPI_PNF_START_REQUEST; - nfapi_vnf_pnf_start_req(config, p5_idx, &req); - } - break; - - } +int vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg) { + printf("[VNF_SIM] %s\n", __FUNCTION__); + + switch(msg->message_id) { + case P5_VENDOR_EXT_RSP: { + vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg; + printf("[VNF_SIM] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code); + // send the start request + nfapi_pnf_start_request_t req; + memset(&req, 0, sizeof(req)); + req.header.message_id = NFAPI_PNF_START_REQUEST; + nfapi_vnf_pnf_start_req(config, p5_idx, &req); + } + break; + } - return 0; + return 0; } -int read_vnf_xml(vnf_info& vnf, const char* xml_file) -{ - try - { - - std::ifstream input(xml_file); - - using boost::property_tree::ptree; - ptree pt; - - read_xml(input, pt); - - - - for(const auto& v : pt.get_child("vnf.vnf_p7_list")) - { - if(v.first == "vnf_p7") - { - vnf_p7_info vnf_p7; - vnf_p7.local_port = v.second.get<unsigned>("port"); - vnf_p7.local_addr = v.second.get<std::string>("address"); - - vnf_p7.timing_window = v.second.get<unsigned>("timing_window"); - vnf_p7.periodic_timing_enabled = v.second.get<unsigned>("periodic_timing_enabled"); - vnf_p7.aperiodic_timing_enabled = v.second.get<unsigned>("aperiodic_timing_enabled"); - vnf_p7.periodic_timing_period = v.second.get<unsigned>("periodic_timing_window"); - - - boost::optional<const boost::property_tree::ptree&> d = v.second.get_child_optional("data.udp"); - if(d.is_initialized()) - { - vnf_p7.udp.enabled = true; - vnf_p7.udp.rx_port = d.get().get<unsigned>("rx_port"); - vnf_p7.udp.tx_port = d.get().get<unsigned>("tx_port"); - vnf_p7.udp.tx_addr = d.get().get<std::string>("tx_addr"); - } - else - { - vnf_p7.udp.enabled = false; - } - - vnf.wireshark_test_mode = v.second.get<unsigned>("wireshark_test_mode", 0); - - vnf_p7.mac = mac_create(vnf.wireshark_test_mode); - vnf_p7.mac->dl_config_req = &mac_dl_config_req; - vnf_p7.mac->ul_config_req = &mac_ul_config_req; - vnf_p7.mac->hi_dci0_req = &mac_hi_dci0_req; - vnf_p7.mac->tx_req = &mac_tx_req; - - if(vnf_p7.udp.enabled) - { - mac_start_data(vnf_p7.mac, - vnf_p7.udp.rx_port, - vnf_p7.udp.tx_addr.c_str(), - vnf_p7.udp.tx_port); - } - - vnf.p7_vnfs.push_back(vnf_p7); - } - } - } - catch(std::exception& e) - { - printf("%s", e.what()); - return -1; - } - catch(boost::exception& e) - { - printf("%s", boost::diagnostic_information(e).c_str()); - } - - struct ifaddrs *ifaddr; - getifaddrs(&ifaddr); - - - while(ifaddr) - { - int family = ifaddr->ifa_addr->sa_family; - if(family == AF_INET) - { - char host[128]; - getnameinfo(ifaddr->ifa_addr, sizeof(sockaddr_in), host, sizeof(host), NULL, 0, 0); - printf("%s\n", host); - } - ifaddr = ifaddr->ifa_next; - } - - return 0; +int read_vnf_xml(vnf_info &vnf, const char *xml_file) { + try { + std::ifstream input(xml_file); + using boost::property_tree::ptree; + ptree pt; + read_xml(input, pt); + + for(const auto &v : pt.get_child("vnf.vnf_p7_list")) { + if(v.first == "vnf_p7") { + vnf_p7_info vnf_p7; + vnf_p7.local_port = v.second.get<unsigned>("port"); + vnf_p7.local_addr = v.second.get<std::string>("address"); + vnf_p7.timing_window = v.second.get<unsigned>("timing_window"); + vnf_p7.periodic_timing_enabled = v.second.get<unsigned>("periodic_timing_enabled"); + vnf_p7.aperiodic_timing_enabled = v.second.get<unsigned>("aperiodic_timing_enabled"); + vnf_p7.periodic_timing_period = v.second.get<unsigned>("periodic_timing_window"); + boost::optional<const boost::property_tree::ptree &> d = v.second.get_child_optional("data.udp"); + + if(d.is_initialized()) { + vnf_p7.udp.enabled = true; + vnf_p7.udp.rx_port = d.get().get<unsigned>("rx_port"); + vnf_p7.udp.tx_port = d.get().get<unsigned>("tx_port"); + vnf_p7.udp.tx_addr = d.get().get<std::string>("tx_addr"); + } else { + vnf_p7.udp.enabled = false; + } + + vnf.wireshark_test_mode = v.second.get<unsigned>("wireshark_test_mode", 0); + vnf_p7.mac = mac_create(vnf.wireshark_test_mode); + vnf_p7.mac->dl_config_req = &mac_dl_config_req; + vnf_p7.mac->ul_config_req = &mac_ul_config_req; + vnf_p7.mac->hi_dci0_req = &mac_hi_dci0_req; + vnf_p7.mac->tx_req = &mac_tx_req; + + if(vnf_p7.udp.enabled) { + mac_start_data(vnf_p7.mac, + vnf_p7.udp.rx_port, + vnf_p7.udp.tx_addr.c_str(), + vnf_p7.udp.tx_port); + } + + vnf.p7_vnfs.push_back(vnf_p7); + } + } + } catch(std::exception &e) { + printf("%s", e.what()); + return -1; + } catch(boost::exception &e) { + printf("%s", boost::diagnostic_information(e).c_str()); + } + + struct ifaddrs *ifaddr; + + getifaddrs(&ifaddr); + + while(ifaddr) { + int family = ifaddr->ifa_addr->sa_family; + + if(family == AF_INET) { + char host[128]; + getnameinfo(ifaddr->ifa_addr, sizeof(sockaddr_in), host, sizeof(host), NULL, 0, 0); + printf("%s\n", host); + } + + ifaddr = ifaddr->ifa_next; + } + return 0; } -int main(int argc, char *argv[]) -{ - if (argc < 3) - { - printf("Use parameters: <P5 Port> <xml config file>\n"); - return 0; - } - - set_thread_priority(50); - - vnf_info vnf; - - if(read_vnf_xml(vnf, argv[2]) < 0) - { - printf("Failed to read xml file>\n"); - return 0; - } - - nfapi_vnf_config_t* config = nfapi_vnf_config_create(); - - config->vnf_ipv4 = 1; - config->vnf_p5_port = atoi(argv[1]); - config->pnf_connection_indication = &pnf_connection_indication_cb; - config->pnf_disconnect_indication = &pnf_disconnection_indication_cb; - config->pnf_param_resp = &pnf_param_resp_cb; - config->pnf_config_resp = &pnf_config_resp_cb; - config->pnf_start_resp = &pnf_start_resp_cb; - config->param_resp = ¶m_resp_cb; - config->config_resp = &config_resp_cb; - config->start_resp = &start_resp_cb; - config->vendor_ext = &vendor_ext_cb; - - - - config->trace = &vnf_sim_trace; - - config->malloc = &vnf_allocate; - config->free = &vnf_deallocate; - - config->user_data = &vnf; - - config->codec_config.unpack_vendor_extension_tlv = &vnf_sim_unpack_vendor_extension_tlv; - config->codec_config.pack_vendor_extension_tlv = &vnf_sim_pack_vendor_extension_tlv; - - config->codec_config.unpack_p4_p5_vendor_extension = &vnf_sim_unpack_p4_p5_vendor_extension; - config->codec_config.pack_p4_p5_vendor_extension = &vnf_sim_pack_p4_p5_vendor_extension; - config->allocate_p4_p5_vendor_ext = &vnf_sim_allocate_p4_p5_vendor_ext; - config->deallocate_p4_p5_vendor_ext = &vnf_sim_deallocate_p4_p5_vendor_ext; - config->codec_config.allocate = &vnf_allocate; - config->codec_config.deallocate = &vnf_deallocate; - - - printf("Calling nfapi_vnf_start\n"); - return nfapi_vnf_start(config); +int main(int argc, char *argv[]) { + if (argc < 3) { + printf("Use parameters: <P5 Port> <xml config file>\n"); + return 0; + } + + set_thread_priority(50); + vnf_info vnf; + + if(read_vnf_xml(vnf, argv[2]) < 0) { + printf("Failed to read xml file>\n"); + return 0; + } + + nfapi_vnf_config_t *config = nfapi_vnf_config_create(); + config->vnf_ipv4 = 1; + config->vnf_p5_port = atoi(argv[1]); + config->pnf_connection_indication = &pnf_connection_indication_cb; + config->pnf_disconnect_indication = &pnf_disconnection_indication_cb; + config->pnf_param_resp = &pnf_param_resp_cb; + config->pnf_config_resp = &pnf_config_resp_cb; + config->pnf_start_resp = &pnf_start_resp_cb; + config->param_resp = ¶m_resp_cb; + config->config_resp = &config_resp_cb; + config->start_resp = &start_resp_cb; + config->vendor_ext = &vendor_ext_cb; + config->trace = &vnf_sim_trace; + config->malloc = &vnf_allocate; + config->free = &vnf_deallocate; + config->user_data = &vnf; + config->codec_config.unpack_vendor_extension_tlv = &vnf_sim_unpack_vendor_extension_tlv; + config->codec_config.pack_vendor_extension_tlv = &vnf_sim_pack_vendor_extension_tlv; + config->codec_config.unpack_p4_p5_vendor_extension = &vnf_sim_unpack_p4_p5_vendor_extension; + config->codec_config.pack_p4_p5_vendor_extension = &vnf_sim_pack_p4_p5_vendor_extension; + config->allocate_p4_p5_vendor_ext = &vnf_sim_allocate_p4_p5_vendor_ext; + config->deallocate_p4_p5_vendor_ext = &vnf_sim_deallocate_p4_p5_vendor_ext; + config->codec_config.allocate = &vnf_allocate; + config->codec_config.deallocate = &vnf_deallocate; + printf("Calling nfapi_vnf_start\n"); + return nfapi_vnf_start(config); } diff --git a/openair1/PHY/CODING/ccoding_byte.c b/openair1/PHY/CODING/ccoding_byte.c index e4617d1404c6df009efab4be9d46a0e299c87d2f..576a947cff3641fffa72c01971e182e71d65eca4 100644 --- a/openair1/PHY/CODING/ccoding_byte.c +++ b/openair1/PHY/CODING/ccoding_byte.c @@ -130,7 +130,7 @@ ccodedot11_encode (unsigned int numbytes, *outPtr++ = (out>>1)&1; #ifdef DEBUG_CCODE - printf("%d: %u -> %d (%u)\n",dummy,state,out,ccodedot11_table[state]); + printf("%u: %u -> %d (%u)\n",dummy,state,out,ccodedot11_table[state]); dummy+=2; #endif //DEBUG_CCODE bit_index=(bit_index==0)?1:0; diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index 06a43fdb79242eed9636c489c00d6ef9c55758d3..29bddeb2cbb097f3d2496ef086c42749b59b3415 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -88,17 +88,17 @@ uint32_t crcbit (uint8_t * inputptr, int32_t octetlen, uint32_t poly) // Reference 38.212 V15.1.1 Section 5.1 (36-212 v8.6.0 , pp 8-9) // The highest degree is set by default -// 1000 0110 0100 1100 1111 1011 D^24 + D^23 + D^18 + D^17 + D^14 + D^11 + D^10 + D^7 + D^6 + D^5 + D^4 + D^3 + D + 1 +// 1000 0110 0100 1100 1111 1011 D^24 + D^23 + D^18 + D^17 + D^14 + D^11 + D^10 + D^7 + D^6 + D^5 + D^4 + D^3 + D + 1 static const uint32_t poly24a = 0x864cfb00; -// 1000 0000 0000 0000 0110 0011 D^24 + D^23 + D^6 + D^5 + D + 1 +// 1000 0000 0000 0000 0110 0011 D^24 + D^23 + D^6 + D^5 + D + 1 static const uint32_t poly24b = 0x80006300; -// 0001 0000 0010 0001 D^16 + D^12 + D^5 + 1 +// 0001 0000 0010 0001 D^16 + D^12 + D^5 + 1 static const uint32_t poly16 = 0x10210000; -// 1000 0000 1111 D^12 + D^11 + D^3 + D^2 + D + 1 +// 1000 0000 1111 D^12 + D^11 + D^3 + D^2 + D + 1 static const uint32_t poly12 = 0x80F00000; -// 1001 1011 D^8 + D^7 + D^4 + D^3 + D + 1 +// 1001 1011 D^8 + D^7 + D^4 + D^3 + D + 1 static const uint32_t poly8 = 0x9B000000; - + void crcTableInit (void) { uint8_t c = 0; diff --git a/openair1/PHY/CODING/lte_rate_matching.c b/openair1/PHY/CODING/lte_rate_matching.c index f850d475494e2ed7eb47fbb05546527ebc83db97..548b7bfcba38bec0c8bb6aee29262872ad263c9f 100644 --- a/openair1/PHY/CODING/lte_rate_matching.c +++ b/openair1/PHY/CODING/lte_rate_matching.c @@ -236,7 +236,7 @@ void sub_block_deinterleaving_cc(uint32_t D,int8_t *d,int8_t *w) { ND = Kpi - D; #ifdef RM_DEBUG2 printf("sub_block_interleaving_cc : D = %d (%d), d %p, w %p\n",D,D*3,d,w); - printf("RCC = %d, Kpi=%d, ND=%ld\n",RCC,Kpi,ND); + printf("RCC = %d, Kpi=%d, ND=%ld\n",RCC,Kpi,(long)ND); #endif ND3 = ND*3; k=0; @@ -253,7 +253,8 @@ void sub_block_deinterleaving_cc(uint32_t D,int8_t *d,int8_t *w) { d[index3-ND3+1] = w[Kpi+k]; d[index3-ND3+2] = w[(Kpi<<1)+k]; #ifdef RM_DEBUG2 - printf("row %d, index %d k %d index3-ND3 %ld w(%d,%d,%d)\n",row,index,k,index3-ND3,w[k],w[Kpi+k],w[(Kpi<<1)+k]); + printf("row %d, index %d k %d index3-ND3 %ld w(%d,%d,%d)\n", + row,index,k,(long)(index3-ND3),w[k],w[Kpi+k],w[(Kpi<<1)+k]); #endif index3+=96; index+=32; @@ -453,7 +454,6 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC, int threed =0; uint32_t nulled=0; static unsigned char *counter_buffer[MAX_NUM_DLSCH_SEGMENTS][4]; - FILE *counter_fd; char fname[512]; #endif @@ -476,7 +476,6 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC, } else if(rvidx==3) { sprintf(fname, "mcs%d_rate_matching_RB_%d.txt", m, nb_rb); // sprintf(fname,"mcs0_rate_matching_RB_6.txt"); - counter_fd = fopen(fname,"w"); } #endif diff --git a/openair1/PHY/CODING/lte_segmentation.c b/openair1/PHY/CODING/lte_segmentation.c index 4dc531c58f9222b1b0460473154c640ae7fccea6..5116c765b86a7e7afdb2c19195fc260a0537e5ac 100644 --- a/openair1/PHY/CODING/lte_segmentation.c +++ b/openair1/PHY/CODING/lte_segmentation.c @@ -59,6 +59,7 @@ int lte_segmentation(unsigned char *input_buffer, } if ((*C)>MAX_NUM_DLSCH_SEGMENTS) { + printf("%d\n",*(int*)0); LOG_E(PHY,"lte_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime); return(-1); } @@ -124,7 +125,8 @@ int lte_segmentation(unsigned char *input_buffer, Bprime,*Cplus,*Kplus,*Cminus,*Kminus); *F = ((*Cplus)*(*Kplus) + (*Cminus)*(*Kminus) - (Bprime)); #ifdef DEBUG_SEGMENTATION - printf("C %u, Cplus %u, Cminus %u, Kplus %u, Kminus %u, Bprime_bytes %u, Bprime %u, F %u\n",*C,*Cplus,*Cminus,*Kplus,*Kminus,Bprime>>3,Bprime,*F); + printf("C %u, Cplus %u, Cminus %u, Kplus %u, Kminus %u, Bprime_bytes %u, Bprime %u, F %u\n", + *C,*Cplus,*Cminus,*Kplus,*Kminus,Bprime>>3,Bprime,*F); #endif if ((input_buffer) && (output_buffers)) { diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index 698f34833d7d12995596530d3cc573d246816fa6..6421eebe28a0cda990683148489eda7633233433 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -83,4 +83,4 @@ void free_lte_top(void) { /* - @}*/ + * @}*/ diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 3ee2c34905d381dff080494e531656165d04f387..9852d392bb5745fd56c98b112cf9d6c8d313b2ce 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -975,3 +975,4 @@ void install_schedule_handlers(IF_Module_t *if_inst) if_inst->PHY_config_req = phy_config_request; if_inst->schedule_response = schedule_response; } + diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index 4a484ea02ca07b3ccd51634b369578138b828637..f7ab91c86ea6d68f53556fd46c7b1a91f7dd3148 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -34,19 +34,17 @@ #include "PHY/LTE_TRANSPORT/transport_common_proto.h" #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #include "PHY/LTE_REFSIG/lte_refsig.h" - +#include "nfapi/oai_integration/vendor_ext.h" void init_7_5KHz(void); uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10}; -extern uint8_t nfapi_mode; + void phy_config_sib1_ue(module_id_t Mod_id,int CC_id, uint8_t eNB_id, LTE_TDD_Config_t *tdd_Config, uint8_t SIwindowsize, - uint16_t SIperiod) -{ - + uint16_t SIperiod) { LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; if (tdd_Config) { @@ -64,44 +62,29 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, LTE_ARFCN_ValueEUTRA_t *ul_CarrierFreq, long *ul_Bandwidth, LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) -{ - + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) { PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; LTE_DL_FRAME_PARMS *fp = &ue->frame_parms; int i; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_IN); - LOG_I(PHY,"[UE%d] Applying radioResourceConfigCommon from eNB%d\n",Mod_id,eNB_id); - fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex; - fp->prach_config_common.prach_Config_enabled=1; fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex; fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.highSpeedFlag; fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset; - compute_prach_seq(fp->prach_config_common.rootSequenceIndex, - fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type,ue->X_u); - - - + fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, + fp->frame_type,ue->X_u); fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon.deltaPUCCH_Shift; fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon.nRB_CQI; fp->pucch_config_common.nCS_AN = radioResourceConfigCommon->pucch_ConfigCommon.nCS_AN; fp->pucch_config_common.n1PUCCH_AN = radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN; - - - fp->pdsch_config_common.referenceSignalPower = radioResourceConfigCommon->pdsch_ConfigCommon.referenceSignalPower; fp->pdsch_config_common.p_b = radioResourceConfigCommon->pdsch_ConfigCommon.p_b; - - fp->pusch_config_common.n_SB = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; fp->pusch_config_common.hoppingMode = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; fp->pusch_config_common.pusch_HoppingOffset = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; @@ -110,8 +93,6 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled; fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = dmrs1_tab_ue[radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift]; - - init_ul_hopping(fp); fp->soundingrs_ul_config_common.enabled_flag = 0; @@ -127,8 +108,6 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; } - - fp->ul_power_control_config_common.p0_NominalPUSCH = radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUSCH; fp->ul_power_control_config_common.alpha = radioResourceConfigCommon->uplinkPowerControlCommon.alpha; fp->ul_power_control_config_common.p0_NominalPUCCH = radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUCCH; @@ -138,16 +117,11 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, fp->ul_power_control_config_common.deltaF_PUCCH_Format2 = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2; fp->ul_power_control_config_common.deltaF_PUCCH_Format2a = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a; fp->ul_power_control_config_common.deltaF_PUCCH_Format2b = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b; - fp->maxHARQ_Msg3Tx = radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx; - // Now configure some of the Physical Channels - // PUCCH init_ncs_cell(fp,ue->ncs_cell); - init_ul_hopping(fp); - // PCH init_ue_paging_info(ue,radioResourceConfigCommon->pcch_Config.defaultPagingCycle,radioResourceConfigCommon->pcch_Config.nB); @@ -171,7 +145,6 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]| (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); - LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %x\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); } @@ -179,16 +152,11 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_OUT); - } void phy_config_sib13_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_idx, - long mbsfn_AreaId_r9) -{ - + long mbsfn_AreaId_r9) { LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; - - LOG_I(PHY,"[UE%d] Applying MBSFN_Area_id %ld for index %d\n",Mod_id,mbsfn_AreaId_r9,mbsfn_Area_idx); if (mbsfn_Area_idx == 0) { @@ -224,9 +192,7 @@ void phy_config_sib1_fembms_ue(module_id_t Mod_id,int CC_id, /* * Configures UE MAC and PHY with radioResourceCommon received in mobilityControlInfo IE during Handover */ -void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, LTE_MobilityControlInfo_t *mobilityControlInfo, uint8_t ho_failed) -{ - +void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, LTE_MobilityControlInfo_t *mobilityControlInfo, uint8_t ho_failed) { if(mobilityControlInfo!=NULL) { LTE_RadioResourceConfigCommon_t *radioResourceConfigCommon = &mobilityControlInfo->radioResourceConfigCommon; LOG_I(PHY,"radioResourceConfigCommon %p\n", radioResourceConfigCommon); @@ -235,44 +201,35 @@ void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, LTE_ sizeof(LTE_DL_FRAME_PARMS)); PHY_vars_UE_g[Mod_id][CC_id]->ho_triggered = 1; //PHY_vars_UE_g[UE_id]->UE_mode[0] = PRACH; - LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; // int N_ZC; // uint8_t prach_fmt; // int u; - LOG_I(PHY,"[UE%d] Handover triggered: Applying radioResourceConfigCommon from eNB %d\n", Mod_id,eNB_id); - fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex; fp->prach_config_common.prach_Config_enabled=1; fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex; fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag; fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig; fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset; - // prach_fmt = get_prach_fmt(radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex,fp->frame_type); // N_ZC = (prach_fmt <4)?839:139; // u = (prach_fmt < 4) ? prach_root_sequence_map0_3[fp->prach_config_common.rootSequenceIndex] : // prach_root_sequence_map4[fp->prach_config_common.rootSequenceIndex]; - //compute_prach_seq(u,N_ZC, PHY_vars_UE_g[Mod_id]->X_u); compute_prach_seq(PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.rootSequenceIndex, - PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag, + PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag, fp->frame_type, PHY_vars_UE_g[Mod_id][CC_id]->X_u); - - fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon->deltaPUCCH_Shift; fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon->nRB_CQI; fp->pucch_config_common.nCS_AN = radioResourceConfigCommon->pucch_ConfigCommon->nCS_AN; fp->pucch_config_common.n1PUCCH_AN = radioResourceConfigCommon->pucch_ConfigCommon->n1PUCCH_AN; fp->pdsch_config_common.referenceSignalPower = radioResourceConfigCommon->pdsch_ConfigCommon->referenceSignalPower; fp->pdsch_config_common.p_b = radioResourceConfigCommon->pdsch_ConfigCommon->p_b; - - fp->pusch_config_common.n_SB = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; fp->pusch_config_common.hoppingMode = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; fp->pusch_config_common.pusch_HoppingOffset = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; @@ -281,7 +238,6 @@ void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, LTE_ fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled; fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; - init_ul_hopping(fp); fp->soundingrs_ul_config_common.enabled_flag = 0; @@ -306,7 +262,6 @@ void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, LTE_ fp->ul_power_control_config_common.deltaF_PUCCH_Format2 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2; fp->ul_power_control_config_common.deltaF_PUCCH_Format2a = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2a; fp->ul_power_control_config_common.deltaF_PUCCH_Format2b = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2b; - fp->maxHARQ_Msg3Tx = radioResourceConfigCommon->rach_ConfigCommon->maxHARQ_Msg3Tx; // Now configure some of the Physical Channels @@ -324,20 +279,14 @@ void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, LTE_ //Target CellId fp->Nid_cell = mobilityControlInfo->targetPhysCellId; fp->nushift = fp->Nid_cell%6; - // PUCCH init_ncs_cell(fp,PHY_vars_UE_g[Mod_id][CC_id]->ncs_cell); - init_ul_hopping(fp); - // RNTI - - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); - LOG_I(PHY,"SET C-RNTI %x %x\n",PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti, - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); + PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); } if(ho_failed) { @@ -347,12 +296,9 @@ void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, LTE_ } } -void phy_config_meas_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n_adj_cells,unsigned int *adj_cell_id) -{ - +void phy_config_meas_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n_adj_cells,unsigned int *adj_cell_id) { PHY_MEASUREMENTS *phy_meas = &PHY_vars_UE_g[Mod_id][CC_id]->measurements; int i; - LOG_I(PHY,"Configuring inter-cell measurements for %d cells, ids: \n",n_adj_cells); for (i=0; i<n_adj_cells; i++) { @@ -361,25 +307,20 @@ void phy_config_meas_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8 } phy_meas->n_adj_cells = n_adj_cells; - memcpy((void*)phy_meas->adj_cell_id,(void *)adj_cell_id,n_adj_cells*sizeof(unsigned int)); - + memcpy((void *)phy_meas->adj_cell_id,(void *)adj_cell_id,n_adj_cells*sizeof(unsigned int)); } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) void phy_config_dedicated_scell_ue(uint8_t Mod_id, uint8_t eNB_index, LTE_SCellToAddMod_r10_t *sCellToAddMod_r10, - int CC_id) -{ - + int CC_id) { } #endif void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, - uint16_t max_harq_tx ) -{ - + uint16_t max_harq_tx ) { PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; phy_vars_ue->ulsch[eNB_id]->Mlimit = max_harq_tx; } @@ -387,12 +328,9 @@ void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, extern uint16_t beta_cqi[16]; void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, - struct LTE_PhysicalConfigDedicated *physicalConfigDedicated ) -{ - + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated ) { static uint8_t first_dedicated_configuration = 0; PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; - phy_vars_ue->total_TBS[eNB_id]=0; phy_vars_ue->total_TBS_last[eNB_id]=0; phy_vars_ue->bitrate[eNB_id]=0; @@ -402,7 +340,6 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, phy_vars_ue->dlsch_received[eNB_id]=0; phy_vars_ue->dlsch_received_last[eNB_id]=0; phy_vars_ue->dlsch_fer[eNB_id]=0; - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; @@ -438,18 +375,14 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; - - LOG_D(PHY,"pusch_config_dedicated.betaOffset_ACK_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index); LOG_D(PHY,"pusch_config_dedicated.betaOffset_RI_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index); - LOG_D(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d => %d)\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index,beta_cqi[phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index]); + LOG_D(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d => %d)\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index, + beta_cqi[phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index]); LOG_D(PHY,"\n"); - - } if (physicalConfigDedicated->uplinkPowerControlDedicated) { - phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH = physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUSCH; phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled= physicalConfigDedicated->uplinkPowerControlDedicated->deltaMCS_Enabled; phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled= physicalConfigDedicated->uplinkPowerControlDedicated->accumulationEnabled; @@ -468,32 +401,40 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, if (physicalConfigDedicated->antennaInfo) { phy_vars_ue->transmission_mode[eNB_id] = 1+(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); LOG_I(PHY,"Transmission Mode %d\n",phy_vars_ue->transmission_mode[eNB_id]); + switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { - case LTE_AntennaInfoDedicated__transmissionMode_tm1: - phy_vars_ue->transmission_mode[eNB_id] = 1; - break; - case LTE_AntennaInfoDedicated__transmissionMode_tm2: - phy_vars_ue->transmission_mode[eNB_id] = 2; - break; - case LTE_AntennaInfoDedicated__transmissionMode_tm3: - phy_vars_ue->transmission_mode[eNB_id] = 3; - break; - case LTE_AntennaInfoDedicated__transmissionMode_tm4: - phy_vars_ue->transmission_mode[eNB_id] = 4; - break; - case LTE_AntennaInfoDedicated__transmissionMode_tm5: - phy_vars_ue->transmission_mode[eNB_id] = 5; - break; - case LTE_AntennaInfoDedicated__transmissionMode_tm6: - phy_vars_ue->transmission_mode[eNB_id] = 6; - break; - case LTE_AntennaInfoDedicated__transmissionMode_tm7: - lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[0][eNB_id]->crnti); - phy_vars_ue->transmission_mode[eNB_id] = 7; - break; - default: - LOG_E(PHY,"Unknown transmission mode!\n"); - break; + case LTE_AntennaInfoDedicated__transmissionMode_tm1: + phy_vars_ue->transmission_mode[eNB_id] = 1; + break; + + case LTE_AntennaInfoDedicated__transmissionMode_tm2: + phy_vars_ue->transmission_mode[eNB_id] = 2; + break; + + case LTE_AntennaInfoDedicated__transmissionMode_tm3: + phy_vars_ue->transmission_mode[eNB_id] = 3; + break; + + case LTE_AntennaInfoDedicated__transmissionMode_tm4: + phy_vars_ue->transmission_mode[eNB_id] = 4; + break; + + case LTE_AntennaInfoDedicated__transmissionMode_tm5: + phy_vars_ue->transmission_mode[eNB_id] = 5; + break; + + case LTE_AntennaInfoDedicated__transmissionMode_tm6: + phy_vars_ue->transmission_mode[eNB_id] = 6; + break; + + case LTE_AntennaInfoDedicated__transmissionMode_tm7: + lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[0][eNB_id]->crnti); + phy_vars_ue->transmission_mode[eNB_id] = 7; + break; + + default: + LOG_E(PHY,"Unknown transmission mode!\n"); + break; } } else { LOG_D(PHY,"[UE %d] Received NULL physicalConfigDedicated->antennaInfo from eNB %d\n",Mod_id, eNB_id); @@ -504,19 +445,17 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex = physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex=physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_ConfigIndex; phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax=physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax; - LOG_D(PHY,"scheduling_request_config.sr_PUCCH_ResourceIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); LOG_D(PHY,"scheduling_request_config.sr_ConfigIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex); LOG_D(PHY,"scheduling_request_config.dsr_TransMax %d\n",phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax); } LOG_D(PHY,"------------------------------------------------------------\n"); - } if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) { - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 0; + if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == LTE_SoundingRS_UL_ConfigDedicated_PR_setup) { phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 1; phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].duration = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration; @@ -526,34 +465,32 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_HoppingBandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth; phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; - - LOG_D(PHY,"soundingrs_ul_config_dedicated.srs_ConfigIndex %d\n",phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex); } LOG_D(PHY,"------------------------------------------------------------\n"); - } - if (physicalConfigDedicated->cqi_ReportConfig) { if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) { // configure PUSCH CQI reporting phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; + if ((phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm12) && (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm30) && (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm31)) LOG_E(PHY,"Unsupported Aperiodic CQI Feedback Mode : %d\n",phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic); } + if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) { if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == LTE_CQI_ReportPeriodic_PR_setup) { - // configure PUCCH CQI reporting + // configure PUCCH CQI reporting phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; + if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex; - } - else if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == LTE_CQI_ReportPeriodic_PR_release) { + } else if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == LTE_CQI_ReportPeriodic_PR_release) { // handle release phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; @@ -579,28 +516,25 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, // fill cqi parameters for periodic CQI reporting get_cqipmiri_params(phy_vars_ue,eNB_id); - // disable MIB SIB decoding once we are on connected mode first_dedicated_configuration ++; - if(first_dedicated_configuration > 1) - { - LOG_I(PHY,"Disable SIB MIB decoding \n"); - phy_vars_ue->decode_SIB = 0; - phy_vars_ue->decode_MIB = 0; + + if(first_dedicated_configuration > 1) { + LOG_I(PHY,"Disable SIB MIB decoding \n"); + phy_vars_ue->decode_SIB = 0; + phy_vars_ue->decode_MIB = 0; } - if(nfapi_mode!=3){ + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) { //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234) - phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; + phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; else - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti, - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); + phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); } - - } /*! \brief Helper function to allocate memory for DLSCH data structures. @@ -608,88 +542,71 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, * \param[in] frame_parms LTE_DL_FRAME_PARMS structure. * \note This function is optimistic in that it expects malloc() to succeed. */ -void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH* const pdsch, const LTE_DL_FRAME_PARMS* const fp ) -{ +void phy_init_lte_ue__PDSCH( LTE_UE_PDSCH *const pdsch, const LTE_DL_FRAME_PARMS *const fp ) { AssertFatal( pdsch, "pdsch==0" ); - - pdsch->pmi_ext = (uint8_t*)malloc16_clear( fp->N_RB_DL ); - pdsch->llr[0] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); - pdsch->llr128 = (int16_t**)malloc16_clear( sizeof(int16_t*) ); + pdsch->pmi_ext = (uint8_t *)malloc16_clear( fp->N_RB_DL ); + pdsch->llr[0] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); + pdsch->llr128 = (int16_t **)malloc16_clear( sizeof(int16_t *) ); // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there - - - pdsch->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->rxdataF_uespec_pilots = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->rxdataF_comp0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) ); - pdsch->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_bf_ch_estimates = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_bf_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + pdsch->rxdataF_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); //pdsch->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); //pdsch->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_ch_mag0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pdsch->dl_ch_magb0 = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - - + pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); // the allocated memory size is fixed: AssertFatal( fp->nb_antennas_rx <= 2, "nb_antennas_rx > 2" ); for (int i=0; i<fp->nb_antennas_rx; i++) { - pdsch->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); + pdsch->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); for (int j=0; j<4; j++) { //fp->nb_antennas_tx; j++) const int idx = (j<<1)+i; const size_t num = 7*2*fp->N_RB_DL*12; - pdsch->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->rxdataF_uespec_pilots[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); - pdsch->rxdataF_comp0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_bf_ch_estimates[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2); - pdsch->dl_bf_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdsch->rxdataF_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + pdsch->rxdataF_uespec_pilots[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); + pdsch->rxdataF_comp0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_bf_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2); + pdsch->dl_bf_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); //pdsch->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); //pdsch->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_mag0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_magb0[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_ch_mag0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_ch_magb0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); } } } int init_lte_ue_signal(PHY_VARS_UE *ue, - int nb_connected_eNB, - uint8_t abstraction_flag) -{ - + int nb_connected_eNB, + uint8_t abstraction_flag) { // create shortcuts - LTE_DL_FRAME_PARMS* const fp = &ue->frame_parms; - LTE_UE_COMMON* const common_vars = &ue->common_vars; - LTE_UE_PDSCH** const pdsch_vars_SI = ue->pdsch_vars_SI; - LTE_UE_PDSCH** const pdsch_vars_ra = ue->pdsch_vars_ra; - LTE_UE_PDSCH** const pdsch_vars_p = ue->pdsch_vars_p; - LTE_UE_PDSCH** const pdsch_vars_mch = ue->pdsch_vars_MCH; + LTE_DL_FRAME_PARMS *const fp = &ue->frame_parms; + LTE_UE_COMMON *const common_vars = &ue->common_vars; + LTE_UE_PDSCH **const pdsch_vars_SI = ue->pdsch_vars_SI; + LTE_UE_PDSCH **const pdsch_vars_ra = ue->pdsch_vars_ra; + LTE_UE_PDSCH **const pdsch_vars_p = ue->pdsch_vars_p; + LTE_UE_PDSCH **const pdsch_vars_mch = ue->pdsch_vars_MCH; LTE_UE_PDSCH* (*pdsch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX+1] = &ue->pdsch_vars; LTE_UE_PDCCH* (*pdcch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX] = &ue->pdcch_vars; - LTE_UE_PBCH** const pbch_vars = ue->pbch_vars; - LTE_UE_PRACH** const prach_vars = ue->prach_vars; - - - + LTE_UE_PBCH **const pbch_vars = ue->pbch_vars; + LTE_UE_PRACH **const prach_vars = ue->prach_vars; int i,j,k,l; int eNB_id; int th_id; - LOG_D(PHY,"Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx); - - - init_dfts(); init_frame_parms(&ue->frame_parms,1); lte_sync_time_init(&ue->frame_parms); init_lte_top(&ue->frame_parms); init_7_5KHz(); init_ul_hopping(&ue->frame_parms); - - // many memory allocation sizes are hard coded AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[eNB_id]" ); AssertFatal( ue->n_connected_eNB <= NUMBER_OF_CONNECTED_eNB_MAX, "n_connected_eNB is too large" ); @@ -710,49 +627,44 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, ue->total_received_bits[eNB_id] = 0; } - for (i=0;i<10;i++) + for (i=0; i<10; i++) ue->tx_power_dBm[i]=-127; - - // init TX buffers - - common_vars->txdata = (int32_t**)malloc16( fp->nb_antennas_tx*sizeof(int32_t*) ); - common_vars->txdataF = (int32_t **)malloc16( fp->nb_antennas_tx*sizeof(int32_t*) ); - + common_vars->txdata = (int32_t **)malloc16( fp->nb_antennas_tx*sizeof(int32_t *) ); + common_vars->txdataF = (int32_t **)malloc16( fp->nb_antennas_tx*sizeof(int32_t *) ); + for (i=0; i<fp->nb_antennas_tx; i++) { - - common_vars->txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); + common_vars->txdata[i] = (int32_t *)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) ); common_vars->txdataF[i] = (int32_t *)malloc16_clear( fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) ); } - + // init RX buffers - - common_vars->rxdata = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - common_vars->common_vars_rx_data_per_thread[0].rxdataF = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - common_vars->common_vars_rx_data_per_thread[1].rxdataF = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - + common_vars->rxdata = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + common_vars->common_vars_rx_data_per_thread[0].rxdataF = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + common_vars->common_vars_rx_data_per_thread[1].rxdataF = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + for (i=0; i<fp->nb_antennas_rx; i++) { - common_vars->rxdata[i] = (int32_t*) malloc16_clear( (fp->samples_per_tti*10+2048)*sizeof(int32_t) ); + common_vars->rxdata[i] = (int32_t *) malloc16_clear( (fp->samples_per_tti*10+2048)*sizeof(int32_t) ); LOG_I(PHY,"common_vars->rxdata[%d] %p\n",i,common_vars->rxdata[i]); - common_vars->common_vars_rx_data_per_thread[0].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); - common_vars->common_vars_rx_data_per_thread[1].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); + common_vars->common_vars_rx_data_per_thread[0].rxdataF[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); + common_vars->common_vars_rx_data_per_thread[1].rxdataF[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) ); } - // Channel estimates for (eNB_id=0; eNB_id<7; eNB_id++) { for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*)); - common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*)); + common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id] = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id] = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); } for (i=0; i<fp->nb_antennas_rx; i++) for (j=0; j<4; j++) { int idx = (j<<1) + i; + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_tti*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) ); - common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 ); + common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id][idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_tti*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) ); + common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id][idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 ); } } } @@ -760,11 +672,11 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, // DLSCH for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) { for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); + (*pdsch_vars_th)[th_id][eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); } for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH)); + (*pdcch_vars_th)[th_id][eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH)); } pdsch_vars_SI[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH)); @@ -779,161 +691,159 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, } for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12); + (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12); (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts_p = (*pdsch_vars_th)[0][eNB_id]->llr_shifts; - (*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); - (*pdsch_vars_th)[th_id][eNB_id]->llr128_2ndstream = (int16_t**)malloc16_clear( sizeof(int16_t*) ); - (*pdsch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) ); + (*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); + (*pdsch_vars_th)[th_id][eNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) ); + (*pdsch_vars_th)[th_id][eNB_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); } - - for (int i=0; i<fp->nb_antennas_rx; i++){ + + for (int i=0; i<fp->nb_antennas_rx; i++) { for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); } - } + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); } - + for (i=0; i<fp->nb_antennas_rx; i++) for (j=0; j<4; j++) { - const int idx = (j<<1)+i; - const size_t num = 7*2*fp->N_RB_DL*12+4; - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - } - + const int idx = (j<<1)+i; + const size_t num = 7*2*fp->N_RB_DL*12+4; + + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + } } - + //const size_t num = 7*2*fp->N_RB_DL*12+4; - for (k=0;k<8;k++) { //harq_pid - for (l=0;l<8;l++) { //round - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - } - - - for (int i=0; i<fp->nb_antennas_rx; i++) - for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) - const int idx = (j<<1)+i; - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - } - - } + for (k=0; k<8; k++) { //harq_pid + for (l=0; l<8; l++) { //round + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + } + + for (int i=0; i<fp->nb_antennas_rx; i++) + for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++) + const int idx = (j<<1)+i; + + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + } + } } } + phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp ); phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp ); phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp ); phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp ); - + // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->wbar = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->e_rx = (int8_t*)malloc16_clear( 4*2*100*12 ); - - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); + (*pdcch_vars_th)[th_id][eNB_id]->llr = (uint16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->wbar = (uint16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->e_rx = (int8_t *)malloc16_clear( 4*2*100*12 ); + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdcch_vars_th)[th_id][eNB_id]->rho = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); } - + for (i=0; i<fp->nb_antennas_rx; i++) { //ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) ); + (*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4) ); } - + for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++) - int idx = (j<<1)+i; - // size_t num = 7*2*fp->N_RB_DL*12; - size_t num = 4*100*12; // 4 symbols, 100 PRBs, 12 REs per PRB - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - } + int idx = (j<<1)+i; + // size_t num = 7*2*fp->N_RB_DL*12; + size_t num = 4*100*12; // 4 symbols, 100 PRBs, 12 REs per PRB + + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + } } } + phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp ); phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp ); phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp ); phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp ); - + // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->llr = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->wbar = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - (*pdcch_vars_th)[th_id][eNB_id]->e_rx = (int8_t*)malloc16_clear( 4*2*100*12 ); - - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->rho = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - + (*pdcch_vars_th)[th_id][eNB_id]->llr = (uint16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->wbar = (uint16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); + (*pdcch_vars_th)[th_id][eNB_id]->e_rx = (int8_t *)malloc16_clear( 4*2*100*12 ); + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdcch_vars_th)[th_id][eNB_id]->rho = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); (*pdcch_vars_th)[th_id][eNB_id]->dciFormat = 0; (*pdcch_vars_th)[th_id][eNB_id]->agregationLevel = 0xFF; } - + for (i=0; i<fp->nb_antennas_rx; i++) { //ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) ); - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) ); + (*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4) ); } - + for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++) - int idx = (j<<1)+i; - // size_t num = 7*2*fp->N_RB_DL*12; - size_t num = 4*100*12; // 4 symbols, 100 PRBs, 12 REs per PRB - for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); - } + int idx = (j<<1)+i; + // size_t num = 7*2*fp->N_RB_DL*12; + size_t num = 4*100*12; // 4 symbols, 100 PRBs, 12 REs per PRB + + for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + } } } - + // PBCH - pbch_vars[eNB_id]->rxdataF_ext = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) ); - pbch_vars[eNB_id]->rxdataF_comp = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); - pbch_vars[eNB_id]->llr = (int8_t*)malloc16_clear( 1920 ); - prach_vars[eNB_id]->prachF = (int16_t*)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); - prach_vars[eNB_id]->prach = (int16_t*)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); - + pbch_vars[eNB_id]->rxdataF_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); + pbch_vars[eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pbch_vars[eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pbch_vars[eNB_id]->llr = (int8_t *)malloc16_clear( 1920 ); + prach_vars[eNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); + prach_vars[eNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); + for (i=0; i<fp->nb_antennas_rx; i++) { - pbch_vars[eNB_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*6*12*4 ); - + pbch_vars[eNB_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*6*12*4 ); + for (j=0; j<4; j++) {//fp->nb_antennas_tx;j++) { - int idx = (j<<1)+i; - pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*6*12*4 ); - pbch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*6*12*4 ); + int idx = (j<<1)+i; + pbch_vars[eNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*6*12*4 ); + pbch_vars[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*6*12*4 ); } } - - - pbch_vars[eNB_id]->decoded_output = (uint8_t*)malloc16_clear( 64 ); + + pbch_vars[eNB_id]->decoded_output = (uint8_t *)malloc16_clear( 64 ); } // initialization for the last instance of pdsch_vars (used for MU-MIMO) for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { - (*pdsch_vars_th)[th_id][eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); + (*pdsch_vars_th)[th_id][eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); } pdsch_vars_SI[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) ); @@ -942,13 +852,12 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) { phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp ); - (*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); + (*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); } - - ue->sinr_CQI_dB = (double*) malloc16_clear( fp->N_RB_DL*12*sizeof(double) ); - + ue->sinr_CQI_dB = (double *) malloc16_clear( fp->N_RB_DL*12*sizeof(double) ); ue->init_averaging = 1; + // default value until overwritten by RRCConnectionReconfiguration if (fp->nb_antenna_ports_eNB==2) ue->pdsch_config_dedicated->p_a = dBm3; @@ -958,40 +867,30 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, // set channel estimation to do linear interpolation in time ue->high_speed_flag = 1; ue->ch_est_alpha = 24576; - // enable MIB/SIB decoding by default ue->decode_MIB = 1; ue->decode_SIB = 1; - init_prach_tables(839); - - return 0; } void init_lte_ue_transport(PHY_VARS_UE *ue,int abstraction_flag) { - int i,j,k; for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) { for (j=0; j<2; j++) { for (k=0; k<2; k++) { - AssertFatal((ue->dlsch[k][i][j] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n"); - - LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[i][j]); + AssertFatal((ue->dlsch[k][i][j] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n"); + LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[i][j]); } } AssertFatal((ue->ulsch[i] = new_ue_ulsch(ue->frame_parms.N_RB_UL, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n"); - ue->dlsch_SI[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag); ue->dlsch_ra[i] = new_ue_dlsch(1,1,NSOFT,MAX_TURBO_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag); - ue->transmission_mode[i] = ue->frame_parms.nb_antenna_ports_eNB==1 ? 1 : 2; } ue->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1; - ue->dlsch_MCH[0] = new_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_TURBO_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL,0); - } diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index dd8c2e54dba3f4229fae2c3eb9f1e24076364c33..1be5f6d520d65846817ae33d01646983645bc55e 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -33,31 +33,29 @@ #include "phy_init.h" #include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/LTE_TRANSPORT/transport_common_proto.h" - +#include "targets/RT/USER/lte-softmodem.h" extern PHY_VARS_eNB *eNB; extern PHY_VARS_UE *UE; extern RU_t *ru; -extern void phy_init_RU(RU_t*); +extern void phy_init_RU(RU_t *); void lte_param_init(PHY_VARS_eNB **eNBp, - PHY_VARS_UE **UEp, - RU_t **rup, - unsigned char N_tx_port_eNB, + PHY_VARS_UE **UEp, + RU_t **rup, + unsigned char N_tx_port_eNB, unsigned char N_tx_phy, - unsigned char N_rx_ru, + unsigned char N_rx_ru, unsigned char N_rx_ue, - unsigned char transmission_mode, - uint8_t extended_prefix_flag, - frame_t frame_type, - uint16_t Nid_cell, - uint8_t tdd_config, - uint8_t N_RB_DL, - uint8_t pa, - uint8_t threequarter_fs, + unsigned char transmission_mode, + uint8_t extended_prefix_flag, + frame_t frame_type, + uint16_t Nid_cell, + uint8_t tdd_config, + uint8_t N_RB_DL, + uint8_t pa, + uint8_t threequarter_fs, uint8_t osf, - uint32_t perfect_ce) -{ - + uint32_t perfect_ce) { LTE_DL_FRAME_PARMS *frame_parms; int i; PHY_VARS_eNB *eNB; @@ -71,23 +69,16 @@ void lte_param_init(PHY_VARS_eNB **eNBp, UE = *UEp; ru = *rup; printf("eNB %p, UE %p, ru %p\n",eNB,UE,ru); - - - - memset((void*)eNB,0,sizeof(PHY_VARS_eNB)); - memset((void*)UE,0,sizeof(PHY_VARS_UE)); - memset((void*)ru,0,sizeof(RU_t)); - + memset((void *)eNB,0,sizeof(PHY_VARS_eNB)); + memset((void *)UE,0,sizeof(PHY_VARS_UE)); + memset((void *)ru,0,sizeof(RU_t)); ru->eNB_list[0] = eNB; eNB->RU_list[0] = ru; ru->num_eNB=1; - srand(0); randominit(0); 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 frame_parms->N_RB_UL = N_RB_DL; frame_parms->threequarter_fs = threequarter_fs; @@ -106,13 +97,9 @@ void lte_param_init(PHY_VARS_eNB **eNBp, // frame_parms->Bsrs = 0; // frame_parms->kTC = 0;44 // frame_parms->n_RRC = 0; - init_frame_parms(frame_parms,osf); - //copy_lte_parms_to_phy_framing(frame_parms, &(PHY_config->PHY_framing)); - // phy_init_top(frame_parms); //allocation - UE->is_secondary_ue = 0; UE->frame_parms = *frame_parms; UE->frame_parms.nb_antennas_rx=N_rx_ue; @@ -121,14 +108,10 @@ void lte_param_init(PHY_VARS_eNB **eNBp, ru->nb_tx = N_tx_phy; ru->nb_rx = N_rx_ru; ru->if_south = LOCAL_RF; - eNB->configured=1; - eNB->transmission_mode[0] = transmission_mode; UE->transmission_mode[0] = transmission_mode; - dump_frame_parms(frame_parms); - UE->measurements.n_adj_cells=0; UE->measurements.adj_cell_id[0] = Nid_cell+1; UE->measurements.adj_cell_id[1] = Nid_cell+2; @@ -144,7 +127,6 @@ void lte_param_init(PHY_VARS_eNB **eNBp, phy_init_RU(ru); generate_pcfich_reg_mapping(&UE->frame_parms); generate_phich_reg_mapping(&UE->frame_parms); - // DL power control init //if (transmission_mode == 1) { UE->pdsch_config_dedicated->p_a = pa; @@ -166,17 +148,13 @@ void lte_param_init(PHY_VARS_eNB **eNBp, if (eNB->frame_parms.N_RB_DL == 100) ru->N_TA_offset = 624; else if (eNB->frame_parms.N_RB_DL == 50) ru->N_TA_offset = 624/2; else if (eNB->frame_parms.N_RB_DL == 25) ru->N_TA_offset = 624/4; - } - else ru->N_TA_offset=0; + } else ru->N_TA_offset=0; -#if BASIC_SIMULATOR - /* this is required for the basic simulator in TDD mode - * TODO: find a proper cleaner solution - */ - UE->N_TA_offset = 0; -#endif + if (IS_SOFTMODEM_BASICSIM) + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ + UE->N_TA_offset = 0; printf("Done lte_param_init\n"); - - } diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c index 716d9dd626dda46ab7a467f185188873d489fd4c..7083d2388731851003a23f1710edd3e8173a0956 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c @@ -566,6 +566,31 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain } +#ifdef PHY_ABSTRACTION +#include "SIMULATION/TOOLS/defs.h" +#include "SIMULATION/RF/defs.h" +//extern channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX]; + +int lte_sync_time_eNB_emul(PHY_VARS_eNB *phy_vars_eNB, + uint8_t sect_id, + int32_t *sync_val) +{ + + uint8_t UE_id; + uint8_t CC_id = phy_vars_eNB->CC_id; + LOG_E(PHY,"[PHY] EMUL lte_sync_time_eNB_emul eNB %d, sect_id %d\n",phy_vars_eNB->Mod_id,sect_id); + *sync_val = 0; + for (UE_id=0; UE_id<NB_UE_INST; UE_id++) { + //LOG_E(PHY,"[PHY] EMUL : eNB %d checking UE %d (PRACH %d) PL %d dB\n",phy_vars_eNB->Mod_id,UE_id,PHY_vars_UE_g[UE_id]->generate_prach,UE2eNB[UE_id][phy_vars_eNB->Mod_id]->path_loss_dB); + if ((PHY_vars_UE_g[UE_id][CC_id]->generate_prach == 1) && (phy_vars_eNB->Mod_id == (UE_id % NB_eNB_INST))) { + *sync_val = 1; + return(0); + } + } + + return(-1); +} +#endif diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index cb50b7b5d3fcc5495baf34481e1bfdf8aa9df8d7..27807028439b2c8f04269d8366644f1cfb7876c8 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -86,7 +86,7 @@ int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB, int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (eNB->ulsch[UE_id]->ue_type > 0) harq_pid = 0; else #endif diff --git a/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c index a9ddf6d31021510c4ef3c739c90ffa2b61e2f0b5..f78da483de8e7a2dc6aca37c07877a48d0d67da1 100644 --- a/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c +++ b/openair1/PHY/LTE_REFSIG/lte_dl_mbsfn.c @@ -35,30 +35,22 @@ int lte_dl_mbsfn(PHY_VARS_eNB *eNB, int32_t *output, short amp, int subframe, - unsigned char l) -{ - + unsigned char l) { unsigned int mprime,mprime_dword,mprime_qpsk_symb,m; unsigned short k=0,a; int32_t qpsk[4]; - a = (amp*ONE_OVER_SQRT2_Q15)>>15; ((short *)&qpsk[0])[0] = a; ((short *)&qpsk[0])[1] = a; - ((short *)&qpsk[1])[0] = -a; ((short *)&qpsk[1])[1] = a; ((short *)&qpsk[2])[0] = a; ((short *)&qpsk[2])[1] = -a; - ((short *)&qpsk[3])[0] = -a; ((short *)&qpsk[3])[1] = -a; - - mprime = 3*(110 - eNB->frame_parms.N_RB_DL); for (m=0; m<eNB->frame_parms.N_RB_DL*6; m++) { - if ((l==0) || (l==2)) k = m<<1; else if (l==1) @@ -69,7 +61,6 @@ int lte_dl_mbsfn(PHY_VARS_eNB *eNB, int32_t *output, } k+=eNB->frame_parms.first_carrier_offset; - mprime_dword = mprime>>4; mprime_qpsk_symb = mprime&0xf; @@ -80,22 +71,18 @@ int lte_dl_mbsfn(PHY_VARS_eNB *eNB, int32_t *output, output[k] = qpsk[(eNB->lte_gold_mbsfn_table[subframe][l][mprime_dword]>>(2*mprime_qpsk_symb))&3]; //output[k] = (lte_gold_table[eNB_offset][subframe][l][mprime_dword]>>(2*mprime_qpsk_symb))&3; - - #ifdef DEBUG_DL_MBSFN LOG_D(PHY,"subframe %d, l %d, m %d, mprime %d, mprime_dword %d, mprime_qpsk_symbol %d\n", - subframe,l,m,mprime,mprime_dword,mprime_qpsk_symb); + subframe,l,m,mprime,mprime_dword,mprime_qpsk_symb); LOG_D(PHY,"index = %d (k %d)(%x)\n",(eNB->lte_gold_mbsfn_table[subframe][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k,eNB->lte_gold_mbsfn_table[subframe][l][mprime_dword]); #endif mprime++; - #ifdef DEBUG_DL_MBSFN if (m<18) printf("subframe %d, l %d output[%d] = (%d,%d)\n",subframe,l,k,((short *)&output[k])[0],((short *)&output[k])[1]); #endif - } return(0); @@ -106,15 +93,11 @@ int lte_dl_mbsfn(PHY_VARS_eNB *eNB, int32_t *output, int lte_dl_mbsfn_rx(PHY_VARS_UE *ue, int *output, int subframe, - unsigned char l) -{ - + unsigned char l) { unsigned int mprime,mprime_dword,mprime_qpsk_symb,m; unsigned short k=0; unsigned int qpsk[4]; - // This includes complex conjugate for channel estimation - ((short *)&qpsk[0])[0] = ONE_OVER_SQRT2_Q15; ((short *)&qpsk[0])[1] = -ONE_OVER_SQRT2_Q15; ((short *)&qpsk[1])[0] = -ONE_OVER_SQRT2_Q15; @@ -123,23 +106,18 @@ int lte_dl_mbsfn_rx(PHY_VARS_UE *ue, ((short *)&qpsk[2])[1] = ONE_OVER_SQRT2_Q15; ((short *)&qpsk[3])[0] = -ONE_OVER_SQRT2_Q15; ((short *)&qpsk[3])[1] = ONE_OVER_SQRT2_Q15; - mprime = 3*(110 - ue->frame_parms.N_RB_DL); for (m=0; m<ue->frame_parms.N_RB_DL*6; m++) { - mprime_dword = mprime>>4; mprime_qpsk_symb = mprime&0xf; - // this is r_mprime from 3GPP 36-211 6.10.1.2 output[k] = qpsk[(ue->lte_gold_mbsfn_table[subframe][l][mprime_dword]>>(2*mprime_qpsk_symb))&3]; - #ifdef DEBUG_DL_MBSFN - printf("subframe %d, l %d, m %d, mprime %d, mprime_dword %d, mprime_qpsk_symbol %d\n", + printf("subframe %d, l %d, m %u, mprime %u, mprime_dword %u, mprime_qpsk_symbol %u\n", subframe,l,m,mprime, mprime_dword,mprime_qpsk_symb); printf("index = %d (k %d) (%x)\n",(ue->lte_gold_mbsfn_table[subframe][l][mprime_dword]>>(2*mprime_qpsk_symb))&3,k,ue->lte_gold_mbsfn_table[subframe][l][mprime_dword]); #endif - mprime++; #ifdef DEBUG_DL_MBSFN @@ -148,7 +126,6 @@ int lte_dl_mbsfn_rx(PHY_VARS_UE *ue, #endif k++; - } return(0); diff --git a/openair1/PHY/LTE_REFSIG/lte_ul_ref.c b/openair1/PHY/LTE_REFSIG/lte_ul_ref.c index ee7619c23c2bf9479b81a9d8e7b221a2e052e9a2..be090214f8475d28d6a81269c66860205856312d 100644 --- a/openair1/PHY/LTE_REFSIG/lte_ul_ref.c +++ b/openair1/PHY/LTE_REFSIG/lte_ul_ref.c @@ -20,9 +20,9 @@ */ #ifdef MAIN -#include <stdio.h> -#include <stdlib.h> -#include <math.h> + #include <stdio.h> + #include <stdlib.h> + #include <math.h> #endif #include "lte_refsig.h" #include "PHY/defs_eNB.h" @@ -43,8 +43,7 @@ char ref24[720] = { -1,3,1,-3,3,-1,1,3,-3,3,1,3,-3,3,1,1,-1,1,3,-3,3,-3,-1,-3,-3,3,-3,-3,-3,1,-3,-3,3,-1,1,1,1,3,1,-1,3,-3,-3,1,3,1,1,-3,3,-1,3,3,1,1,-3,3,3,3,3,1,-1,3,-1,1,1,-1,-3,-1,-1,1,3,3,-1,-3,1,1,3,-3,1,1,-3,-1,-1,1,3,1,3,1,-1,3,1,1,-3,-1,-3,-1,-1,-1,-1,-3,-3,-1,1,1,3,3,-1,3,-1,1,-1,-3,1,-1,-3,-3,1,-3,-1,-1,-3,1,1,3,-1,1,3,1,-3,1,-3,1,1,-1,-1,3,-1,-3,3,-3,-3,-3,1,1,1,1,-1,-1,3,-3,-3,3,-3,1,-1,-1,1,-1,1,1,-1,-3,-1,1,-1,3,-1,-3,-3,3,3,-1,-1,-3,-1,3,1,3,1,3,1,1,-1,3,1,-1,1,3,-3,-1,-1,1,-3,1,3,-3,1,-1,-3,3,-3,3,-1,-1,-1,-1,1,-3,-3,-3,1,-3,-3,-3,1,-3,1,1,-3,3,3,-1,-3,-1,3,-3,3,3,3,-1,1,1,-3,1,-1,1,1,-3,1,1,-1,1,-3,-3,3,-1,3,-1,-1,-3,-3,-3,-1,-3,-3,1,-1,1,3,3,-1,1,-1,3,1,3,3,-3,-3,1,3,1,-1,-3,-3,-3,3,3,-3,3,3,-1,-3,3,-1,1,-3,1,1,3,3,1,1,1,-1,-1,1,-3,3,-1,1,1,-3,3,3,-1,-3,3,-3,-1,-3,-1,3,-1,-1,-1,-1,-3,-1,3,3,1,-1,1,3,3,3,-1,1,1,-3,1,3,-1,-3,3,-3,-3,3,1,3,1,-3,3,1,3,1,1,3,3,-1,-1,-3,1,-3,-1,3,1,1,3,-1,-1,1,-3,1,3,-3,1,-1,-3,-1,3,1,3,1,-1,-3,-3,-1,-1,-3,-3,-3,-1,-1,-3,3,-1,-1,-1,-1,1,1,-3,3,1,3,3,1,-1,1,-3,1,-3,1,1,-3,-1,1,3,-1,3,3,-1,-3,1,-1,-3,3,3,3,-1,1,1,3,-1,-3,-1,3,-1,-1,-1,1,1,1,1,1,-1,3,-1,-3,1,1,3,-3,1,-3,-1,1,1,-3,-3,3,1,1,-3,1,3,3,1,-1,-3,3,-1,3,3,3,-3,1,-1,1,-1,-3,-1,1,3,-1,3,-3,-3,-1,-3,3,-3,-3,-3,-1,-1,-3,-1,-3,3,1,3,-3,-1,3,-1,1,-1,3,-3,1,-1,-3,-3,1,1,-1,1,-1,1,-1,3,1,-3,-1,1,-1,1,-1,-1,3,3,-3,-1,1,-3,-3,-1,-3,3,1,-1,-3,-1,-3,-3,3,-3,3,-3,-1,1,3,1,-3,1,3,3,-1,-3,-1,-1,-1,-1,3,3,3,1,3,3,-3,1,3,-1,3,-1,3,3,-3,3,1,-1,3,3,1,-1,3,3,-1,-3,3,-3,-1,-1,3,-1,3,-1,-1,1,1,1,1,-1,-1,-3,-1,3,1,-1,1,-1,3,-1,3,1,1,-1,-1,-3,1,1,-3,1,3,-3,1,1,-3,-3,-1,-1,-3,-1,1,3,1,1,-3,-1,-1,-3,3,-3,3,1,-3,3,-3,1,-1,1,-3,1,1,1,-1,-3,3,3,1,1,3,-1,-3,-1,-1,-1,3,1,-3,-3,-1,3,-3,-1,-3,-1,-3,-1,-1,-3,-1,-1,1,-3,-1,-1,1,-1,-3,1,1,-3,1,-3,-3,3,1,1,-1,3,-1,-1,1,1,-1,-1,-3,-1,3,-1,3,-1,1,3,1,-1,3,1,3,-3,-3,1,-1,-1,1,3 }; -void generate_ul_ref_sigs(void) -{ +void generate_ul_ref_sigs(void) { double qbar,phase; unsigned int u,v,Msc_RS,q,m,n; @@ -53,7 +52,7 @@ void generate_ul_ref_sigs(void) for (u=0; u<30; u++) { for (v=0; v<2; v++) { qbar = ref_primes[Msc_RS] * (u+1)/(double)31; - ul_ref_sigs[u][v][Msc_RS] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[Msc_RS]); + ul_ref_sigs[u][v][Msc_RS] = (int16_t *)malloc16(2*sizeof(int16_t)*dftsizes[Msc_RS]); if ((((int)floor(2*qbar))&1) == 0) q = (int)(floor(qbar+.5)) - v; @@ -61,7 +60,7 @@ void generate_ul_ref_sigs(void) q = (int)(floor(qbar+.5)) + v; #ifdef MAIN - printf("Msc_RS %d (%d), u %d, v %d -> q %d (qbar %f)\n",Msc_RS,dftsizes[Msc_RS],u,v,q,qbar); + printf("Msc_RS %u (%d), u %u, v %u -> q %u (qbar %f)\n",Msc_RS,dftsizes[Msc_RS],u,v,q,qbar); #endif for (n=0; n<dftsizes[Msc_RS]; n++) { @@ -89,32 +88,26 @@ void generate_ul_ref_sigs(void) // These are the sequences for RB 1 for (u=0; u<30; u++) { - ul_ref_sigs[u][0][0] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[0]); + ul_ref_sigs[u][0][0] = (int16_t *)malloc16(2*sizeof(int16_t)*dftsizes[0]); for (n=0; n<dftsizes[0]; n++) { ul_ref_sigs[u][0][0][n<<1] =(int16_t)(floor(32767*cos(M_PI*ref12[(u*12) + n]/4))); ul_ref_sigs[u][0][0][1+(n<<1)]=(int16_t)(floor(32767*sin(M_PI*ref12[(u*12) + n]/4))); } - } // These are the sequences for RB 2 for (u=0; u<30; u++) { - ul_ref_sigs[u][0][1] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[1]); + ul_ref_sigs[u][0][1] = (int16_t *)malloc16(2*sizeof(int16_t)*dftsizes[1]); for (n=0; n<dftsizes[1]; n++) { ul_ref_sigs[u][0][1][n<<1] =(int16_t)(floor(32767*cos(M_PI*ref24[(u*24) + n]/4))); ul_ref_sigs[u][0][1][1+(n<<1)]=(int16_t)(floor(32767*sin(M_PI*ref24[(u*24) + n]/4))); } - - - } - } -void generate_ul_ref_sigs_rx(void) -{ +void generate_ul_ref_sigs_rx(void) { double qbar,phase; unsigned int u,v,Msc_RS,q,m,n; @@ -123,7 +116,7 @@ void generate_ul_ref_sigs_rx(void) for (u=0; u<30; u++) { for (v=0; v<2; v++) { qbar = ref_primes[Msc_RS] * (u+1)/(double)31; - ul_ref_sigs_rx[u][v][Msc_RS] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[Msc_RS]); + ul_ref_sigs_rx[u][v][Msc_RS] = (int16_t *)malloc16(2*sizeof(int16_t)*dftsizes[Msc_RS]); if ((((int)floor(2*qbar))&1) == 0) q = (int)(floor(qbar+.5)) - v; @@ -131,7 +124,7 @@ void generate_ul_ref_sigs_rx(void) q = (int)(floor(qbar+.5)) + v; #ifdef MAIN - printf("Msc_RS %d (%d), u %d, v %d -> q %d (qbar %f)\n",Msc_RS,dftsizes[Msc_RS],u,v,q,qbar); + printf("Msc_RS %u (%d), u %u, v %u -> q %u (qbar %f)\n",Msc_RS,dftsizes[Msc_RS],u,v,q,qbar); #endif for (n=0; n<dftsizes[Msc_RS]; n++) { @@ -159,7 +152,7 @@ void generate_ul_ref_sigs_rx(void) // These are the sequences for RB 1 for (u=0; u<30; u++) { - ul_ref_sigs_rx[u][0][0] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[0]); + ul_ref_sigs_rx[u][0][0] = (int16_t *)malloc16(2*sizeof(int16_t)*dftsizes[0]); for (n=0; n<dftsizes[0]; n++) { ul_ref_sigs_rx[u][0][0][n<<1] = (int16_t)(floor(32767*cos(M_PI*ref12[(u*12) + n]/4))); @@ -169,21 +162,17 @@ void generate_ul_ref_sigs_rx(void) // These are the sequences for RB 2 for (u=0; u<30; u++) { - ul_ref_sigs_rx[u][0][1] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[1]); + ul_ref_sigs_rx[u][0][1] = (int16_t *)malloc16(2*sizeof(int16_t)*dftsizes[1]); for (n=0; n<dftsizes[1]; n++) { ul_ref_sigs_rx[u][0][1][n<<1] = (int16_t)(floor(32767*cos(M_PI*ref24[(u*24) + n]/4))); ul_ref_sigs_rx[u][0][1][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref24[(u*24) + n]/4))); } - } - } -void free_ul_ref_sigs(void) -{ - +void free_ul_ref_sigs(void) { unsigned int u,v,Msc_RS; for (Msc_RS=0; Msc_RS<34; Msc_RS++) { @@ -204,9 +193,7 @@ void free_ul_ref_sigs(void) } #ifdef MAIN -main() -{ - +main() { generate_ul_ref_sigs(); generate_ul_ref_sigs_rx(); free_ul_ref_sigs(); diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 6b5863edc96e0acbb620272b0e583f9b2ae0f231..b4b253a297648df6e0dbaa4ae91a358f7e4f9575 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -45,7 +45,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "PHY/LTE_TRANSPORT/transport_extern.h" #include "PHY/LTE_REFSIG/lte_refsig.h" - +#include "targets/RT/USER/lte-softmodem.h" //#define DEBUG_DCI_ENCODING 1 //#define DEBUG_DCI_DECODING 1 //#define DEBUG_PHY @@ -64,63 +64,47 @@ void dci_encoding(uint8_t *a, uint8_t A, uint16_t E, uint8_t *e, - uint16_t rnti) -{ - - + uint16_t rnti) { uint8_t D = (A + 16); uint32_t RCC; uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96]; uint8_t w[3*3*(MAX_DCI_SIZE_BITS+16)]; - #ifdef DEBUG_DCI_ENCODING int32_t i; -#endif - // encode dci - -#ifdef DEBUG_DCI_ENCODING printf("Doing DCI encoding for %d bits, e %p, rnti %x, E %d\n",A,e,rnti,E); #endif - + // encode dci memset((void *)d,LTE_NULL,96); - ccodelte_encode(A,2,a,d+96,rnti); - #ifdef DEBUG_DCI_ENCODING for (i=0; i<16+A; i++) printf("%d : (%d,%d,%d)\n",i,*(d+96+(3*i)),*(d+97+(3*i)),*(d+98+(3*i))); - -#endif - -#ifdef DEBUG_DCI_ENCODING printf("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e); #endif + RCC = sub_block_interleaving_cc(D,d+96,w); - //#ifdef DEBUG_DCI_ENCODING +#ifdef DEBUG_DCI_ENCODING if (E>1000) printf("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e); - //#endif - lte_rate_matching_cc(RCC,E,w,e); - - +#endif + lte_rate_matching_cc(RCC,E,w,e); } uint8_t *generate_dci0(uint8_t *dci, uint8_t *e, uint8_t DCI_LENGTH, - uint16_t coded_bits, - uint16_t rnti) -{ - + uint16_t coded_bits, + uint16_t rnti) { uint8_t dci_flip[8]; +#ifdef DEBUG_DCI_ENCODING - #ifdef DEBUG_DCI_ENCODING - for (int i=0;i<1+((DCI_LENGTH+16)/8);i++) + for (int i=0; i<1+((DCI_LENGTH+16)/8); i++) printf("i %d : %x\n",i,dci[i]); - #endif + +#endif if (DCI_LENGTH<=32) { dci_flip[0] = dci[3]; @@ -129,8 +113,7 @@ uint8_t *generate_dci0(uint8_t *dci, dci_flip[3] = dci[0]; #ifdef DEBUG_DCI_ENCODING printf("DCI => %x,%x,%x,%x\n", - dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3]); - + dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3]); #endif } else { dci_flip[0] = dci[7]; @@ -143,13 +126,12 @@ uint8_t *generate_dci0(uint8_t *dci, dci_flip[7] = dci[0]; #ifdef DEBUG_DCI_ENCODING printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n", - dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3], - dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]); + dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3], + dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]); #endif } dci_encoding(dci_flip,DCI_LENGTH,coded_bits,e,rnti); - return(e+coded_bits); } @@ -160,9 +142,7 @@ uint8_t *generate_dci0(uint8_t *dci, -void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi) -{ - +void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi) { int32_t *wptr,*wptr2,*zptr; uint32_t Mquad = get_nquad(n_symbols_pdcch,frame_parms,mi); uint32_t RCC = (Mquad>>5), ND; @@ -180,7 +160,6 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w Kpi = (RCC<<5); ND = Kpi - Mquad; - k=0; for (col=0; col<32; col++) { @@ -191,12 +170,9 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w if (index>=ND) { for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) { //printf("a %d k %d\n",a,k); - wptr = &wtemp[a][k<<2]; zptr = &z[a][(index-ND)<<2]; - //printf("wptr=%p, zptr=%p\n",wptr,zptr); - wptr[0] = zptr[0]; wptr[1] = zptr[1]; wptr[2] = zptr[2]; @@ -212,9 +188,7 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w // permutation for (i=0; i<Mquad; i++) { - for (a=0; a<frame_parms->nb_antenna_ports_eNB; a++) { - //wptr = &wtemp[a][i<<2]; //wptr2 = &wbar[a][((i+frame_parms->Nid_cell)%Mquad)<<2]; wptr = &wtemp[a][((i+frame_parms->Nid_cell)%Mquad)<<2]; @@ -230,17 +204,13 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, uint8_t subframe, uint8_t *e, - uint32_t length) -{ + uint32_t length) { int i; uint8_t reset; uint32_t x1, x2, s=0; - //LOG_D(PHY, "%s(fp, subframe:%d, e, length:%d)\n", __FUNCTION__, subframe, length); - reset = 1; // x1 is set in lte_gold_generic - x2 = (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 for (i=0; i<length; i++) { @@ -257,16 +227,13 @@ void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, } uint8_t generate_dci_top(uint8_t num_pdcch_symbols, - uint8_t num_dci, + uint8_t num_dci, DCI_ALLOC_t *dci_alloc, uint32_t n_rnti, int16_t amp, LTE_DL_FRAME_PARMS *frame_parms, int32_t **txdataF, - uint32_t subframe) -{ - - + uint32_t subframe) { uint8_t *e_ptr; int8_t L; uint32_t i, lprime; @@ -276,46 +243,42 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, uint8_t e[DCI_BITS_MAX]; uint32_t Msymb=(DCI_BITS_MAX/2); int32_t yseq0[Msymb],yseq1[Msymb],wbar0[Msymb],wbar1[Msymb]; - int32_t *y[2]; int32_t *wbar[2]; - int nushiftmod3 = frame_parms->nushift%3; - int Msymb2; int split_flag=0; switch (frame_parms->N_RB_DL) { - case 100: - Msymb2 = Msymb; - break; + case 100: + Msymb2 = Msymb; + break; - case 75: - Msymb2 = 3*Msymb/4; - break; + case 75: + Msymb2 = 3*Msymb/4; + break; - case 50: - Msymb2 = Msymb>>1; - break; + case 50: + Msymb2 = Msymb>>1; + break; - case 25: - Msymb2 = Msymb>>2; - break; + case 25: + Msymb2 = Msymb>>2; + break; - case 15: - Msymb2 = Msymb*15/100; - break; + case 15: + Msymb2 = Msymb*15/100; + break; - case 6: - Msymb2 = Msymb*6/100; - break; + case 6: + Msymb2 = Msymb*6/100; + break; - default: - Msymb2 = Msymb>>2; - break; + default: + Msymb2 = Msymb>>2; + break; } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PCFICH,1); generate_pcfich(num_pdcch_symbols, amp, @@ -328,42 +291,37 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, y[0] = &yseq0[0]; y[1] = &yseq1[0]; -#if BASIC_SIMULATOR - /* this should be the normal case - * but it has to be validated for all the various cases - * so let's just do it for the basic simulator - */ - memset(e, 2, DCI_BITS_MAX); -#else -#if 1 - // reset all bits to <NIL>, here we set <NIL> elements as 2 - // memset(e, 2, DCI_BITS_MAX); - // here we interpret NIL as a random QPSK sequence. That makes power estimation easier. - for (i=0; i<DCI_BITS_MAX; i++) - e[i]=taus()&1; -#endif - - /* clear all bits, the above code may generate too much false detections - * (not sure about this, to be checked somehow) - */ - //memset(e, 0, DCI_BITS_MAX); -#endif /* BASIC_SIMULATOR */ + if (IS_SOFTMODEM_BASICSIM) { + /* this should be the normal case + * but it has to be validated for all the various cases + * so let's just do it for the basic simulator + */ + // memset(e, 2, DCI_BITS_MAX); + } else { + // reset all bits to <NIL>, here we set <NIL> elements as 2 + // memset(e, 2, DCI_BITS_MAX); + // here we interpret NIL as a random QPSK sequence. That makes power estimation easier. + for (i=0; i<DCI_BITS_MAX; i++) + e[i]=taus()&1; + + /* clear all bits, the above code may generate too much false detections + * (not sure about this, to be checked somehow) + */ + //memset(e, 0, DCI_BITS_MAX); + }/* BASIC_SIMULATOR */ e_ptr = e; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,1); // generate DCIs in order of decreasing aggregation level, then common/ue spec // MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization for (L=8; L>=1; L>>=1) { for (i=0; i<num_dci; i++) { - if (dci_alloc[i].L == (uint8_t)L) { - LOG_D(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x), rnti %x\n", i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L, - *(unsigned int*)dci_alloc[i].dci_pdu, - dci_alloc[i].rnti); + *(unsigned int *)dci_alloc[i].dci_pdu, + dci_alloc[i].rnti); if (dci_alloc[i].firstCCE>=0) { e_ptr = generate_dci0(dci_alloc[i].dci_pdu, @@ -375,14 +333,13 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, } } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,0); // Scrambling #ifdef DEBUG_DCI_ENCODING printf("pdcch scrambling\n"); #endif //LOG_D(PHY, "num_pdcch_symbols:%d mi:%d nquad:%d\n", num_pdcch_symbols, mi, get_nquad(num_pdcch_symbols, frame_parms, mi)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING,1); pdcch_scrambling(frame_parms, subframe, @@ -390,11 +347,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, 8*get_nquad(num_pdcch_symbols, frame_parms, mi)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING,0); //72*get_nCCE(num_pdcch_symbols,frame_parms,mi)); - - - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,1); + // Now do modulation if (frame_parms->nb_antenna_ports_eNB==1) gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15); @@ -402,7 +356,6 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, gain_lin_QPSK = amp/2; e_ptr = e; - #ifdef DEBUG_DCI_ENCODING printf(" PDCCH Modulation, Msymb %d, Msymb2 %d,gain_lin_QPSK %d\n",Msymb,Msymb2,gain_lin_QPSK); #endif @@ -410,91 +363,73 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, //LOG_D(PHY,"%s() Msymb2:%d\n", __FUNCTION__, Msymb2); if (frame_parms->nb_antenna_ports_eNB==1) { //SISO - - for (i=0; i<Msymb2; i++) { - //((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; //((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; - ((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; - ((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; + ((int16_t *)(&(y[0][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; + ((int16_t *)(&(y[1][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; //((int16_t*)(&(y[0][i])))[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; //((int16_t*)(&(y[1][i])))[1] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; - ((int16_t*)(&(y[0][i])))[1] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; - ((int16_t*)(&(y[1][i])))[1] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; - + ((int16_t *)(&(y[0][i])))[1] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; + ((int16_t *)(&(y[1][i])))[1] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; } } else { //ALAMOUTI - - for (i=0; i<Msymb2; i+=2) { - #ifdef DEBUG_DCI_ENCODING printf(" PDCCH Modulation (TX diversity): REG %d\n",i>>2); #endif // first antenna position n -> x0 - ((int16_t*)&y[0][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; + ((int16_t *)&y[0][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; - ((int16_t*)&y[0][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; + ((int16_t *)&y[0][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; - // second antenna position n -> -x1* - ((int16_t*)&y[1][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK; + ((int16_t *)&y[1][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK; e_ptr++; - ((int16_t*)&y[1][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; + ((int16_t *)&y[1][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; e_ptr++; - // fill in the rest of the ALAMOUTI precoding - ((int16_t*)&y[0][i+1])[0] = -((int16_t*)&y[1][i])[0]; - ((int16_t*)&y[0][i+1])[1] = ((int16_t*)&y[1][i])[1]; - ((int16_t*)&y[1][i+1])[0] = ((int16_t*)&y[0][i])[0]; - ((int16_t*)&y[1][i+1])[1] = -((int16_t*)&y[0][i])[1]; - + ((int16_t *)&y[0][i+1])[0] = -((int16_t *)&y[1][i])[0]; + ((int16_t *)&y[0][i+1])[1] = ((int16_t *)&y[1][i])[1]; + ((int16_t *)&y[1][i+1])[0] = ((int16_t *)&y[0][i])[0]; + ((int16_t *)&y[1][i+1])[1] = -((int16_t *)&y[0][i])[1]; } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,0); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,0); #ifdef DEBUG_DCI_ENCODING printf(" PDCCH Interleaving\n"); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING,1); // printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]); // This is the interleaving procedure defined in 36-211, first part of Section 6.8.5 pdcch_interleaving(frame_parms,&y[0],&wbar[0],num_pdcch_symbols,mi); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING,0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,1); mprime=0; nsymb = (frame_parms->Ncp==0) ? 14:12; re_offset = frame_parms->first_carrier_offset; - // This is the REG allocation algorithm from 36-211, second part of Section 6.8.5 // printf("DCI (SF %d) : txdataF %p (0 %p)\n",subframe,&txdataF[0][512*14*subframe],&txdataF[0][0]); #ifdef DEBUG_DCI_ENCODING printf("kprime loop - N_RB_DL:%d lprime:num_pdcch_symbols:%d Ncp:%d pcfich:%02x,%02x,%02x,%02x ofdm_symbol_size:%d first_carrier_offset:%d nb_antenna_ports_eNB:%d\n", - frame_parms->N_RB_DL, num_pdcch_symbols,frame_parms->Ncp, - frame_parms->pcfich_reg[0], - frame_parms->pcfich_reg[1], - frame_parms->pcfich_reg[2], - frame_parms->pcfich_reg[3], - frame_parms->ofdm_symbol_size, - frame_parms->first_carrier_offset, - frame_parms->nb_antenna_ports_eNB - ); + frame_parms->N_RB_DL, num_pdcch_symbols,frame_parms->Ncp, + frame_parms->pcfich_reg[0], + frame_parms->pcfich_reg[1], + frame_parms->pcfich_reg[2], + frame_parms->pcfich_reg[3], + frame_parms->ofdm_symbol_size, + frame_parms->first_carrier_offset, + frame_parms->nb_antenna_ports_eNB + ); #endif + for (kprime=0; kprime<frame_parms->N_RB_DL*12; kprime++) { for (lprime=0; lprime<num_pdcch_symbols; lprime++) { - symbol_offset = (uint32_t)frame_parms->ofdm_symbol_size*(lprime+(subframe*nsymb)); - - - tti_offset = symbol_offset + re_offset; - (re_offset==(frame_parms->ofdm_symbol_size-2)) ? (split_flag=1) : (split_flag=0); // printf("kprime %d, lprime %d => REG %d (symbol %d)\n",kprime,lprime,(lprime==0)?(kprime/6) : (kprime>>2),symbol_offset); @@ -505,16 +440,13 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, #endif } else { // Copy REG to TX buffer - if ((lprime == 0)|| ((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) { // first symbol, or second symbol+4 TX antennas skip pilots - kprime_mod12 = kprime%12; if ((kprime_mod12 == 0) || (kprime_mod12 == 6)) { // kprime represents REG - for (i=0; i<6; i++) { if ((i!=(nushiftmod3))&&(i!=(nushiftmod3+3))) { txdataF[0][tti_offset+i] = wbar[0][mprime]; @@ -523,9 +455,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset+i] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); + printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime])); #endif - mprime++; } } @@ -543,7 +474,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset+i] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); + LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime])); #endif mprime++; } @@ -554,7 +485,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset+0] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); + printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime])); #endif mprime++; txdataF[0][tti_offset+1] = wbar[0][mprime]; @@ -563,7 +494,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset+1] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime])); + printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime])); #endif mprime++; txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[0][mprime]; @@ -572,8 +503,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short*)&wbar[0][mprime], - *(1+(short*)&wbar[0][mprime])); + printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short *)&wbar[0][mprime], + *(1+(short *)&wbar[0][mprime])); #endif mprime++; txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[0][mprime]; @@ -582,11 +513,10 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[1][mprime]; #ifdef DEBUG_DCI_ENCODING - printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short*)&wbar[0][mprime], - *(1+(short*)&wbar[0][mprime])); + printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short *)&wbar[0][mprime], + *(1+(short *)&wbar[0][mprime])); #endif mprime++; - } } } @@ -594,7 +524,6 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, if (mprime>=Msymb2) return(num_pdcch_symbols); } // check_phich_reg - } //lprime loop re_offset++; @@ -602,8 +531,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, if (re_offset == (frame_parms->ofdm_symbol_size)) re_offset = 1; } // kprime loop - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,0); return(num_pdcch_symbols); } diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 36cc48b14467c213548e9ae8a2ee0a0289946c88..29bbd774a1b632594f9fd2490b6ebfa812056142 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -300,7 +300,8 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t dlsch0 = eNB->dlsch[UE_id][0]; dlsch1 = eNB->dlsch[UE_id][1]; - + dlsch0->ue_type = 0; + dlsch1->ue_type = 0; beamforming_mode = eNB->transmission_mode[(uint8_t)UE_id]<7?0:eNB->transmission_mode[(uint8_t)UE_id]; dlsch0_harq = dlsch0->harq_processes[rel8->harq_process]; dlsch0_harq->codeword = 0; @@ -351,7 +352,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t &rel8->resource_block_coding,rel8->resource_block_coding,rel8->rnti,rel8->rnti_type,rel8->dci_format,rel8->harq_process); dci_alloc->format = format1A; - + switch (fp->N_RB_DL) { case 6: if (fp->frame_type == TDD) { @@ -527,7 +528,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t dlsch0->harq_mask |= (1 << rel8->harq_process); - if (rel8->rnti_type == 1) LOG_I(PHY,"DCI 1A: round %d, mcs %d, rballoc %x, rv %d, rnti %x, harq process %d\n",dlsch0_harq->round,rel8->mcs_1,rel8->resource_block_coding,rel8->redundancy_version_1,rel8->rnti,rel8->harq_process); + if (rel8->rnti_type == 1) LOG_D(PHY,"DCI 1A: round %d, mcs %d, TBS %d, rballoc %x, rv %d, rnti %x, harq process %d\n",dlsch0_harq->round,rel8->mcs_1,dlsch0_harq->TBS,rel8->resource_block_coding,rel8->redundancy_version_1,rel8->rnti,rel8->harq_process); break; case NFAPI_DL_DCI_FORMAT_1: @@ -1559,7 +1560,6 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc case 10: // Format 6-1A dci_alloc->format = format6_1A; - dlsch0->active = 1; switch (fp->N_RB_DL) { case 25: @@ -1594,7 +1594,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc ((DCI6_1A_10MHz_t *) dci_pdu)->harq_ack_off = rel13->harq_resource_offset; ((DCI6_1A_10MHz_t *) dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number; - LOG_I(PHY,"Frame %d, Subframe %d : Programming Format 6-1A DCI, type %d, hopping %d, narrowband %d, rballoc %x, mcs %d, rep %d, harq_pid %d, ndi %d, rv %d, TPC %d, srs_req %d, harq_ack_off %d, dci_rep r%d => %x\n", + LOG_D(PHY,"Frame %d, Subframe %d : Programming Format 6-1A DCI, type %d, hopping %d, narrowband %d, rballoc %x, mcs %d, rep %d, harq_pid %d, ndi %d, rv %d, TPC %d, srs_req %d, harq_ack_off %d, dci_rep r%d => %x\n", frame,subframe, ((DCI6_1A_10MHz_t *) dci_pdu)->type, ((DCI6_1A_10MHz_t *) dci_pdu)->hopping, @@ -1630,7 +1630,6 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc break; case 11: // Format 6-1B dci_alloc->format = format6_1B; - dlsch0->active = 1; switch (fp->N_RB_DL) { case 25: @@ -1670,7 +1669,6 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc } case 12: // Format 6-2 dci_alloc->format = format6_2; - dlsch0->active = 1; switch (fp->N_RB_DL) { case 25: dci_alloc->dci_length = sizeof_DCI6_2_5MHz_t; @@ -1719,15 +1717,17 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc } AssertFatal (rel13->harq_process < 8, "ERROR: Format 6_1A: harq_pid=%d >= 8\n", rel13->harq_process); + dlsch0->ue_type = rel13->ce_mode; + dlsch0_harq = dlsch0->harq_processes[rel13->harq_process]; dlsch0_harq->codeword = 0; // printf("DCI: Setting subframe_tx for subframe %d\n",subframe); dlsch0->subframe_tx[(subframe + 2) % 10] = 1; - LOG_I(PHY,"PDSCH : resource_block_coding %x\n",rel13->resource_block_coding); + LOG_D(PHY,"PDSCH : resource_block_coding %x\n",rel13->resource_block_coding); - conv_eMTC_rballoc (rel13->resource_block_coding, - fp->N_RB_DL, + conv_eMTC_rballoc (rel13->resource_block_coding, + fp->N_RB_DL, dlsch0_harq->rb_alloc); dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rel13->resource_block_coding & 31]; // this is the 6PRB RIV @@ -1750,6 +1750,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc if (dlsch0->rnti != rel13->rnti) { // if rnti of dlsch is not the same as in the config, this is a new entry dlsch0_harq->round = 0; dlsch0->harq_mask =0; + printf("*********************** rnti %x => %x, pos %d\n",rel13->rnti,dlsch0->rnti,UE_id); } if ((dlsch0->harq_mask & (1 << rel13->harq_process)) > 0) { if ((rel13->new_data_indicator != dlsch0_harq->ndi)||(dci_alloc->ra_flag==1)) @@ -1767,8 +1768,9 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc else if (rel13->tpc == 0) //N1A_PRB=2, get TBS from table using mcs and nb_rb=2 dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][1]; else if (rel13->tpc == 1) //N1A_PRB=3, get TBS from table using mcs and nb_rb=3 - dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][2]; - LOG_I(PHY,"TBS = %d(%d)\n",dlsch0_harq->TBS,dlsch0_harq->mcs); + dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][2]; + else AssertFatal(1==0,"Don't know how to set TBS (TPC %d)\n",rel13->tpc); + LOG_D(PHY,"fill_mdci_and_dlsch : TBS = %d(%d) %p, %x\n",dlsch0_harq->TBS,dlsch0_harq->mcs,dlsch0,rel13->rnti); } dlsch0->active = 1; dlsch0->harq_mask |= (1 << rel13->harq_process); @@ -1776,11 +1778,11 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dc dlsch0_harq->frame = (subframe >= 8) ? ((frame + 1) & 1023) : frame; dlsch0_harq->subframe = (subframe + 2) % 10; - LOG_I(PHY,"Setting DLSCH harq_ids[%d] to %d\n",dlsch0_harq->subframe,dlsch0->harq_ids[frame%2][dlsch0_harq->subframe]); - dlsch0->harq_ids[frame%2][dlsch0_harq->subframe] = rel13->harq_process; + LOG_D(PHY,"Setting DLSCH UEid %d harq_ids[%d] from %d to %d\n",UE_id,dlsch0_harq->subframe,dlsch0->harq_ids[frame%2][dlsch0_harq->subframe],rel13->harq_process); + dlsch0->harq_ids[dlsch0_harq->frame%2][dlsch0_harq->subframe] = rel13->harq_process; dlsch0_harq->pdsch_start = rel13->start_symbol; - LOG_I(PHY,"Setting DLSCH harq %d round %d to active for %d.%d\n",rel13->harq_process,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe); + LOG_D(PHY,"Setting DLSCH harq %d round %d to active for %d.%d\n",rel13->harq_process,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe); dlsch0->rnti = rel13->rnti; @@ -1968,7 +1970,7 @@ void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int get_narrowband_index(int N_RB_UL,int rb) { - + switch (N_RB_UL) { case 6: // 6 PRBs, N_NB=1, i_0=0 case 25: // 25 PRBs, N_NB=4, i_0=0 @@ -2011,6 +2013,7 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu ulsch->harq_mask |= 1 << harq_pid; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LOG_D(PHY,"Filling ULSCH : ue_type %d, harq_pid %d\n",ulsch->ue_type,harq_pid); ulsch->ue_type = ulsch_pdu->ulsch_pdu_rel13.ue_type; AssertFatal(harq_pid ==0 || ulsch->ue_type == NOCE, "Harq PID is not zero for BL/CE UE\n"); @@ -2115,7 +2118,7 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int get_first_rb_in_narrowband(int N_RB_UL,int rb) { - + switch (N_RB_UL) { case 6: // 6 PRBs, N_NB=1, i_0=0 case 25: // 25 PRBs, N_NB=4, i_0=0 @@ -2236,7 +2239,7 @@ void fill_mpdcch_dci0 (PHY_VARS_eNB * eNB, L1_rxtx_proc_t * proc, mDCI_ALLOC_t * ((DCI6_0A_10MHz_t *) dci_pdu)->csi_req = cqi_req; ((DCI6_0A_10MHz_t *) dci_pdu)->srs_req = rel13->srs_request; ((DCI6_0A_10MHz_t *) dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number; - LOG_I(PHY,"Frame %d, Subframe %d : Programming Format 6-0A DCI, type %d, hopping %d, narrowband %d, rballoc %x, mcs %d, rep %d, harq_pid %d, ndi %d, rv %d, TPC %d, csi_req %d, srs_req %d, dci_rep r%d => %x\n", + LOG_D(PHY,"Frame %d, Subframe %d : Programming Format 6-0A DCI, type %d, hopping %d, narrowband %d, rballoc %x, mcs %d, rep %d, harq_pid %d, ndi %d, rv %d, TPC %d, csi_req %d, srs_req %d, dci_rep r%d => %x\n", proc->frame_tx,proc->subframe_tx, ((DCI6_0A_10MHz_t *) dci_pdu)->type, ((DCI6_0A_10MHz_t *) dci_pdu)->hopping, @@ -2287,6 +2290,3 @@ void fill_mpdcch_dci0 (PHY_VARS_eNB * eNB, L1_rxtx_proc_t * proc, mDCI_ALLOC_t * } } #endif - - - diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c index dbf5814f30ef2366ddcc6dbf930c8ca69999f7b9..583d12eedb4a6d86f99e4ec9bbddcc4f0fc80b6e 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c @@ -367,11 +367,11 @@ void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t if ((rb_alloc&(1<<i)) != 0) rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32)); } - + // bit mask across if ((rb_alloc2[0]>>31)==1) rb_alloc2[1] |= 1; - + if ((rb_alloc&1) != 0) rb_alloc2[1] |= (3<<16); } @@ -385,7 +385,7 @@ void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t for (i=0; i<25; i++) { if ((rb_alloc&(1<<(24-i))) != 0) rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32)); - + // printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i)); } } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 3331ba50c357ffbb7c6567c2001aa0e269958e50..b44a04eb742488b2dc599ba83997619987630d41 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -53,71 +53,73 @@ */ #define is_not_pilot(pilots,first_pilot,re) (1) /*extern void thread_top_init(char *thread_name, - int affinity, - uint64_t runtime, - uint64_t deadline, - uint64_t period);*/ + int affinity, + uint64_t runtime, + uint64_t deadline, + uint64_t period);*/ extern WORKER_CONF_t get_thread_worker_conf(void); -void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) -{ +void free_eNB_dlsch(LTE_eNB_DLSCH_t *dlsch) { int i, r, aa, layer; if (dlsch) { for (layer=0; layer<4; layer++) { for (aa=0; aa<64; aa++) free16(dlsch->ue_spec_bf_weights[layer][aa], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t)); - free16(dlsch->ue_spec_bf_weights[layer], 64*sizeof(int32_t*)); + + free16(dlsch->ue_spec_bf_weights[layer], 64*sizeof(int32_t *)); } + for (i=0; i<dlsch->Mdlharq; i++) { if (dlsch->harq_processes[i]) { if (dlsch->harq_processes[i]->b) { free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); dlsch->harq_processes[i]->b = NULL; } + for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) { if (dlsch->harq_processes[i]->c[r]) { free16(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); dlsch->harq_processes[i]->c[r] = NULL; } + if (dlsch->harq_processes[i]->d[r]) { free16(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144))); dlsch->harq_processes[i]->d[r] = NULL; } - } - free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t)); - dlsch->harq_processes[i] = NULL; + } + + free16(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t)); + dlsch->harq_processes[i] = NULL; } } + free16(dlsch,sizeof(LTE_eNB_DLSCH_t)); - dlsch = NULL; } } -LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS* frame_parms) -{ - +LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_t Nsoft,unsigned char N_RB_DL, uint8_t abstraction_flag, LTE_DL_FRAME_PARMS *frame_parms) { LTE_eNB_DLSCH_t *dlsch; unsigned char exit_flag = 0,i,j,r,aa,layer; int re; unsigned char bw_scaling =1; switch (N_RB_DL) { - case 6: - bw_scaling =16; - break; + case 6: + bw_scaling =16; + break; - case 25: - bw_scaling =4; - break; + case 25: + bw_scaling =4; + break; - case 50: - bw_scaling =2; - break; + case 50: + bw_scaling =2; + break; - default: - bw_scaling =1; - break; + default: + bw_scaling =1; + break; } dlsch = (LTE_eNB_DLSCH_t *)malloc16(sizeof(LTE_eNB_DLSCH_t)); @@ -128,15 +130,16 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ dlsch->Mdlharq = Mdlharq; dlsch->Mlimit = 8; dlsch->Nsoft = Nsoft; - + for (layer=0; layer<4; layer++) { - dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*)); - + dlsch->ue_spec_bf_weights[layer] = (int32_t **)malloc16(64*sizeof(int32_t *)); + for (aa=0; aa<64; aa++) { - dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t)); - for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) { - dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff; - } + dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t)); + + for (re=0; re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) { + dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff; + } } } @@ -159,7 +162,7 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ if (dlsch->harq_processes[i]) { bzero(dlsch->harq_processes[i],sizeof(LTE_DL_eNB_HARQ_t)); // dlsch->harq_processes[i]->first_tx=1; - dlsch->harq_processes[i]->b = (unsigned char*)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); + dlsch->harq_processes[i]->b = (unsigned char *)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); if (dlsch->harq_processes[i]->b) { bzero(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); @@ -171,14 +174,16 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ if (abstraction_flag==0) { for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) { // account for filler in first segment and CRCs for multiple segment case - dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+ 768); - dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16((96+12+3+(3*6144))); + dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(((r==0)?8:0) + 3+ 768); + dlsch->harq_processes[i]->d[r] = (uint8_t *)malloc16((96+12+3+(3*6144))); + if (dlsch->harq_processes[i]->c[r]) { bzero(dlsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+ 768); } else { printf("Can't get c\n"); exit_flag=2; } + if (dlsch->harq_processes[i]->d[r]) { bzero(dlsch->harq_processes[i]->d[r],(96+12+3+(3*6144))); } else { @@ -197,13 +202,12 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ for (i=0; i<Mdlharq; i++) { dlsch->harq_processes[i]->round=0; - for (j=0; j<96; j++) - for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) { - // printf("dlsch->harq_processes[%d]->d[%d] %p\n",i,r,dlsch->harq_processes[i]->d[r]); - if (dlsch->harq_processes[i]->d[r]) - dlsch->harq_processes[i]->d[r][j] = LTE_NULL; - } - + for (j=0; j<96; j++) + for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) { + // printf("dlsch->harq_processes[%d]->d[%d] %p\n",i,r,dlsch->harq_processes[i]->d[r]); + if (dlsch->harq_processes[i]->d[r]) + dlsch->harq_processes[i]->d[r][j] = LTE_NULL; + } } return(dlsch); @@ -211,16 +215,12 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_ } LOG_D(PHY,"new_eNB_dlsch exit flag %d, size of %ld\n", - exit_flag, sizeof(LTE_eNB_DLSCH_t)); + exit_flag, sizeof(LTE_eNB_DLSCH_t)); free_eNB_dlsch(dlsch); return(NULL); - - } -void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) -{ - +void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) { unsigned char Mdlharq; unsigned char i,j,r; @@ -228,8 +228,10 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) Mdlharq = dlsch->Mdlharq; dlsch->rnti = 0; #ifdef PHY_TX_THREAD + for (i=0; i<10; i++) dlsch->active[i] = 0; + #else dlsch->active = 0; #endif @@ -244,11 +246,10 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) dlsch->harq_processes[i]->status = 0; dlsch->harq_processes[i]->round = 0; - for (j=0; j<96; j++) - for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) - if (dlsch->harq_processes[i]->d[r]) - dlsch->harq_processes[i]->d[r][j] = LTE_NULL; - + for (j=0; j<96; j++) + for (r=0; r<MAX_NUM_DLSCH_SEGMENTS; r++) + if (dlsch->harq_processes[i]->d[r]) + dlsch->harq_processes[i]->d[r][j] = LTE_NULL; } } } @@ -258,31 +259,24 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch) int dlsch_encoding_2threads0(te_params *tep) { - LTE_eNB_DLSCH_t *dlsch = tep->dlsch; unsigned int G = tep->G; unsigned char harq_pid = tep->harq_pid; unsigned int total_worker = tep->total_worker; unsigned int current_worker = tep->current_worker; - unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; unsigned int Kr=0,Kr_bytes,r,r_offset=0; // unsigned short m=dlsch->harq_processes[harq_pid]->mcs; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_IN); if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet - for (r=(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*current_worker; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) { - if (r<dlsch->harq_processes[harq_pid]->Cminus) Kr = dlsch->harq_processes[harq_pid]->Kminus; else Kr = dlsch->harq_processes[harq_pid]->Kplus; Kr_bytes = Kr>>3; - encoder(dlsch->harq_processes[harq_pid]->c[r], Kr>>3, &dlsch->harq_processes[harq_pid]->d[r][96], @@ -293,25 +287,24 @@ int dlsch_encoding_2threads0(te_params *tep) { &dlsch->harq_processes[harq_pid]->d[r][96], dlsch->harq_processes[harq_pid]->w[r]); } - } // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the // outputs for each code segment, see Section 5.1.5 p.20 for (r=0,r_offset=0; r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker+1); r++) { - if(r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker)){ - int Nl=dlsch->harq_processes[harq_pid]->Nl; + if(r<(dlsch->harq_processes[harq_pid]->C/(total_worker+1))*(current_worker)) { + int Nl=dlsch->harq_processes[harq_pid]->Nl; int Qm=dlsch->harq_processes[harq_pid]->Qm; int C = dlsch->harq_processes[harq_pid]->C; int Gp = G/Nl/Qm; int GpmodC = Gp%C; + if (r < (C-(GpmodC))) - r_offset += Nl*Qm * (Gp/C); + r_offset += Nl*Qm * (Gp/C); else - r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); - } - else{ + r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); + } else { r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], G, //G dlsch->harq_processes[harq_pid]->w[r], @@ -330,7 +323,6 @@ int dlsch_encoding_2threads0(te_params *tep) { } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING_W, VCD_FUNCTION_OUT); - return(0); } @@ -339,19 +331,16 @@ extern int oai_exit; void *te_thread(void *param) { cpu_set_t cpuset; CPU_ZERO(&cpuset); - thread_top_init("te_thread",1,200000,250000,500000); pthread_setname_np( pthread_self(),"te processing"); LOG_I(PHY,"thread te created id=%ld\n", syscall(__NR_gettid)); - - te_params *tep = (te_params *)param; - + //wait_sync("te_thread"); - - while (!oai_exit) { + while (!oai_exit) { if (wait_on_condition(&tep->mutex_te,&tep->cond_te,&tep->instance_cnt_te,"te thread")<0) break; + if(oai_exit) break; dlsch_encoding_2threads0(tep); @@ -363,6 +352,7 @@ void *te_thread(void *param) { exit_fun( "ERROR pthread_cond_signal" ); return(NULL); } + /*if(opp_enabled == 1 && te_wakeup_stats0->p_time>50*3000){ print_meas_now(te_wakeup_stats0,"coding_wakeup",stderr); printf("te_thread0 delay for waking up in frame_rx: %d subframe_rx: %d \n",proc->frame_rx,proc->subframe_rx); @@ -375,61 +365,56 @@ void *te_thread(void *param) { int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, - unsigned char *a, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe, - time_stats_t *rm_stats, - time_stats_t *te_stats, - time_stats_t *te_wait_stats, - time_stats_t *te_main_stats, - time_stats_t *te_wakeup_stats0, - time_stats_t *te_wakeup_stats1, - time_stats_t *i_stats, - int worker_num) -{ - + unsigned char *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *te_wait_stats, + time_stats_t *te_main_stats, + time_stats_t *te_wakeup_stats0, + time_stats_t *te_wakeup_stats1, + time_stats_t *i_stats, + int worker_num) { //start_meas(&eNB->dlsch_turbo_encoding_preperation_stats); - LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; L1_proc_t *proc = &eNB->proc; unsigned int G; unsigned int crc=1; - unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe]; + if(harq_pid >= dlsch->Mdlharq) { LOG_E(PHY,"dlsch_encoding_2threads illegal harq_pid %d\n", harq_pid); return(-1); } + unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; unsigned int A; unsigned char mod_order; unsigned int Kr=0,Kr_bytes,r,r_offset=0; // unsigned short m=dlsch->harq_processes[harq_pid]->mcs; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); - A = dlsch->harq_processes[harq_pid]->TBS; //6228 mod_order = dlsch->harq_processes[harq_pid]->Qm; - G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0); + G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe, + dlsch->harq_processes[harq_pid]->mimo_mode==TM7?7:0); if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet - start_meas(&eNB->dlsch_turbo_encoding_preperation_stats); // Add 24-bit crc (polynomial A) to payload crc = crc24a(a, A)>>8; stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats); - a[A>>3] = ((uint8_t*)&crc)[2]; - a[1+(A>>3)] = ((uint8_t*)&crc)[1]; - a[2+(A>>3)] = ((uint8_t*)&crc)[0]; - + a[A>>3] = ((uint8_t *)&crc)[2]; + a[1+(A>>3)] = ((uint8_t *)&crc)[1]; + a[2+(A>>3)] = ((uint8_t *)&crc)[0]; dlsch->harq_processes[harq_pid]->B = A+24; memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); //stop_meas(&eNB->dlsch_turbo_encoding_preperation_stats); - start_meas(&eNB->dlsch_turbo_encoding_segmentation_stats); + if (lte_segmentation(dlsch->harq_processes[harq_pid]->b, dlsch->harq_processes[harq_pid]->c, dlsch->harq_processes[harq_pid]->B, @@ -442,48 +427,46 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, return(-1); stop_meas(&eNB->dlsch_turbo_encoding_segmentation_stats); - start_meas(&eNB->dlsch_turbo_encoding_signal_stats); - for(int i=0;i<worker_num;i++) - { + + for(int i=0; i<worker_num; i++) { proc->tep[i].eNB = eNB; proc->tep[i].dlsch = dlsch; proc->tep[i].G = G; proc->tep[i].harq_pid = harq_pid; proc->tep[i].total_worker = worker_num; proc->tep[i].current_worker = i; - pthread_mutex_lock( &proc->tep[i].mutex_te ); + if (proc->tep[i].instance_cnt_te==0) { printf("[eNB] TE thread busy\n"); exit_fun("TE thread busy"); pthread_mutex_unlock( &proc->tep[i].mutex_te ); return(-1); } - + ++proc->tep[i].instance_cnt_te; - + // wakeup worker to do segments if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) { printf("[eNB] ERROR pthread_cond_signal for te thread %d exit\n",i); exit_fun( "ERROR pthread_cond_signal" ); return (-1); } - + pthread_mutex_unlock( &proc->tep[i].mutex_te ); } stop_meas(&eNB->dlsch_turbo_encoding_signal_stats); start_meas(te_main_stats); - for (r=(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num; r<dlsch->harq_processes[harq_pid]->C; r++) { + for (r=(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num; r<dlsch->harq_processes[harq_pid]->C; r++) { if (r<dlsch->harq_processes[harq_pid]->Cminus) Kr = dlsch->harq_processes[harq_pid]->Kminus; else Kr = dlsch->harq_processes[harq_pid]->Kplus; Kr_bytes = Kr>>3; - start_meas(te_stats); encoder(dlsch->harq_processes[harq_pid]->c[r], Kr>>3, @@ -491,7 +474,6 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, (r==0) ? dlsch->harq_processes[harq_pid]->F : 0 ); stop_meas(te_stats); - start_meas(i_stats); dlsch->harq_processes[harq_pid]->RTC[r] = sub_block_interleaving_turbo(4+(Kr_bytes*8), @@ -499,17 +481,14 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, dlsch->harq_processes[harq_pid]->w[r]); stop_meas(i_stats); } - - } - else { - - for(int i=0;i<worker_num;i++) - { + } else { + for(int i=0; i<worker_num; i++) { proc->tep[i].eNB = eNB; proc->tep[i].dlsch = dlsch; proc->tep[i].G = G; proc->tep[i].total_worker = worker_num; proc->tep[i].current_worker = i; + if (pthread_cond_signal(&proc->tep[i].cond_te) != 0) { printf("[eNB] ERROR pthread_cond_signal for te thread exit\n"); exit_fun( "ERROR pthread_cond_signal" ); @@ -521,7 +500,6 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the // outputs for each code segment, see Section 5.1.5 p.20 for (r=0,r_offset=0; r<dlsch->harq_processes[harq_pid]->C; r++) { - // get information for E for the segments that are handled by the worker thread if (r<(dlsch->harq_processes[harq_pid]->C/(worker_num+1))*worker_num) { int Nl=dlsch->harq_processes[harq_pid]->Nl; @@ -529,209 +507,188 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, int C = dlsch->harq_processes[harq_pid]->C; int Gp = G/Nl/Qm; int GpmodC = Gp%C; + if (r < (C-(GpmodC))) - r_offset += Nl*Qm * (Gp/C); + r_offset += Nl*Qm * (Gp/C); else - r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); - } - else { + r_offset += Nl*Qm * ((GpmodC==0?0:1) + (Gp/C)); + } else { start_meas(rm_stats); r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], - G, //G - dlsch->harq_processes[harq_pid]->w[r], - dlsch->harq_processes[harq_pid]->e+r_offset, - dlsch->harq_processes[harq_pid]->C, // C - dlsch->Nsoft, // Nsoft, - dlsch->Mdlharq, - dlsch->Kmimo, - dlsch->harq_processes[harq_pid]->rvidx, - dlsch->harq_processes[harq_pid]->Qm, - dlsch->harq_processes[harq_pid]->Nl, - r, - nb_rb); - // m); // r + G, //G + dlsch->harq_processes[harq_pid]->w[r], + dlsch->harq_processes[harq_pid]->e+r_offset, + dlsch->harq_processes[harq_pid]->C, // C + dlsch->Nsoft, // Nsoft, + dlsch->Mdlharq, + dlsch->Kmimo, + dlsch->harq_processes[harq_pid]->rvidx, + dlsch->harq_processes[harq_pid]->Qm, + dlsch->harq_processes[harq_pid]->Nl, + r, + nb_rb); + // m); // r stop_meas(rm_stats); } } - stop_meas(te_main_stats); + stop_meas(te_main_stats); start_meas(te_wait_stats); - if(worker_num == 1) - { + + if(worker_num == 1) { wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0"); - } - else if(worker_num == 2) - { + } else if(worker_num == 2) { wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0"); wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1"); - } - else - { + } else { wait_on_busy_condition(&proc->tep[0].mutex_te,&proc->tep[0].cond_te,&proc->tep[0].instance_cnt_te,"te thread 0"); wait_on_busy_condition(&proc->tep[1].mutex_te,&proc->tep[1].cond_te,&proc->tep[1].instance_cnt_te,"te thread 1"); wait_on_busy_condition(&proc->tep[2].mutex_te,&proc->tep[2].cond_te,&proc->tep[2].instance_cnt_te,"te thread 2"); } + stop_meas(te_wait_stats); - /*if(opp_enabled == 1 && te_wait_stats->p_time>100*3000){ print_meas_now(te_wait_stats,"coding_wait",stderr); - printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx); + printf("coding delay in wait on codition in frame_rx: %d \n",proc->frame_rx); }*/ - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); - return(0); } int dlsch_encoding_all(PHY_VARS_eNB *eNB, - unsigned char *a, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe, - time_stats_t *rm_stats, - time_stats_t *te_stats, - time_stats_t *te_wait_stats, - time_stats_t *te_main_stats, - time_stats_t *te_wakeup_stats0, - time_stats_t *te_wakeup_stats1, - time_stats_t *i_stats) -{ - int encoding_return = 0; - unsigned int L,C,B; - B = dlsch->harq_processes[dlsch->harq_ids[frame%2][subframe]]->B; - if(B<=6144) - { - L=0; - C=1; - } - else - { - L=24; - C = B/(6144-L); - if((6144-L)*C < B) - { - C = C+1; - } - } - - - if(get_thread_worker_conf() == WORKER_ENABLE) - { - if(C >= 8)//one main three worker - { - encoding_return = - dlsch_encoding_2threads(eNB, - a, - num_pdcch_symbols, - dlsch, - frame, - subframe, - rm_stats, - te_stats, - te_wait_stats, - te_main_stats, - te_wakeup_stats0, - te_wakeup_stats1, - i_stats, - 3); - } - else if(C >= 6)//one main two worker - { - encoding_return = - dlsch_encoding_2threads(eNB, - a, - num_pdcch_symbols, - dlsch, - frame, - subframe, - rm_stats, - te_stats, - te_wait_stats, - te_main_stats, - te_wakeup_stats0, - te_wakeup_stats1, - i_stats, - 2); - } - else if(C >= 4)//one main one worker - { - encoding_return = - dlsch_encoding_2threads(eNB, - a, - num_pdcch_symbols, - dlsch, - frame, - subframe, - rm_stats, - te_stats, - te_wait_stats, - te_main_stats, - te_wakeup_stats0, - te_wakeup_stats1, - i_stats, - 1); - } - else - { - encoding_return = - dlsch_encoding(eNB, - a, - num_pdcch_symbols, - dlsch, - frame, - subframe, - rm_stats, - te_stats, - i_stats); - } + unsigned char *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *te_wait_stats, + time_stats_t *te_main_stats, + time_stats_t *te_wakeup_stats0, + time_stats_t *te_wakeup_stats1, + time_stats_t *i_stats) { + int encoding_return = 0; + unsigned int L,C,B; + B = dlsch->harq_processes[dlsch->harq_ids[frame%2][subframe]]->B; + + LOG_D(PHY,"B %d, harq_pid %d\n",B,dlsch->harq_ids[frame%2][subframe]); + + if(B<=6144) { + L=0; + C=1; + } else { + L=24; + C = B/(6144-L); + + if((6144-L)*C < B) { + C = C+1; } - else - { - encoding_return = - dlsch_encoding(eNB, - a, - num_pdcch_symbols, - dlsch, - frame, - subframe, - rm_stats, - te_stats, - i_stats); + } + + if(get_thread_worker_conf() == WORKER_ENABLE) { + if(C >= 8) { //one main three worker + encoding_return = + dlsch_encoding_2threads(eNB, + a, + num_pdcch_symbols, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + te_wait_stats, + te_main_stats, + te_wakeup_stats0, + te_wakeup_stats1, + i_stats, + 3); + } else if(C >= 6) { //one main two worker + encoding_return = + dlsch_encoding_2threads(eNB, + a, + num_pdcch_symbols, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + te_wait_stats, + te_main_stats, + te_wakeup_stats0, + te_wakeup_stats1, + i_stats, + 2); + } else if(C >= 4) { //one main one worker + encoding_return = + dlsch_encoding_2threads(eNB, + a, + num_pdcch_symbols, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + te_wait_stats, + te_main_stats, + te_wakeup_stats0, + te_wakeup_stats1, + i_stats, + 1); + } else { + encoding_return = + dlsch_encoding(eNB, + a, + num_pdcch_symbols, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + i_stats); } - return encoding_return; + } else { + encoding_return = + dlsch_encoding(eNB, + a, + num_pdcch_symbols, + dlsch, + frame, + subframe, + rm_stats, + te_stats, + i_stats); + } + + return encoding_return; } int dlsch_encoding(PHY_VARS_eNB *eNB, - unsigned char *a, + unsigned char *a, uint8_t num_pdcch_symbols, LTE_eNB_DLSCH_t *dlsch, int frame, uint8_t subframe, time_stats_t *rm_stats, time_stats_t *te_stats, - time_stats_t *i_stats) -{ - + time_stats_t *i_stats) { unsigned int G; unsigned int crc=1; - LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe]; + if(harq_pid >= dlsch->Mdlharq) { LOG_E(PHY,"dlsch_encoding illegal harq_pid %d\n", harq_pid); return(-1); } + unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; unsigned int A; unsigned char mod_order; unsigned int Kr=0,Kr_bytes,r,r_offset=0; // unsigned short m=dlsch->harq_processes[harq_pid]->mcs; uint8_t beamforming_mode=0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); - A = dlsch->harq_processes[harq_pid]->TBS; //6228 // printf("Encoder: A: %d\n",A); mod_order = dlsch->harq_processes[harq_pid]->Qm; @@ -742,13 +699,13 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, beamforming_mode = 8; else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10) beamforming_mode = 9; - G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode); + G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode); // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet #ifdef DEBUG_DLSCH_CODING - printf("encoding thinks this is a new packet for harq_pid %d (%p) \n",harq_pid,dlsch->harq_processes[harq_pid]->b); + printf("encoding thinks this is a new packet for harq_pid %d (%p), A %u \n",harq_pid,dlsch,A); #endif /* int i; @@ -758,14 +715,12 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, printf("\n"); */ // Add 24-bit crc (polynomial A) to payload - crc = crc24a(a, A)>>8; - a[A>>3] = ((uint8_t*)&crc)[2]; - a[1+(A>>3)] = ((uint8_t*)&crc)[1]; - a[2+(A>>3)] = ((uint8_t*)&crc)[0]; + a[A>>3] = ((uint8_t *)&crc)[2]; + a[1+(A>>3)] = ((uint8_t *)&crc)[1]; + a[2+(A>>3)] = ((uint8_t *)&crc)[0]; // printf("CRC %x (A %d)\n",crc,A); - dlsch->harq_processes[harq_pid]->B = A+24; // dlsch->harq_processes[harq_pid]->b = a; memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); @@ -782,25 +737,20 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, return(-1); for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { - if (r<dlsch->harq_processes[harq_pid]->Cminus) Kr = dlsch->harq_processes[harq_pid]->Kminus; else Kr = dlsch->harq_processes[harq_pid]->Kplus; Kr_bytes = Kr>>3; - #ifdef DEBUG_DLSCH_CODING - printf("Generating Code Segment %d (%d bits)\n",r,Kr); + printf("Generating Code Segment %u (%u bits)\n",r,Kr); // generate codewords - - printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A); + printf("bits_per_codeword (Kr)= %u, A %u\n",Kr,A); printf("N_RB = %d\n",nb_rb); printf("Ncp %d\n",frame_parms->Ncp); printf("mod_order %d\n",mod_order); #endif - - start_meas(te_stats); encoder(dlsch->harq_processes[harq_pid]->c[r], Kr>>3, @@ -821,7 +771,6 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, dlsch->harq_processes[harq_pid]->w[r]); stop_meas(i_stats); } - } // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the @@ -829,16 +778,15 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { #ifdef DEBUG_DLSCH_CODING - printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", - r, - G, - Kr*3, - mod_order,nb_rb); + printf("Rate Matching, Code segment %u (coded bits (G) %u,unpunctured/repeated bits per code segment %u,mod_order %d, nb_rb %d)...\n", + r, + G, + Kr*3, + mod_order,nb_rb); #endif - start_meas(rm_stats); #ifdef DEBUG_DLSCH_CODING - printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx); + printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx); #endif r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r], G, //G @@ -853,7 +801,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, dlsch->harq_processes[harq_pid]->Nl, r, nb_rb); - // m); // r + // m); // r stop_meas(rm_stats); #ifdef DEBUG_DLSCH_CODING @@ -864,7 +812,6 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); - return(0); } diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index bfdcdc1e94694f0f549e3ed885db322baef8bd2f..e8b56f3bdfe99292b3a5db85d91b5d99f1fba697 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -1960,6 +1960,10 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, case 4: //16QAM + if (qam_table_s == NULL) { + LOG_E(PHY,"qam table pointer is NULL\n"); + return -1; + } qam16_table_offset_re = 0; qam16_table_offset_im = 0; @@ -2029,7 +2033,9 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF, ((int16_t *)&txdataF[4][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15); break; - + default: + LOG_E(PHY,"Invalid modulation order %i_n",mod_order); + break; } } diff --git a/openair1/PHY/LTE_TRANSPORT/edci.c b/openair1/PHY/LTE_TRANSPORT/edci.c index 41016bdb6574b29234f0bac622bdb60fd3c30861..0df94e55e55e52698607f22c30f37ab28d014c0e 100644 --- a/openair1/PHY/LTE_TRANSPORT/edci.c +++ b/openair1/PHY/LTE_TRANSPORT/edci.c @@ -84,7 +84,7 @@ void mpdcch_scrambling(LTE_DL_FRAME_PARMS * frame_parms, mDCI_ALLOC_t * mdci, ui // rule for BL/CE UEs from Section 6.8.B2 in 36.211 x2 = ((((j0 + j) * Nacc) % 10) << 9) + mdci->dmrs_scrambling_init; - LOG_I(PHY,"MPDCCH cinit = %x (mdci->dmrs_scrambling_init = %d), scrambling %d encoded DCI bits\n", + LOG_D(PHY,"MPDCCH cinit = %x (mdci->dmrs_scrambling_init = %d), scrambling %d encoded DCI bits\n", x2,mdci->dmrs_scrambling_init,length); for (n = 0; n < length; n++) { if ((n & 0x1f) == 0) { @@ -109,17 +109,16 @@ void init_mpdcch5ss1tab_normal_regular_subframe_evenNRBDL(PHY_VARS_eNB * eNB) { int l, k, kmod, re=0; - LOG_I(PHY, "Inititalizing mpdcchss15tab for normal prefix, normal prefix, no PSS/SSS/PBCH, even N_RB_DL\n"); + LOG_D(PHY, "Inititalizing mpdcchss15tab for normal prefix, normal prefix, no PSS/SSS/PBCH, even N_RB_DL\n"); for (l = 1; l < 14; l++) { for (k = 0; k < 72; k++) { kmod = k % 12; if (((l != 5) && (l != 6) && (l != 12) && (l != 13)) || (kmod == 2) || (kmod == 3) || (kmod == 4) || (kmod == 7) || (kmod == 8) || (kmod == 9)) { - mpdcch5ss1tab[re] = (l * eNB->frame_parms.ofdm_symbol_size) + k; - re++; - printf("l %d, k %d (kmod %d) => re %d\n", l, k, kmod, re); + mpdcch5ss1tab[re] = (l * eNB->frame_parms.ofdm_symbol_size) + k; + re++; } else if ((kmod == 0) || (kmod == 5) || (kmod == 10)) { - mpdcch5ss1tab[re++] = (l * eNB->frame_parms.ofdm_symbol_size) + k; + mpdcch5ss1tab[re++] = (l * eNB->frame_parms.ofdm_symbol_size) + k; } } } @@ -139,7 +138,7 @@ void init_mpdcch5ss2tab_normal_regular_subframe_evenNRBDL(PHY_VARS_eNB * eNB) int nushift = eNB->frame_parms.Nid_cell % 6; int nushiftp3 = (eNB->frame_parms.Nid_cell+3) % 6; // NOTE : THIS IS FOR TM1 ONLY FOR NOW!!!!!!! - LOG_I(PHY, "Inititalizing mpdcch5ss2tab for normal prefix, normal prefix, no PSS/SSS/PBCH, even N_RB_DL\n"); + LOG_D(PHY, "Inititalizing mpdcch5ss2tab for normal prefix, normal prefix, no PSS/SSS/PBCH, even N_RB_DL\n"); for (l = 2; l < 14; l++) { for (k = 0; k < 72; k++) { kmod = k % 12; @@ -168,7 +167,7 @@ void init_mpdcch5ss3tab_normal_regular_subframe_evenNRBDL(PHY_VARS_eNB * eNB) { int l, k, kmod, re=0; - LOG_I(PHY, "Inititalizing mpdcch5ss3tab for normal prefix, normal prefix, no PSS/SSS/PBCH, even N_RB_DL\n"); + LOG_D(PHY, "Inititalizing mpdcch5ss3tab for normal prefix, normal prefix, no PSS/SSS/PBCH, even N_RB_DL\n"); for (l = 3; l < 14; l++) { for (k = 0; k < 72; k++) { kmod = k % 12; @@ -194,7 +193,7 @@ void init_mpdcch3ss1tab_normal_regular_subframe_evenNRBDL(PHY_VARS_eNB * eNB) { int l, k, kmod, re=0; - LOG_I(PHY, "Inititalizing mpdcch3ss1tab for normal prefix, normal prefix, no PSS/SSS/PBCH, even N_RB_DL\n"); + LOG_D(PHY, "Inititalizing mpdcch3ss1tab for normal prefix, normal prefix, no PSS/SSS/PBCH, even N_RB_DL\n"); for (l = 1, re = 0; l < 14; l++) { for (k = 0; k < 48; k++) { kmod = k % 12; @@ -218,7 +217,7 @@ void init_mpdcch2ss1tab_normal_regular_subframe_evenNRBDL(PHY_VARS_eNB * eNB) { int l, k, kmod, re=0; - LOG_I(PHY, "Inititalizing mpdcch2ss1tab for normal prefix, normal prefix, no PSS/SSS/PBCH, even N_RB_DL\n"); + LOG_D(PHY, "Inititalizing mpdcch2ss1tab for normal prefix, normal prefix, no PSS/SSS/PBCH, even N_RB_DL\n"); for (l = 1, re = 0; l < 14; l++) { for (k = 0; k < 24; k++) { kmod = k % 12; @@ -288,7 +287,7 @@ void generate_mdci_top(PHY_VARS_eNB * eNB, int frame, int subframe, int16_t amp, int wp[2][4] = {{1,1,1,1},{1,-1,1,-1}}; int *w; - LOG_I(PHY, "generate_mdci_top: num_dci %d\n", mpdcch->num_dci); + LOG_D(PHY, "generate_mdci_top: num_dci %d\n", mpdcch->num_dci); for (i = 0; i < mpdcch->num_dci; i++) { mdci = &mpdcch->mdci_alloc[i]; @@ -320,7 +319,7 @@ void generate_mdci_top(PHY_VARS_eNB * eNB, int frame, int subframe, int16_t amp, } else AssertFatal(1 == 0, "Illegal combination start_symbol %d, a_index %d\n", mdci->start_symbol, a_index); - LOG_I(PHY, "mdci %d, length %d: rnti %x, L %d, prb_pairs %d, ce_mode %d, transmission type %s, i0 %d, ss %d ,coded_bits %d\n", + LOG_D(PHY, "mdci %d, length %d: rnti %x, L %d, prb_pairs %d, ce_mode %d, transmission type %s, i0 %d, ss %d ,coded_bits %d\n", i, mdci->dci_length,mdci->rnti, mdci->L, mdci->number_of_prb_pairs, mdci->ce_mode, @@ -422,7 +421,7 @@ void generate_mdci_top(PHY_VARS_eNB * eNB, int frame, int subframe, int16_t amp, uint32_t b = ((mdci->dmrs_scrambling_init << 1) + 1) << 16; x2 = a * b; x2 = x2 + 2; - LOG_I(PHY, "mpdcch_dmrs cinit %x (a=%d,b=%d,i0=%d,j0=%d)\n", x2,a,b,i0,j0); + LOG_D(PHY, "mpdcch_dmrs cinit %x (a=%d,b=%d,i0=%d,j0=%d)\n", x2,a,b,i0,j0); // add MPDCCH pilots int reset = 1; diff --git a/openair1/PHY/LTE_TRANSPORT/pbch.c b/openair1/PHY/LTE_TRANSPORT/pbch.c index a27c6dbc9087d5b045104b16615c92c3c78b86b7..37997c94b49e97b8acd53c83673e75dc0caac716 100644 --- a/openair1/PHY/LTE_TRANSPORT/pbch.c +++ b/openair1/PHY/LTE_TRANSPORT/pbch.c @@ -308,7 +308,7 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, #ifdef DEBUG_PBCH if (frame_mod4==0) { - LOG_M"pbch_e.m","pbch_e", + LOG_M("pbch_e.m","pbch_e", eNB_pbch->pbch_e, pbch_E, 1, @@ -325,7 +325,7 @@ int generate_pbch(LTE_eNB_PBCH *eNB_pbch, pbch_E); #ifdef DEBUG_PBCH if (frame_mod4==0) { - LOG_M"pbch_e_s.m","pbch_e_s", + LOG_M("pbch_e_s.m","pbch_e_s", eNB_pbch->pbch_e, pbch_E, 1, diff --git a/openair1/PHY/LTE_TRANSPORT/phich_common.c b/openair1/PHY/LTE_TRANSPORT/phich_common.c index f56c25e8af2679da807e4cb21848c9ccccce498c..89c826be66db08e69a8310417a8ea6758b4db3bd 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich_common.c +++ b/openair1/PHY/LTE_TRANSPORT/phich_common.c @@ -46,96 +46,91 @@ uint8_t get_mi(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) // for TDD switch (frame_parms->tdd_config) { + case 0: + if ((subframe==0) || (subframe==5)) + return(2); + else return(1); - case 0: - if ((subframe==0) || (subframe==5)) - return(2); - else return(1); + break; - break; + case 1: + if ((subframe==0) || (subframe==5)) + return(0); + else return(1); - case 1: - if ((subframe==0) || (subframe==5)) - return(0); - else return(1); - - break; + break; - case 2: - if ((subframe==3) || (subframe==8)) - return(1); - else return(0); + case 2: + if ((subframe==3) || (subframe==8)) + return(1); + else return(0); - break; + break; - case 3: - if ((subframe==0) || (subframe==8) || (subframe==9)) - return(1); - else return(0); + case 3: + if ((subframe==0) || (subframe==8) || (subframe==9)) + return(1); + else return(0); - break; + break; - case 4: - if ((subframe==8) || (subframe==9)) - return(1); - else return(0); + case 4: + if ((subframe==8) || (subframe==9)) + return(1); + else return(0); - break; + break; - case 5: - if (subframe==8) - return(1); - else return(0); + case 5: + if (subframe==8) + return(1); + else return(0); - break; + break; - case 6: - return(1); - break; + case 6: + return(1); + break; - default: - return(0); + default: + return(0); } } -unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe) -{ - +unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe) { if (frame_parms->frame_type == FDD) return(subframe&7); switch (frame_parms->tdd_config) { - case 3: - if ( (subframe == 8) || (subframe == 9) ) { - return(subframe-8); - } else if (subframe==0) - return(2); - else { - LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - return(0); - } - - break; - - case 4: - if ( (subframe == 8) || (subframe == 9) ) { - return(subframe-8); - } else { - LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - return(0); - } - - break; - + case 3: + if ( (subframe == 8) || (subframe == 9) ) { + return(subframe-8); + } else if (subframe==0) + return(2); + else { + LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + return(0); + } + + break; + + case 4: + if ( (subframe == 8) || (subframe == 9) ) { + return(subframe-8); + } else { + LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + return(0); + } + + break; } return(0); } -int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int subframe) -{ +int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int subframe) { int pusch_frame; if (frame_parms->frame_type == FDD) { @@ -149,127 +144,124 @@ int phich_frame2_pusch_frame(LTE_DL_FRAME_PARMS *frame_parms, int frame, int sub return pusch_frame % 1024; } -uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) -{ +uint8_t phich_subframe2_pusch_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe) { uint8_t pusch_subframe = 255; if (frame_parms->frame_type == FDD) return subframe < 4 ? subframe + 6 : subframe - 4; switch (frame_parms->tdd_config) { - case 0: - if (subframe == 0) - pusch_subframe = (3); - else if (subframe == 5) { - pusch_subframe = (8); - } else if (subframe == 6) - pusch_subframe = (2); - else if (subframe == 1) - pusch_subframe = (7); - else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 1: - if (subframe == 6) - pusch_subframe = (2); - else if (subframe == 9) - pusch_subframe = (3); - else if (subframe == 1) - pusch_subframe = (7); - else if (subframe == 4) - pusch_subframe = (8); - else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); + case 0: + if (subframe == 0) + pusch_subframe = (3); + else if (subframe == 5) { + pusch_subframe = (8); + } else if (subframe == 6) + pusch_subframe = (2); + else if (subframe == 1) + pusch_subframe = (7); + else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 1: + if (subframe == 6) + pusch_subframe = (2); + else if (subframe == 9) + pusch_subframe = (3); + else if (subframe == 1) + pusch_subframe = (7); + else if (subframe == 4) + pusch_subframe = (8); + else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 2: + if (subframe == 8) + pusch_subframe = (2); + else if (subframe == 3) + pusch_subframe = (7); + else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 3: + if ( (subframe == 8) || (subframe == 9) ) { + pusch_subframe = (subframe-6); + } else if (subframe==0) + pusch_subframe = (4); + else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 4: + if ( (subframe == 8) || (subframe == 9) ) { + pusch_subframe = (subframe-6); + } else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 5: + if (subframe == 8) { + pusch_subframe = (2); + } else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + case 6: + if (subframe == 6) { + pusch_subframe = (2); + } else if (subframe == 9) { + pusch_subframe = (3); + } else if (subframe == 0) { + pusch_subframe = (4); + } else if (subframe == 1) { + pusch_subframe = (7); + } else if (subframe == 5) { + pusch_subframe = (8); + } else { + AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + pusch_subframe = (0); + } + + break; + + default: + AssertFatal(1==0, "no implementation for TDD UL/DL-config = %d!\n", frame_parms->tdd_config); pusch_subframe = (0); - } - - break; - - case 2: - if (subframe == 8) - pusch_subframe = (2); - else if (subframe == 3) - pusch_subframe = (7); - else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 3: - if ( (subframe == 8) || (subframe == 9) ) { - pusch_subframe = (subframe-6); - } else if (subframe==0) - pusch_subframe = (4); - else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 4: - if ( (subframe == 8) || (subframe == 9) ) { - pusch_subframe = (subframe-6); - } else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 5: - if (subframe == 8) { - pusch_subframe = (2); - } else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - case 6: - if (subframe == 6) { - pusch_subframe = (2); - } else if (subframe == 9) { - pusch_subframe = (3); - } else if (subframe == 0) { - pusch_subframe = (4); - } else if (subframe == 1) { - pusch_subframe = (7); - } else if (subframe == 5) { - pusch_subframe = (8); - } else { - AssertFatal(1==0,"phich.c: phich_subframe2_pusch_subframe, illegal subframe %d for tdd_config %d\n", - subframe,frame_parms->tdd_config); - pusch_subframe = (0); - } - - break; - - default: - AssertFatal(1==0, "no implementation for TDD UL/DL-config = %d!\n", frame_parms->tdd_config); - pusch_subframe = (0); } LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", subframe, pusch_subframe); return pusch_subframe; } -int check_pcfich(LTE_DL_FRAME_PARMS *frame_parms,uint16_t reg) -{ - +int check_pcfich(LTE_DL_FRAME_PARMS *frame_parms,uint16_t reg) { if ((reg == frame_parms->pcfich_reg[0]) || (reg == frame_parms->pcfich_reg[1]) || (reg == frame_parms->pcfich_reg[2]) || @@ -279,9 +271,7 @@ int check_pcfich(LTE_DL_FRAME_PARMS *frame_parms,uint16_t reg) return(0); } -void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) -{ - +void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) { unsigned short n0 = (frame_parms->N_RB_DL * 2) - 4; // 2 REG per RB less the 4 used by PCFICH in first symbol unsigned short n1 = (frame_parms->N_RB_DL * 3); // 3 REG per RB in second and third symbol unsigned short n2 = n1; @@ -289,11 +279,9 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) unsigned short Ngroup_PHICH; // uint16_t *phich_reg = frame_parms->phich_reg; uint16_t *pcfich_reg = frame_parms->pcfich_reg; - // compute Ngroup_PHICH (see formula at beginning of Section 6.9 in 36-211 Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48; - if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0) Ngroup_PHICH++; @@ -303,25 +291,24 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) } #ifdef DEBUG_PHICH - LOG_D(PHY,"Ngroup_PHICH %d (phich_config_common.phich_resource %d,phich_config_common.phich_duration %s, NidCell %d,Ncp %d, frame_type %d), smallest pcfich REG %d, n0 %d, n1 %d (first PHICH REG %d)\n", - ((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)), - frame_parms->phich_config_common.phich_resource, - frame_parms->phich_config_common.phich_duration==normal?"normal":"extended", - frame_parms->Nid_cell,frame_parms->Ncp,frame_parms->frame_type, - pcfich_reg[frame_parms->pcfich_first_reg_idx], - n0, - n1, - ((frame_parms->Nid_cell))%n0); + LOG_D(PHY, + "Ngroup_PHICH %d (phich_config_common.phich_resource %d,phich_config_common.phich_duration %s, NidCell %d,Ncp %d, frame_type %d), smallest pcfich REG %d, n0 %d, n1 %d (first PHICH REG %d)\n", + ((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)), + frame_parms->phich_config_common.phich_resource, + frame_parms->phich_config_common.phich_duration==normal?"normal":"extended", + frame_parms->Nid_cell,frame_parms->Ncp,frame_parms->frame_type, + pcfich_reg[frame_parms->pcfich_first_reg_idx], + n0, + n1, + ((frame_parms->Nid_cell))%n0); #endif // This is the algorithm from Section 6.9.3 in 36-211, it works only for normal PHICH duration for now ... - for (mprime=0; - mprime<((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)); + for (mprime=0; + mprime<((frame_parms->Ncp == NORMAL)?Ngroup_PHICH:(Ngroup_PHICH>>1)); mprime++) { - if (frame_parms->phich_config_common.phich_duration==normal) { // normal PHICH duration - frame_parms->phich_reg[mprime][0] = (frame_parms->Nid_cell + mprime)%n0; if (frame_parms->phich_reg[mprime][0]>=pcfich_reg[frame_parms->pcfich_first_reg_idx]) @@ -338,10 +325,9 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) frame_parms->phich_reg[mprime][1] = (frame_parms->Nid_cell + mprime + (n0/3))%n0; - if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[frame_parms->pcfich_first_reg_idx]) frame_parms->phich_reg[mprime][1]++; - + if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+1)&3]) frame_parms->phich_reg[mprime][1]++; @@ -350,10 +336,9 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) if (frame_parms->phich_reg[mprime][1]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3]) frame_parms->phich_reg[mprime][1]++; - frame_parms->phich_reg[mprime][2] = (frame_parms->Nid_cell + mprime + (2*n0/3))%n0; - + if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[frame_parms->pcfich_first_reg_idx]) frame_parms->phich_reg[mprime][2]++; @@ -365,21 +350,19 @@ void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms) if (frame_parms->phich_reg[mprime][2]>=pcfich_reg[(frame_parms->pcfich_first_reg_idx+3)&3]) frame_parms->phich_reg[mprime][2]++; - + #ifdef DEBUG_PHICH printf("phich_reg :%d => %d,%d,%d\n",mprime,frame_parms->phich_reg[mprime][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]); #endif } else { // extended PHICH duration frame_parms->phich_reg[mprime<<1][0] = (frame_parms->Nid_cell + mprime)%n0; frame_parms->phich_reg[1+(mprime<<1)][0] = (frame_parms->Nid_cell + mprime)%n0; - frame_parms->phich_reg[mprime<<1][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1; frame_parms->phich_reg[mprime<<1][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2; - frame_parms->phich_reg[1+(mprime<<1)][1] = ((frame_parms->Nid_cell*n1/n0) + mprime + (n1/3))%n1; frame_parms->phich_reg[1+(mprime<<1)][2] = ((frame_parms->Nid_cell*n2/n0) + mprime + (2*n2/3))%n2; //#ifdef DEBUG_PHICH - printf("phich_reg :%d => %d,%d,%d\n",mprime<<1,frame_parms->phich_reg[mprime<<1][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]); + printf("phich_reg :%u => %d,%d,%d\n",mprime<<1,frame_parms->phich_reg[mprime<<1][0],frame_parms->phich_reg[mprime][1],frame_parms->phich_reg[mprime][2]); printf("phich_reg :%d => %d,%d,%d\n",1+(mprime<<1),frame_parms->phich_reg[1+(mprime<<1)][0],frame_parms->phich_reg[1+(mprime<<1)][1],frame_parms->phich_reg[1+(mprime<<1)][2]); //#endif } diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index 59450cf08114a1329c9a572b76440f47c5071f73..1d665682e01e0d80ea098601da3b72353b165ddb 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -56,7 +56,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, #endif ) { int i; - LTE_DL_FRAME_PARMS *fp; + LTE_DL_FRAME_PARMS *fp=NULL; lte_frame_type_t frame_type; uint16_t rootSequenceIndex; uint8_t prach_ConfigIndex; @@ -66,7 +66,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, int subframe; int16_t *prachF=NULL; int16_t **rxsigF=NULL; - int nb_rx; + int nb_rx=0; int16_t *prach2; uint8_t preamble_index; uint16_t NCS,NCS2; @@ -96,13 +96,17 @@ void rx_prach0(PHY_VARS_eNB *eNB, int prach_ifft_cnt=0; #endif - if (ru) { - fp = &ru->frame_parms; - nb_rx = ru->nb_rx; - } else if (eNB) { - fp = &eNB->frame_parms; + + if(eNB) { + fp = &(eNB->frame_parms); nb_rx = fp->nb_antennas_rx; - } else AssertFatal(1==0,"rx_prach called without valid RU or eNB descriptor\n"); + } else { + fp = &(ru->frame_parms); + nb_rx = ru->nb_rx; + } + AssertFatal(fp!=NULL,"rx_prach called without valid RU or eNB descriptor\n"); + + frame_type = fp->frame_type; frame_type = fp->frame_type; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -148,29 +152,26 @@ void rx_prach0(PHY_VARS_eNB *eNB, prachF = eNB->prach_vars_br.prachF; rxsigF = eNB->prach_vars_br.rxsigF[ce_level]; - if (LOG_DEBUGFLAG(PRACH)) { - if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY, - "PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n", - br_flag,ce_level,ru->proc.frame_prach,subframe, - fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level], - prach_ConfigIndex,rootSequenceIndex, - eNB->prach_vars_br.repetition_number[ce_level], - fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level]); + if (LOG_DEBUGFLAG(PRACH)){ + if (((eNB->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n", + br_flag,ce_level,eNB->proc.frame_prach,subframe, + fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level], + prach_ConfigIndex,rootSequenceIndex, + eNB->prach_vars_br.repetition_number[ce_level], + fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level]); } } else #endif - { - prach_ifftp = eNB->prach_vars.prach_ifft[0]; - subframe = eNB->proc.subframe_prach; - prachF = eNB->prach_vars.prachF; - rxsigF = eNB->prach_vars.rxsigF[0]; - - if (LOG_DEBUGFLAG(PRACH)) { - if (((ru->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe, - fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex); + { + prach_ifftp = eNB->prach_vars.prach_ifft[0]; + subframe = eNB->proc.subframe_prach; + prachF = eNB->prach_vars.prachF; + rxsigF = eNB->prach_vars.rxsigF[0]; + if (LOG_DEBUGFLAG(PRACH)){ + if (((eNB->proc.frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex); + } } - } - } else { + } else { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) { @@ -421,7 +422,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, } } - if ((eNB==NULL) && ru->function == NGFI_RRU_IF4p5) { + if ((eNB==NULL) && ru->function == NGFI_RRU_IF4p5) { /// **** send_IF4 of rxsigF to RAU **** /// #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH+1+ce_level); @@ -445,26 +446,27 @@ void rx_prach0(PHY_VARS_eNB *eNB, uint8_t update_TA2 = 1; switch (eNB->frame_parms.N_RB_DL) { - case 6: - update_TA = 16; - break; - case 25: - update_TA = 4; - break; + case 6: + update_TA = 16; + break; + + case 25: + update_TA = 4; + break; + + case 50: + update_TA = 2; + break; + + case 75: + update_TA = 3; + update_TA2 = 2; + break; + case 100: + update_TA = 1; + break; - case 50: - update_TA = 2; - break; - - case 75: - update_TA = 3; - update_TA2 = 2; - break; - - case 100: - update_TA = 1; - break; } *max_preamble_energy=0; diff --git a/openair1/PHY/LTE_TRANSPORT/prach_common.c b/openair1/PHY/LTE_TRANSPORT/prach_common.c index 4962f6a7f917b3da8eda0af841d963c1bbd47d54..5f7a904db16f522a8a34972063c0e2f5ffde9235 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach_common.c +++ b/openair1/PHY/LTE_TRANSPORT/prach_common.c @@ -565,17 +565,16 @@ int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex return(prach_mask); } -int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe) { +int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint8_t subframe) { uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; - int prach_mask = is_prach_subframe0(frame_parms,prach_ConfigIndex,frame,subframe); + int prach_mask = is_prach_subframe0(frame_parms, prach_ConfigIndex, frame, subframe); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - int i; - - for (i=0;i<4;i++) { + for (int i=0; i<4; i++) { if (frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i] == 1) - prach_mask|=(is_prach_subframe0(frame_parms,frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i],frame,subframe)<<(i+1)); + prach_mask |= (is_prach_subframe0(frame_parms, frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i], + frame, subframe) << (i+1)); } #endif return(prach_mask); diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c index 005287935e88d932d144014d7fb8a78e9bc75f35..e86b7ff37692f7663a8311a43a1897166e465fcc 100644 --- a/openair1/PHY/LTE_TRANSPORT/print_stats.c +++ b/openair1/PHY/LTE_TRANSPORT/print_stats.c @@ -507,7 +507,7 @@ int dump_ue_stats(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,char* buffer, int length len += sprintf(&buffer[len], "[UE PROC] DLSCH Total %d, Error %d, FER %d\n",ue->dlsch_received[0],ue->dlsch_errors[0],ue->dlsch_fer[0]); len += sprintf(&buffer[len], "[UE PROC] DLSCH (SI) Total %d, Error %d\n",ue->dlsch_SI_received[0],ue->dlsch_SI_errors[0]); len += sprintf(&buffer[len], "[UE PROC] DLSCH (RA) Total %d, Error %d\n",ue->dlsch_ra_received[0],ue->dlsch_ra_errors[0]); -#if defined(Rel10) || defined(Rel14) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int i=0; //len += sprintf(&buffer[len], "[UE PROC] MCH Total %d\n", ue->dlsch_mch_received[0]); diff --git a/openair1/PHY/LTE_TRANSPORT/pss.c b/openair1/PHY/LTE_TRANSPORT/pss.c index 33bd5cc7e8246f06b49ec8e85b30072cd4d10f33..9ebd841430927e1c165d14234099948f37f0793b 100644 --- a/openair1/PHY/LTE_TRANSPORT/pss.c +++ b/openair1/PHY/LTE_TRANSPORT/pss.c @@ -38,72 +38,65 @@ //#include "defs.h" #include "PHY/defs_eNB.h" #include "PHY/phy_extern.h" +#include "targets/RT/USER/lte-softmodem.h" int generate_pss(int32_t **txdataF, short amp, LTE_DL_FRAME_PARMS *frame_parms, unsigned short symbol, - unsigned short slot_offset) -{ - + unsigned short slot_offset) { unsigned int Nsymb; unsigned short k,m,aa,a; uint8_t Nid2; short *primary_sync; - - Nid2 = frame_parms->Nid_cell % 3; switch (Nid2) { - case 0: - primary_sync = primary_synch0; - break; + case 0: + primary_sync = primary_synch0; + break; - case 1: - primary_sync = primary_synch1; - break; + case 1: + primary_sync = primary_synch1; + break; - case 2: - primary_sync = primary_synch2; - break; + case 2: + primary_sync = primary_synch2; + break; - default: - LOG_E(PHY,"[PSS] eNb_id has to be 0,1,2\n"); - return(-1); + default: + LOG_E(PHY,"[PSS] eNb_id has to be 0,1,2\n"); + return(-1); } a = (frame_parms->nb_antenna_ports_eNB == 1) ? amp: (amp*ONE_OVER_SQRT2_Q15)>>15; //printf("[PSS] amp=%d, a=%d\n",amp,a); -#if BASIC_SIMULATOR - /* a hack to remove at some point (the UE doesn't synch with 100 RBs) */ - a = (frame_parms->nb_antenna_ports_eNB == 1) ? 4*amp: (amp*ONE_OVER_SQRT2_Q15)>>15; -#endif + if (IS_SOFTMODEM_BASICSIM) + /* a hack to remove at some point (the UE doesn't synch with 100 RBs) */ + a = (frame_parms->nb_antenna_ports_eNB == 1) ? 4*amp: (amp*ONE_OVER_SQRT2_Q15)>>15; Nsymb = (frame_parms->Ncp==NORMAL)?14:12; for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) { // aa = 0; - // The PSS occupies the inner 6 RBs, which start at k = frame_parms->ofdm_symbol_size-3*12+5; //printf("[PSS] k = %d\n",k); for (m=5; m<67; m++) { - ((short*)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size + - symbol*frame_parms->ofdm_symbol_size + k)] = - (a * primary_sync[2*m]) >> 15; - ((short*)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size + - symbol*frame_parms->ofdm_symbol_size + k) + 1] = - (a * primary_sync[2*m+1]) >> 15; - + ((short *)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size + + symbol*frame_parms->ofdm_symbol_size + k)] = + (a * primary_sync[2*m]) >> 15; + ((short *)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size + + symbol*frame_parms->ofdm_symbol_size + k) + 1] = + (a * primary_sync[2*m+1]) >> 15; k+=1; if (k >= frame_parms->ofdm_symbol_size) { k++; //skip DC k-=frame_parms->ofdm_symbol_size; } - } } diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index ac12ee44272985f0da947383c6b8ce8ec58efe90..676d753ab5d61bcf7c42f19200a5e9a57f728d05 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -719,20 +719,16 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, int frame, uint8_t subframe, uint8_t pucch1_thres -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,uint8_t br_flag #endif - ) +) +//----------------------------------------------------------------------------- { - - - static int first_call=1; - LTE_eNB_COMMON *common_vars = &eNB->common_vars; - LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; - // PUCCH_CONFIG_DEDICATED *pucch_config_dedicated = &eNB->pucch_config_dedicated[UE_id]; - - int8_t sigma2_dB = max(eNB->measurements.n0_subband_power_tot_dB[0], - eNB->measurements.n0_subband_power_tot_dB[eNB->frame_parms.N_RB_UL-1]); + static int first_call = 1; + LTE_eNB_COMMON *common_vars = &eNB->common_vars; + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + int8_t sigma2_dB = max(eNB->measurements.n0_subband_power_tot_dB[0], eNB->measurements.n0_subband_power_tot_dB[eNB->frame_parms.N_RB_UL-1]); uint32_t u,v,n,aa; uint32_t z[12*14]; @@ -770,7 +766,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, uint16_t Ret = 0; int16_t SubCarrierDeMapData[NB_ANTENNAS_RX][14][12][2]; //[Antenna][Symbol][Subcarrier][Complex] int16_t CshData_fmt3[NB_ANTENNAS_RX][14][12][2]; //[Antenna][Symbol][Subcarrier][Complex] - double delta_theta[NB_ANTENNAS_RX][12]; //[Antenna][Subcarrier][Complex] + double delta_theta[NB_ANTENNAS_RX][12]; //[Antenna][Subcarrier][Complex] int16_t ChestValue[NB_ANTENNAS_RX][2][12][2]; //[Antenna][Slot][Subcarrier][Complex] int16_t ChdetAfterValue_fmt3[NB_ANTENNAS_RX][14][12][2]; //[Antenna][Symbol][Subcarrier][Complex] int16_t RemoveFrqDev_fmt3[NB_ANTENNAS_RX][2][5][12][2]; //[Antenna][Slot][PUCCH_Symbol][Subcarrier][Complex] @@ -779,7 +775,6 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, int16_t Fmt3xDataAvgSym[2][12][2]; //[Slot][Subcarrier][Complex] int16_t IFFTOutData_Fmt3[2][12][2]; //[Slot][Subcarrier][Complex] int16_t b[48]; //[bit] - //int16_t IP_CsData_allavg[NB_ANTENNAS_RX][12][4][2]; //[Antenna][Symbol][Nouse Cyclic Shift][Complex] int16_t payload_entity = -1; int16_t Interpw; int16_t payload_max; @@ -978,7 +973,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, m = (n1_pucch < thres) ? NRB2 : (((n1_pucch-thres)/(12*c/deltaPUCCH_Shift))+NRB2+((deltaPUCCH_Shift*Ncs1_div_deltaPUCCH_Shift)>>3)+rem); #ifdef DEBUG_PUCCH_RX - printf("[eNB] PUCCH: m %d\n",m); + printf("[eNB] PUCCH: m %d, thres %d, NRB2 %d\n",m,thres,NRB2); #endif nsymb = N_UL_symb<<1; @@ -989,7 +984,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, //for (j=0,l=0;l<(nsymb-1);l++) { for (j=0,l=0; l<nsymb; l++) { -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag > 0 ) { if ((m&1) == 0) re_offset = (m*6) + frame_parms->first_carrier_offset; @@ -1227,7 +1222,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, stat_max/=(12); //normalize to energy per symbol and RE #ifdef DEBUG_PUCCH_RX - printf("[eNB] PUCCH fmt1a/b: stat_max : %d, phase_max : %d\n",stat_max,phase_max); + LOG_I(PHY,"[eNB] PUCCH fmt1a/b: stat_max : %d (%d : sigma2 %d), phase_max : %d\n",stat_max,dB_fixed(stat_max),sigma2_dB,phase_max); #endif stat_re=0; @@ -1368,7 +1363,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, LOG_D(PHY,"PUCCH 1a/b: subframe %d : stat %d,%d (pos %d)\n",subframe,stat_re,stat_im, (subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])); - LOG_D(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); + LOG_D(PHY,"In pucch.c PUCCH 1a/b: ACK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); eNB->pucch1ab_stats[UE_id][(subframe<<11) + 2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_re); eNB->pucch1ab_stats[UE_id][(subframe<<11) + 1+2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_im); @@ -1385,8 +1380,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, #if defined(USRP_REC_PLAY) LOG_D(PHY,"PUCCH 1a/b: NAK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); #else - LOG_D(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); -#endif + LOG_D(PHY,"In pucch.c PUCCH 1a/b: NAK subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); +#endif + *payload = 4; // DTX ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re); ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[1] = (int16_t)(stat_im); diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h index ddf3594880ed147933d1a3e49a1968f3ab5f045b..6c1f6747886ad9225482c5764c42a317147a01b6 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h @@ -153,6 +153,8 @@ typedef struct { #else uint8_t active; #endif + /// indicator of UE type (0 = LTE, 1,2 = Cat-M) + int ue_type; /// HARQ process mask, indicates which processes are currently active uint16_t harq_mask; /// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK. @@ -327,7 +329,7 @@ typedef struct { uint8_t subframe; /// corresponding UE RNTI uint16_t rnti; - /// Type (SR,HARQ,CQI,HARQ_SR,HARQ_CQI,SR_CQI,HARQ_SR_CQI) + /// Type (SR, HARQ, CQI, HARQ_SR, HARQ_CQI, SR_CQI, HARQ_SR_CQI) UCI_type_t type; /// SRS active flag uint8_t srs_active; diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index f4919c6403c9bd34d6badc9c793049b4f4485ba7..41dff9c5c01cb9b1cd7776a349ce062928534a12 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -553,7 +553,11 @@ uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, uint8_t *payload, int frame, uint8_t subframe, - uint8_t pucch1_thres); + uint8_t pucch1_thres +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,int br_flag +#endif + ); /*! diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index cc62f83f4c057f25862ab4f30e31e94dc905eaee..1dcbec06640dbd34d638159d9eb2fb01fc958e37 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -47,9 +47,7 @@ extern WORKER_CONF_t get_thread_worker_conf(void); -void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) -{ - +void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) { int i,r; if (ulsch) { @@ -77,33 +75,30 @@ void free_eNB_ulsch(LTE_eNB_ULSCH_t *ulsch) } free16(ulsch,sizeof(LTE_eNB_ULSCH_t)); - ulsch = NULL; } } -LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag) -{ - +LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag) { LTE_eNB_ULSCH_t *ulsch; uint8_t exit_flag = 0,i,r; unsigned char bw_scaling =1; switch (N_RB_UL) { - case 6: - bw_scaling =16; - break; + case 6: + bw_scaling =16; + break; - case 25: - bw_scaling =4; - break; + case 25: + bw_scaling =4; + break; - case 50: - bw_scaling =2; - break; + case 50: + bw_scaling =2; + break; - default: - bw_scaling =1; - break; + default: + bw_scaling =1; + break; } ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t)); @@ -119,7 +114,7 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin if (ulsch->harq_processes[i]) { memset(ulsch->harq_processes[i],0,sizeof(LTE_UL_eNB_HARQ_t)); - ulsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling); + ulsch->harq_processes[i]->b = (uint8_t *)malloc16(MAX_ULSCH_PAYLOAD_BYTES/bw_scaling); if (ulsch->harq_processes[i]->b) memset(ulsch->harq_processes[i]->b,0,MAX_ULSCH_PAYLOAD_BYTES/bw_scaling); @@ -128,13 +123,14 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin if (abstraction_flag==0) { for (r=0; r<MAX_NUM_ULSCH_SEGMENTS/bw_scaling; r++) { - ulsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+768); + ulsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(((r==0)?8:0) + 3+768); + if (ulsch->harq_processes[i]->c[r]) memset(ulsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+768); else exit_flag=2; - ulsch->harq_processes[i]->d[r] = (short*)malloc16(((3*8*6144)+12+96)*sizeof(short)); + ulsch->harq_processes[i]->d[r] = (short *)malloc16(((3*8*6144)+12+96)*sizeof(short)); if (ulsch->harq_processes[i]->d[r]) memset(ulsch->harq_processes[i]->d[r],0,((3*8*6144)+12+96)*sizeof(short)); @@ -153,13 +149,10 @@ LTE_eNB_ULSCH_t *new_eNB_ulsch(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uin LOG_E(PHY,"new_ue_ulsch: exit_flag = %d\n",exit_flag); free_eNB_ulsch(ulsch); - return(NULL); } -void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch) -{ - +void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch) { unsigned char i; //ulsch = (LTE_eNB_ULSCH_t *)malloc16(sizeof(LTE_eNB_ULSCH_t)); @@ -180,9 +173,11 @@ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch) ulsch->harq_processes[i]->TBS = 0; ulsch->harq_processes[i]->Or1 = 0; ulsch->harq_processes[i]->Or2 = 0; + for ( int j = 0; j < 2; j++ ) { ulsch->harq_processes[i]->o_RI[j] = 0; } + ulsch->harq_processes[i]->O_ACK = 0; ulsch->harq_processes[i]->srs_active = 0; ulsch->harq_processes[i]->rvidx = 0; @@ -190,6 +185,7 @@ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch) ulsch->harq_processes[i]->Nsymb_initial = 0; } } + ulsch->beta_offset_cqi_times8 = 0; ulsch->beta_offset_ri_times8 = 0; ulsch->beta_offset_harqack_times8 = 0; @@ -198,11 +194,8 @@ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch) } -uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) -{ - +uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) { uint8_t crc; - crc = cqi[CQI_LENGTH>>3]; // printf("crc1: %x, shift %d\n",crc,CQI_LENGTH&0x7); crc = (crc<<(CQI_LENGTH&0x7)); @@ -212,22 +205,18 @@ uint8_t extract_cqi_crc(uint8_t *cqi,uint8_t CQI_LENGTH) crc |= (cqi[1+(CQI_LENGTH>>3)])>>(8-(CQI_LENGTH&0x7)); // clear crc bits //(((char *)cqi)[1+(CQI_LENGTH>>3)]) = 0; - // printf("crc : %x\n",crc); return(crc); - } -int ulsch_decoding_data_2thread0(td_params* tdp) { - +int ulsch_decoding_data_2thread0(td_params *tdp) { PHY_VARS_eNB *eNB = tdp->eNB; int UE_id = tdp->UE_id; int harq_pid = tdp->harq_pid; int llr8_flag = tdp->llr8_flag; - unsigned int r,r_offset=0,Kr,Kr_bytes; uint8_t crc_type; int offset = 0; @@ -247,11 +236,8 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { else tc = decoder8; - - // go through first half of segments to get r_offset for (r=0; r<(ulsch_harq->C/2); r++) { - // Get Turbo interleaver parameters if (r<ulsch_harq->Cminus) Kr = ulsch_harq->Kminus; @@ -259,17 +245,15 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { Kr = ulsch_harq->Kplus; Kr_bytes = Kr>>3; - // This is stolen from rate-matching algorithm to get the value of E - Gp = G/Nl/Q_m; GpmodC = Gp%C; - + if (r < (C-(GpmodC))) E = Nl*Q_m * (Gp/C); else E = Nl*Q_m * ((GpmodC==0?0:1) + (Gp/C)); - + r_offset += E; if (r==0) { @@ -281,8 +265,6 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { // go through second half of segments for (; r<(ulsch_harq->C); r++) { - - // printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); // Get Turbo interleaver parameters if (r<ulsch_harq->Cminus) @@ -291,26 +273,23 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { Kr = ulsch_harq->Kplus; Kr_bytes = Kr>>3; - memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short)); ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), - (uint8_t*)&dummy_w[r][0], + (uint8_t *)&dummy_w[r][0], (r==0) ? ulsch_harq->F : 0); - #ifdef DEBUG_ULSCH_DECODING - printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...\n", - r, G, - Kr*3, - Q_m, - nb_rb, - ulsch_harq->Nl); + printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, nb_rb %d, Nl %d)...\n", + r, G, + Kr*3, + Q_m, + nb_rb, + ulsch_harq->Nl); #endif - if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r], G, ulsch_harq->w[r], - (uint8_t*) &dummy_w[r][0], + (uint8_t *) &dummy_w[r][0], ulsch_harq->e+r_offset, ulsch_harq->C, NSOFT, @@ -327,7 +306,6 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { } r_offset += E; - sub_block_deinterleaving_turbo(4+Kr, &ulsch_harq->d[r][96], ulsch_harq->w[r]); @@ -336,44 +314,39 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { crc_type = CRC24_A; else crc_type = CRC24_B; - - + ret = tc(&ulsch_harq->d[r][96], NULL, - ulsch_harq->c[r], + ulsch_harq->c[r], NULL, - Kr, - ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS, - crc_type, - (r==0) ? ulsch_harq->F : 0, - &eNB->ulsch_tc_init_stats, - &eNB->ulsch_tc_alpha_stats, - &eNB->ulsch_tc_beta_stats, - &eNB->ulsch_tc_gamma_stats, - &eNB->ulsch_tc_ext_stats, - &eNB->ulsch_tc_intl1_stats, - &eNB->ulsch_tc_intl2_stats); - + Kr, + ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS, + crc_type, + (r==0) ? ulsch_harq->F : 0, + &eNB->ulsch_tc_init_stats, + &eNB->ulsch_tc_alpha_stats, + &eNB->ulsch_tc_beta_stats, + &eNB->ulsch_tc_gamma_stats, + &eNB->ulsch_tc_ext_stats, + &eNB->ulsch_tc_intl1_stats, + &eNB->ulsch_tc_intl2_stats); + // Reassembly of Transport block here if (ret != (1+ulsch->max_turbo_iterations)) { if (r<ulsch_harq->Cminus) - Kr = ulsch_harq->Kminus; + Kr = ulsch_harq->Kminus; else - Kr = ulsch_harq->Kplus; - + Kr = ulsch_harq->Kplus; + Kr_bytes = Kr>>3; - memcpy(ulsch_harq->b+offset, - ulsch_harq->c[r], - Kr_bytes - ((ulsch_harq->C>1)?3:0)); + ulsch_harq->c[r], + Kr_bytes - ((ulsch_harq->C>1)?3:0)); offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); - - } else { break; } - } return(ret); @@ -381,22 +354,21 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { extern int oai_exit; void *td_thread(void *param) { - PHY_VARS_eNB *eNB = ((td_params*)param)->eNB; + PHY_VARS_eNB *eNB = ((td_params *)param)->eNB; L1_proc_t *proc = &eNB->proc; cpu_set_t cpuset; CPU_ZERO(&cpuset); - thread_top_init("td_thread",1,200000,250000,500000); pthread_setname_np( pthread_self(),"td processing"); LOG_I(PHY,"thread td created id=%ld\n", syscall(__NR_gettid)); //wait_sync("td_thread"); while (!oai_exit) { + if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break; - if (wait_on_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread")<0) break; if(oai_exit) break; - ((td_params*)param)->ret = ulsch_decoding_data_2thread0((td_params*)param); + ((td_params *)param)->ret = ulsch_decoding_data_2thread0((td_params *)param); if (release_thread(&proc->mutex_td,&proc->instance_cnt_td,"td thread")<0) break; @@ -411,7 +383,6 @@ void *td_thread(void *param) { } int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) { - L1_proc_t *proc = &eNB->proc; unsigned int r,r_offset=0,Kr,Kr_bytes; uint8_t crc_type; @@ -420,18 +391,14 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; - int G = ulsch_harq->G; unsigned int E; int Cby2; decoder_if_t *tc; - struct timespec wait; - wait.tv_sec=0; wait.tv_nsec=5000000L; - if (llr8_flag == 0) tc = decoder16; else @@ -443,23 +410,21 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr exit_fun( "error locking mutex_fep" ); return -1; } - + if (proc->instance_cnt_td==0) { printf("[eNB] TD thread busy\n"); exit_fun("TD thread busy"); pthread_mutex_unlock( &proc->mutex_td ); return -1; } - + ++proc->instance_cnt_td; - proc->tdp.eNB = eNB; proc->tdp.UE_id = UE_id; proc->tdp.harq_pid = harq_pid; proc->tdp.llr8_flag = llr8_flag; - - - // wakeup worker to do second half segments + + // wakeup worker to do second half segments if (pthread_cond_signal(&proc->cond_td) != 0) { printf("[eNB] ERROR pthread_cond_signal for td thread exit\n"); exit_fun( "ERROR pthread_cond_signal" ); @@ -468,14 +433,12 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr pthread_mutex_unlock( &proc->mutex_td ); Cby2 = ulsch_harq->C/2; - } - else { + } else { Cby2 = 1; } // go through first half of segments in main thread for (r=0; r<Cby2; r++) { - // printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); // Get Turbo interleaver parameters if (r<ulsch_harq->Cminus) @@ -484,27 +447,24 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr Kr = ulsch_harq->Kplus; Kr_bytes = Kr>>3; - memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short)); ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), - (uint8_t*)&dummy_w[r][0], + (uint8_t *)&dummy_w[r][0], (r==0) ? ulsch_harq->F : 0); - #ifdef DEBUG_ULSCH_DECODING - printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...\n", - r, G, - Kr*3, - Q_m, - nb_rb, - ulsch_harq->Nl); + printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, nb_rb %d, Nl %d)...\n", + r, G, + Kr*3, + Q_m, + nb_rb, + ulsch_harq->Nl); #endif - start_meas(&eNB->ulsch_rate_unmatching_stats); if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r], G, ulsch_harq->w[r], - (uint8_t*) &dummy_w[r][0], + (uint8_t *) &dummy_w[r][0], ulsch_harq->e+r_offset, ulsch_harq->C, NSOFT, @@ -522,7 +482,6 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr stop_meas(&eNB->ulsch_rate_unmatching_stats); r_offset += E; - start_meas(&eNB->ulsch_deinterleaving_stats); sub_block_deinterleaving_turbo(4+Kr, &ulsch_harq->d[r][96], @@ -535,61 +494,57 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr crc_type = CRC24_B; start_meas(&eNB->ulsch_turbo_decoding_stats); - ret = tc(&ulsch_harq->d[r][96], NULL, - ulsch_harq->c[r], + ulsch_harq->c[r], NULL, - Kr, - ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS, - crc_type, - (r==0) ? ulsch_harq->F : 0, - &eNB->ulsch_tc_init_stats, - &eNB->ulsch_tc_alpha_stats, - &eNB->ulsch_tc_beta_stats, - &eNB->ulsch_tc_gamma_stats, - &eNB->ulsch_tc_ext_stats, - &eNB->ulsch_tc_intl1_stats, - &eNB->ulsch_tc_intl2_stats); - - // Reassembly of Transport block here + Kr, + ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS, + crc_type, + (r==0) ? ulsch_harq->F : 0, + &eNB->ulsch_tc_init_stats, + &eNB->ulsch_tc_alpha_stats, + &eNB->ulsch_tc_beta_stats, + &eNB->ulsch_tc_gamma_stats, + &eNB->ulsch_tc_ext_stats, + &eNB->ulsch_tc_intl1_stats, + &eNB->ulsch_tc_intl2_stats); + + // Reassembly of Transport block here if (ret != (1+ulsch->max_turbo_iterations)) { if (r<ulsch_harq->Cminus) - Kr = ulsch_harq->Kminus; + Kr = ulsch_harq->Kminus; else - Kr = ulsch_harq->Kplus; - + Kr = ulsch_harq->Kplus; + Kr_bytes = Kr>>3; - + if (r==0) { - memcpy(ulsch_harq->b, - &ulsch_harq->c[0][(ulsch_harq->F>>3)], - Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0)); - offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0); + memcpy(ulsch_harq->b, + &ulsch_harq->c[0][(ulsch_harq->F>>3)], + Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0)); + offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0); } else { - memcpy(ulsch_harq->b+offset, - ulsch_harq->c[r], - Kr_bytes - ((ulsch_harq->C>1)?3:0)); - offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); + memcpy(ulsch_harq->b+offset, + ulsch_harq->c[r], + Kr_bytes - ((ulsch_harq->C>1)?3:0)); + offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); } - } else { break; } - stop_meas(&eNB->ulsch_turbo_decoding_stats); - //printf("/////////////////////////////////////////**************************loop for %d time in ulsch_decoding main\n",r); - } - - // wait for worker to finish - wait_on_busy_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread"); + stop_meas(&eNB->ulsch_turbo_decoding_stats); + //printf("/////////////////////////////////////////**************************loop for %d time in ulsch_decoding main\n",r); + } + // wait for worker to finish + wait_on_busy_condition(&proc->mutex_td,&proc->cond_td,&proc->instance_cnt_td,"td thread"); return( (ret>proc->tdp.ret) ? ret : proc->tdp.ret ); } int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) { - unsigned int r,r_offset=0,Kr,Kr_bytes; uint8_t crc_type; int offset = 0; @@ -597,7 +552,6 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) int16_t dummy_w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)]; LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; - int G = ulsch_harq->G; unsigned int E; decoder_if_t *tc; @@ -607,9 +561,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) else tc = *decoder8; - for (r=0; r<ulsch_harq->C; r++) { - // printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]); // Get Turbo interleaver parameters if (r<ulsch_harq->Cminus) @@ -618,27 +570,24 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) Kr = ulsch_harq->Kplus; Kr_bytes = Kr>>3; - memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short)); ulsch_harq->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), - (uint8_t*)&dummy_w[r][0], + (uint8_t *)&dummy_w[r][0], (r==0) ? ulsch_harq->F : 0); - #ifdef DEBUG_ULSCH_DECODING - printf("Rate Matching Segment %d (coded bits (G) %d,unpunctured/repeated bits %d, Q_m %d, nb_rb %d, Nl %d)...\n", - r, G, - Kr*3, - Q_m, - nb_rb, - ulsch_harq->Nl); + printf("Rate Matching Segment %u (coded bits (G) %d,unpunctured/repeated bits %u, Q_m %d, nb_rb %d, Nl %d)...\n", + r, G, + Kr*3, + Q_m, + nb_rb, + ulsch_harq->Nl); #endif - start_meas(&eNB->ulsch_rate_unmatching_stats); if (lte_rate_matching_turbo_rx(ulsch_harq->RTC[r], G, ulsch_harq->w[r], - (uint8_t*) &dummy_w[r][0], + (uint8_t *) &dummy_w[r][0], ulsch_harq->e+r_offset, ulsch_harq->C, NSOFT, @@ -656,7 +605,6 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) stop_meas(&eNB->ulsch_rate_unmatching_stats); r_offset += E; - start_meas(&eNB->ulsch_deinterleaving_stats); sub_block_deinterleaving_turbo(4+Kr, &ulsch_harq->d[r][96], @@ -667,61 +615,55 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) crc_type = CRC24_A; else crc_type = CRC24_B; - - + start_meas(&eNB->ulsch_turbo_decoding_stats); - ret = tc(&ulsch_harq->d[r][96], NULL, - ulsch_harq->c[r], + ulsch_harq->c[r], NULL, - Kr, - ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS, - crc_type, - (r==0) ? ulsch_harq->F : 0, - &eNB->ulsch_tc_init_stats, - &eNB->ulsch_tc_alpha_stats, - &eNB->ulsch_tc_beta_stats, - &eNB->ulsch_tc_gamma_stats, - &eNB->ulsch_tc_ext_stats, - &eNB->ulsch_tc_intl1_stats, - &eNB->ulsch_tc_intl2_stats); - + Kr, + ulsch->max_turbo_iterations,//MAX_TURBO_ITERATIONS, + crc_type, + (r==0) ? ulsch_harq->F : 0, + &eNB->ulsch_tc_init_stats, + &eNB->ulsch_tc_alpha_stats, + &eNB->ulsch_tc_beta_stats, + &eNB->ulsch_tc_gamma_stats, + &eNB->ulsch_tc_ext_stats, + &eNB->ulsch_tc_intl1_stats, + &eNB->ulsch_tc_intl2_stats); stop_meas(&eNB->ulsch_turbo_decoding_stats); - - // Reassembly of Transport block here + + // Reassembly of Transport block here if (ret != (1+ulsch->max_turbo_iterations)) { if (r<ulsch_harq->Cminus) - Kr = ulsch_harq->Kminus; + Kr = ulsch_harq->Kminus; else - Kr = ulsch_harq->Kplus; - + Kr = ulsch_harq->Kplus; + Kr_bytes = Kr>>3; - + if (r==0) { - memcpy(ulsch_harq->b, - &ulsch_harq->c[0][(ulsch_harq->F>>3)], - Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0)); - offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0); + memcpy(ulsch_harq->b, + &ulsch_harq->c[0][(ulsch_harq->F>>3)], + Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0)); + offset = Kr_bytes - (ulsch_harq->F>>3) - ((ulsch_harq->C>1)?3:0); } else { - memcpy(ulsch_harq->b+offset, - ulsch_harq->c[r], - Kr_bytes - ((ulsch_harq->C>1)?3:0)); - offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); + memcpy(ulsch_harq->b+offset, + ulsch_harq->c[r], + Kr_bytes - ((ulsch_harq->C>1)?3:0)); + offset += (Kr_bytes- ((ulsch_harq->C>1)?3:0)); } - } else { break; } - } return(ret); } -int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) -{ +int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) { int ret = 0; /*if(get_thread_worker_conf() == WORKER_ENABLE) { @@ -735,8 +677,7 @@ int ulsch_decoding_data_all(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_fl } static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline)); -static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) -{ +static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, unsigned char reset) { int n; if (reset) { @@ -759,17 +700,13 @@ static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28); return(*x1^*x2); // printf("n=%d : c %x\n",n,x1^x2); - } - + unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, uint8_t UE_id, uint8_t control_only_flag, uint8_t Nbundled, - uint8_t llr8_flag) -{ - - + uint8_t llr8_flag) { int16_t *ulsch_llr = eNB->pusch_vars[UE_id]->llr; LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; @@ -780,10 +717,8 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, unsigned int i,i2,q,j,j2; int iprime; unsigned int ret=0; - // uint8_t dummy_channel_output[(3*8*block_length)+12]; int r,Kr; - uint8_t *columnset; unsigned int sumKr=0; unsigned int Qprime,L,G,Q_CQI,Q_RI,H,Hprime,Hpp,Cmux,Rmux_prime,O_RCC; @@ -799,14 +734,12 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, // uint8_t ytag2[6*14*1200],*ytag2_ptr; int16_t cseq[6*14*1200] __attribute__((aligned(32))); int off; - int frame = proc->frame_rx; int subframe = proc->subframe_rx; LTE_UL_eNB_HARQ_t *ulsch_harq; - - -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LOG_D(PHY,"ue_type %d\n",ulsch->ue_type); if (ulsch->ue_type>0) harq_pid = 0; else #endif @@ -815,60 +748,49 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,1); - + // x1 is set in lte_gold_generic x2 = ((uint32_t)ulsch->rnti<<14) + ((uint32_t)subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.3.1 ulsch_harq = ulsch->harq_processes[harq_pid]; - AssertFatal(harq_pid!=255, "FATAL ERROR: illegal harq_pid, returning\n"); - AssertFatal(ulsch_harq->Nsymb_pusch != 0, "FATAL ERROR: harq_pid %d, Nsymb 0!\n",harq_pid); - - nb_rb = ulsch_harq->nb_rb; - A = ulsch_harq->TBS; - - Q_m = ulsch_harq->Qm; G = nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch; - - //#ifdef DEBUG_ULSCH_DECODING LOG_D(PHY,"[PUSCH %d] Frame %d, Subframe %d: ulsch_decoding (Nid_cell %d, rnti %x, x2 %x): A %d, round %d, RV %d, O_r1 %d, O_RI %d, O_ACK %d, G %d, Q_m %d Nsymb_pusch %d nb_rb %d\n", - harq_pid, - proc->frame_rx,subframe, - frame_parms->Nid_cell,ulsch->rnti,x2, - A, - ulsch_harq->round, - ulsch_harq->rvidx, - ulsch_harq->Or1, - ulsch_harq->O_RI, - ulsch_harq->O_ACK, - G, + harq_pid, + proc->frame_rx,subframe, + frame_parms->Nid_cell,ulsch->rnti,x2, + A, + ulsch_harq->round, + ulsch_harq->rvidx, + ulsch_harq->Or1, + ulsch_harq->O_RI, + ulsch_harq->O_ACK, + G, ulsch_harq->Qm, ulsch_harq->Nsymb_pusch, nb_rb); - //#endif //if (ulsch_harq->round == 0) { // delete for RB shortage pattern - // This is a new packet, so compute quantities regarding segmentation - ulsch_harq->B = A+24; - lte_segmentation(NULL, - NULL, - ulsch_harq->B, - &ulsch_harq->C, - &ulsch_harq->Cplus, - &ulsch_harq->Cminus, - &ulsch_harq->Kplus, - &ulsch_harq->Kminus, - &ulsch_harq->F); - // CLEAR LLR's HERE for first packet in process + // This is a new packet, so compute quantities regarding segmentation + ulsch_harq->B = A+24; + lte_segmentation(NULL, + NULL, + ulsch_harq->B, + &ulsch_harq->C, + &ulsch_harq->Cplus, + &ulsch_harq->Cminus, + &ulsch_harq->Kplus, + &ulsch_harq->Kminus, + &ulsch_harq->F); + // CLEAR LLR's HERE for first packet in process //} // printf("after segmentation c[%d] = %p\n",0,ulsch_harq->c[0]); - sumKr = 0; for (r=0; r<ulsch_harq->C; r++) { @@ -881,17 +803,15 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, } AssertFatal(sumKr>0, - "[eNB] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n", - frame_parms->Nid_cell,ulsch->rnti,x2, - harq_pid, - ulsch_harq->round, - ulsch_harq->rvidx, - ulsch_harq->O_RI, - ulsch_harq->O_ACK, - G, - subframe); - - + "[eNB] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n", + frame_parms->Nid_cell,ulsch->rnti,x2, + harq_pid, + ulsch_harq->round, + ulsch_harq->rvidx, + ulsch_harq->O_RI, + ulsch_harq->O_ACK, + G, + subframe); // Compute Q_ri Qprime = ulsch_harq->O_RI*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_ri_times8; @@ -907,10 +827,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, Q_RI = Q_m*Qprime; Qprime_RI = Qprime; - - // Compute Q_ack - Qprime = ulsch_harq->O_ACK*ulsch_harq->Msc_initial*ulsch_harq->Nsymb_initial * ulsch->beta_offset_harqack_times8; if (Qprime > 0) { @@ -926,8 +843,8 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, // Q_ACK = Qprime * Q_m; Qprime_ACK = Qprime; #ifdef DEBUG_ULSCH_DECODING - printf("ulsch_decoding.c: Qprime_ACK %d, Msc_initial %d, Nsymb_initial %d, sumKr %d\n", - Qprime_ACK,ulsch_harq->Msc_initial,ulsch_harq->Nsymb_initial,sumKr); + printf("ulsch_decoding.c: Qprime_ACK %u, Msc_initial %d, Nsymb_initial %d, sumKr %u\n", + Qprime_ACK,ulsch_harq->Msc_initial,ulsch_harq->Nsymb_initial,sumKr); #endif // Compute Q_cqi @@ -950,43 +867,27 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, } G = nb_rb * (12 * Q_m) * (ulsch_harq->Nsymb_pusch); - - - Q_CQI = Q_m * Qprime; #ifdef DEBUG_ULSCH_DECODING - printf("ulsch_decoding: G %d, Q_RI %d, Q_CQI %d (L %d, Or1 %d) O_ACK %d\n",G,Q_RI,Q_CQI,L,ulsch_harq->Or1,ulsch_harq->O_ACK); + printf("ulsch_decoding: G %u, Q_RI %u, Q_CQI %u (L %u, Or1 %d) O_ACK %d\n",G,Q_RI,Q_CQI,L,ulsch_harq->Or1,ulsch_harq->O_ACK); #endif - G = G - Q_RI - Q_CQI; ulsch_harq->G = G; - AssertFatal((int)G > 0, "FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d\n",G,Q_RI,Q_CQI); - H = G + Q_CQI; Hprime = H/Q_m; - - // Demultiplexing/Deinterleaving of PUSCH/ACK/RI/CQI start_meas(&eNB->ulsch_demultiplexing_stats); Hpp = Hprime + Qprime_RI; - Cmux = ulsch_harq->Nsymb_pusch; Rmux_prime = Hpp/Cmux; - // Clear "tag" interleaving matrix to allow for CQI/DATA identification memset(ytag,0,Cmux*Rmux_prime); - - - i=0; memset(y,LTE_NULL,Q_m*Hpp); - // read in buffer and unscramble llrs for everything but placeholder bits // llrs stored per symbol correspond to columns of interleaving matrix - - s = lte_gold_unscram(&x1, &x2, 1); i2=0; @@ -998,26 +899,25 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, */ #if defined(__x86_64__) || defined(__i386__) #ifndef __AVX2__ - ((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[(s&65535)<<1]; - ((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[1+((s&65535)<<1)]; + ((__m128i *)cseq)[i2++] = ((__m128i *)unscrambling_lut)[(s&65535)<<1]; + ((__m128i *)cseq)[i2++] = ((__m128i *)unscrambling_lut)[1+((s&65535)<<1)]; s>>=16; - ((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[(s&65535)<<1]; - ((__m128i*)cseq)[i2++] = ((__m128i*)unscrambling_lut)[1+((s&65535)<<1)]; + ((__m128i *)cseq)[i2++] = ((__m128i *)unscrambling_lut)[(s&65535)<<1]; + ((__m128i *)cseq)[i2++] = ((__m128i *)unscrambling_lut)[1+((s&65535)<<1)]; #else - ((__m256i*)cseq)[i2++] = ((__m256i*)unscrambling_lut)[s&65535]; - ((__m256i*)cseq)[i2++] = ((__m256i*)unscrambling_lut)[(s>>16)&65535]; + ((__m256i *)cseq)[i2++] = ((__m256i *)unscrambling_lut)[s&65535]; + ((__m256i *)cseq)[i2++] = ((__m256i *)unscrambling_lut)[(s>>16)&65535]; #endif #elif defined(__arm__) - ((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[(s&65535)<<1]; - ((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[1+((s&65535)<<1)]; + ((int16x8_t *)cseq)[i2++] = ((int16x8_t *)unscrambling_lut)[(s&65535)<<1]; + ((int16x8_t *)cseq)[i2++] = ((int16x8_t *)unscrambling_lut)[1+((s&65535)<<1)]; s>>=16; - ((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[(s&65535)<<1]; - ((int16x8_t*)cseq)[i2++] = ((int16x8_t*)unscrambling_lut)[1+((s&65535)<<1)]; + ((int16x8_t *)cseq)[i2++] = ((int16x8_t *)unscrambling_lut)[(s&65535)<<1]; + ((int16x8_t *)cseq)[i2++] = ((int16x8_t *)unscrambling_lut)[1+((s&65535)<<1)]; #endif s = lte_gold_unscram(&x1, &x2, 0); } - // printf("after unscrambling c[%d] = %p\n",0,ulsch_harq->c[0]); if (frame_parms->Ncp == 0) @@ -1040,7 +940,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, cseq[off+q] = -1; // PUSCH_x j=(j+3)&3; - } // printf("after RI c[%d] = %p\n",0,ulsch_harq->c[0]); @@ -1069,87 +968,82 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, } #ifdef DEBUG_ULSCH_DECODING - printf("ulsch_decoding.c: ACK i %d, r %d, j %d, ColumnSet[j] %d\n",i,r,j,columnset[j]); + printf("ulsch_decoding.c: ACK i %u, r %d, j %u, ColumnSet[j] %d\n",i,r,j,columnset[j]); #endif j=(j+3)&3; } - - i=0; switch (Q_m) { - case 2: - for (j=0; j<Cmux; j++) { - i2=j<<1; - - for (r=0; r<Rmux_prime; r++) { - c = cseq[i]; - // printf("ulsch %d: %d * ",i,c); - y[i2++] = c*ulsch_llr[i++]; - // printf("%d\n",ulsch_llr[i-1]); - c = cseq[i]; - // printf("ulsch %d: %d * ",i,c); - y[i2] = c*ulsch_llr[i++]; - // printf("%d\n",ulsch_llr[i-1]); - i2=(i2+(Cmux<<1)-1); + case 2: + for (j=0; j<Cmux; j++) { + i2=j<<1; + + for (r=0; r<Rmux_prime; r++) { + c = cseq[i]; + // printf("ulsch %d: %d * ",i,c); + y[i2++] = c*ulsch_llr[i++]; + // printf("%d\n",ulsch_llr[i-1]); + c = cseq[i]; + // printf("ulsch %d: %d * ",i,c); + y[i2] = c*ulsch_llr[i++]; + // printf("%d\n",ulsch_llr[i-1]); + i2=(i2+(Cmux<<1)-1); + } } - } - - break; - - case 4: - for (j=0; j<Cmux; j++) { - i2=j<<2; - - for (r=0; r<Rmux_prime; r++) { - /* - c = cseq[i]; - y[i2++] = c*ulsch_llr[i++]; - c = cseq[i]; - y[i2++] = c*ulsch_llr[i++]; - c = cseq[i]; - y[i2++] = c*ulsch_llr[i++]; - c = cseq[i]; - y[i2] = c*ulsch_llr[i++]; - i2=(i2+(Cmux<<2)-3); - */ - // slightly more optimized version (equivalent to above) for 16QAM to improve computational performance - *(__m64 *)&y[i2] = _mm_sign_pi16(*(__m64*)&ulsch_llr[i],*(__m64*)&cseq[i]);i+=4;i2+=(Cmux<<2); + break; + case 4: + for (j=0; j<Cmux; j++) { + i2=j<<2; + + for (r=0; r<Rmux_prime; r++) { + /* + c = cseq[i]; + y[i2++] = c*ulsch_llr[i++]; + c = cseq[i]; + y[i2++] = c*ulsch_llr[i++]; + c = cseq[i]; + y[i2++] = c*ulsch_llr[i++]; + c = cseq[i]; + y[i2] = c*ulsch_llr[i++]; + i2=(i2+(Cmux<<2)-3); + */ + // slightly more optimized version (equivalent to above) for 16QAM to improve computational performance + *(__m64 *)&y[i2] = _mm_sign_pi16(*(__m64 *)&ulsch_llr[i],*(__m64 *)&cseq[i]); + i+=4; + i2+=(Cmux<<2); + } } - } - break; - - case 6: - for (j=0; j<Cmux; j++) { - i2=j*6; - - for (r=0; r<Rmux_prime; r++) { - c = cseq[i]; - y[i2++] = c*ulsch_llr[i++]; - c = cseq[i]; - y[i2++] = c*ulsch_llr[i++]; - c = cseq[i]; - y[i2++] = c*ulsch_llr[i++]; - c = cseq[i]; - y[i2++] = c*ulsch_llr[i++]; - c = cseq[i]; - y[i2++] = c*ulsch_llr[i++]; - c = cseq[i]; - y[i2] = c*ulsch_llr[i++]; - i2=(i2+(Cmux*6)-5); + break; + + case 6: + for (j=0; j<Cmux; j++) { + i2=j*6; + + for (r=0; r<Rmux_prime; r++) { + c = cseq[i]; + y[i2++] = c*ulsch_llr[i++]; + c = cseq[i]; + y[i2++] = c*ulsch_llr[i++]; + c = cseq[i]; + y[i2++] = c*ulsch_llr[i++]; + c = cseq[i]; + y[i2++] = c*ulsch_llr[i++]; + c = cseq[i]; + y[i2++] = c*ulsch_llr[i++]; + c = cseq[i]; + y[i2] = c*ulsch_llr[i++]; + i2=(i2+(Cmux*6)-5); + } } - } - break; + break; } - - - if (i!=(H+Q_RI)) LOG_D(PHY,"ulsch_decoding.c: Error in input buffer length (j %d, H+Q_RI %d)\n",i,H+Q_RI); @@ -1164,33 +1058,33 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, if (ulsch_harq->O_ACK == 1) { switch (Q_m) { - case 2: - len_ACK = 2; - break; + case 2: + len_ACK = 2; + break; - case 4: - len_ACK = 4; - break; + case 4: + len_ACK = 4; + break; - case 6: - len_ACK = 6; - break; + case 6: + len_ACK = 6; + break; } } if (ulsch_harq->O_ACK == 2) { switch (Q_m) { - case 2: - len_ACK = 6; - break; + case 2: + len_ACK = 6; + break; - case 4: - len_ACK = 12; - break; + case 4: + len_ACK = 12; + break; - case 6: - len_ACK = 18; - break; + case 6: + len_ACK = 18; + break; } } @@ -1202,13 +1096,13 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, for (i=0; i<len_ACK; i++) ulsch_harq->q_ACK[i] = 0; - for (i=0; i<Qprime_ACK; i++) { r = Rmux_prime -1 - (i>>2); for (q=0; q<Q_m; q++) { if (y[q+(Q_m*((r*Cmux) + columnset[j]))]!=0) ulsch_harq->q_ACK[(q+(Q_m*i))%len_ACK] += y[q+(Q_m*((r*Cmux) + columnset[j]))]; + y[q+(Q_m*((r*Cmux) + columnset[j]))]=0; // NULL LLRs in ACK positions } @@ -1221,17 +1115,17 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, if (ulsch_harq->O_RI == 1) { switch (Q_m) { - case 2: - len_RI=2; - break; + case 2: + len_RI=2; + break; - case 4: - len_RI=4; - break; + case 4: + len_RI=4; + break; - case 6: - len_RI=6; - break; + case 6: + len_RI=6; + break; } } @@ -1261,7 +1155,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, } // printf("after RI2 c[%d] = %p\n",0,ulsch_harq->c[0]); - // CQI and Data bits j=0; j2=0; @@ -1269,116 +1162,108 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, // r=0; if (Q_RI>0) { for (i=0; i<(Q_CQI/Q_m); i++) { - while (ytag[j]==LTE_NULL) { - j++; - j2+=Q_m; + j++; + j2+=Q_m; } - + for (q=0; q<Q_m; q++) { - // ys = y[q+(Q_m*((r*Cmux)+j))]; - ys = y[q+j2]; - - if (ys>127) - ulsch_harq->q[q+(Q_m*i)] = 127; - else if (ys<-128) - ulsch_harq->q[q+(Q_m*i)] = -128; - else - ulsch_harq->q[q+(Q_m*i)] = ys; + // ys = y[q+(Q_m*((r*Cmux)+j))]; + ys = y[q+j2]; + + if (ys>127) + ulsch_harq->q[q+(Q_m*i)] = 127; + else if (ys<-128) + ulsch_harq->q[q+(Q_m*i)] = -128; + else + ulsch_harq->q[q+(Q_m*i)] = ys; } - + j2+=Q_m; } - - + switch (Q_m) { - case 2: - for (iprime=0; iprime<G;) { - while (ytag[j]==LTE_NULL) { - j++; - j2+=2; - } - - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - - } - - - break; - - case 4: - for (iprime=0; iprime<G;) { - while (ytag[j]==LTE_NULL) { - j++; - j2+=4; - } - - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - - } - - break; - - case 6: - for (iprime=0; iprime<G;) { - while (ytag[j]==LTE_NULL) { - j++; - j2+=6; - } - - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - ulsch_harq->e[iprime++] = y[j2++]; - - } - - break; + case 2: + for (iprime=0; iprime<G;) { + while (ytag[j]==LTE_NULL) { + j++; + j2+=2; + } - } - + ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->e[iprime++] = y[j2++]; + } + + break; + + case 4: + for (iprime=0; iprime<G;) { + while (ytag[j]==LTE_NULL) { + j++; + j2+=4; + } + + ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->e[iprime++] = y[j2++]; + } + break; + + case 6: + for (iprime=0; iprime<G;) { + while (ytag[j]==LTE_NULL) { + j++; + j2+=6; + } + + ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->e[iprime++] = y[j2++]; + ulsch_harq->e[iprime++] = y[j2++]; + } + + break; + } } // Q_RI>0 else { - for (i=0; i<(Q_CQI/Q_m); i++) { - for (q=0; q<Q_m; q++) { - ys = y[q+j2]; - if (ys>127) - ulsch_harq->q[q+(Q_m*i)] = 127; - else if (ys<-128) - ulsch_harq->q[q+(Q_m*i)] = -128; - else - ulsch_harq->q[q+(Q_m*i)] = ys; + ys = y[q+j2]; + + if (ys>127) + ulsch_harq->q[q+(Q_m*i)] = 127; + else if (ys<-128) + ulsch_harq->q[q+(Q_m*i)] = -128; + else + ulsch_harq->q[q+(Q_m*i)] = ys; } - + j2+=Q_m; } + /* To be improved according to alignment of j2 -#if defined(__x86_64__)||defined(__i386__) -#ifndef __AVX2__ + #if defined(__x86_64__)||defined(__i386__) + #ifndef __AVX2__ for (iprime=0; iprime<G;iprime+=8,j2+=8) *((__m128i *)&ulsch_harq->e[iprime]) = *((__m128i *)&y[j2]); -#else + #else for (iprime=0; iprime<G;iprime+=16,j2+=16) *((__m256i *)&ulsch_harq->e[iprime]) = *((__m256i *)&y[j2]); -#endif -#elif defined(__arm__) + #endif + #elif defined(__arm__) for (iprime=0; iprime<G;iprime+=8,j2+=8) *((int16x8_t *)&ulsch_harq->e[iprime]) = *((int16x8_t *)&y[j2]); -#endif + #endif */ int16_t *yp,*ep; - for (iprime=0,yp=&y[j2],ep=&ulsch_harq->e[0]; - iprime<G; - iprime+=8,j2+=8,ep+=8,yp+=8) { + + for (iprime=0,yp=&y[j2],ep=&ulsch_harq->e[0]; + iprime<G; + iprime+=8,j2+=8,ep+=8,yp+=8) { ep[0] = yp[0]; ep[1] = yp[1]; ep[2] = yp[2]; @@ -1389,14 +1274,10 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, ep[7] = yp[7]; } } - - - stop_meas(&eNB->ulsch_demultiplexing_stats); + stop_meas(&eNB->ulsch_demultiplexing_stats); // printf("after ACKNAK2 c[%d] = %p (iprime %d, G %d)\n",0,ulsch_harq->c[0],iprime,G); - // Do CQI/RI/HARQ-ACK Decoding first and pass to MAC - // HARQ-ACK wACK_idx = (ulsch->bundling==0) ? 4 : ((Nbundled-1)&3); @@ -1412,22 +1293,23 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, if (ulsch_harq->O_ACK == 2) { switch (Q_m) { - - case 2: - ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[3]*wACK_RX[wACK_idx][1]; - ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[4]*wACK_RX[wACK_idx][1]; - ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[2]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX[wACK_idx][1]; - break; - case 4: - ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX[wACK_idx][1]; - ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[8]*wACK_RX[wACK_idx][1]; - ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[4]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[9]*wACK_RX[wACK_idx][1]; - break; - case 6: - ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[7]*wACK_RX[wACK_idx][1]; - ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[12]*wACK_RX[wACK_idx][1]; - ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[6]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[13]*wACK_RX[wACK_idx][1]; - break; + case 2: + ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[3]*wACK_RX[wACK_idx][1]; + ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[4]*wACK_RX[wACK_idx][1]; + ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[2]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX[wACK_idx][1]; + break; + + case 4: + ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[5]*wACK_RX[wACK_idx][1]; + ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[8]*wACK_RX[wACK_idx][1]; + ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[4]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[9]*wACK_RX[wACK_idx][1]; + break; + + case 6: + ulsch_harq->q_ACK[0] = ulsch_harq->q_ACK[0]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[7]*wACK_RX[wACK_idx][1]; + ulsch_harq->q_ACK[1] = ulsch_harq->q_ACK[1]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[12]*wACK_RX[wACK_idx][1]; + ulsch_harq->q_ACK[2] = ulsch_harq->q_ACK[6]*wACK_RX[wACK_idx][0] + ulsch_harq->q_ACK[13]*wACK_RX[wACK_idx][1]; + break; } ulsch_harq->o_ACK[0] = 1; @@ -1443,7 +1325,6 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, metric_new = ulsch_harq->q_ACK[0]-ulsch_harq->q_ACK[1]+ulsch_harq->q_ACK[2]; - if (metric_new > metric) { ulsch_harq->o_ACK[0] = 1; ulsch_harq->o_ACK[1] = 0; @@ -1467,26 +1348,21 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, } // CQI - // printf("before cqi c[%d] = %p\n",0,ulsch_harq->c[0]); ulsch_harq->cqi_crc_status = 0; + if (Q_CQI>0) { memset((void *)&dummy_w_cc[0],0,3*(ulsch_harq->Or1+8+32)); - O_RCC = generate_dummy_w_cc(ulsch_harq->Or1+8, &dummy_w_cc[0]); - - lte_rate_matching_cc_rx(O_RCC, Q_CQI, ulsch_harq->o_w, dummy_w_cc, ulsch_harq->q); - sub_block_deinterleaving_cc((unsigned int)(ulsch_harq->Or1+8), &ulsch_harq->o_d[96], &ulsch_harq->o_w[0]); - memset(ulsch_harq->o,0,(7+8+ulsch_harq->Or1) / 8); phy_viterbi_lte_sse2(ulsch_harq->o_d+96,ulsch_harq->o,8+ulsch_harq->Or1); @@ -1497,7 +1373,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, printf("ulsch_decoding: Or1=%d\n",ulsch_harq->Or1); for (i=0; i<1+((8+ulsch_harq->Or1)/8); i++) - printf("ulsch_decoding: O[%d] %d\n",i,ulsch_harq->o[i]); + printf("ulsch_decoding: O[%u] %d\n",i,ulsch_harq->o[i]); if (ulsch_harq->cqi_crc_status == 1) printf("RX CQI CRC OK (%x)\n",extract_cqi_crc(ulsch_harq->o,ulsch_harq->Or1)); @@ -1508,12 +1384,8 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, } LOG_D(PHY,"frame %d subframe %d O_ACK:%d o_ACK[]=%d:%d:%d:%d\n",frame,subframe,ulsch_harq->O_ACK,ulsch_harq->o_ACK[0],ulsch_harq->o_ACK[1],ulsch_harq->o_ACK[2],ulsch_harq->o_ACK[3]); - // Do ULSCH Decoding for data portion - ret = ulsch_decoding_data_all(eNB,UE_id,harq_pid,llr8_flag); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0); - return(ret); } diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 0c799d8494fcf416fe3682b10bbfca4d07b9be8c..da213c39199b6e748de919d8aa4d41a605cdd3db 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -687,7 +687,7 @@ void ulsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, ul_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(ul_ch_mag128_0[i],1),_mm_srai_epi16(ul_ch_mag128_1[i],1)); ul_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(ul_ch_mag128_0b[i],1),_mm_srai_epi16(ul_ch_mag128_1b[i],1)); rxdataF_comp128_0[i] = _mm_add_epi16(rxdataF_comp128_0[i],(*(__m128i*)&jitterc[0])); - + } #elif defined(__arm__) rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[0][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12]; @@ -702,10 +702,10 @@ void ulsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, ul_ch_mag128_0[i] = vhaddq_s16(ul_ch_mag128_0[i],ul_ch_mag128_1[i]); ul_ch_mag128_0b[i] = vhaddq_s16(ul_ch_mag128_0b[i],ul_ch_mag128_1b[i]); rxdataF_comp128_0[i] = vqaddq_s16(rxdataF_comp128_0[i],(*(int16x8_t*)&jitterc[0])); - + } #endif - } + } #if defined(__x86_64__) || defined(__i386__) @@ -1127,7 +1127,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, int16_t *llrp; int subframe = proc->subframe_rx; -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (ulsch[UE_id]->ue_type > 0) harq_pid =0; else #endif diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c index 89f0016c2396499fa55e03f9d95c6de34e695c01..4f65edd6d5fe5b87fac4866b08ce23ca4e8ea879 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c @@ -46,6 +46,7 @@ //#define DEBUG_DCI + #include "../LTE_TRANSPORT/dci_tools_common_extern.h" #include "../LTE_TRANSPORT/transport_proto.h" #include "transport_proto_ue.h" @@ -1281,7 +1282,7 @@ void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms, symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp)) { - if (frame_parms->nb_antenna_ports_eNB == 2) + if (frame_parms->nb_antenna_ports_eNB == 2) crs_re = 4; else crs_re = 2; @@ -2170,8 +2171,6 @@ int generate_ue_dlsch_params_from_dci(int frame, uint8_t beamforming_mode, uint16_t tc_rnti) { - - uint8_t harq_pid=0; uint8_t frame_type=frame_parms->frame_type; uint8_t tpmi=0; LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; @@ -2487,15 +2486,15 @@ int generate_ue_dlsch_params_from_dci(int frame, case format1E_2A_M10PRB: if (!dlsch[0]) return -1; - harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid; + dci_info_extarcted.harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid; - if (harq_pid>=8) { - LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid); + if (dci_info_extarcted.harq_pid>=8) { + LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", dci_info_extarcted.harq_pid); return(-1); } - dlsch[0]->current_harq_pid = harq_pid; - dlsch[0]->harq_ack[subframe].harq_id = harq_pid; + dlsch[0]->current_harq_pid = dci_info_extarcted.harq_pid; + dlsch[0]->harq_ack[subframe].harq_id = dci_info_extarcted.harq_pid; /* tbswap = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tb_swap; @@ -2510,7 +2509,7 @@ int generate_ue_dlsch_params_from_dci(int frame, */ dlsch0 = dlsch[0]; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; // Needs to be checked dlsch0_harq->codeword=0; conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, @@ -2626,7 +2625,7 @@ int generate_ue_dlsch_params_from_dci(int frame, // is NAK or an ACK was not received dlsch0->harq_ack[subframe].ack = 1; - dlsch0->harq_ack[subframe].harq_id = harq_pid; + dlsch0->harq_ack[subframe].harq_id = dci_info_extarcted.harq_pid; dlsch0->harq_ack[subframe].send_harq_status = 1; dlsch0->active = 0; return(0); @@ -2682,7 +2681,7 @@ int generate_ue_dlsch_params_from_dci(int frame, { T(T_UE_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame%1024), T_INT(subframe), T_INT(dlsch[0]->rnti), T_INT(dci_format), - T_INT(harq_pid), + T_INT(dci_info_extarcted.harq_pid), T_INT(dlsch0_harq->mcs), T_INT(dlsch0_harq->TBS)); } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c index 38caf7b44db67d12839e30d496be4b5e49f253f4..5091c8925af8d54604cd0518c6c815c0354bd838 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_ue.c @@ -362,6 +362,10 @@ void pdcch_channel_level(int32_t **dl_ch_estimates_ext, #elif defined(__arm__) int16x8_t *dl_ch128; int32x4_t *avg128P; +#else + int16_t *dl_ch128; + int32_t *avg128P; +#error Unsupported CPU architecture, cannot build __FILE__ #endif for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { @@ -370,7 +374,11 @@ void pdcch_channel_level(int32_t **dl_ch_estimates_ext, avg128P = _mm_setzero_si128(); dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][0]; #elif defined(__arm__) - + dl_ch128=&dl_ch_estimates_ext[(aatx<<1)+aarx][0]; +#error __arm__ not yet implemented, cannot build __FILE__ +#else + dl_ch128=&dl_ch_estimates_ext[(aatx<<1)+aarx][0]; +#error Unsupported CPU architecture, cannot build __FILE__ #endif for (rb=0; rb<nb_rb; rb++) { @@ -379,7 +387,8 @@ void pdcch_channel_level(int32_t **dl_ch_estimates_ext, avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[1],dl_ch128[1])); avg128P = _mm_add_epi32(avg128P,_mm_madd_epi16(dl_ch128[2],dl_ch128[2])); #elif defined(__arm__) - +#else +#error Unsupported CPU architecture, cannot build __FILE__ #endif dl_ch128+=3; /* @@ -423,6 +432,8 @@ void pdcch_detection_mrc_i(LTE_DL_FRAME_PARMS *frame_parms, __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1; #elif defined(__arm__) int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1; +#else +#error Unsupported CPU architecture, cannot build __FILE__ #endif int32_t i; @@ -436,6 +447,8 @@ void pdcch_detection_mrc_i(LTE_DL_FRAME_PARMS *frame_parms, #elif defined(__arm__) rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; +#else +#error Unsupported CPU architecture, cannot build __FILE__ #endif // MRC on each re of rb on MF output for (i=0; i<frame_parms->N_RB_DL*3; i++) { diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c index 1b4ca3ed2fb37e19b5beaa284a00e55a7c7b7e00..4ca9a7c7625f19470fb3023269e37081ade943d2 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c @@ -40,9 +40,7 @@ //#define DEBUG_DLSCH_DECODING //#define UE_DEBUG_TRACE 1 -void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) -{ - +void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) { int i,r; if (dlsch) { @@ -70,34 +68,30 @@ void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) } free16(dlsch,sizeof(LTE_UE_DLSCH_t)); - dlsch = NULL; } } -LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag) -{ - +LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag) { LTE_UE_DLSCH_t *dlsch; uint8_t exit_flag = 0,i,r; - unsigned char bw_scaling =1; switch (N_RB_DL) { - case 6: - bw_scaling =16; - break; + case 6: + bw_scaling =16; + break; - case 25: - bw_scaling =4; - break; + case 25: + bw_scaling =4; + break; - case 50: - bw_scaling =2; - break; + case 50: + bw_scaling =2; + break; - default: - bw_scaling =1; - break; + default: + bw_scaling =1; + break; } dlsch = (LTE_UE_DLSCH_t *)malloc16(sizeof(LTE_UE_DLSCH_t)); @@ -116,7 +110,7 @@ LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_ if (dlsch->harq_processes[i]) { memset(dlsch->harq_processes[i],0,sizeof(LTE_DL_UE_HARQ_t)); dlsch->harq_processes[i]->first_tx=1; - dlsch->harq_processes[i]->b = (uint8_t*)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); + dlsch->harq_processes[i]->b = (uint8_t *)malloc16(MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); if (dlsch->harq_processes[i]->b) memset(dlsch->harq_processes[i]->b,0,MAX_DLSCH_PAYLOAD_BYTES/bw_scaling); @@ -125,14 +119,14 @@ LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_ if (abstraction_flag == 0) { for (r=0; r<MAX_NUM_DLSCH_SEGMENTS/bw_scaling; r++) { - dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(((r==0)?8:0) + 3+ 768); + dlsch->harq_processes[i]->c[r] = (uint8_t *)malloc16(((r==0)?8:0) + 3+ 768); if (dlsch->harq_processes[i]->c[r]) memset(dlsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+ 768); else exit_flag=2; - dlsch->harq_processes[i]->d[r] = (short*)malloc16(((3*8*6144)+12+96)*sizeof(short)); + dlsch->harq_processes[i]->d[r] = (short *)malloc16(((3*8*6144)+12+96)*sizeof(short)); if (dlsch->harq_processes[i]->d[r]) memset(dlsch->harq_processes[i]->d[r],0,((3*8*6144)+12+96)*sizeof(short)); @@ -151,7 +145,6 @@ LTE_UE_DLSCH_t *new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_ printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(LTE_DL_UE_HARQ_t), exit_flag); free_ue_dlsch(dlsch); - return(NULL); } @@ -164,9 +157,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, uint8_t subframe, uint8_t harq_pid, uint8_t is_crnti, - uint8_t llr8_flag) -{ - + uint8_t llr8_flag) { #if UE_TIMING_TRACE time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats; time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats; @@ -186,26 +177,24 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, #if 0 int Kr_last,skipped_last=0; uint8_t (*tc_2cw)(int16_t *y, - int16_t *y2, - uint8_t *, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); - -#endif -decoder_if_t *tc; - + int16_t *y2, + uint8_t *, + uint8_t *, + uint16_t, + uint16_t, + uint16_t, + uint8_t, + uint8_t, + uint8_t, + time_stats_t *, + time_stats_t *, + time_stats_t *, + time_stats_t *, + time_stats_t *, + time_stats_t *, + time_stats_t *); +#endif + decoder_if_t *tc; if (!dlsch_llr) { printf("dlsch_decoding.c: NULL dlsch_llr pointer\n"); @@ -229,42 +218,32 @@ decoder_if_t *tc; if (dlsch->harq_ack[subframe].ack != 2) { LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n", - phy_vars_ue->Mod_id, subframe, dlsch->harq_ack[subframe].ack); + phy_vars_ue->Mod_id, subframe, dlsch->harq_ack[subframe].ack); } if (llr8_flag == 0) { tc = decoder16; - } - else - { + } else { AssertFatal (harq_process->TBS >= 256 , "Mismatch flag nbRB=%d TBS=%d mcs=%d Qm=%d RIV=%d round=%d \n", - harq_process->nb_rb, harq_process->TBS,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); + harq_process->nb_rb, harq_process->TBS,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); tc = decoder8; } - // nb_rb = dlsch->nb_rb; - /* if (nb_rb > frame_parms->N_RB_DL) { printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb); return(max_turbo_iterations); }*/ - /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]]; if (harq_pid >= 8) { printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid); return(max_turbo_iterations); } */ - harq_process->trials[harq_process->round]++; - A = harq_process->TBS; //2072 for QPSK 1/3 - ret = dlsch->max_turbo_iterations; - - G = harq_process->G; //get_G(frame_parms,nb_rb,dlsch->rb_alloc,mod_order,num_pdcch_symbols,phy_vars_ue->frame,subframe); @@ -293,40 +272,37 @@ decoder_if_t *tc; */ err_flag = 0; r_offset = 0; - unsigned char bw_scaling =1; switch (frame_parms->N_RB_DL) { - case 6: - bw_scaling =16; - break; + case 6: + bw_scaling =16; + break; - case 25: - bw_scaling =4; - break; + case 25: + bw_scaling =4; + break; - case 50: - bw_scaling =2; - break; + case 50: + bw_scaling =2; + break; - default: - bw_scaling =1; - break; + default: + bw_scaling =1; + break; } if (harq_process->C > MAX_NUM_DLSCH_SEGMENTS/bw_scaling) { LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,MAX_NUM_DLSCH_SEGMENTS/bw_scaling); return((1+dlsch->max_turbo_iterations)); } + #ifdef DEBUG_DLSCH_DECODING printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus); #endif - opp_enabled=1; for (r=0; r<harq_process->C; r++) { - - // Get Turbo interleaver parameters if (r<harq_process->Cminus) Kr = harq_process->Kminus; @@ -334,15 +310,13 @@ decoder_if_t *tc; Kr = harq_process->Kplus; Kr_bytes = Kr>>3; - #if UE_TIMING_TRACE start_meas(dlsch_rate_unmatching_stats); #endif memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short)); harq_process->RTC[r] = generate_dummy_w(4+(Kr_bytes*8), - (uint8_t*) &dummy_w[r][0], + (uint8_t *) &dummy_w[r][0], (r==0) ? harq_process->F : 0); - #ifdef DEBUG_DLSCH_DECODING LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", harq_pid,r, G, @@ -354,14 +328,14 @@ decoder_if_t *tc; harq_process->rvidx, harq_process->round); #endif - #ifdef DEBUG_DLSCH_DECODING printf(" in decoding dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx); #endif + if (lte_rate_matching_turbo_rx(harq_process->RTC[r], G, harq_process->w[r], - (uint8_t*)&dummy_w[r][0], + (uint8_t *)&dummy_w[r][0], dlsch_llr+r_offset, harq_process->C, dlsch->Nsoft, @@ -378,14 +352,13 @@ decoder_if_t *tc; #endif LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n"); return(dlsch->max_turbo_iterations); - } else - { + } else { #if UE_TIMING_TRACE stop_meas(dlsch_rate_unmatching_stats); #endif } - r_offset += E; + r_offset += E; /* printf("Subblock deinterleaving, d %p w %p\n", harq_process->d[r], @@ -396,7 +369,6 @@ decoder_if_t *tc; #endif sub_block_deinterleaving_turbo(4+Kr, &harq_process->d[r][96], - harq_process->w[r]); #if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); @@ -413,8 +385,6 @@ decoder_if_t *tc; printf("%d : %d\n",i,harq_process->d[r][96+i]); printf("\n");*/ #endif - - // printf("Clearing c, %p\n",harq_process->c[r]); memset(harq_process->c[r],0,Kr_bytes); @@ -432,21 +402,22 @@ decoder_if_t *tc; printf("%d : %d\n",i,harq_process->d[r][96+i]); printf("\n"); */ - //#ifndef __AVX2__ #if 1 + if (err_flag == 0) { -/* - LOG_I(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n", - Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS, - harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_turbo_iterations); -*/ - if (llr8_flag) { - AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", - Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); - } + /* + LOG_I(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n", + Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS, + harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_turbo_iterations); + */ + if (llr8_flag) { + AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", + Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); + } + #if UE_TIMING_TRACE - start_meas(dlsch_turbo_decoding_stats); + start_meas(dlsch_turbo_decoding_stats); #endif LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); ret = tc @@ -465,17 +436,17 @@ decoder_if_t *tc; &phy_vars_ue->dlsch_tc_ext_stats, &phy_vars_ue->dlsch_tc_intl1_stats, &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); - #if UE_TIMING_TRACE stop_meas(dlsch_turbo_decoding_stats); #endif } + #else - if ((harq_process->C == 1) || - ((r==harq_process->C-1) && (skipped_last==0))) { // last segment with odd number of segments + if ((harq_process->C == 1) || + ((r==harq_process->C-1) && (skipped_last==0))) { // last segment with odd number of segments #if UE_TIMING_TRACE - start_meas(dlsch_turbo_decoding_stats); + start_meas(dlsch_turbo_decoding_stats); #endif ret = tc (&harq_process->d[r][96], @@ -491,123 +462,115 @@ decoder_if_t *tc; &phy_vars_ue->dlsch_tc_ext_stats, &phy_vars_ue->dlsch_tc_intl1_stats, &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); - #if UE_TIMING_TRACE +#if UE_TIMING_TRACE stop_meas(dlsch_turbo_decoding_stats); #endif // printf("single decode, exit\n"); // exit(-1); - } - else { - // we can merge code segments + } else { + // we can merge code segments if ((skipped_last == 0) && (r<harq_process->C-1)) { - skipped_last = 1; - Kr_last = Kr; - } - else { - skipped_last=0; + skipped_last = 1; + Kr_last = Kr; + } else { + skipped_last=0; - if (Kr_last == Kr) { // decode 2 code segments with AVX2 version + if (Kr_last == Kr) { // decode 2 code segments with AVX2 version #ifdef DEBUG_DLSCH_DECODING - printf("single decoding segment %d (%p)\n",r-1,&harq_process->d[r-1][96]); + printf("single decoding segment %d (%p)\n",r-1,&harq_process->d[r-1][96]); #endif #if UE_TIMING_TRACE - start_meas(dlsch_turbo_decoding_stats); + start_meas(dlsch_turbo_decoding_stats); #endif #ifdef DEBUG_DLSCH_DECODING - printf("double decoding segments %d,%d (%p,%p)\n",r-1,r,&harq_process->d[r-1][96],&harq_process->d[r][96]); -#endif - ret = tc_2cw - (&harq_process->d[r-1][96], - &harq_process->d[r][96], - harq_process->c[r-1], - harq_process->c[r], - Kr, - dlsch->max_turbo_iterations, - crc_type, - (r==0) ? harq_process->F : 0, - &phy_vars_ue->dlsch_tc_init_stats, - &phy_vars_ue->dlsch_tc_alpha_stats, - &phy_vars_ue->dlsch_tc_beta_stats, - &phy_vars_ue->dlsch_tc_gamma_stats, - &phy_vars_ue->dlsch_tc_ext_stats, - &phy_vars_ue->dlsch_tc_intl1_stats, - &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); - /* - ret = tc - (&harq_process->d[r-1][96], - harq_process->c[r-1], - Kr_last, - dlsch->max_turbo_iterations, - crc_type, - (r==0) ? harq_process->F : 0, - &phy_vars_ue->dlsch_tc_init_stats, - &phy_vars_ue->dlsch_tc_alpha_stats, - &phy_vars_ue->dlsch_tc_beta_stats, - &phy_vars_ue->dlsch_tc_gamma_stats, - &phy_vars_ue->dlsch_tc_ext_stats, - &phy_vars_ue->dlsch_tc_intl1_stats, - &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); - - exit(-1);*/ + printf("double decoding segments %d,%d (%p,%p)\n",r-1,r,&harq_process->d[r-1][96],&harq_process->d[r][96]); +#endif + ret = tc_2cw + (&harq_process->d[r-1][96], + &harq_process->d[r][96], + harq_process->c[r-1], + harq_process->c[r], + Kr, + dlsch->max_turbo_iterations, + crc_type, + (r==0) ? harq_process->F : 0, + &phy_vars_ue->dlsch_tc_init_stats, + &phy_vars_ue->dlsch_tc_alpha_stats, + &phy_vars_ue->dlsch_tc_beta_stats, + &phy_vars_ue->dlsch_tc_gamma_stats, + &phy_vars_ue->dlsch_tc_ext_stats, + &phy_vars_ue->dlsch_tc_intl1_stats, + &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); + /* + ret = tc + (&harq_process->d[r-1][96], + harq_process->c[r-1], + Kr_last, + dlsch->max_turbo_iterations, + crc_type, + (r==0) ? harq_process->F : 0, + &phy_vars_ue->dlsch_tc_init_stats, + &phy_vars_ue->dlsch_tc_alpha_stats, + &phy_vars_ue->dlsch_tc_beta_stats, + &phy_vars_ue->dlsch_tc_gamma_stats, + &phy_vars_ue->dlsch_tc_ext_stats, + &phy_vars_ue->dlsch_tc_intl1_stats, + &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); + + exit(-1);*/ #if UE_TIMING_TRACE - stop_meas(dlsch_turbo_decoding_stats); + stop_meas(dlsch_turbo_decoding_stats); #endif - } - else { // Kr_last != Kr + } else { // Kr_last != Kr #if UE_TIMING_TRACE - start_meas(dlsch_turbo_decoding_stats); -#endif - ret = tc - (&harq_process->d[r-1][96], - harq_process->c[r-1], - Kr_last, - dlsch->max_turbo_iterations, - crc_type, - (r==0) ? harq_process->F : 0, - &phy_vars_ue->dlsch_tc_init_stats, - &phy_vars_ue->dlsch_tc_alpha_stats, - &phy_vars_ue->dlsch_tc_beta_stats, - &phy_vars_ue->dlsch_tc_gamma_stats, - &phy_vars_ue->dlsch_tc_ext_stats, - &phy_vars_ue->dlsch_tc_intl1_stats, - &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); + start_meas(dlsch_turbo_decoding_stats); +#endif + ret = tc + (&harq_process->d[r-1][96], + harq_process->c[r-1], + Kr_last, + dlsch->max_turbo_iterations, + crc_type, + (r==0) ? harq_process->F : 0, + &phy_vars_ue->dlsch_tc_init_stats, + &phy_vars_ue->dlsch_tc_alpha_stats, + &phy_vars_ue->dlsch_tc_beta_stats, + &phy_vars_ue->dlsch_tc_gamma_stats, + &phy_vars_ue->dlsch_tc_ext_stats, + &phy_vars_ue->dlsch_tc_intl1_stats, + &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); #if UE_TIMING_TRACE - stop_meas(dlsch_turbo_decoding_stats); - - start_meas(dlsch_turbo_decoding_stats); -#endif - - ret = tc - (&harq_process->d[r][96], - harq_process->c[r], - Kr, - dlsch->max_turbo_iterations, - crc_type, - (r==0) ? harq_process->F : 0, - &phy_vars_ue->dlsch_tc_init_stats, - &phy_vars_ue->dlsch_tc_alpha_stats, - &phy_vars_ue->dlsch_tc_beta_stats, - &phy_vars_ue->dlsch_tc_gamma_stats, - &phy_vars_ue->dlsch_tc_ext_stats, - &phy_vars_ue->dlsch_tc_intl1_stats, - &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); - + stop_meas(dlsch_turbo_decoding_stats); + start_meas(dlsch_turbo_decoding_stats); +#endif + ret = tc + (&harq_process->d[r][96], + harq_process->c[r], + Kr, + dlsch->max_turbo_iterations, + crc_type, + (r==0) ? harq_process->F : 0, + &phy_vars_ue->dlsch_tc_init_stats, + &phy_vars_ue->dlsch_tc_alpha_stats, + &phy_vars_ue->dlsch_tc_beta_stats, + &phy_vars_ue->dlsch_tc_gamma_stats, + &phy_vars_ue->dlsch_tc_ext_stats, + &phy_vars_ue->dlsch_tc_intl1_stats, + &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1); #if UE_TIMING_TRACE - - stop_meas(dlsch_turbo_decoding_stats); - - /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f dlsch_turbo_decoding_stats %5.3f \n", - harq_process->C, - r, - dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0), - dlsch_deinterleaving_stats->p_time/(cpuf*1000.0), - dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/ + stop_meas(dlsch_turbo_decoding_stats); + /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f dlsch_turbo_decoding_stats %5.3f \n", + harq_process->C, + r, + dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0), + dlsch_deinterleaving_stats->p_time/(cpuf*1000.0), + dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/ #endif - } + } } } -#endif +#endif if ((err_flag == 0) && (ret>=(1+dlsch->max_turbo_iterations))) {// a Code segment is in error so break; LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); @@ -617,16 +580,18 @@ decoder_if_t *tc; int32_t frame_rx_prev = frame; int32_t subframe_rx_prev = subframe - 1; + if (subframe_rx_prev < 0) { frame_rx_prev--; subframe_rx_prev += 10; } + frame_rx_prev = frame_rx_prev%1024; if (err_flag == 1) { #if UE_DEBUG_TRACE LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", - phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); + phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); #endif dlsch->harq_ack[subframe].ack = 0; dlsch->harq_ack[subframe].harq_id = harq_pid; @@ -634,39 +599,36 @@ decoder_if_t *tc; harq_process->errors[harq_process->round]++; harq_process->round++; - // printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); if (harq_process->round >= dlsch->Mdlharq) { harq_process->status = SCH_IDLE; harq_process->round = 0; } - if(is_crnti) - { - LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", - phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); + + if(is_crnti) { + LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); } return((1+dlsch->max_turbo_iterations)); } else { #if UE_DEBUG_TRACE - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d mcs %d nb_rb %d\n", - phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d mcs %d nb_rb %d\n", + phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); #endif - harq_process->status = SCH_IDLE; harq_process->round = 0; dlsch->harq_ack[subframe].ack = 1; dlsch->harq_ack[subframe].harq_id = harq_pid; dlsch->harq_ack[subframe].send_harq_status = 1; //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n", - // phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs); + // phy_vars_ue->Mod_id, frame, subframe, harq_pid, harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs); - if(is_crnti) - { - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS); + if(is_crnti) { + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS); } - //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); + //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); } // Reassembly of Transport block here @@ -706,24 +668,20 @@ decoder_if_t *tc; } dlsch->last_iteration_cnt = ret; - return(ret); } int dlsch_encoding_SIC(PHY_VARS_UE *ue, - unsigned char *a, - uint8_t num_pdcch_symbols, - LTE_eNB_DLSCH_t *dlsch, - int frame, - uint8_t subframe, - time_stats_t *rm_stats, - time_stats_t *te_stats, - time_stats_t *i_stats) -{ - + unsigned char *a, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe, + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats) { unsigned int G; unsigned int crc=1; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; unsigned char harq_pid = ue->dlsch[subframe&2][0][0]->rnti; unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb; @@ -732,9 +690,7 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue, unsigned int Kr=0,Kr_bytes,r,r_offset=0; // unsigned short m=dlsch->harq_processes[harq_pid]->mcs; uint8_t beamforming_mode=0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); - A = dlsch->harq_processes[harq_pid]->TBS; //6228 // printf("Encoder: A: %d\n",A); mod_order = dlsch->harq_processes[harq_pid]->Qm; @@ -745,13 +701,13 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue, beamforming_mode = 8; else if(dlsch->harq_processes[harq_pid]->mimo_mode == TM9_10) beamforming_mode = 9; - G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode); + G = get_G(frame_parms,nb_rb,dlsch->harq_processes[harq_pid]->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,frame,subframe,beamforming_mode); // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet #ifdef DEBUG_DLSCH_CODING - printf("SIC encoding thinks this is a new packet \n"); + printf("SIC encoding thinks this is a new packet \n"); #endif /* int i; @@ -763,11 +719,10 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue, // Add 24-bit crc (polynomial A) to payload crc = crc24a(a, A)>>8; - a[A>>3] = ((uint8_t*)&crc)[2]; - a[1+(A>>3)] = ((uint8_t*)&crc)[1]; - a[2+(A>>3)] = ((uint8_t*)&crc)[0]; + a[A>>3] = ((uint8_t *)&crc)[2]; + a[1+(A>>3)] = ((uint8_t *)&crc)[1]; + a[2+(A>>3)] = ((uint8_t *)&crc)[0]; // printf("CRC %x (A %d)\n",crc,A); - dlsch->harq_processes[harq_pid]->B = A+24; // dlsch->harq_processes[harq_pid]->b = a; memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4); @@ -784,25 +739,20 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue, return(-1); for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { - if (r<dlsch->harq_processes[harq_pid]->Cminus) Kr = dlsch->harq_processes[harq_pid]->Kminus; else Kr = dlsch->harq_processes[harq_pid]->Kplus; Kr_bytes = Kr>>3; - #ifdef DEBUG_DLSCH_CODING - printf("Generating Code Segment %d (%d bits)\n",r,Kr); + printf("Generating Code Segment %u (%u bits)\n",r,Kr); // generate codewords - - printf("bits_per_codeword (Kr)= %d, A %d\n",Kr,A); + printf("bits_per_codeword (Kr)= %u, A %u\n",Kr,A); printf("N_RB = %d\n",nb_rb); printf("Ncp %d\n",frame_parms->Ncp); printf("mod_order %d\n",mod_order); #endif - - start_meas(te_stats); encoder(dlsch->harq_processes[harq_pid]->c[r], Kr>>3, @@ -823,7 +773,6 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue, dlsch->harq_processes[harq_pid]->w[r]); stop_meas(i_stats); } - } // Fill in the "e"-sequence from 36-212, V8.6 2009-03, p. 16-17 (for each "e") and concatenate the @@ -831,13 +780,12 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue, for (r=0; r<dlsch->harq_processes[harq_pid]->C; r++) { #ifdef DEBUG_DLSCH_CODING - printf("Rate Matching, Code segment %d (coded bits (G) %d,unpunctured/repeated bits per code segment %d,mod_order %d, nb_rb %d)...\n", - r, - G, - Kr*3, - mod_order,nb_rb); + printf("Rate Matching, Code segment %u (coded bits (G) %u,unpunctured/repeated bits per code segment %u,mod_order %d, nb_rb %d)...\n", + r, + G, + Kr*3, + mod_order,nb_rb); #endif - start_meas(rm_stats); #ifdef DEBUG_DLSCH_CODING printf("rvidx in SIC encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx); @@ -866,6 +814,5 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue, } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT); - return(0); } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index b4d8517ad824ac1a703f9b298f1d47685224d1ae..aafd579899ad023de7cbc7e0c843b75bab09215d 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -42,11 +42,11 @@ #include <string.h> #include <linux/version.h> #if RHEL_RELEASE_CODE >= 1796 -#include <lapacke/lapacke_utils.h> -#include <lapacke/lapacke.h> + #include <lapacke/lapacke_utils.h> + #include <lapacke/lapacke.h> #else -#include <lapacke_utils.h> -#include <lapacke.h> + #include <lapacke_utils.h> + #include <lapacke.h> #endif #include <cblas.h> #include "linear_preprocessing_rec.h" @@ -72,10 +72,12 @@ int16_t interf_unaw_shift = 13; // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; //inferference-free case -unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, - 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ; -unsigned char interf_unaw_shift_tm1_mcs[29]={5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1, - 0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6} ; // mcs 21, 26, 28 seem to be errorneous +unsigned char interf_unaw_shift_tm4_mcs[29]= {5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0 + } ; +unsigned char interf_unaw_shift_tm1_mcs[29]= {5, 5, 4, 3, 3, 3, 2, 2, 4, 4, 2, 3, 3, 3, 1, 1, + 0, 1, 1, 2, 5, 4, 4, 6, 5, 1, 0, 5, 6 + } ; // mcs 21, 26, 28 seem to be errorneous /* //original values from sebastion + same hand tuning @@ -83,14 +85,14 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{ {5,5,4},{5,5,5},{5,5,5},{3,3,3},{2,2,2},{2,2,2},{2,2,2}, // 16-QAM {2,2,1},{3,3,3},{3,3,3},{3,3,1},{2,2,2},{2,2,2},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}}; //64-QAM */ - /* - //first optimization try - unsigned char offset_mumimo_llr_drange[29][3]={{7, 8, 7},{6, 6, 7},{6, 6, 7},{6, 6, 6},{5, 6, 6},{5, 5, 6},{5, 5, 6},{4, 5, 4},{4, 3, 4},{3, 2, 2},{6, 5, 5},{5, 4, 4},{5, 5, 4},{3, 3, 2},{2, 2, 1},{2, 1, 1},{2, 2, 2},{3, 3, 3},{3, 3, 2},{3, 3, 2},{3, 2, 1},{2, 2, 2},{2, 2, 2},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}}; - */ - //second optimization try - /* - unsigned char offset_mumimo_llr_drange[29][3]={{5, 8, 7},{4, 6, 8},{3, 6, 7},{7, 7, 6},{4, 7, 8},{4, 7, 4},{6, 6, 6},{3, 6, 6},{3, 6, 6},{1, 3, 4},{1, 1, 0},{3, 3, 2},{3, 4, 1},{4, 0, 1},{4, 2, 2},{3, 1, 2},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}}; w - */ +/* +//first optimization try +unsigned char offset_mumimo_llr_drange[29][3]={{7, 8, 7},{6, 6, 7},{6, 6, 7},{6, 6, 6},{5, 6, 6},{5, 5, 6},{5, 5, 6},{4, 5, 4},{4, 3, 4},{3, 2, 2},{6, 5, 5},{5, 4, 4},{5, 5, 4},{3, 3, 2},{2, 2, 1},{2, 1, 1},{2, 2, 2},{3, 3, 3},{3, 3, 2},{3, 3, 2},{3, 2, 1},{2, 2, 2},{2, 2, 2},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}}; +*/ +//second optimization try +/* + unsigned char offset_mumimo_llr_drange[29][3]={{5, 8, 7},{4, 6, 8},{3, 6, 7},{7, 7, 6},{4, 7, 8},{4, 7, 4},{6, 6, 6},{3, 6, 6},{3, 6, 6},{1, 3, 4},{1, 1, 0},{3, 3, 2},{3, 4, 1},{4, 0, 1},{4, 2, 2},{3, 1, 2},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}}; w +*/ unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}}; @@ -107,111 +109,99 @@ int rx_pdsch(PHY_VARS_UE *ue, unsigned char first_symbol_flag, RX_type_t rx_type, unsigned char i_mod, - unsigned char harq_pid) -{ - + unsigned char harq_pid) { LTE_UE_COMMON *common_vars = &ue->common_vars; LTE_UE_PDSCH **pdsch_vars; LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; PHY_MEASUREMENTS *measurements = &ue->measurements; LTE_UE_DLSCH_t **dlsch; - int avg[4]; int avg_0[2]; int avg_1[2]; unsigned short mmse_flag=0; - #if UE_TIMING_TRACE uint8_t slot = 0; #endif - unsigned char aatx,aarx; - unsigned short nb_rb = 0, round; int avgs = 0, rb; LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0; - uint8_t beamforming_mode; uint32_t *rballoc; - int32_t **rxdataF_comp_ptr; int32_t **dl_ch_mag_ptr; int32_t codeword_TB0 = -1; int32_t codeword_TB1 = -1; - - switch (type) { - case SI_PDSCH: - pdsch_vars = &ue->pdsch_vars_SI[eNB_id]; - dlsch = &ue->dlsch_SI[eNB_id]; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - beamforming_mode = 0; - break; - - case RA_PDSCH: - pdsch_vars = &ue->pdsch_vars_ra[eNB_id]; - dlsch = &ue->dlsch_ra[eNB_id]; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - beamforming_mode = 0; - break; - - case PDSCH: - pdsch_vars = ue->pdsch_vars[ue->current_thread_id[subframe]]; - dlsch = ue->dlsch[ue->current_thread_id[subframe]][eNB_id]; - //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status); - LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", - frame,subframe,symbol,harq_pid, - dlsch[0]->harq_processes[harq_pid]->status, - dlsch[1]->harq_processes[harq_pid]->status); - - if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) && - (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE)){ - codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword; - codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword; - dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid]; - dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid]; + case SI_PDSCH: + pdsch_vars = &ue->pdsch_vars_SI[eNB_id]; + dlsch = &ue->dlsch_SI[eNB_id]; + dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + beamforming_mode = 0; + break; + + case RA_PDSCH: + pdsch_vars = &ue->pdsch_vars_ra[eNB_id]; + dlsch = &ue->dlsch_ra[eNB_id]; + dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + beamforming_mode = 0; + break; + + case PDSCH: + pdsch_vars = ue->pdsch_vars[ue->current_thread_id[subframe]]; + dlsch = ue->dlsch[ue->current_thread_id[subframe]][eNB_id]; + //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status); + LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", + frame,subframe,symbol,harq_pid, + dlsch[0]->harq_processes[harq_pid]->status, + dlsch[1]->harq_processes[harq_pid]->status); + + if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) && + (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE)) { + codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword; + codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword; + dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid]; + dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid]; #ifdef DEBUG_HARQ - printf("[DEMOD] I am assuming both TBs are active\n"); + printf("[DEMOD] I am assuming both TBs are active\n"); #endif - } - else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) && - (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) { - codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - dlsch1_harq = NULL; - codeword_TB1 = -1; + } else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) && + (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) { + codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword; + dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + dlsch1_harq = NULL; + codeword_TB1 = -1; #ifdef DEBUG_HARQ - printf("[DEMOD] I am assuming only TB0 is active\n"); + printf("[DEMOD] I am assuming only TB0 is active\n"); #endif - } - else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) && - (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ){ - codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword; - dlsch0_harq = dlsch[1]->harq_processes[harq_pid]; - dlsch1_harq = NULL; - codeword_TB0 = -1; + } else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) && + (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ) { + codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword; + dlsch0_harq = dlsch[1]->harq_processes[harq_pid]; + dlsch1_harq = NULL; + codeword_TB0 = -1; #ifdef DEBUG_HARQ - printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch0_harq->codeword); + printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch0_harq->codeword); #endif - } - else { - LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,subframe); - return(-1); - } - beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]; - break; + } else { + LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,subframe); + return(-1); + } - default: - LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: Unknown PDSCH format %d\n",ue->proc.proc_rxtx[0].frame_rx,subframe,type); - return(-1); - break; + beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]; + break; + + default: + LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: Unknown PDSCH format %d\n",ue->proc.proc_rxtx[0].frame_rx,subframe,type); + return(-1); + break; } + #ifdef DEBUG_HARQ printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode); printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1); #endif - DevAssert(dlsch0_harq); round = dlsch0_harq->round; //printf("round = %d\n", round); @@ -247,15 +237,14 @@ int rx_pdsch(PHY_VARS_UE *ue, else rballoc = dlsch0_harq->rb_alloc_even; - if (dlsch0_harq->mimo_mode>DUALSTREAM_PUSCH_PRECODING) { LOG_E(PHY,"This transmission mode is not yet supported!\n"); return(-1); } - if ((dlsch0_harq->mimo_mode==LARGE_CDD) || ((dlsch0_harq->mimo_mode>=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode<=DUALSTREAM_PUSCH_PRECODING))) { DevAssert(dlsch1_harq); + if (eNB_id!=eNB_id_i) { LOG_E(PHY,"TM3/TM4 requires to set eNB_id==eNB_id_i!\n"); return(-1); @@ -263,12 +252,12 @@ int rx_pdsch(PHY_VARS_UE *ue, } #if UE_TIMING_TRACE - if(symbol > ue->frame_parms.symbols_per_tti>>1) - { - slot = 1; + + if(symbol > ue->frame_parms.symbols_per_tti>>1) { + slot = 1; } -#endif +#endif #ifdef DEBUG_HARQ printf("Demod dlsch0_harq->pmi_alloc %d\n", dlsch0_harq->pmi_alloc); #endif @@ -277,7 +266,6 @@ int rx_pdsch(PHY_VARS_UE *ue, #ifdef DEBUG_DLSCH_MOD LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0],dlsch0_harq->rb_alloc_even[0]); #endif - #if UE_TIMING_TRACE start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif @@ -294,15 +282,17 @@ int rx_pdsch(PHY_VARS_UE *ue, frame_parms, dlsch0_harq->mimo_mode); #ifdef DEBUG_DLSCH_MOD - printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc); - for (rb=0;rb<nb_rb;rb++) - printf("%d",pdsch_vars[eNB_id]->pmi_ext[rb]); - printf("\n"); + printf("dlsch: using pmi %lx, rb_alloc %x, pmi_ext ",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),*rballoc); + + for (rb=0; rb<nb_rb; rb++) + printf("%d",pdsch_vars[eNB_id]->pmi_ext[rb]); + + printf("\n"); #endif - if (rx_type >= rx_IC_single_stream) { + if (rx_type >= rx_IC_single_stream) { if (eNB_id_i<ue->n_connected_eNB) // we are in TM5 - nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, + nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i], pdsch_vars[eNB_id_i]->rxdataF_ext, pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, @@ -341,8 +331,8 @@ int rx_pdsch(PHY_VARS_UE *ue, ue->high_speed_flag, frame_parms); - if (rx_type==rx_IC_single_stream) { - if (eNB_id_i<ue->n_connected_eNB) + if (rx_type==rx_IC_single_stream) { + if (eNB_id_i<ue->n_connected_eNB) nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF, common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i], pdsch_vars[eNB_id_i]->rxdataF_ext, @@ -377,7 +367,6 @@ int rx_pdsch(PHY_VARS_UE *ue, subframe, ue->high_speed_flag, frame_parms); - } else if(beamforming_mode>7) { LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n"); } @@ -388,25 +377,21 @@ int rx_pdsch(PHY_VARS_UE *ue, return(-1); } - #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,subframe,slot, - symbol,ue->high_speed_flag,type,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,subframe,slot, + symbol,ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,subframe,slot,symbol, - ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,subframe,slot,symbol, + ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #endif #endif - - #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif aatx = frame_parms->nb_antenna_ports_eNB; aarx = frame_parms->nb_antennas_rx; - dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, dlsch, @@ -417,8 +402,7 @@ int rx_pdsch(PHY_VARS_UE *ue, (rx_type==rx_IC_single_stream) && (eNB_id_i==ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0) - ) // TM5 two-user - { + ) { // TM5 two-user dlsch_scale_channel(pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, frame_parms, dlsch, @@ -427,109 +411,100 @@ int rx_pdsch(PHY_VARS_UE *ue, } #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #endif #endif - #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif + if (first_symbol_flag==1) { - if (beamforming_mode==0){ + if (beamforming_mode==0) { if (dlsch0_harq->mimo_mode<LARGE_CDD) { dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - avg, - symbol, - nb_rb); + frame_parms, + avg, + symbol, + nb_rb); avgs = 0; - for (aatx=0;aatx<frame_parms->nb_antenna_ports_eNB;aatx++) - for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) + + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) avgs = cmax(avgs,avg[(aatx<<1)+aarx]); pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2)+1; - } - else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || - ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) - { - dlsch_channel_level_TM34(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - pdsch_vars[eNB_id]->pmi_ext, - avg_0, - avg_1, - symbol, - nb_rb, - mmse_flag, - dlsch0_harq->mimo_mode); - - LOG_D(PHY,"Channel Level TM34 avg_0 %d, avg_1 %d, rx_type %d, rx_standard %d, dlsch_demod_shift %d \n", avg_0[0], + } else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || + ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && + (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) { + dlsch_channel_level_TM34(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + pdsch_vars[eNB_id]->pmi_ext, + avg_0, + avg_1, + symbol, + nb_rb, + mmse_flag, + dlsch0_harq->mimo_mode); + LOG_D(PHY,"Channel Level TM34 avg_0 %d, avg_1 %d, rx_type %d, rx_standard %d, dlsch_demod_shift %d \n", avg_0[0], avg_1[0], rx_type, rx_standard, dlsch_demod_shift); + if (rx_type>rx_standard) { avg_0[0] = (log2_approx(avg_0[0])/2) + dlsch_demod_shift;// + 2 ;//+ 4; avg_1[0] = (log2_approx(avg_1[0])/2) + dlsch_demod_shift;// + 2 ;//+ 4; pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); - // printf("dlsch_demod_shift %d\n", dlsch_demod_shift); - } - else { + // printf("dlsch_demod_shift %d\n", dlsch_demod_shift); + } else { avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift; avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift; pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0); pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0); } - } - else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) {// single-layer precoding (TM5, TM6) + } else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) { // single-layer precoding (TM5, TM6) if ((rx_type==rx_IC_single_stream) && (eNB_id_i==ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0)) { - dlsch_channel_level_TM56(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - frame_parms, - pdsch_vars[eNB_id]->pmi_ext, - avg, - symbol, - nb_rb); - avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]; - pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); - - } - else if (dlsch0_harq->dl_power_off==1) { //TM6 - - dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + dlsch_channel_level_TM56(pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, + pdsch_vars[eNB_id]->pmi_ext, avg, symbol, nb_rb); - + avg[0] = log2_approx(avg[0]) - 13 + offset_mumimo_llr_drange[dlsch0_harq->mcs][(i_mod>>1)-1]; + pdsch_vars[eNB_id]->log2_maxh = cmax(avg[0],0); + } else if (dlsch0_harq->dl_power_off==1) { //TM6 + dlsch_channel_level(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + frame_parms, + avg, + symbol, + nb_rb); avgs = 0; - for (aatx=0;aatx<frame_parms->nb_antenna_ports_eNB;aatx++) - for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) + + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) avgs = cmax(avgs,avg[(aatx<<1)+aarx]); pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; pdsch_vars[eNB_id]->log2_maxh++; - } } - - } - else if (beamforming_mode==7) - dlsch_channel_level_TM7(pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext, + } else if (beamforming_mode==7) + dlsch_channel_level_TM7(pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext, frame_parms, avg, symbol, nb_rb); + #ifdef UE_DEBUG_TRACE LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", - frame%1024,subframe, pdsch_vars[eNB_id]->log2_maxh, - pdsch_vars[eNB_id]->log2_maxh0, - pdsch_vars[eNB_id]->log2_maxh1, - avg[0],avgs); + frame%1024,subframe, pdsch_vars[eNB_id]->log2_maxh, + pdsch_vars[eNB_id]->log2_maxh0, + pdsch_vars[eNB_id]->log2_maxh1, + avg[0],avgs); //LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); #endif - //wait until pdcch is decoded //proc->channel_level = 1; } @@ -542,39 +517,36 @@ int rx_pdsch(PHY_VARS_UE *ue, wait++; } */ - #if T_TRACER - if (type == PDSCH) - { - T(T_UE_PHY_PDSCH_ENERGY, T_INT(eNB_id), T_INT(frame%1024), T_INT(subframe), - T_INT(avg[0]), T_INT(avg[1]), T_INT(avg[2]), T_INT(avg[3])); - } -#endif + if (type == PDSCH) { + T(T_UE_PHY_PDSCH_ENERGY, T_INT(eNB_id), T_INT(frame%1024), T_INT(subframe), + T_INT(avg[0]), T_INT(avg[1]), T_INT(avg[2]), T_INT(avg[3])); + } + +#endif #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag, + ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag, + ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #endif #endif - - #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif - if (rx_type==rx_IC_dual_stream && mmse_flag==1){ - + if (rx_type==rx_IC_dual_stream && mmse_flag==1) { precode_channel_est(pdsch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, pdsch_vars[eNB_id], symbol, nb_rb, dlsch0_harq->mimo_mode); - - mmse_processing_oai(pdsch_vars[eNB_id], + mmse_processing_oai(pdsch_vars[eNB_id], frame_parms, measurements, first_symbol_flag, @@ -585,7 +557,7 @@ int rx_pdsch(PHY_VARS_UE *ue, nb_rb); } -// Now channel compensation + // Now channel compensation if (dlsch0_harq->mimo_mode<LARGE_CDD) { dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext, pdsch_vars[eNB_id]->dl_ch_estimates_ext, @@ -600,13 +572,14 @@ int rx_pdsch(PHY_VARS_UE *ue, nb_rb, pdsch_vars[eNB_id]->log2_maxh, measurements); // log2_maxh+I0_shift + if (symbol == 5) { - //LOG_M("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + LOG_M("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } if ((rx_type==rx_IC_single_stream) && (eNB_id_i<ue->n_connected_eNB)) { - dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext, + dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext, pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, pdsch_vars[eNB_id_i]->dl_ch_mag0, pdsch_vars[eNB_id_i]->dl_ch_magb0, @@ -619,6 +592,7 @@ int rx_pdsch(PHY_VARS_UE *ue, nb_rb, pdsch_vars[eNB_id]->log2_maxh, measurements); // log2_maxh+I0_shift + if (symbol == 5) { LOG_M("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); LOG_M("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); @@ -633,55 +607,58 @@ int rx_pdsch(PHY_VARS_UE *ue, pdsch_vars[eNB_id]->log2_maxh); } } else if ((dlsch0_harq->mimo_mode == LARGE_CDD) || ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ - dlsch_channel_compensation_TM34(frame_parms, - pdsch_vars[eNB_id], - measurements, - eNB_id, - symbol, - dlsch0_harq->Qm, - dlsch1_harq->Qm, - harq_pid, - dlsch0_harq->round, - dlsch0_harq->mimo_mode, - nb_rb, - mmse_flag, - pdsch_vars[eNB_id]->log2_maxh0, - pdsch_vars[eNB_id]->log2_maxh1); - if (symbol == 5) { - LOG_M("rxF_comp_d00.m","rxF_c_d00",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM - LOG_M("rxF_comp_d01.m","rxF_c_d01",&pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - LOG_M("rxF_comp_d10.m","rxF_c_d10",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - LOG_M("rxF_comp_d11.m","rxF_c_d11",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - } - // compute correlation between signal and interference channels (rho12 and rho21) - dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22 + (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) { + dlsch_channel_compensation_TM34(frame_parms, + pdsch_vars[eNB_id], + measurements, + eNB_id, symbol, + dlsch0_harq->Qm, + dlsch1_harq->Qm, + harq_pid, + dlsch0_harq->round, + dlsch0_harq->mimo_mode, nb_rb, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->log2_maxh0); - //printf("rho stream1 =%d\n", &pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); - //to be optimized (just take complex conjugate) - dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21 - symbol, - nb_rb, - &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + mmse_flag, + pdsch_vars[eNB_id]->log2_maxh0, pdsch_vars[eNB_id]->log2_maxh1); + + if (symbol == 5) { + LOG_M("rxF_comp_d00.m","rxF_c_d00",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM + LOG_M("rxF_comp_d01.m","rxF_c_d01",&pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + LOG_M("rxF_comp_d10.m","rxF_c_d10",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + LOG_M("rxF_comp_d11.m","rxF_c_d11",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM + } + + // compute correlation between signal and interference channels (rho12 and rho21) + dlsch_dual_stream_correlation(frame_parms, // this is doing h11'*h12 and h21'*h22 + symbol, + nb_rb, + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), + pdsch_vars[eNB_id]->dl_ch_rho2_ext, + pdsch_vars[eNB_id]->log2_maxh0); + //printf("rho stream1 =%d\n", &pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); + //to be optimized (just take complex conjugate) + dlsch_dual_stream_correlation(frame_parms, // this is doing h12'*h11 and h22'*h21 + symbol, + nb_rb, + &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), + pdsch_vars[eNB_id]->dl_ch_estimates_ext, + pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[eNB_id]->log2_maxh1); + // printf("rho stream2 =%d\n",&pdsch_vars[eNB_id]->dl_ch_rho2_ext ); - //printf("TM3 log2_maxh : %d\n",pdsch_vars[eNB_id]->log2_maxh); - if (symbol == 5) { - LOG_M("rho0_0.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM - LOG_M("rho2_0.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - LOG_M("rho0_1.m.m","rho0_1",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - LOG_M("rho2_1.m","rho2_1",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM - } - } else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) {// single-layer precoding (TM5, TM6) - if ((rx_type==rx_IC_single_stream) && (eNB_id_i==ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0)) { - dlsch_channel_compensation_TM56(pdsch_vars[eNB_id]->rxdataF_ext, + //printf("TM3 log2_maxh : %d\n",pdsch_vars[eNB_id]->log2_maxh); + if (symbol == 5) { + LOG_M("rho0_0.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM + LOG_M("rho2_0.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + LOG_M("rho0_1.m.m","rho0_1",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + LOG_M("rho2_1.m","rho2_1",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM + } + } else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) {// single-layer precoding (TM5, TM6) + if ((rx_type==rx_IC_single_stream) && (eNB_id_i==ue->n_connected_eNB) && (dlsch0_harq->dl_power_off==0)) { + dlsch_channel_compensation_TM56(pdsch_vars[eNB_id]->rxdataF_ext, pdsch_vars[eNB_id]->dl_ch_estimates_ext, pdsch_vars[eNB_id]->dl_ch_mag0, pdsch_vars[eNB_id]->dl_ch_magb0, @@ -696,24 +673,29 @@ int rx_pdsch(PHY_VARS_UE *ue, pdsch_vars[eNB_id]->log2_maxh, dlsch0_harq->dl_power_off); - for (rb=0; rb<nb_rb; rb++) { - switch(pdsch_vars[eNB_id]->pmi_ext[rb]) { + for (rb=0; rb<nb_rb; rb++) { + switch(pdsch_vars[eNB_id]->pmi_ext[rb]) { case 0: pdsch_vars[eNB_id_i]->pmi_ext[rb]=1; break; - case 1: + + case 1: pdsch_vars[eNB_id_i]->pmi_ext[rb]=0; break; - case 2: + + case 2: pdsch_vars[eNB_id_i]->pmi_ext[rb]=3; break; + case 3: pdsch_vars[eNB_id_i]->pmi_ext[rb]=2; break; - } - // if (rb==0) + } + + // if (rb==0) // printf("pmi %d, pmi_i %d\n",pdsch_vars[eNB_id]->pmi_ext[rb],pdsch_vars[eNB_id_i]->pmi_ext[rb]); } + dlsch_channel_compensation_TM56(pdsch_vars[eNB_id_i]->rxdataF_ext, pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, pdsch_vars[eNB_id_i]->dl_ch_mag0, @@ -728,9 +710,10 @@ int rx_pdsch(PHY_VARS_UE *ue, nb_rb, pdsch_vars[eNB_id]->log2_maxh, dlsch0_harq->dl_power_off); + if (symbol==5) { LOG_M("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); - LOG_M("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + LOG_M("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } dlsch_dual_stream_correlation(frame_parms, @@ -755,45 +738,43 @@ int rx_pdsch(PHY_VARS_UE *ue, nb_rb, pdsch_vars[eNB_id]->log2_maxh, 1); - - } - - - } else if (dlsch0_harq->mimo_mode==TM7) { //TM7 - - dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext, - pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - pdsch_vars[eNB_id]->rxdataF_comp0, - (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL, - frame_parms, - symbol, - first_symbol_flag, - get_Qm(dlsch0_harq->mcs), - nb_rb, - //9, - pdsch_vars[eNB_id]->log2_maxh, - measurements); // log2_maxh+I0_shift + } + } else if (dlsch0_harq->mimo_mode==TM7) { //TM7 + dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext, + pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + pdsch_vars[eNB_id]->rxdataF_comp0, + (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL, + frame_parms, + symbol, + first_symbol_flag, + get_Qm(dlsch0_harq->mcs), + nb_rb, + //9, + pdsch_vars[eNB_id]->log2_maxh, + measurements); // log2_maxh+I0_shift } #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level, + ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh, + ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #endif #endif -// MRC + // MRC #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif - if (frame_parms->nb_antennas_rx > 1) { + if (frame_parms->nb_antennas_rx > 1) { if ((dlsch0_harq->mimo_mode == LARGE_CDD) || ((dlsch0_harq->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) && - (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))){ // TM3 or TM4 + (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) { // TM3 or TM4 if (frame_parms->nb_antenna_ports_eNB == 2) { dlsch_detection_mrc_TM34(frame_parms, pdsch_vars[eNB_id], @@ -802,9 +783,10 @@ int rx_pdsch(PHY_VARS_UE *ue, symbol, nb_rb, 1); - if (symbol == 5) { - LOG_M("rho0_mrc.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM - LOG_M("rho2_mrc.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + + if (symbol == 5) { + LOG_M("rho0_mrc.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM + LOG_M("rho2_mrc.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 } } } else { @@ -822,11 +804,12 @@ int rx_pdsch(PHY_VARS_UE *ue, rx_type==rx_IC_single_stream); } } + // printf("Combining"); if ((dlsch0_harq->mimo_mode == SISO) || ((dlsch0_harq->mimo_mode >= UNIFORM_PRECODING11) && (dlsch0_harq->mimo_mode <= PUSCH_PRECODING0)) || - (dlsch0_harq->mimo_mode == TM7)) { + (dlsch0_harq->mimo_mode == TM7)) { /* dlsch_siso(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp, @@ -849,24 +832,22 @@ int rx_pdsch(PHY_VARS_UE *ue, (dlsch0_harq->mimo_mode <=DUALSTREAM_PUSCH_PRECODING))) { rxdataF_comp_ptr = pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round]; dl_ch_mag_ptr = pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round]; - } - else { + } else { rxdataF_comp_ptr = pdsch_vars[eNB_id_i]->rxdataF_comp0; dl_ch_mag_ptr = pdsch_vars[eNB_id_i]->dl_ch_mag0; //i_mod should have been passed as a parameter } #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #endif #endif - #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif //printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol); // compute LLRs @@ -875,10 +856,11 @@ int rx_pdsch(PHY_VARS_UE *ue, int8_t *pllr_symbol_cw1; uint32_t llr_offset_symbol; llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol]; - pllr_symbol_cw0 = (int8_t*)pdsch_vars[eNB_id]->llr[0]; - pllr_symbol_cw1 = (int8_t*)pdsch_vars[eNB_id]->llr[1]; + pllr_symbol_cw0 = (int8_t *)pdsch_vars[eNB_id]->llr[0]; + pllr_symbol_cw1 = (int8_t *)pdsch_vars[eNB_id]->llr[1]; pllr_symbol_cw0 += llr_offset_symbol; pllr_symbol_cw1 += llr_offset_symbol; + /* LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n", frame, subframe,symbol, @@ -889,31 +871,26 @@ int rx_pdsch(PHY_VARS_UE *ue, pllr_symbol_cw0); */ switch (dlsch0_harq->Qm) { - case 2 : - if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { - - + case 2 : + if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { dlsch_qpsk_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, - (int16_t*)pllr_symbol_cw0, + (int16_t *)pllr_symbol_cw0, symbol, first_symbol_flag, nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), beamforming_mode); - - } else if (codeword_TB0 == -1){ - + } else if (codeword_TB0 == -1) { dlsch_qpsk_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, - (int16_t*)pllr_symbol_cw1, + (int16_t *)pllr_symbol_cw1, symbol, first_symbol_flag, nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), beamforming_mode); - } - else if (rx_type >= rx_IC_single_stream) { + } else if (rx_type >= rx_IC_single_stream) { if (dlsch1_harq->Qm == 2) { dlsch_qpsk_qpsk_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, @@ -923,6 +900,7 @@ int rx_pdsch(PHY_VARS_UE *ue, symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { dlsch_qpsk_qpsk_llr(frame_parms, rxdataF_comp_ptr, @@ -933,8 +911,7 @@ int rx_pdsch(PHY_VARS_UE *ue, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), pdsch_vars[eNB_id]->llr128_2ndstream); } - } - else if (dlsch1_harq->Qm == 4) { + } else if (dlsch1_harq->Qm == 4) { dlsch_qpsk_16qam_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr,//i @@ -944,6 +921,7 @@ int rx_pdsch(PHY_VARS_UE *ue, symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { dlsch_16qam_qpsk_llr(frame_parms, rxdataF_comp_ptr, @@ -955,8 +933,7 @@ int rx_pdsch(PHY_VARS_UE *ue, adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), pdsch_vars[eNB_id]->llr128_2ndstream); } - } - else { + } else { dlsch_qpsk_64qam_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, rxdataF_comp_ptr,//i @@ -966,6 +943,7 @@ int rx_pdsch(PHY_VARS_UE *ue, symbol,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), pdsch_vars[eNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { dlsch_64qam_qpsk_llr(frame_parms, rxdataF_comp_ptr, @@ -979,260 +957,272 @@ int rx_pdsch(PHY_VARS_UE *ue, } } } - break; - case 4 : - if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) { - dlsch_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->llr[0], - pdsch_vars[eNB_id]->dl_ch_mag0, - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), - pdsch_vars[eNB_id]->llr128, - beamforming_mode); - } else if (codeword_TB0 == -1){ - dlsch_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->llr[1], - pdsch_vars[eNB_id]->dl_ch_mag0, - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream, - beamforming_mode); - } - else if (rx_type >= rx_IC_single_stream) { - if (dlsch1_harq->Qm == 2) { - dlsch_16qam_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - dlsch_qpsk_16qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - pdsch_vars[eNB_id]->dl_ch_mag0,//i - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->llr[1], + + break; + + case 4 : + if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) { + dlsch_16qam_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->llr[0], + pdsch_vars[eNB_id]->dl_ch_mag0, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), + pdsch_vars[eNB_id]->llr128, + beamforming_mode); + } else if (codeword_TB0 == -1) { + dlsch_16qam_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->llr[1], + pdsch_vars[eNB_id]->dl_ch_mag0, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), + pdsch_vars[eNB_id]->llr128_2ndstream, + beamforming_mode); + } else if (rx_type >= rx_IC_single_stream) { + if (dlsch1_harq->Qm == 2) { + dlsch_16qam_qpsk_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_rho2_ext, + pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } - } - else if (dlsch1_harq->Qm == 4) { - dlsch_16qam_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), + pdsch_vars[eNB_id]->llr128); + + if (rx_type==rx_IC_dual_stream) { + dlsch_qpsk_16qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[eNB_id]->rxdataF_comp0,//i + pdsch_vars[eNB_id]->dl_ch_mag0,//i + pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), + pdsch_vars[eNB_id]->llr128_2ndstream); + } + } else if (dlsch1_harq->Qm == 4) { dlsch_16qam_16qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[eNB_id]->dl_ch_mag0,//i - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->llr[1], + pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + pdsch_vars[eNB_id]->dl_ch_rho2_ext, + pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } - } - else { - dlsch_16qam_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - dlsch_64qam_16qam_llr(frame_parms, - rxdataF_comp_ptr, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), + pdsch_vars[eNB_id]->llr128); + + if (rx_type==rx_IC_dual_stream) { + dlsch_16qam_16qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + pdsch_vars[eNB_id]->dl_ch_mag0,//i + pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), + pdsch_vars[eNB_id]->llr128_2ndstream); + } + } else { + dlsch_16qam_64qam_llr(frame_parms, pdsch_vars[eNB_id]->rxdataF_comp0, - dl_ch_mag_ptr, + rxdataF_comp_ptr,//i pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->llr[1], + dl_ch_mag_ptr,//i + pdsch_vars[eNB_id]->dl_ch_rho2_ext, + pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), + pdsch_vars[eNB_id]->llr128); + + if (rx_type==rx_IC_dual_stream) { + dlsch_64qam_16qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[eNB_id]->rxdataF_comp0, + dl_ch_mag_ptr, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), + pdsch_vars[eNB_id]->llr128_2ndstream); + } } } - } - break; - case 6 : - if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { - dlsch_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - (int16_t*)pllr_symbol_cw0, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), - pdsch_vars[eNB_id]->llr_offset[symbol], - beamforming_mode); - } else if (codeword_TB0 == -1){ - dlsch_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - (int16_t*)pllr_symbol_cw1, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), - pdsch_vars[eNB_id]->llr_offset[symbol], - beamforming_mode); - } - else if (rx_type >= rx_IC_single_stream) { - if (dlsch1_harq->Qm == 2) { - dlsch_64qam_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - dlsch_qpsk_64qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i + + break; + + case 6 : + if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { + dlsch_64qam_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + (int16_t *)pllr_symbol_cw0, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), + pdsch_vars[eNB_id]->llr_offset[symbol], + beamforming_mode); + } else if (codeword_TB0 == -1) { + dlsch_64qam_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + (int16_t *)pllr_symbol_cw1, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), + pdsch_vars[eNB_id]->llr_offset[symbol], + beamforming_mode); + } else if (rx_type >= rx_IC_single_stream) { + if (dlsch1_harq->Qm == 2) { + dlsch_64qam_qpsk_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->llr[1], + pdsch_vars[eNB_id]->dl_ch_rho2_ext, + pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } - } - else if (dlsch1_harq->Qm == 4) { - dlsch_64qam_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - dlsch_16qam_64qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[eNB_id]->dl_ch_mag0,//i - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->llr[1], + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), + pdsch_vars[eNB_id]->llr128); + + if (rx_type==rx_IC_dual_stream) { + dlsch_qpsk_64qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[eNB_id]->rxdataF_comp0,//i + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,subframe,symbol), + pdsch_vars[eNB_id]->llr128_2ndstream); + } + } else if (dlsch1_harq->Qm == 4) { + dlsch_64qam_16qam_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + pdsch_vars[eNB_id]->dl_ch_rho2_ext, + pdsch_vars[eNB_id]->llr[0], symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } - } - else { - dlsch_64qam_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - (int16_t*)pllr_symbol_cw0, - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), - pdsch_vars[eNB_id]->llr_offset[symbol]); - if (rx_type==rx_IC_dual_stream) { + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), + pdsch_vars[eNB_id]->llr128); + + if (rx_type==rx_IC_dual_stream) { + dlsch_16qam_64qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + pdsch_vars[eNB_id]->dl_ch_mag0,//i + pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[eNB_id]->llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,subframe,symbol), + pdsch_vars[eNB_id]->llr128_2ndstream); + } + } else { dlsch_64qam_64qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[eNB_id]->dl_ch_mag0,//i - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - (int16_t*)pllr_symbol_cw1, + pdsch_vars[eNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + pdsch_vars[eNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + pdsch_vars[eNB_id]->dl_ch_rho2_ext, + (int16_t *)pllr_symbol_cw0, symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), pdsch_vars[eNB_id]->llr_offset[symbol]); + + if (rx_type==rx_IC_dual_stream) { + dlsch_64qam_64qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[eNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + pdsch_vars[eNB_id]->dl_ch_mag0,//i + pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], + (int16_t *)pllr_symbol_cw1, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol), + pdsch_vars[eNB_id]->llr_offset[symbol]); + } } } - } - break; - default: - LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); - return(-1); - break; + + break; + + default: + LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); + return(-1); + break; } + if (dlsch1_harq) { - switch (get_Qm(dlsch1_harq->mcs)) { - case 2 : - if (rx_type==rx_standard) { - dlsch_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - (int16_t*)pllr_symbol_cw0, - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), - beamforming_mode); - } - break; - case 4: - if (rx_type==rx_standard) { - dlsch_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->llr[0], - pdsch_vars[eNB_id]->dl_ch_mag0, - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), - pdsch_vars[eNB_id]->llr128, - beamforming_mode); + switch (get_Qm(dlsch1_harq->mcs)) { + case 2 : + if (rx_type==rx_standard) { + dlsch_qpsk_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + (int16_t *)pllr_symbol_cw0, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol), + beamforming_mode); + } + + break; + + case 4: + if (rx_type==rx_standard) { + dlsch_16qam_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + pdsch_vars[eNB_id]->llr[0], + pdsch_vars[eNB_id]->dl_ch_mag0, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol), + pdsch_vars[eNB_id]->llr128, + beamforming_mode); + } + + break; + + case 6 : + if (rx_type==rx_standard) { + dlsch_64qam_llr(frame_parms, + pdsch_vars[eNB_id]->rxdataF_comp0, + (int16_t *)pllr_symbol_cw0, + pdsch_vars[eNB_id]->dl_ch_mag0, + pdsch_vars[eNB_id]->dl_ch_magb0, + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), + pdsch_vars[eNB_id]->llr_offset[symbol], + beamforming_mode); + } + + break; + + default: + LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); + return(-1); + break; } - break; - case 6 : - if (rx_type==rx_standard) { - dlsch_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - (int16_t*)pllr_symbol_cw0, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol), - pdsch_vars[eNB_id]->llr_offset[symbol], - beamforming_mode); - } - break; - default: - LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); - return(-1); - break; - } } #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); + stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #else - LOG_D(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #endif #endif - - // Please keep it: useful for debugging + // Please keep it: useful for debugging #if 0 - if( (symbol == 13) && (subframe==0) && (dlsch0_harq->Qm == 6) /*&& (nb_rb==25)*/) - { - LOG_E(PHY,"Dump Phy Chan Est \n"); - if(1) - { + + if( (symbol == 13) && (subframe==0) && (dlsch0_harq->Qm == 6) /*&& (nb_rb==25)*/) { + LOG_E(PHY,"Dump Phy Chan Est \n"); + + if(1) { #if 1 LOG_M("rxdataF0.m" , "rxdataF0", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); //LOG_M("rxdataF1.m" , "rxdataF1", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1); @@ -1240,8 +1230,6 @@ int rx_pdsch(PHY_VARS_UE *ue, //LOG_M("dl_ch_estimates01.m", "dl_ch_estimates01", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0],14*frame_parms->ofdm_symbol_size,1,1); //LOG_M("dl_ch_estimates10.m", "dl_ch_estimates10", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0],14*frame_parms->ofdm_symbol_size,1,1); //LOG_M("dl_ch_estimates11.m", "dl_ch_estimates11", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0],14*frame_parms->ofdm_symbol_size,1,1); - - //LOG_M("rxdataF_ext00.m" , "rxdataF_ext00", &pdsch_vars[eNB_id]->rxdataF_ext[0][0],14*frame_parms->N_RB_DL*12,1,1); //LOG_M("rxdataF_ext01.m" , "rxdataF_ext01", &pdsch_vars[eNB_id]->rxdataF_ext[1][0],14*frame_parms->N_RB_DL*12,1,1); //LOG_M("rxdataF_ext10.m" , "rxdataF_ext10", &pdsch_vars[eNB_id]->rxdataF_ext[2][0],14*frame_parms->N_RB_DL*12,1,1); @@ -1257,20 +1245,16 @@ int rx_pdsch(PHY_VARS_UE *ue, #endif LOG_M("llr0.m","llr0", &pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); //LOG_M("llr1.m","llr1", &pdsch_vars[eNB_id]->llr[1][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); - - AssertFatal(0," "); - } - + } } -#endif +#endif T(T_UE_PHY_PDSCH_IQ, T_INT(eNB_id), T_INT(frame%1024), T_INT(subframe), T_INT(nb_rb), T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_tti), T_BUFFER(&pdsch_vars[eNB_id]->rxdataF_comp0[eNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2)); - return 0; } @@ -1290,20 +1274,15 @@ void dlsch_channel_compensation(int **rxdataF_ext, unsigned char mod_order, unsigned short nb_rb, unsigned char output_shift, - PHY_MEASUREMENTS *measurements) -{ - + PHY_MEASUREMENTS *measurements) { #if defined(__i386) || defined(__x86_64) - unsigned short rb; unsigned char aatx,aarx,symbol_mod,pilots=0; __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { - if (frame_parms->nb_antenna_ports_eNB==1) // 10 out of 12 so don't reduce size nb_rb=1+(5*nb_rb/6); else @@ -1312,6 +1291,7 @@ void dlsch_channel_compensation(int **rxdataF_ext, for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { __m128i QAM_amp128b = _mm_setzero_si128(); + if (mod_order == 4) { QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) } else if (mod_order == 6) { @@ -1335,17 +1315,12 @@ void dlsch_channel_compensation(int **rxdataF_ext, for (rb=0; rb<nb_rb; rb++) { if (mod_order>2) { // get channel amplitude if not QPSK - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - // store channel magnitude here in a new field of dlsch - dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[0] = dl_ch_mag128[0]; dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); @@ -1362,18 +1337,14 @@ void dlsch_channel_compensation(int **rxdataF_ext, mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); dl_ch_mag128b[2] = dl_ch_mag128[2]; - dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); } dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); - - dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); @@ -1385,11 +1356,10 @@ void dlsch_channel_compensation(int **rxdataF_ext, // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)&conjugate[0]); // print_ints("im",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) @@ -1405,20 +1375,18 @@ void dlsch_channel_compensation(int **rxdataF_ext, // print_shorts("rx:",rxdataF128); // print_shorts("ch:",dl_ch128); // print_shorts("pack:",rxdataF_comp128); - // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+1); // print_shorts("ch:",dl_ch128+1); @@ -1430,19 +1398,17 @@ void dlsch_channel_compensation(int **rxdataF_ext, // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+2); // print_shorts("ch:",dl_ch128+2); - // print_shorts("pack:",rxdataF_comp128+2); - + // print_shorts("pack:",rxdataF_comp128+2); dl_ch128+=3; dl_ch_mag128+=3; dl_ch_mag128b+=3; @@ -1455,14 +1421,11 @@ void dlsch_channel_compensation(int **rxdataF_ext, rxdataF128+=2; rxdataF_comp128+=2; } - } } } if (rho) { - - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; @@ -1472,11 +1435,10 @@ void dlsch_channel_compensation(int **rxdataF_ext, // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]); // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)&conjugate[0]); // print_ints("im",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) @@ -1489,25 +1451,21 @@ void dlsch_channel_compensation(int **rxdataF_ext, // print_ints("c0",&mmtmpD2); // print_ints("c1",&mmtmpD3); rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - //print_shorts("rx:",dl_ch128_2); //print_shorts("ch:",dl_ch128); //print_shorts("pack:",rho128); - // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - - rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3); //print_shorts("rx:",dl_ch128_2+1); //print_shorts("ch:",dl_ch128+1); @@ -1517,23 +1475,20 @@ void dlsch_channel_compensation(int **rxdataF_ext, // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[2]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); //print_shorts("rx:",dl_ch128_2+2); //print_shorts("ch:",dl_ch128+2); //print_shorts("pack:",rho128+2); - dl_ch128+=3; dl_ch128_2+=3; rho128+=3; - } if (first_symbol_flag==1) { @@ -1544,29 +1499,22 @@ void dlsch_channel_compensation(int **rxdataF_ext, _mm_empty(); _m_empty(); - #elif defined(__arm__) - - unsigned short rb; unsigned char aatx,aarx,symbol_mod,pilots=0; - int16x4_t *dl_ch128,*dl_ch128_2,*rxdataF128; int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b; int16x8_t *dl_ch_mag128,*dl_ch_mag128b,mmtmpD2,mmtmpD3,mmtmpD4; int16x8_t QAM_amp128,QAM_amp128b; int16x4x2_t *rxdataF_comp128,*rho128; - int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1}; int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift); - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { if (frame_parms->nb_antenna_ports_eNB==1) { // 10 out of 12 so don't reduce size nb_rb=1+(5*nb_rb/6); - } - else { + } else { pilots=1; } } @@ -1579,171 +1527,160 @@ void dlsch_channel_compensation(int **rxdataF_ext, QAM_amp128 = vmovq_n_s16(QAM64_n1); // QAM_amp128b = vmovq_n_s16(QAM64_n2); } + // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - dl_ch128 = (int16x4_t*)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128 = (int16x8_t*)&dl_ch_mag[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128b = (int16x8_t*)&dl_ch_magb[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128 = (int16x4x2_t*)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch128 = (int16x4_t *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128 = (int16x8_t *)&dl_ch_mag[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128b = (int16x8_t *)&dl_ch_magb[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF128 = (int16x4_t *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128 = (int16x4x2_t *)&rxdataF_comp[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { - if (mod_order>2) { - // get channel amplitude if not QPSK - mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128[0]); - // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits - mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128[1]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits - mmtmpD0 = vmull_s16(dl_ch128[2], dl_ch128[2]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128[3]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - } + if (mod_order>2) { + // get channel amplitude if not QPSK + mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128[0]); + // mmtmpD0 = [ch0*ch0,ch1*ch1,ch2*ch2,ch3*ch3]; + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + // mmtmpD0 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3]>>output_shift128 on 32-bits + mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128[1]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD2 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + // mmtmpD2 = [ch0*ch0 + ch1*ch1,ch0*ch0 + ch1*ch1,ch2*ch2 + ch3*ch3,ch2*ch2 + ch3*ch3,ch4*ch4 + ch5*ch5,ch4*ch4 + ch5*ch5,ch6*ch6 + ch7*ch7,ch6*ch6 + ch7*ch7]>>output_shift128 on 16-bits + mmtmpD0 = vmull_s16(dl_ch128[2], dl_ch128[2]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128[3]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b); - dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b); - dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128); - dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128); + if (pilots==0) { + mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + } - if (pilots==0) { - dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); - dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); - } - } + dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b); + dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b); + dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128); + dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128); - mmtmpD0 = vmull_s16(dl_ch128[0], rxdataF128[0]); - //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] - mmtmpD1 = vmull_s16(dl_ch128[1], rxdataF128[1]); - //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[0],*(int16x4_t*)conj)), rxdataF128[0]); - //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[1],*(int16x4_t*)conj)), rxdataF128[1]); - //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - mmtmpD0 = vmull_s16(dl_ch128[2], rxdataF128[2]); - mmtmpD1 = vmull_s16(dl_ch128[3], rxdataF128[3]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[2],*(int16x4_t*)conj)), rxdataF128[2]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[3],*(int16x4_t*)conj)), rxdataF128[3]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]); - mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - - dl_ch128+=6; - dl_ch_mag128+=3; - dl_ch_mag128b+=3; - rxdataF128+=6; - rxdataF_comp128+=3; - - } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less - dl_ch128+=4; - dl_ch_mag128+=2; - dl_ch_mag128b+=2; - rxdataF128+=4; - rxdataF_comp128+=2; - } + if (pilots==0) { + dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); + dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); + } + } + + mmtmpD0 = vmull_s16(dl_ch128[0], rxdataF128[0]); + //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] + mmtmpD1 = vmull_s16(dl_ch128[1], rxdataF128[1]); + //mmtmpD1 = [Re(ch[2])Re(rx[2]) Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3]) Im(ch[3])Im(ch[3])] + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[0],*(int16x4_t *)conj)), rxdataF128[0]); + //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[1],*(int16x4_t *)conj)), rxdataF128[1]); + //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + mmtmpD0 = vmull_s16(dl_ch128[2], rxdataF128[2]); + mmtmpD1 = vmull_s16(dl_ch128[3], rxdataF128[3]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[2],*(int16x4_t *)conj)), rxdataF128[2]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[3],*(int16x4_t *)conj)), rxdataF128[3]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + + if (pilots==0) { + mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]); + mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t *)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t *)conj)), rxdataF128[5]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + dl_ch128+=6; + dl_ch_mag128+=3; + dl_ch_mag128b+=3; + rxdataF128+=6; + rxdataF_comp128+=3; + } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less + dl_ch128+=4; + dl_ch_mag128+=2; + dl_ch_mag128b+=2; + rxdataF128+=4; + rxdataF_comp128+=2; + } } } } if (rho) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - rho128 = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch128_2 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + rho128 = (int16x4x2_t *)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch128 = (int16x4_t *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch128_2 = (int16x4_t *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + for (rb=0; rb<nb_rb; rb++) { - mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128_2[0]); - mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128_2[1]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[0],*(int16x4_t*)conj)), dl_ch128_2[0]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[1],*(int16x4_t*)conj)), dl_ch128_2[1]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rho128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - mmtmpD0 = vmull_s16(dl_ch128[2], dl_ch128_2[2]); - mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128_2[3]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[2],*(int16x4_t*)conj)), dl_ch128_2[2]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[3],*(int16x4_t*)conj)), dl_ch128_2[3]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rho128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128_2[0]); - mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128_2[1]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), dl_ch128_2[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), dl_ch128_2[5]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rho128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - - dl_ch128+=6; - dl_ch128_2+=6; - rho128+=3; + mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128_2[0]); + mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128_2[1]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[0],*(int16x4_t *)conj)), dl_ch128_2[0]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[1],*(int16x4_t *)conj)), dl_ch128_2[1]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rho128[0] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + mmtmpD0 = vmull_s16(dl_ch128[2], dl_ch128_2[2]); + mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128_2[3]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[2],*(int16x4_t *)conj)), dl_ch128_2[2]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[3],*(int16x4_t *)conj)), dl_ch128_2[3]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rho128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128_2[0]); + mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128_2[1]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t *)conj)), dl_ch128_2[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t *)conj)), dl_ch128_2[5]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rho128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + dl_ch128+=6; + dl_ch128_2+=6; + rho128+=3; } if (first_symbol_flag==1) { - measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12); + measurements->rx_correlation[0][aarx] = signal_energy(&rho[aarx][symbol*frame_parms->N_RB_DL*12],rb*12); } } } + #endif } @@ -1761,7 +1698,6 @@ void dlsch_channel_compensation_core(int **rxdataF_ext, int start_point) { - unsigned short ii; int length_mod8 = 0; int length2; @@ -1771,6 +1707,7 @@ void dlsch_channel_compensation_core(int **rxdataF_ext, for (aatx=0; aatx<n_tx; aatx++) { __m128i QAM_amp128b; + if (mod_order == 4) { QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) QAM_amp128b = _mm_setzero_si128(); @@ -1785,31 +1722,25 @@ void dlsch_channel_compensation_core(int **rxdataF_ext, * Elena's commit. */ int x = n_rx > 1 ? n_rx : 2; - - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aatx*x + aarx][start_point]; - dl_ch_mag128 = (__m128i *)&dl_ch_mag[aatx*x + aarx][start_point]; - dl_ch_mag128b = (__m128i *)&dl_ch_magb[aatx*x + aarx][start_point]; - rxdataF128 = (__m128i *)&rxdataF_ext[aarx][start_point]; - rxdataF_comp128 = (__m128i *)&rxdataF_comp[aatx*x + aarx][start_point]; - + dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aatx*x + aarx][start_point]; + dl_ch_mag128 = (__m128i *)&dl_ch_mag[aatx*x + aarx][start_point]; + dl_ch_mag128b = (__m128i *)&dl_ch_magb[aatx*x + aarx][start_point]; + rxdataF128 = (__m128i *)&rxdataF_ext[aarx][start_point]; + rxdataF_comp128 = (__m128i *)&rxdataF_comp[aatx*x + aarx][start_point]; length_mod8 = length&7; - if (length_mod8 == 0){ + + if (length_mod8 == 0) { length2 = length>>3; for (ii=0; ii<length2; ++ii) { if (mod_order>2) { // get channel amplitude if not QPSK - mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128[0]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - // store channel magnitude here in a new field of dlsch - dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[0] = dl_ch_mag128[0]; dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); @@ -1821,22 +1752,18 @@ void dlsch_channel_compensation_core(int **rxdataF_ext, dl_ch_mag128b[1] = dl_ch_mag128[1]; dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); - dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); - dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); - } // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)&conjugate[0]); // print_ints("im",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) @@ -1852,59 +1779,53 @@ void dlsch_channel_compensation_core(int **rxdataF_ext, // print_shorts("rx:",rxdataF128); // print_shorts("ch:",dl_ch128); // print_shorts("pack:",rxdataF_comp128); - // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+1); // print_shorts("ch:",dl_ch128+1); //print_shorts("pack:",rxdataF_comp128+1); - dl_ch128+=2; dl_ch_mag128+=2; dl_ch_mag128b+=2; rxdataF128+=2; rxdataF_comp128+=2; } - }else { + } else { printf ("Channel Compensation: Received number of subcarriers is not multiple of 8, \n" - "need to adapt the code!\n"); + "need to adapt the code!\n"); } } } -/*This part of code makes sense only for processing in 2x2 blocks*/ + /*This part of code makes sense only for processing in 2x2 blocks*/ if (rho) { - - for (aarx=0; aarx<n_rx; aarx++) { rho128 = (__m128i *)&rho[aarx][start_point]; dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][start_point]; dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][start_point]; - if (length_mod8 == 0){ + if (length_mod8 == 0) { length2 = length>>3; for (ii=0; ii<length2; ++ii) { // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]); // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)&conjugate[0]); // print_ints("im",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) @@ -1917,124 +1838,115 @@ void dlsch_channel_compensation_core(int **rxdataF_ext, // print_ints("c0",&mmtmpD2); // print_ints("c1",&mmtmpD3); rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - //print_shorts("rx:",dl_ch128_2); //print_shorts("ch:",dl_ch128); //print_shorts("pack:",rho128); - // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128_2[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128_2[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3); dl_ch128+=2; dl_ch128_2+=2; rho128+=2; } - }else { + } else { printf ("Channel Compensation: Received number of subcarriers is not multiple of 8, \n" - "need to adapt the code!\n"); + "need to adapt the code!\n"); } } } + _mm_empty(); _m_empty(); } #if defined(__x86_64__) || defined(__i386__) -void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) -{ - +void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) { __m128i amp; amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); switch (pmi) { - - case 0 : // +1 +1 - // print_shorts("phase 0 :ch0",ch0); - // print_shorts("phase 0 :ch1",ch1); - ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); - break; - - case 1 : // +1 -1 - // print_shorts("phase 1 :ch0",ch0); - // print_shorts("phase 1 :ch1",ch1); - ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]); - // print_shorts("phase 1 :ch0-ch1",ch0); - break; - - case 2 : // +1 +j - ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); - ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); - ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); - ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]); - - break; // +1 -j - - case 3 : - ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); - ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); - ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); - ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); - break; + case 0 : // +1 +1 + // print_shorts("phase 0 :ch0",ch0); + // print_shorts("phase 0 :ch1",ch1); + ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); + break; + + case 1 : // +1 -1 + // print_shorts("phase 1 :ch0",ch0); + // print_shorts("phase 1 :ch1",ch1); + ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]); + // print_shorts("phase 1 :ch0-ch1",ch0); + break; + + case 2 : // +1 +j + ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i *)&conjugate[0]); + ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]); + break; // +1 -j + + case 3 : + ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i *)&conjugate[0]); + ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); + break; } ch0[0] = _mm_mulhi_epi16(ch0[0],amp); ch0[0] = _mm_slli_epi16(ch0[0],1); - _mm_empty(); _m_empty(); } #elif defined(__arm__) void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) { - // sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b, //so removed it //__m128i amp; //amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); - switch (pmi) { - - case 0 : // +1 +1 - // print_shorts("phase 0 :ch0",ch0); - // print_shorts("phase 0 :ch1",ch1); - ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); - break; - case 1 : // +1 -1 - // print_shorts("phase 1 :ch0",ch0); - // print_shorts("phase 1 :ch1",ch1); - ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]); - // print_shorts("phase 1 :ch0-ch1",ch0); - break; - case 2 : // +1 +j - ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); - ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); - ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); - ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]); - - break; // +1 -j - case 3 : - ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); - ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); - ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); - ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); - break; + case 0 : // +1 +1 + // print_shorts("phase 0 :ch0",ch0); + // print_shorts("phase 0 :ch1",ch1); + ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); + break; + + case 1 : // +1 -1 + // print_shorts("phase 1 :ch0",ch0); + // print_shorts("phase 1 :ch1",ch1); + ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]); + // print_shorts("phase 1 :ch0-ch1",ch0); + break; + + case 2 : // +1 +j + ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i *)&conjugate[0]); + ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + ch0[0] = _mm_subs_epi16(ch0[0],ch1[0]); + break; // +1 -j + + case 3 : + ch1[0] = _mm_sign_epi16(ch1[0],*(__m128i *)&conjugate[0]); + ch1[0] = _mm_shufflelo_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + ch1[0] = _mm_shufflehi_epi16(ch1[0],_MM_SHUFFLE(2,3,0,1)); + ch0[0] = _mm_adds_epi16(ch0[0],ch1[0]); + break; } //ch0[0] = _mm_mulhi_epi16(ch0[0],amp); //ch0[0] = _mm_slli_epi16(ch0[0],1); - _mm_empty(); _m_empty(); } @@ -2046,42 +1958,30 @@ void prec2A_TM56_128(unsigned char pmi,__m128i *ch0,__m128i *ch1) { short TM3_prec[8]__attribute__((aligned(16))) = {1,1,-1,-1,1,1,-1,-1} ; void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { - __m128i amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); - __m128i tmp0,tmp1; - //_mm_mulhi_epi16 // print_shorts("prec2A_TM3 ch0 (before):",ch0); // print_shorts("prec2A_TM3 ch1 (before):",ch1); - tmp0 = ch0[0]; - tmp1 = _mm_sign_epi16(ch1[0],((__m128i*)&TM3_prec)[0]); + tmp1 = _mm_sign_epi16(ch1[0],((__m128i *)&TM3_prec)[0]); // print_shorts("prec2A_TM3 ch1*s (mid):",(__m128i*)TM3_prec); - ch0[0] = _mm_adds_epi16(ch0[0],tmp1); ch1[0] = _mm_subs_epi16(tmp0,tmp1); - ch0[0] = _mm_mulhi_epi16(ch0[0],amp); ch0[0] = _mm_slli_epi16(ch0[0],1); - ch1[0] = _mm_mulhi_epi16(ch1[0],amp); ch1[0] = _mm_slli_epi16(ch1[0],1); - // print_shorts("prec2A_TM3 ch0 (mid):",&tmp0); // print_shorts("prec2A_TM3 ch1 (mid):",ch1); - //ch0[0] = _mm_mulhi_epi16(ch0[0],amp); //ch0[0] = _mm_slli_epi16(ch0[0],1); //ch1[0] = _mm_mulhi_epi16(ch1[0],amp); //ch1[0] = _mm_slli_epi16(ch1[0],1); - //ch0[0] = _mm_srai_epi16(ch0[0],1); //ch1[0] = _mm_srai_epi16(ch1[0],1); - // print_shorts("prec2A_TM3 ch0 (after):",ch0); // print_shorts("prec2A_TM3 ch1 (after):",ch1); - _mm_empty(); _m_empty(); } @@ -2090,27 +1990,24 @@ void prec2A_TM3_128(__m128i *ch0,__m128i *ch1) { // pmi = 1 => stream 0 (1,j), stream 2 (1,-j) void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { - -// sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b, -//so divide by 2 is replaced by divide by sqrt(2). - - // printf ("demod pmi=%d\n", pmi); - __m128i amp; - amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); + // sqrt(2) is already taken into account in computation sqrt_rho_a, sqrt_rho_b, + //so divide by 2 is replaced by divide by sqrt(2). + // printf ("demod pmi=%d\n", pmi); + __m128i amp; + amp = _mm_set1_epi16(ONE_OVER_SQRT2_Q15); __m128i tmp0,tmp1; - // print_shorts("prec2A_TM4 ch0 (before):",ch0); - // print_shorts("prec2A_TM4 ch1 (before):",ch1); + // print_shorts("prec2A_TM4 ch0 (before):",ch0); + // print_shorts("prec2A_TM4 ch1 (before):",ch1); if (pmi == 0) { //[1 1;1 -1] tmp0 = ch0[0]; tmp1 = ch1[0]; ch0[0] = _mm_adds_epi16(tmp0,tmp1); ch1[0] = _mm_subs_epi16(tmp0,tmp1); - } - else { //ch0+j*ch1 ch0-j*ch1 + } else { //ch0+j*ch1 ch0-j*ch1 tmp0 = ch0[0]; - tmp1 = _mm_sign_epi16(ch1[0],*(__m128i*)&conjugate[0]); + tmp1 = _mm_sign_epi16(ch1[0],*(__m128i *)&conjugate[0]); tmp1 = _mm_shufflelo_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); tmp1 = _mm_shufflehi_epi16(tmp1,_MM_SHUFFLE(2,3,0,1)); ch0[0] = _mm_subs_epi16(tmp0,tmp1); @@ -2119,20 +2016,17 @@ void prec2A_TM4_128(int pmi,__m128i *ch0,__m128i *ch1) { //print_shorts("prec2A_TM4 ch0 (middle):",ch0); //print_shorts("prec2A_TM4 ch1 (middle):",ch1); - ch0[0] = _mm_mulhi_epi16(ch0[0],amp); ch0[0] = _mm_slli_epi16(ch0[0],1); ch1[0] = _mm_mulhi_epi16(ch1[0],amp); ch1[0] = _mm_slli_epi16(ch1[0],1); - - - // ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2 - // ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2 + // ch0[0] = _mm_srai_epi16(ch0[0],1); //divide by 2 + // ch1[0] = _mm_srai_epi16(ch1[0],1); //divide by 2 //print_shorts("prec2A_TM4 ch0 (end):",ch0); //print_shorts("prec2A_TM4 ch1 (end):",ch1); _mm_empty(); _m_empty(); - // print_shorts("prec2A_TM4 ch0 (end):",ch0); + // print_shorts("prec2A_TM4 ch0 (end):",ch0); //print_shorts("prec2A_TM4 ch1 (end):",ch1); } @@ -2149,25 +2043,21 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, unsigned char mod_order, unsigned short nb_rb, unsigned char output_shift, - unsigned char dl_power_off) -{ - + unsigned char dl_power_off) { #if defined(__x86_64__) || defined(__i386__) - unsigned short rb,Nre; __m128i *dl_ch0_128,*dl_ch1_128,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128; unsigned char aarx=0,symbol_mod,pilots=0; int precoded_signal_strength=0; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) pilots=1; - //printf("comp prec: symbol %d, pilots %d\n",symbol, pilots); __m128i QAM_amp128b = _mm_setzero_si128(); + if (mod_order == 4) { QAM_amp128 = _mm_set1_epi16(QAM16_n1); } else if (mod_order == 6) { @@ -2176,17 +2066,13 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, } for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - - dl_ch_mag128 = (__m128i *)&dl_ch_mag[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128b = (__m128i *)&dl_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128 = (__m128i *)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0; rb<nb_rb; rb++) { // combine TX channels using precoder from pmi #ifdef DEBUG_DLSCH_DEMOD @@ -2196,31 +2082,22 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); if (pilots==0) { - prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); } if (mod_order>2) { // get channel amplitude if not QPSK - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[0] = dl_ch_mag128[0]; dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); - - //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]); - //print_shorts("dl_ch_mag128[0]=",&dl_ch_mag128[0]); - dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[1] = dl_ch_mag128[1]; dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); @@ -2229,40 +2106,32 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); dl_ch_mag128b[2] = dl_ch_mag128[2]; - dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); } dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); - //print_shorts("dl_ch_mag128b[0]=",&dl_ch_mag128b[0]); - dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); if (pilots==0) { dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); - } } // MF multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]); // print_ints("re",&mmtmpD0); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)&conjugate[0]); // print_ints("im",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) @@ -2278,20 +2147,18 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, // print_shorts("rx:",rxdataF128); // print_shorts("ch:",dl_ch128); // print_shorts("pack:",rxdataF_comp128); - // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+1); // print_shorts("ch:",dl_ch128+1); @@ -2303,19 +2170,17 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[2],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); // print_shorts("rx:",rxdataF128+2); // print_shorts("ch:",dl_ch128+2); // print_shorts("pack:",rxdataF_comp128+2); - dl_ch0_128+=3; dl_ch1_128+=3; dl_ch_mag128+=3; @@ -2333,45 +2198,37 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, } Nre = (pilots==0) ? 12 : 8; - precoded_signal_strength += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))) - (measurements->n0_power[aarx])); + (nb_rb*Nre))) - (measurements->n0_power[aarx])); } // rx_antennas measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,measurements->n0_power_tot); - //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, // measurements->precoded_cqi_dB[eNB_id][0]); - #elif defined(__arm__) - uint32_t rb,Nre; uint32_t aarx,symbol_mod,pilots=0; - int16x4_t *dl_ch0_128,*dl_ch1_128,*rxdataF128; int16x8_t *dl_ch0_128b,*dl_ch1_128b; int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b; int16x8_t *dl_ch_mag128,*dl_ch_mag128b,mmtmpD2,mmtmpD3,mmtmpD4,*rxdataF_comp128; int16x8_t QAM_amp128,QAM_amp128b; - int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1}; int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift); int32_t precoded_signal_strength=0; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { - if (frame_parms->nb_antenna_ports_eNB==1) // 10 out of 12 so don't reduce size - { nb_rb=1+(5*nb_rb/6); } - else - { pilots=1; } + if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { + if (frame_parms->nb_antenna_ports_eNB==1) { // 10 out of 12 so don't reduce size + nb_rb=1+(5*nb_rb/6); + } else { + pilots=1; + } } - if (mod_order == 4) { QAM_amp128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) QAM_amp128b = vmovq_n_s16(0); - } else if (mod_order == 6) { QAM_amp128 = vmovq_n_s16(QAM64_n1); // QAM_amp128b = vmovq_n_s16(QAM64_n2); @@ -2380,21 +2237,18 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - - - - dl_ch0_128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch1_128 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch0_128b = (int16x8_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch1_128b = (int16x8_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128 = (int16x8_t*)&dl_ch_mag[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128b = (int16x8_t*)&dl_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128 = (int16x8_t*)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch0_128 = (int16x4_t *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch1_128 = (int16x4_t *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch0_128b = (int16x8_t *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch1_128b = (int16x8_t *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128 = (int16x8_t *)&dl_ch_mag[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128b = (int16x8_t *)&dl_ch_magb[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF128 = (int16x4_t *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128 = (int16x8_t *)&rxdataF_comp[aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { #ifdef DEBUG_DLSCH_DEMOD - printf("mode 6 prec: rb %d, pmi->%d\n",rb,pmi_ext[rb]); + printf("mode 6 prec: rb %d, pmi->%u\n",rb,pmi_ext[rb]); #endif prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[0],&dl_ch1_128b[0]); prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128b[1],&dl_ch1_128b[1]); @@ -2418,14 +2272,13 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, mmtmpD1 = vmull_s16(dl_ch0_128[3], dl_ch0_128[3]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + if (pilots==0) { mmtmpD0 = vmull_s16(dl_ch0_128[4], dl_ch0_128[4]); mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - } dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b); @@ -2433,12 +2286,12 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128); dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128); - if (pilots==0) { dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); } } + mmtmpD0 = vmull_s16(dl_ch0_128[0], rxdataF128[0]); //mmtmpD0 = [Re(ch[0])Re(rx[0]) Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1]) Im(ch[1])Im(ch[1])] mmtmpD1 = vmull_s16(dl_ch0_128[1], rxdataF128[1]); @@ -2446,29 +2299,24 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t *)conj)), rxdataF128[0]); //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t *)conj)), rxdataF128[1]); //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]); mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t *)conj)), rxdataF128[2]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t *)conj)), rxdataF128[3]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); @@ -2478,25 +2326,19 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t *)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t *)conj)), rxdataF128[5]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - dl_ch0_128+=6; dl_ch1_128+=6; dl_ch_mag128+=3; dl_ch_mag128b+=3; rxdataF128+=6; rxdataF_comp128+=3; - } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less dl_ch0_128+=4; dl_ch1_128+=4; @@ -2508,109 +2350,103 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, } Nre = (pilots==0) ? 12 : 8; - - precoded_signal_strength += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], - - (nb_rb*Nre))) - (measurements->n0_power[aarx])); + (nb_rb*Nre))) - (measurements->n0_power[aarx])); // rx_antennas } - measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,measurements->n0_power_tot); + measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength,measurements->n0_power_tot); //printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, // measurements->precoded_cqi_dB[eNB_id][0]); - #endif _mm_empty(); _m_empty(); } void precode_channel_est(int32_t **dl_ch_estimates_ext, - LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDSCH *pdsch_vars, - unsigned char symbol, - unsigned short nb_rb, - MIMO_mode_t mimo_mode){ - + LTE_DL_FRAME_PARMS *frame_parms, + LTE_UE_PDSCH *pdsch_vars, + unsigned char symbol, + unsigned short nb_rb, + MIMO_mode_t mimo_mode) { unsigned short rb; __m128i *dl_ch0_128,*dl_ch1_128; unsigned char aarx=0,symbol_mod,pilots=0; unsigned char *pmi_ext = pdsch_vars->pmi_ext; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) pilots=1; - for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) { - + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12 for (rb=0; rb<nb_rb; rb++) { if (mimo_mode==LARGE_CDD) { - prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]); - if (pilots==0) { - prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]); - } - }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { - prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); - if (pilots==0) { - prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); - } - }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { - prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]); - if (pilots==0) { - prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); - } - }else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); - if (pilots==0) { - prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); - } - }else { - LOG_E(PHY,"Unknown MIMO mode\n"); - return; - } - if (pilots==0){ - dl_ch0_128+=3; - dl_ch1_128+=3; - }else { - dl_ch0_128+=2; - dl_ch1_128+=2; - } + prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]); + + if (pilots==0) { + prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]); + } + } else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { + prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); + + if (pilots==0) { + prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); + } + } else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { + prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]); + + if (pilots==0) { + prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); + } + } else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); + + if (pilots==0) { + prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); } + } else { + LOG_E(PHY,"Unknown MIMO mode\n"); + return; + } + if (pilots==0) { + dl_ch0_128+=3; + dl_ch1_128+=3; + } else { + dl_ch0_128+=2; + dl_ch1_128+=2; } + } + } } void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, - LTE_UE_PDSCH *pdsch_vars, - PHY_MEASUREMENTS *measurements, - int eNB_id, - unsigned char symbol, - unsigned char mod_order0, - unsigned char mod_order1, - int harq_pid, - int round, - MIMO_mode_t mimo_mode, - unsigned short nb_rb, - unsigned short mmse_flag, - unsigned char output_shift0, - unsigned char output_shift1) { - + LTE_UE_PDSCH *pdsch_vars, + PHY_MEASUREMENTS *measurements, + int eNB_id, + unsigned char symbol, + unsigned char mod_order0, + unsigned char mod_order1, + int harq_pid, + int round, + MIMO_mode_t mimo_mode, + unsigned short nb_rb, + unsigned short mmse_flag, + unsigned char output_shift0, + unsigned char output_shift1) { #if defined(__x86_64__) || defined(__i386__) - unsigned short rb,Nre; __m128i *dl_ch0_128,*dl_ch1_128,*dl_ch_mag0_128,*dl_ch_mag1_128,*dl_ch_mag0_128b,*dl_ch_mag1_128b,*rxdataF128,*rxdataF_comp0_128,*rxdataF_comp1_128; unsigned char aarx=0,symbol_mod,pilots=0; int precoded_signal_strength0=0,precoded_signal_strength1=0; int rx_power_correction; - int **rxdataF_ext = pdsch_vars->rxdataF_ext; int **dl_ch_estimates_ext = pdsch_vars->dl_ch_estimates_ext; int **dl_ch_mag0 = pdsch_vars->dl_ch_mag0; @@ -2621,17 +2457,15 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[harq_pid][round]; unsigned char *pmi_ext = pdsch_vars->pmi_ext; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp1_128; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) pilots=1; rx_power_correction = 1; - - // printf("comp prec: symbol %d, pilots %d\n",symbol, pilots); - + // printf("comp prec: symbol %d, pilots %d\n",symbol, pilots); __m128i QAM_amp0_128b = _mm_setzero_si128(); + if (mod_order0 == 4) { QAM_amp0_128 = _mm_set1_epi16(QAM16_n1); } else if (mod_order0 == 6) { @@ -2640,6 +2474,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, } __m128i QAM_amp1_128b = _mm_setzero_si128(); + if (mod_order1 == 4) { QAM_amp1_128 = _mm_set1_epi16(QAM16_n1); } else if (mod_order1 == 6) { @@ -2647,8 +2482,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, QAM_amp1_128b = _mm_set1_epi16(QAM64_n2); } - for (aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) { - + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; // this is h11 dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; // this is h12 dl_ch_mag0_128 = (__m128i *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; //responsible for x1 @@ -2661,57 +2495,53 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, for (rb=0; rb<nb_rb; rb++) { if (mmse_flag == 0) { - // combine TX channels using precoder from pmi + // combine TX channels using precoder from pmi if (mimo_mode==LARGE_CDD) { prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]); prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]); } - }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { + } else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); } - }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { + } else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]); prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); } - }else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { + } else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) { prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[0],&dl_ch1_128[0]); prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128[2],&dl_ch1_128[2]); } - }else { + } else { LOG_E(PHY,"Unknown MIMO mode\n"); return; } } - if (mod_order0>2) { // get channel amplitude if not QPSK - mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch0_128[0]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = _mm_madd_epi16(dl_ch0_128[1],dl_ch0_128[1]); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - dl_ch_mag0_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag0_128b[0] = dl_ch_mag0_128[0]; dl_ch_mag0_128[0] = _mm_mulhi_epi16(dl_ch_mag0_128[0],QAM_amp0_128); dl_ch_mag0_128[0] = _mm_slli_epi16(dl_ch_mag0_128[0],1); - // print_shorts("dl_ch_mag0_128[0]=",&dl_ch_mag0_128[0]); - - dl_ch_mag0_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); dl_ch_mag0_128b[1] = dl_ch_mag0_128[1]; dl_ch_mag0_128[1] = _mm_mulhi_epi16(dl_ch_mag0_128[1],QAM_amp0_128); @@ -2720,21 +2550,16 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch0_128[2],dl_ch0_128[2]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag0_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); dl_ch_mag0_128b[2] = dl_ch_mag0_128[2]; - dl_ch_mag0_128[2] = _mm_mulhi_epi16(dl_ch_mag0_128[2],QAM_amp0_128); dl_ch_mag0_128[2] = _mm_slli_epi16(dl_ch_mag0_128[2],1); } dl_ch_mag0_128b[0] = _mm_mulhi_epi16(dl_ch_mag0_128b[0],QAM_amp0_128b); dl_ch_mag0_128b[0] = _mm_slli_epi16(dl_ch_mag0_128b[0],1); - - // print_shorts("dl_ch_mag0_128b[0]=",&dl_ch_mag0_128b[0]); - + // print_shorts("dl_ch_mag0_128b[0]=",&dl_ch_mag0_128b[0]); dl_ch_mag0_128b[1] = _mm_mulhi_epi16(dl_ch_mag0_128b[1],QAM_amp0_128b); dl_ch_mag0_128b[1] = _mm_slli_epi16(dl_ch_mag0_128b[1],1); @@ -2746,22 +2571,16 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (mod_order1>2) { // get channel amplitude if not QPSK - mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],dl_ch1_128[0]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - mmtmpD1 = _mm_madd_epi16(dl_ch1_128[1],dl_ch1_128[1]); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); - dl_ch_mag1_128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag1_128b[0] = dl_ch_mag1_128[0]; dl_ch_mag1_128[0] = _mm_mulhi_epi16(dl_ch_mag1_128[0],QAM_amp1_128); dl_ch_mag1_128[0] = _mm_slli_epi16(dl_ch_mag1_128[0],1); - - // print_shorts("dl_ch_mag1_128[0]=",&dl_ch_mag1_128[0]); - + // print_shorts("dl_ch_mag1_128[0]=",&dl_ch_mag1_128[0]); dl_ch_mag1_128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); dl_ch_mag1_128b[1] = dl_ch_mag1_128[1]; dl_ch_mag1_128[1] = _mm_mulhi_epi16(dl_ch_mag1_128[1],QAM_amp1_128); @@ -2770,21 +2589,16 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (pilots==0) { mmtmpD0 = _mm_madd_epi16(dl_ch1_128[2],dl_ch1_128[2]); mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - dl_ch_mag1_128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); dl_ch_mag1_128b[2] = dl_ch_mag1_128[2]; - dl_ch_mag1_128[2] = _mm_mulhi_epi16(dl_ch_mag1_128[2],QAM_amp1_128); dl_ch_mag1_128[2] = _mm_slli_epi16(dl_ch_mag1_128[2],1); } dl_ch_mag1_128b[0] = _mm_mulhi_epi16(dl_ch_mag1_128b[0],QAM_amp1_128b); dl_ch_mag1_128b[0] = _mm_slli_epi16(dl_ch_mag1_128b[0],1); - - // print_shorts("dl_ch_mag1_128b[0]=",&dl_ch_mag1_128b[0]); - + // print_shorts("dl_ch_mag1_128b[0]=",&dl_ch_mag1_128b[0]); dl_ch_mag1_128b[1] = _mm_mulhi_epi16(dl_ch_mag1_128b[1],QAM_amp1_128b); dl_ch_mag1_128b[1] = _mm_slli_epi16(dl_ch_mag1_128b[1],1); @@ -2797,47 +2611,43 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // layer 0 // MF multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); - + // print_ints("re",&mmtmpD0); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)&conjugate[0]); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); - // print_ints("im",&mmtmpD1); + // print_ints("im",&mmtmpD1); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); - // printf("Shift: %d\n",output_shift); - // print_ints("re(shift)",&mmtmpD0); + // printf("Shift: %d\n",output_shift); + // print_ints("re(shift)",&mmtmpD0); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); - // print_ints("im(shift)",&mmtmpD1); + // print_ints("im(shift)",&mmtmpD1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); rxdataF_comp0_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch0_128); + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch0_128); //print_shorts("pack:",rxdataF_comp0_128); - // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch0_128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp0_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch0_128+1); - // print_shorts("pack:",rxdataF_comp0_128+1); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch0_128+1); + // print_shorts("pack:",rxdataF_comp0_128+1); if (pilots==0) { // multiply by conjugated channel @@ -2845,64 +2655,58 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[2],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp0_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch0_128+2); - // print_shorts("pack:",rxdataF_comp0_128+2); - + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch0_128+2); + // print_shorts("pack:",rxdataF_comp0_128+2); } - // layer 1 // MF multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch1_128[0],rxdataF128[0]); - // print_ints("re",&mmtmpD0); - - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + // print_ints("re",&mmtmpD0); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); - // print_ints("im",&mmtmpD1); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)&conjugate[0]); + // print_ints("im",&mmtmpD1); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[0]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); - // print_ints("re(shift)",&mmtmpD0); + // print_ints("re(shift)",&mmtmpD0); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); - // print_ints("im(shift)",&mmtmpD1); + // print_ints("im(shift)",&mmtmpD1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - // print_ints("c0",&mmtmpD2); - // print_ints("c1",&mmtmpD3); + // print_ints("c0",&mmtmpD2); + // print_ints("c1",&mmtmpD3); rxdataF_comp1_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch1_128); - // print_shorts("pack:",rxdataF_comp1_128); - - // multiply by conjugated channel + // print_shorts("rx:",rxdataF128); + // print_shorts("ch:",dl_ch1_128); + // print_shorts("pack:",rxdataF_comp1_128); + // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch1_128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp1_128[1] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+1); - // print_shorts("ch:",dl_ch1_128+1); - // print_shorts("pack:",rxdataF_comp1_128+1); + // print_shorts("rx:",rxdataF128+1); + // print_shorts("ch:",dl_ch1_128+1); + // print_shorts("pack:",rxdataF_comp1_128+1); if (pilots==0) { // multiply by conjugated channel @@ -2910,19 +2714,17 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch1_128[2],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift1); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift1); mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp1_128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rx:",rxdataF128+2); - // print_shorts("ch:",dl_ch1_128+2); - // print_shorts("pack:",rxdataF_comp1_128+2); - + // print_shorts("rx:",rxdataF128+2); + // print_shorts("ch:",dl_ch1_128+2); + // print_shorts("pack:",rxdataF_comp1_128+2); dl_ch0_128+=3; dl_ch1_128+=3; dl_ch_mag0_128+=3; @@ -2932,8 +2734,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, rxdataF128+=3; rxdataF_comp0_128+=3; rxdataF_comp1_128+=3; - } - else { + } else { dl_ch0_128+=2; dl_ch1_128+=2; dl_ch_mag0_128+=2; @@ -2944,40 +2745,32 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, rxdataF_comp0_128+=2; rxdataF_comp1_128+=2; } - } // rb loop - Nre = (pilots==0) ? 12 : 8; + Nre = (pilots==0) ? 12 : 8; precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx])); - + (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx])); precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx])); + (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx])); } // rx_antennas measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,measurements->n0_power_tot); measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,measurements->n0_power_tot); - - // printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, - // measurements->precoded_cqi_dB[eNB_id][0]); - + // printf("eNB_id %d, symbol %d: precoded CQI %d dB\n",eNB_id,symbol, + // measurements->precoded_cqi_dB[eNB_id][0]); _mm_empty(); _m_empty(); - - #elif defined(__arm__) - +#elif defined(__arm__) unsigned short rb,Nre; unsigned char aarx,symbol_mod,pilots=0; int precoded_signal_strength0=0,precoded_signal_strength1=0, rx_power_correction; int16x4_t *dl_ch0_128,*rxdataF128; int16x4_t *dl_ch1_128; int16x8_t *dl_ch0_128b,*dl_ch1_128b; - int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b; int16x8_t *dl_ch_mag0_128,*dl_ch_mag0_128b,*dl_ch_mag1_128,*dl_ch_mag1_128b,mmtmpD2,mmtmpD3,mmtmpD4,*rxdataF_comp0_128,*rxdataF_comp1_128; int16x8_t QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift); - int **rxdataF_ext = pdsch_vars->rxdataF_ext; int **dl_ch_estimates_ext = pdsch_vars->dl_ch_estimates_ext; int **dl_ch_mag0 = pdsch_vars->dl_ch_mag0; @@ -2986,17 +2779,15 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_magb1 = pdsch_vars->dl_ch_magb1[harq_pid][round]; int **rxdataF_comp0 = pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[harq_pid][round]; - int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1}; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { - if (frame_parms->nb_antenna_ports_eNB==1) // 10 out of 12 so don't reduce size - { nb_rb=1+(5*nb_rb/6); } - - else - { pilots=1; } + if (frame_parms->nb_antenna_ports_eNB==1) { // 10 out of 12 so don't reduce size + nb_rb=1+(5*nb_rb/6); + } else { + pilots=1; + } } rx_power_correction=1; @@ -3004,7 +2795,6 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (mod_order0 == 4) { QAM_amp0_128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) QAM_amp0_128b = vmovq_n_s16(0); - } else if (mod_order0 == 6) { QAM_amp0_128 = vmovq_n_s16(QAM64_n1); // QAM_amp0_128b = vmovq_n_s16(QAM64_n2); @@ -3013,7 +2803,6 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (mod_order1 == 4) { QAM_amp1_128 = vmovq_n_s16(QAM16_n1); // 2/sqrt(10) QAM_amp1_128b = vmovq_n_s16(0); - } else if (mod_order1 == 6) { QAM_amp1_128 = vmovq_n_s16(QAM64_n1); // QAM_amp1_128b = vmovq_n_s16(QAM64_n2); @@ -3022,20 +2811,17 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - - - - dl_ch0_128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch1_128 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch0_128b = (int16x8_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch1_128b = (int16x8_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag0_128 = (int16x8_t*)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag0_128b = (int16x8_t*)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag1_128 = (int16x8_t*)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag1_128b = (int16x8_t*)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp0_128 = (int16x8_t*)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp1_128 = (int16x8_t*)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch0_128 = (int16x4_t *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch1_128 = (int16x4_t *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch0_128b = (int16x8_t *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch1_128b = (int16x8_t *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag0_128 = (int16x8_t *)&dl_ch_mag0[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag0_128b = (int16x8_t *)&dl_ch_magb0[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag1_128 = (int16x8_t *)&dl_ch_mag1[aarx][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag1_128b = (int16x8_t *)&dl_ch_magb1[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF128 = (int16x4_t *)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp0_128 = (int16x8_t *)&rxdataF_comp0[aarx][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp1_128 = (int16x8_t *)&rxdataF_comp1[aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { if (mmse_flag == 0) { @@ -3043,28 +2829,30 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, if (mimo_mode==LARGE_CDD) { prec2A_TM3_128(&dl_ch0_128[0],&dl_ch1_128[0]); prec2A_TM3_128(&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { prec2A_TM3_128(&dl_ch0_128[2],&dl_ch1_128[2]); } - }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { + } else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) { prec2A_TM4_128(0,&dl_ch0_128[0],&dl_ch1_128[0]); prec2A_TM4_128(0,&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { prec2A_TM4_128(0,&dl_ch0_128[2],&dl_ch1_128[2]); } - }else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { + } else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODINGj) { prec2A_TM4_128(1,&dl_ch0_128[0],&dl_ch1_128[0]); prec2A_TM4_128(1,&dl_ch0_128[1],&dl_ch1_128[1]); + if (pilots==0) { prec2A_TM4_128(1,&dl_ch0_128[2],&dl_ch1_128[2]); } - }else { + } else { LOG_E(PHY,"Unknown MIMO mode\n"); return; } } - if (mod_order0>2) { // get channel amplitude if not QPSK mmtmpD0 = vmull_s16(dl_ch0_128[0], dl_ch0_128[0]); @@ -3087,8 +2875,6 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = vmull_s16(dl_ch0_128[5], dl_ch0_128[5]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - } dl_ch_mag0_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128b); @@ -3096,7 +2882,6 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, dl_ch_mag0_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp0_128); dl_ch_mag0_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp0_128); - if (pilots==0) { dl_ch_mag0_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128b); dl_ch_mag0_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp0_128); @@ -3125,8 +2910,6 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = vmull_s16(dl_ch1_128[5], dl_ch1_128[5]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - - } dl_ch_mag1_128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128b); @@ -3134,7 +2917,6 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, dl_ch_mag1_128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp1_128); dl_ch_mag1_128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp1_128); - if (pilots==0) { dl_ch_mag1_128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128b); dl_ch_mag1_128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp1_128); @@ -3148,60 +2930,49 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); //mmtmpD0 = [Re(ch[0])Re(rx[0])+Im(ch[0])Im(ch[0]) Re(ch[1])Re(rx[1])+Im(ch[1])Im(ch[1]) Re(ch[2])Re(rx[2])+Im(ch[2])Im(ch[2]) Re(ch[3])Re(rx[3])+Im(ch[3])Im(ch[3])] - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t *)conj)), rxdataF128[0]); //mmtmpD0 = [-Im(ch[0])Re(rx[0]) Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1]) Re(ch[1])Im(rx[1])] - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t *)conj)), rxdataF128[1]); //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp0_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - mmtmpD0 = vmull_s16(dl_ch0_128[2], rxdataF128[2]); mmtmpD1 = vmull_s16(dl_ch0_128[3], rxdataF128[3]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t *)conj)), rxdataF128[2]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t *)conj)), rxdataF128[3]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp0_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - // second stream mmtmpD0 = vmull_s16(dl_ch1_128[0], rxdataF128[0]); mmtmpD1 = vmull_s16(dl_ch1_128[1], rxdataF128[1]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t*)conj)), rxdataF128[0]); - - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t*)conj)), rxdataF128[1]); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[0],*(int16x4_t *)conj)), rxdataF128[0]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[1],*(int16x4_t *)conj)), rxdataF128[1]); //mmtmpD0 = [-Im(ch[2])Re(rx[2]) Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3]) Re(ch[3])Im(rx[3])] mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); //mmtmpD1 = [-Im(ch[0])Re(rx[0])+Re(ch[0])Im(rx[0]) -Im(ch[1])Re(rx[1])+Re(ch[1])Im(rx[1]) -Im(ch[2])Re(rx[2])+Re(ch[2])Im(rx[2]) -Im(ch[3])Re(rx[3])+Re(ch[3])Im(rx[3])] - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp1_128[0] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - mmtmpD0 = vmull_s16(dl_ch1_128[2], rxdataF128[2]); mmtmpD1 = vmull_s16(dl_ch1_128[3], rxdataF128[3]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t*)conj)), rxdataF128[2]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t*)conj)), rxdataF128[3]); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[2],*(int16x4_t *)conj)), rxdataF128[2]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[3],*(int16x4_t *)conj)), rxdataF128[3]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp1_128[1] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); @@ -3211,13 +2982,10 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = vmull_s16(dl_ch0_128[5], rxdataF128[5]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t*)conj)), rxdataF128[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[4],*(int16x4_t *)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch0_128[5],*(int16x4_t *)conj)), rxdataF128[5]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp0_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); @@ -3225,37 +2993,27 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD1 = vmull_s16(dl_ch1_128[5], rxdataF128[5]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[4],*(int16x4_t*)conj)), rxdataF128[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[4],*(int16x4_t *)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch1_128[5],*(int16x4_t *)conj)), rxdataF128[5]); mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp1_128[2] = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); } } - - Nre = (pilots==0) ? 12 : 8; - // rx_antennas } - Nre = (pilots==0) ? 12 : 8; - precoded_signal_strength0 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx])); + (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx])); precoded_signal_strength1 += ((signal_energy_nodc(&dl_ch_estimates_ext[aarx+2][symbol*frame_parms->N_RB_DL*Nre], - (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx])); - + (nb_rb*Nre))*rx_power_correction) - (measurements->n0_power[aarx])); measurements->precoded_cqi_dB[eNB_id][0] = dB_fixed2(precoded_signal_strength0,measurements->n0_power_tot); measurements->precoded_cqi_dB[eNB_id][1] = dB_fixed2(precoded_signal_strength1,measurements->n0_power_tot); - #endif } @@ -3266,17 +3024,12 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_estimates_ext, int **dl_ch_estimates_ext_i, int **dl_ch_rho_ext, - unsigned char output_shift) -{ - + unsigned char output_shift) { #if defined(__x86_64__)||defined(__i386__) - unsigned short rb; __m128i *dl_ch128,*dl_ch128i,*dl_ch_rho128,mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; unsigned char aarx,symbol_mod,pilots=0; - // printf("dlsch_dual_stream_correlation: symbol %d\n",symbol); - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { @@ -3286,7 +3039,6 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, // printf("Dual stream correlation (%p)\n",dl_ch_estimates_ext_i); for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; if (dl_ch_estimates_ext_i == NULL) // TM3/4 @@ -3303,7 +3055,7 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)&conjugate[0]); mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[0]); // print_ints("im",&mmtmpD1); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) @@ -3316,13 +3068,13 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, // print_ints("c0",&mmtmpD2); // print_ints("c1",&mmtmpD3); dl_ch_rho128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - // print_shorts("rho 0:",dl_ch_rho128); + // print_shorts("rho 0:",dl_ch_rho128); // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[1],dl_ch128i[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[1]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); @@ -3331,15 +3083,13 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); dl_ch_rho128[1] =_mm_packs_epi32(mmtmpD2,mmtmpD3); - if (pilots==0) { - // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128i[2]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i *)conjugate); mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch128i[2]); // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); @@ -3347,25 +3097,20 @@ void dlsch_dual_stream_correlation(LTE_DL_FRAME_PARMS *frame_parms, mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); dl_ch_rho128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - - dl_ch128+=3; + dl_ch128+=3; dl_ch128i+=3; dl_ch_rho128+=3; } else { - dl_ch128+=2; dl_ch128i+=2; dl_ch_rho128+=2; } } - } _mm_empty(); _m_empty(); - #elif defined(__arm__) - #endif } @@ -3381,20 +3126,15 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_magb_i, unsigned char symbol, unsigned short nb_rb, - unsigned char dual_stream_UE) -{ - + unsigned char dual_stream_UE) { #if defined(__x86_64__)||defined(__i386__) - unsigned char aatx; int i; __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1, - *dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; + *dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; if (frame_parms->nb_antennas_rx>1) { - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; @@ -3403,29 +3143,28 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) - for (i=0;i<nb_rb*3;i++) { + for (i=0; i<nb_rb*3; i++) { rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1)); dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1)); - // print_shorts("mrc comp0:",&rxdataF_comp128_0[i]); + // print_shorts("mrc comp0:",&rxdataF_comp128_0[i]); // print_shorts("mrc mag0:",&dl_ch_mag128_0[i]); // print_shorts("mrc mag0b:",&dl_ch_mag128_0b[i]); // print_shorts("mrc rho1:",&rho128_1[i]); - } } if (rho) { rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12]; rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12]; - for (i=0;i<nb_rb*3;i++) { + + for (i=0; i<nb_rb*3; i++) { // print_shorts("mrc rho0:",&rho128_0[i]); // print_shorts("mrc rho1:",&rho128_1[i]); rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1)); } } - if (dual_stream_UE == 1) { rho128_i0 = (__m128i *) &rho_i[0][symbol*frame_parms->N_RB_DL*12]; rho128_i1 = (__m128i *) &rho_i[1][symbol*frame_parms->N_RB_DL*12]; @@ -3439,7 +3178,6 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, for (i=0; i<nb_rb*3; i++) { rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1)); rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1)); - dl_ch_mag128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0[i],1),_mm_srai_epi16(dl_ch_mag128_i1[i],1)); dl_ch_mag128_i0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0b[i],1),_mm_srai_epi16(dl_ch_mag128_i1b[i],1)); } @@ -3448,17 +3186,14 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, _mm_empty(); _m_empty(); - #elif defined(__arm__) - unsigned char aatx; int i; - int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1,*dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; + int16x8_t *rxdataF_comp128_0,*rxdataF_comp128_1,*rxdataF_comp128_i0,*rxdataF_comp128_i1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*rho128_0,*rho128_1,*rho128_i0,*rho128_i1, + *dl_ch_mag128_i0,*dl_ch_mag128_i1,*dl_ch_mag128_i0b,*dl_ch_mag128_i1b; if (frame_parms->nb_antennas_rx>1) { - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { - rxdataF_comp128_0 = (int16x8_t *)&rxdataF_comp[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[(aatx<<1)+1][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_0 = (int16x8_t *)&dl_ch_mag[(aatx<<1)][symbol*frame_parms->N_RB_DL*12]; @@ -3485,13 +3220,11 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, } } - if (dual_stream_UE == 1) { rho128_i0 = (int16x8_t *) &rho_i[0][symbol*frame_parms->N_RB_DL*12]; rho128_i1 = (int16x8_t *) &rho_i[1][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_i0 = (int16x8_t *)&rxdataF_comp_i[0][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_i1 = (int16x8_t *)&rxdataF_comp_i[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i0 = (int16x8_t *)&dl_ch_mag_i[0][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_i1 = (int16x8_t *)&dl_ch_mag_i[1][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_i0b = (int16x8_t *)&dl_ch_magb_i[0][symbol*frame_parms->N_RB_DL*12]; @@ -3500,7 +3233,6 @@ void dlsch_detection_mrc(LTE_DL_FRAME_PARMS *frame_parms, for (i=0; i<nb_rb*3; i++) { rxdataF_comp128_i0[i] = vhaddq_s16(rxdataF_comp128_i0[i],rxdataF_comp128_i1[i]); rho128_i0[i] = vhaddq_s16(rho128_i0[i],rho128_i1[i]); - dl_ch_mag128_i0[i] = vhaddq_s16(dl_ch_mag128_i0[i],dl_ch_mag128_i1[i]); dl_ch_mag128_i0b[i] = vhaddq_s16(dl_ch_mag128_i0b[i],dl_ch_mag128_i1b[i]); } @@ -3517,14 +3249,11 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, unsigned char symbol, unsigned short nb_rb, unsigned char dual_stream_UE) { - int i; __m128i *rxdataF_comp128_0,*rxdataF_comp128_1; __m128i *dl_ch_mag128_0,*dl_ch_mag128_1; __m128i *dl_ch_mag128_0b,*dl_ch_mag128_1b; __m128i *rho128_0, *rho128_1; - - int **rxdataF_comp0 = pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[harq_pid][round]; int **dl_ch_rho_ext = pdsch_vars->dl_ch_rho_ext[harq_pid][round]; //for second stream @@ -3533,7 +3262,6 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_mag1 = pdsch_vars->dl_ch_mag1[harq_pid][round]; int **dl_ch_magb0 = pdsch_vars->dl_ch_magb0; int **dl_ch_magb1 = pdsch_vars->dl_ch_magb1[harq_pid][round]; - rxdataF_comp128_0 = (__m128i *)&rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_1 = (__m128i *)&rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_0 = (__m128i *)&dl_ch_mag0[0][symbol*frame_parms->N_RB_DL*12]; @@ -3543,15 +3271,14 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, rho128_0 = (__m128i *) &dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12]; rho128_1 = (__m128i *) &dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12]; - // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) - for (i=0;i<nb_rb*3;i++) { + // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) + for (i=0; i<nb_rb*3; i++) { rxdataF_comp128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_0[i],1),_mm_srai_epi16(rxdataF_comp128_1[i],1)); dl_ch_mag128_0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0[i],1),_mm_srai_epi16(dl_ch_mag128_1[i],1)); dl_ch_mag128_0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_0b[i],1),_mm_srai_epi16(dl_ch_mag128_1b[i],1)); rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1)); if (frame_parms->nb_antennas_rx>2) { - __m128i *rxdataF_comp128_2 = NULL; __m128i *rxdataF_comp128_3 = NULL; __m128i *dl_ch_mag128_2 = NULL; @@ -3560,7 +3287,6 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, __m128i *dl_ch_mag128_3b = NULL; __m128i *rho128_2 = NULL; __m128i *rho128_3 = NULL; - rxdataF_comp128_2 = (__m128i *)&rxdataF_comp0[2][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128_3 = (__m128i *)&rxdataF_comp0[3][symbol*frame_parms->N_RB_DL*12]; dl_ch_mag128_2 = (__m128i *)&dl_ch_mag0[2][symbol*frame_parms->N_RB_DL*12]; @@ -3584,65 +3310,58 @@ void dlsch_detection_mrc_TM34(LTE_DL_FRAME_PARMS *frame_parms, } } - if (dual_stream_UE == 1) { - - __m128i *dl_ch_mag128_i0, *dl_ch_mag128_i1; - __m128i *dl_ch_mag128_i0b, *dl_ch_mag128_i1b; - __m128i *rho128_i0, *rho128_i1; - __m128i *rxdataF_comp128_i0, *rxdataF_comp128_i1; - - rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i0 = (__m128i *)&dl_ch_mag1[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i1 = (__m128i *)&dl_ch_mag1[1][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i0b = (__m128i *)&dl_ch_magb1[0][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i1b = (__m128i *)&dl_ch_magb1[1][symbol*frame_parms->N_RB_DL*12]; - rho128_i0 = (__m128i *) &dl_ch_rho_ext[0][symbol*frame_parms->N_RB_DL*12]; - rho128_i1 = (__m128i *) &dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12]; - - - for (i=0;i<nb_rb*3;i++) { - rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1)); - dl_ch_mag128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0[i],1),_mm_srai_epi16(dl_ch_mag128_i1[i],1)); - dl_ch_mag128_i0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0b[i],1),_mm_srai_epi16(dl_ch_mag128_i1b[i],1)); - rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1)); - - if (frame_parms->nb_antennas_rx>2) { - - __m128i *rxdataF_comp128_i2 = NULL; - __m128i *rxdataF_comp128_i3 = NULL; - __m128i *dl_ch_mag128_i2 = NULL; - __m128i *dl_ch_mag128_i3 = NULL; - __m128i *dl_ch_mag128_i2b = NULL; - __m128i *dl_ch_mag128_i3b = NULL; - __m128i *rho128_i2 = NULL; - __m128i *rho128_i3 = NULL; - - rxdataF_comp128_i2 = (__m128i *)&rxdataF_comp1[2][symbol*frame_parms->N_RB_DL*12]; - rxdataF_comp128_i3 = (__m128i *)&rxdataF_comp1[3][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i2 = (__m128i *)&dl_ch_mag1[2][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i3 = (__m128i *)&dl_ch_mag1[3][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i2b = (__m128i *)&dl_ch_magb1[2][symbol*frame_parms->N_RB_DL*12]; - dl_ch_mag128_i3b = (__m128i *)&dl_ch_magb1[3][symbol*frame_parms->N_RB_DL*12]; - rho128_i2 = (__m128i *) &dl_ch_rho_ext[2][symbol*frame_parms->N_RB_DL*12]; - rho128_i3 = (__m128i *) &dl_ch_rho_ext[3][symbol*frame_parms->N_RB_DL*12]; - - - /*rxdataF_comp*/ - rxdataF_comp128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i2[i],1),_mm_srai_epi16(rxdataF_comp128_i3[i],1)); - rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i2[i],1)); - /*dl_ch_mag*/ - dl_ch_mag128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i2[i],1),_mm_srai_epi16(dl_ch_mag128_i3[i],1)); - dl_ch_mag128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0[i],1),_mm_srai_epi16(dl_ch_mag128_i2[i],1)); - /*dl_ch_mag*/ - dl_ch_mag128_i2b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i2b[i],1),_mm_srai_epi16(dl_ch_mag128_i3b[i],1)); - dl_ch_mag128_i0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0b[i],1),_mm_srai_epi16(dl_ch_mag128_i2b[i],1)); - /*rho*/ - rho128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i2[i],1),_mm_srai_epi16(rho128_i3[i],1)); - rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i2[i],1)); - } + if (dual_stream_UE == 1) { + __m128i *dl_ch_mag128_i0, *dl_ch_mag128_i1; + __m128i *dl_ch_mag128_i0b, *dl_ch_mag128_i1b; + __m128i *rho128_i0, *rho128_i1; + __m128i *rxdataF_comp128_i0, *rxdataF_comp128_i1; + rxdataF_comp128_i0 = (__m128i *)&rxdataF_comp1[0][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i1 = (__m128i *)&rxdataF_comp1[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i0 = (__m128i *)&dl_ch_mag1[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i1 = (__m128i *)&dl_ch_mag1[1][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i0b = (__m128i *)&dl_ch_magb1[0][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i1b = (__m128i *)&dl_ch_magb1[1][symbol*frame_parms->N_RB_DL*12]; + rho128_i0 = (__m128i *) &dl_ch_rho_ext[0][symbol*frame_parms->N_RB_DL*12]; + rho128_i1 = (__m128i *) &dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12]; + + for (i=0; i<nb_rb*3; i++) { + rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i1[i],1)); + dl_ch_mag128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0[i],1),_mm_srai_epi16(dl_ch_mag128_i1[i],1)); + dl_ch_mag128_i0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0b[i],1),_mm_srai_epi16(dl_ch_mag128_i1b[i],1)); + rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i1[i],1)); + + if (frame_parms->nb_antennas_rx>2) { + __m128i *rxdataF_comp128_i2 = NULL; + __m128i *rxdataF_comp128_i3 = NULL; + __m128i *dl_ch_mag128_i2 = NULL; + __m128i *dl_ch_mag128_i3 = NULL; + __m128i *dl_ch_mag128_i2b = NULL; + __m128i *dl_ch_mag128_i3b = NULL; + __m128i *rho128_i2 = NULL; + __m128i *rho128_i3 = NULL; + rxdataF_comp128_i2 = (__m128i *)&rxdataF_comp1[2][symbol*frame_parms->N_RB_DL*12]; + rxdataF_comp128_i3 = (__m128i *)&rxdataF_comp1[3][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i2 = (__m128i *)&dl_ch_mag1[2][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i3 = (__m128i *)&dl_ch_mag1[3][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i2b = (__m128i *)&dl_ch_magb1[2][symbol*frame_parms->N_RB_DL*12]; + dl_ch_mag128_i3b = (__m128i *)&dl_ch_magb1[3][symbol*frame_parms->N_RB_DL*12]; + rho128_i2 = (__m128i *) &dl_ch_rho_ext[2][symbol*frame_parms->N_RB_DL*12]; + rho128_i3 = (__m128i *) &dl_ch_rho_ext[3][symbol*frame_parms->N_RB_DL*12]; + /*rxdataF_comp*/ + rxdataF_comp128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i2[i],1),_mm_srai_epi16(rxdataF_comp128_i3[i],1)); + rxdataF_comp128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rxdataF_comp128_i0[i],1),_mm_srai_epi16(rxdataF_comp128_i2[i],1)); + /*dl_ch_mag*/ + dl_ch_mag128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i2[i],1),_mm_srai_epi16(dl_ch_mag128_i3[i],1)); + dl_ch_mag128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0[i],1),_mm_srai_epi16(dl_ch_mag128_i2[i],1)); + /*dl_ch_mag*/ + dl_ch_mag128_i2b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i2b[i],1),_mm_srai_epi16(dl_ch_mag128_i3b[i],1)); + dl_ch_mag128_i0b[i] = _mm_adds_epi16(_mm_srai_epi16(dl_ch_mag128_i0b[i],1),_mm_srai_epi16(dl_ch_mag128_i2b[i],1)); + /*rho*/ + rho128_i2[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i2[i],1),_mm_srai_epi16(rho128_i3[i],1)); + rho128_i0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_i0[i],1),_mm_srai_epi16(rho128_i2[i],1)); } } + } _mm_empty(); _m_empty(); @@ -3652,15 +3371,11 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, LTE_UE_DLSCH_t **dlsch_ue, uint8_t symbol, - unsigned short nb_rb) -{ - + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) - short rb, ch_amp; unsigned char aatx,aarx,pilots=0,symbol_mod; __m128i *dl_ch128, ch_amp128; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { @@ -3671,24 +3386,18 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext, } // Determine scaling amplitude based the symbol - ch_amp = ((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a)); - LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol_mod,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol); - // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); - + // printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp); ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0;rb<nb_rb;rb++) { - + for (rb=0; rb<nb_rb; rb++) { dl_ch128[0] = _mm_mulhi_epi16(dl_ch128[0],ch_amp128); dl_ch128[0] = _mm_slli_epi16(dl_ch128[0],3); - dl_ch128[1] = _mm_mulhi_epi16(dl_ch128[1],ch_amp128); dl_ch128[1] = _mm_slli_epi16(dl_ch128[1],3); @@ -3698,14 +3407,12 @@ void dlsch_scale_channel(int **dl_ch_estimates_ext, dl_ch128[2] = _mm_mulhi_epi16(dl_ch128[2],ch_amp128); dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3); dl_ch128+=3; - } } } } #elif defined(__arm__) - #endif } @@ -3714,16 +3421,12 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, int32_t *avg, uint8_t symbol, - unsigned short nb_rb) -{ - + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) //printf("symbol = %d\n", symbol); - short rb; unsigned char aatx,aarx,nre=12,symbol_mod; __m128i *dl_ch128, avg128D; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) @@ -3739,17 +3442,13 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - //clear average level + //clear average level //printf("aatx = %d, aarx = %d, aatx*frame_parms->nb_antennas_rx + aarx] = %d \n", aatx, aarx, aatx*frame_parms->nb_antennas_rx + aarx); - avg128D = _mm_setzero_si128(); // 5 is always a symbol with no pilots for both normal and extended prefix - - dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*2 + aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0;rb<nb_rb;rb++) { - + for (rb=0; rb<nb_rb; rb++) { //printf("rb %d : ",rb); avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x)); avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x)); @@ -3759,37 +3458,32 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { dl_ch128+=2; - } - else { - avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x)); + } else { + avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x)); //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[2], coeff128),15))); dl_ch128+=3; } - /*if(rb==0){ - print_shorts("dl_ch128",&dl_ch128[0]); - print_shorts("dl_ch128",&dl_ch128[1]); - print_shorts("dl_ch128",&dl_ch128[2]); - }*/ - + /*if(rb==0){ + print_shorts("dl_ch128",&dl_ch128[0]); + print_shorts("dl_ch128",&dl_ch128[1]); + print_shorts("dl_ch128",&dl_ch128[2]); + }*/ } - avg[aatx*frame_parms->nb_antennas_rx + aarx] =(((int32_t*)&avg128D)[0] + - ((int32_t*)&avg128D)[1] + - ((int32_t*)&avg128D)[2] + - ((int32_t*)&avg128D)[3])/y; - } + avg[aatx*frame_parms->nb_antennas_rx + aarx] =(((int32_t *)&avg128D)[0] + + ((int32_t *)&avg128D)[1] + + ((int32_t *)&avg128D)[2] + + ((int32_t *)&avg128D)[3])/y; + } _mm_empty(); _m_empty(); - #elif defined(__arm__) - short rb; unsigned char aatx,aarx,nre=12,symbol_mod; int32x4_t avg128D; int16x4_t *dl_ch128; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) @@ -3797,7 +3491,6 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, //clear average level avg128D = vdupq_n_s32(0); // 5 is always a symbol with no pilots for both normal and extended prefix - dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { @@ -3832,15 +3525,14 @@ void dlsch_channel_level(int **dl_ch_estimates_ext, else nre=12; - avg[aatx*frame_parms->nb_antennas_rx + aarx] = (((int32_t*)&avg128D)[0] + - ((int32_t*)&avg128D)[1] + - ((int32_t*)&avg128D)[2] + - ((int32_t*)&avg128D)[3])/(nb_rb*nre); - + avg[aatx*frame_parms->nb_antennas_rx + aarx] = (((int32_t *)&avg128D)[0] + + ((int32_t *)&avg128D)[1] + + ((int32_t *)&avg128D)[2] + + ((int32_t *)&avg128D)[3])/(nb_rb*nre); //printf("Channel level : %d\n",avg[aatx*(frame_parms->nb_antennas_rx-1) + aarx]); } -#endif +#endif } void dlsch_channel_level_core(int **dl_ch_estimates_ext, @@ -3848,63 +3540,50 @@ void dlsch_channel_level_core(int **dl_ch_estimates_ext, int n_tx, int n_rx, int length, - int start_point) -{ - + int start_point) { #if defined(__x86_64__)||defined(__i386__) - short ii; int aatx,aarx; int length_mod8; int length2; __m128i *dl_ch128, avg128D; - int16_t x = factor2(length); int16_t y = (length)>>x; for (aatx=0; aatx<n_tx; aatx++) for (aarx=0; aarx<n_rx; aarx++) { - avg128D = _mm_setzero_si128(); - dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*2 + aarx][start_point]; - length_mod8=length&7; - if (length_mod8 == 0){ - + if (length_mod8 == 0) { length2 = length>>3; - for (ii=0;ii<length2;ii++) { + for (ii=0; ii<length2; ii++) { avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x)); avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x)); - dl_ch128+=2; } - }else { + } else { printf ("Channel level: Received number of subcarriers is not multiple of 4, \n" - "need to adapt the code!\n"); + "need to adapt the code!\n"); } - - avg[aatx*n_rx + aarx] =(((int32_t*)&avg128D)[0] + - ((int32_t*)&avg128D)[1] + - ((int32_t*)&avg128D)[2] + - ((int32_t*)&avg128D)[3])/y; + avg[aatx*n_rx + aarx] =(((int32_t *)&avg128D)[0] + + ((int32_t *)&avg128D)[1] + + ((int32_t *)&avg128D)[2] + + ((int32_t *)&avg128D)[3])/y; //printf("Channel level [%d]: %d\n",aatx*n_rx + aarx, avg[aatx*n_rx + aarx]); - } + } _mm_empty(); _m_empty(); - - /* FIXME This part needs to be adapted like the one above */ + /* FIXME This part needs to be adapted like the one above */ #elif defined(__arm__) - short rb; unsigned char aatx,aarx,nre=12,symbol_mod; int32x4_t avg128D; int16x4_t *dl_ch128; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) @@ -3912,7 +3591,6 @@ void dlsch_channel_level_core(int **dl_ch_estimates_ext, //clear average level avg128D = vdupq_n_s32(0); // 5 is always a symbol with no pilots for both normal and extended prefix - dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { @@ -3932,7 +3610,6 @@ void dlsch_channel_level_core(int **dl_ch_estimates_ext, } } - if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) nre=8; else if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB==1)) @@ -3940,15 +3617,14 @@ void dlsch_channel_level_core(int **dl_ch_estimates_ext, else nre=12; - avg[aatx*frame_parms->nb_antennas_rx + aarx] = (((int32_t*)&avg128D)[0] + - ((int32_t*)&avg128D)[1] + - ((int32_t*)&avg128D)[2] + - ((int32_t*)&avg128D)[3])/(nb_rb*nre); - + avg[aatx*frame_parms->nb_antennas_rx + aarx] = (((int32_t *)&avg128D)[0] + + ((int32_t *)&avg128D)[1] + + ((int32_t *)&avg128D)[2] + + ((int32_t *)&avg128D)[3])/(nb_rb*nre); //printf("Channel level : %d\n",avg[aatx*(frame_parms->nb_antennas_rx-1) + aarx]); } -#endif +#endif } void dlsch_channel_level_median(int **dl_ch_estimates_ext, @@ -3956,11 +3632,8 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext, int n_tx, int n_rx, int length, - int start_point) -{ - + int start_point) { #if defined(__x86_64__)||defined(__i386__) - short ii; int aatx,aarx; int length2; @@ -3968,101 +3641,92 @@ void dlsch_channel_level_median(int **dl_ch_estimates_ext, int norm_pack; __m128i *dl_ch128, norm128D; - for (aatx=0; aatx<n_tx; aatx++){ + for (aatx=0; aatx<n_tx; aatx++) { for (aarx=0; aarx<n_rx; aarx++) { max = 0; min = 0; norm128D = _mm_setzero_si128(); - dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*2 + aarx][start_point]; - length2 = length>>2; - for (ii=0;ii<length2;ii++) { + for (ii=0; ii<length2; ii++) { norm128D = _mm_srai_epi32( _mm_madd_epi16(dl_ch128[0],dl_ch128[0]), 1); - //print_ints("norm128D",&norm128D[0]); - - norm_pack = ((int32_t*)&norm128D)[0] + - ((int32_t*)&norm128D)[1] + - ((int32_t*)&norm128D)[2] + - ((int32_t*)&norm128D)[3]; + //print_ints("norm128D",&norm128D[0]); + norm_pack = ((int32_t *)&norm128D)[0] + + ((int32_t *)&norm128D)[1] + + ((int32_t *)&norm128D)[2] + + ((int32_t *)&norm128D)[3]; if (norm_pack > max) max = norm_pack; + if (norm_pack < min) min = norm_pack; dl_ch128+=1; } - median[aatx*n_rx + aarx] = (max+min)>>1; - - // printf("Channel level median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]); - } + median[aatx*n_rx + aarx] = (max+min)>>1; + // printf("Channel level median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]); } + } _mm_empty(); _m_empty(); - #elif defined(__arm__) - short rb; unsigned char aatx,aarx,nre=12,symbol_mod; int32x4_t norm128D; int16x4_t *dl_ch128; - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++){ + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { max = 0; min = 0; norm128D = vdupq_n_s32(0); - dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[aatx*n_rx + aarx][start_point]; - length_mod8=length&3; length2 = length>>2; - for (ii=0;ii<length2;ii++) { + for (ii=0; ii<length2; ii++) { norm128D = vshrq_n_u32(vmull_s16(dl_ch128[0],dl_ch128[0]), 1); - norm_pack = ((int32_t*)&norm128D)[0] + - ((int32_t*)&norm128D)[1] + - ((int32_t*)&norm128D)[2] + - ((int32_t*)&norm128D)[3]; + norm_pack = ((int32_t *)&norm128D)[0] + + ((int32_t *)&norm128D)[1] + + ((int32_t *)&norm128D)[2] + + ((int32_t *)&norm128D)[3]; if (norm_pack > max) max = norm_pack; + if (norm_pack < min) min = norm_pack; - dl_ch128+=1; + dl_ch128+=1; } - median[aatx*n_rx + aarx] = (max+min)>>1; - + median[aatx*n_rx + aarx] = (max+min)>>1; //printf("Channel level median [%d]: %d\n",aatx*n_rx + aarx, median[aatx*n_rx + aarx]); - } } -#endif + } +#endif } void mmse_processing_oai(LTE_UE_PDSCH *pdsch_vars, - LTE_DL_FRAME_PARMS *frame_parms, - PHY_MEASUREMENTS *measurements, - unsigned char first_symbol_flag, - MIMO_mode_t mimo_mode, - unsigned short mmse_flag, - int noise_power, - unsigned char symbol, - unsigned short nb_rb){ - + LTE_DL_FRAME_PARMS *frame_parms, + PHY_MEASUREMENTS *measurements, + unsigned char first_symbol_flag, + MIMO_mode_t mimo_mode, + unsigned short mmse_flag, + int noise_power, + unsigned char symbol, + unsigned short nb_rb) { int **rxdataF_ext = pdsch_vars->rxdataF_ext; int **dl_ch_estimates_ext = pdsch_vars->dl_ch_estimates_ext; unsigned char *pmi_ext = pdsch_vars->pmi_ext; int avg_00[frame_parms->nb_antenna_ports_eNB*frame_parms->nb_antennas_rx]; int avg_01[frame_parms->nb_antenna_ports_eNB*frame_parms->nb_antennas_rx]; int symbol_mod, length, start_point, nre; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) @@ -4074,8 +3738,6 @@ void mmse_processing_oai(LTE_UE_PDSCH *pdsch_vars, length = nre*nb_rb; start_point = symbol*nb_rb*12; - - mmse_processing_core(rxdataF_ext, dl_ch_estimates_ext, noise_power, @@ -4084,7 +3746,6 @@ void mmse_processing_oai(LTE_UE_PDSCH *pdsch_vars, length, start_point); - /*dlsch_channel_aver_band(dl_ch_estimates_ext, frame_parms, chan_avg, @@ -4098,21 +3759,20 @@ void mmse_processing_oai(LTE_UE_PDSCH *pdsch_vars, // printf("H [%d] = (%f, %f) \n", aatx*frame_parms->nb_antennas_rx + aarx, creal(H[aatx*frame_parms->nb_antennas_rx + aarx]), cimag(H[aatx*frame_parms->nb_antennas_rx + aarx])); }*/ - if (first_symbol_flag == 1){ - dlsch_channel_level_TM34(dl_ch_estimates_ext, - frame_parms, - pmi_ext, - avg_00, - avg_01, - symbol, - nb_rb, - mmse_flag, - mimo_mode); - - avg_00[0] = (log2_approx(avg_00[0])/2) + dlsch_demod_shift+4;// + 2 ;//+ 4; - avg_01[0] = (log2_approx(avg_01[0])/2) + dlsch_demod_shift+4;// + 2 ;//+ 4; - pdsch_vars->log2_maxh0 = cmax(avg_00[0],0); - pdsch_vars->log2_maxh1 = cmax(avg_01[0],0); + if (first_symbol_flag == 1) { + dlsch_channel_level_TM34(dl_ch_estimates_ext, + frame_parms, + pmi_ext, + avg_00, + avg_01, + symbol, + nb_rb, + mmse_flag, + mimo_mode); + avg_00[0] = (log2_approx(avg_00[0])/2) + dlsch_demod_shift+4;// + 2 ;//+ 4; + avg_01[0] = (log2_approx(avg_01[0])/2) + dlsch_demod_shift+4;// + 2 ;//+ 4; + pdsch_vars->log2_maxh0 = cmax(avg_00[0],0); + pdsch_vars->log2_maxh1 = cmax(avg_01[0],0); } } @@ -4122,27 +3782,26 @@ void mmse_processing_core(int32_t **rxdataF_ext, int n_tx, int n_rx, int length, - int start_point){ - + int start_point) { int aatx, aarx, re; float imag; float real; + float complex **W_MMSE= malloc(n_tx*n_rx*sizeof(float complex *)); - - float complex **W_MMSE= malloc(n_tx*n_rx*sizeof(float complex*)); - for (int j=0; j<n_tx*n_rx; j++) { - W_MMSE[j] = malloc(sizeof(float complex)*length); + for (int j=0; j<n_tx*n_rx; j++) { + W_MMSE[j] = malloc(sizeof(float complex)*length); } float complex *H= malloc(n_tx*n_rx*sizeof(float complex)); float complex *W_MMSE_re= malloc(n_tx*n_rx*sizeof(float complex)); + float complex **dl_ch_estimates_ext_flcpx = malloc(n_tx*n_rx*sizeof(float complex *)); - float complex** dl_ch_estimates_ext_flcpx = malloc(n_tx*n_rx*sizeof(float complex*)); for (int j=0; j<n_tx*n_rx; j++) { dl_ch_estimates_ext_flcpx[j] = malloc(sizeof(float complex)*length); } - float complex** rxdataF_ext_flcpx = malloc(n_rx*sizeof(float complex*)); + float complex **rxdataF_ext_flcpx = malloc(n_rx*sizeof(float complex *)); + for (int j=0; j<n_rx; j++) { rxdataF_ext_flcpx[j] = malloc(sizeof(float complex)*length); } @@ -4154,16 +3813,18 @@ void mmse_processing_core(int32_t **rxdataF_ext, length, start_point); - for (re=0; re<length; re++){ - for (aatx=0; aatx<n_tx; aatx++){ + for (re=0; re<length; re++) { + for (aatx=0; aatx<n_tx; aatx++) { for (aarx=0; aarx<n_rx; aarx++) { imag = cimag(dl_ch_estimates_ext_flcpx[aatx*n_rx + aarx][re]); real = creal(dl_ch_estimates_ext_flcpx[aatx*n_rx + aarx][re]); H[aatx*n_rx + aarx] = real+ I*imag; } } + compute_MMSE(H, n_tx, noise_power, W_MMSE_re); - for (aatx=0; aatx<n_tx; aatx++){ + + for (aatx=0; aatx<n_tx; aatx++) { for (aarx=0; aarx<n_rx; aarx++) { W_MMSE[aatx*n_rx + aarx][re] = W_MMSE_re[aatx*n_rx + aarx]; } @@ -4175,49 +3836,40 @@ void mmse_processing_core(int32_t **rxdataF_ext, n_rx, length, start_point); - mult_mmse_rxdataF(W_MMSE, rxdataF_ext_flcpx, n_tx, n_rx, length, start_point); - - mult_mmse_chan_est(W_MMSE, dl_ch_estimates_ext_flcpx, n_tx, n_rx, length, start_point); - - float_to_rxdataF(rxdataF_ext, rxdataF_ext_flcpx, n_tx, n_rx, length, start_point); - - float_to_chan_est(dl_ch_estimates_ext, dl_ch_estimates_ext_flcpx, n_tx, n_rx, length, start_point); - -free(W_MMSE); -free(H); -free(W_MMSE_re); -free(dl_ch_estimates_ext_flcpx); -free(rxdataF_ext_flcpx); - + free(W_MMSE); + free(H); + free(W_MMSE_re); + free(dl_ch_estimates_ext_flcpx); + free(rxdataF_ext_flcpx); } /*THIS FUNCTION TAKES FLOAT_POINT INPUT. SHOULD NOT BE USED WITH OAI*/ -void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx, +void mmse_processing_core_flp(float complex **rxdataF_ext_flcpx, float complex **H, int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, @@ -4225,79 +3877,85 @@ void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx, int n_tx, int n_rx, int length, - int start_point){ - + int start_point) { int aatx, aarx, re; float max = 0; float one_over_max = 0; + float complex **W_MMSE= malloc(n_tx*n_rx*sizeof(float complex *)); - float complex **W_MMSE= malloc(n_tx*n_rx*sizeof(float complex*)); - for (int j=0; j<n_tx*n_rx; j++) { - W_MMSE[j] = malloc(sizeof(float complex)*length); + for (int j=0; j<n_tx*n_rx; j++) { + W_MMSE[j] = malloc(sizeof(float complex)*length); } float complex *H_re= malloc(n_tx*n_rx*sizeof(float complex)); float complex *W_MMSE_re= malloc(n_tx*n_rx*sizeof(float complex)); - for (re=0; re<length; re++){ - for (aatx=0; aatx<n_tx; aatx++){ + for (re=0; re<length; re++) { + for (aatx=0; aatx<n_tx; aatx++) { for (aarx=0; aarx<n_rx; aarx++) { H_re[aatx*n_rx + aarx] = H[aatx*n_rx + aarx][re]; #ifdef DEBUG_MMSE + if (re == 0) - printf(" H_re[%d]= (%f + i%f)\n", aatx*n_rx + aarx, creal(H_re[aatx*n_rx + aarx]), cimag(H_re[aatx*n_rx + aarx])); + printf(" H_re[%d]= (%f + i%f)\n", aatx*n_rx + aarx, creal(H_re[aatx*n_rx + aarx]), cimag(H_re[aatx*n_rx + aarx])); + #endif } } + compute_MMSE(H_re, n_tx, noise_power, W_MMSE_re); - for (aatx=0; aatx<n_tx; aatx++){ + + for (aatx=0; aatx<n_tx; aatx++) { for (aarx=0; aarx<n_rx; aarx++) { W_MMSE[aatx*n_rx + aarx][re] = W_MMSE_re[aatx*n_rx + aarx]; + if (fabs(creal(W_MMSE_re[aatx*n_rx + aarx])) > max) max = fabs(creal(W_MMSE_re[aatx*n_rx + aarx])); + if (fabs(cimag(W_MMSE_re[aatx*n_rx + aarx])) > max) max = fabs(cimag(W_MMSE_re[aatx*n_rx + aarx])); } } } + one_over_max = 1.0/max; for (re=0; re<length; re++) for (aatx=0; aatx<n_tx; aatx++) - for (aarx=0; aarx<n_rx; aarx++){ + for (aarx=0; aarx<n_rx; aarx++) { #ifdef DEBUG_MMSE + if (re == 0) printf(" W_MMSE[%d] = (%f + i%f)\n", aatx*n_rx + aarx, creal(W_MMSE[aatx*n_rx + aarx][re]), cimag(W_MMSE[aatx*n_rx + aarx][re])); + #endif W_MMSE[aatx*n_rx + aarx][re] = one_over_max*W_MMSE[aatx*n_rx + aarx][re]; #ifdef DEBUG_MMSE + if (re == 0) printf(" AFTER NORM W_MMSE[%d] = (%f + i%f), max = %f \n", aatx*n_rx + aarx, creal(W_MMSE[aatx*n_rx + aarx][re]), cimag(W_MMSE[aatx*n_rx + aarx][re]), max); + #endif } - mult_mmse_rxdataF(W_MMSE, rxdataF_ext_flcpx, n_tx, n_rx, length, start_point); - mult_mmse_chan_est(W_MMSE, H, n_tx, n_rx, length, start_point); - float_to_rxdataF(rxdataF_ext, rxdataF_ext_flcpx, n_tx, n_rx, length, start_point); - float_to_chan_est(dl_ch_estimates_ext, H, n_tx, @@ -4307,7 +3965,6 @@ void mmse_processing_core_flp(float complex** rxdataF_ext_flcpx, free(H_re); free(W_MMSE); free(W_MMSE_re); - } @@ -4315,16 +3972,12 @@ void dlsch_channel_aver_band(int **dl_ch_estimates_ext, LTE_DL_FRAME_PARMS *frame_parms, struct complex32 *chan_avg, unsigned char symbol, - unsigned short nb_rb) -{ - + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) - short rb; unsigned char aatx,aarx,nre=12,symbol_mod; __m128i *dl_ch128, avg128D; int32_t chan_est_avg[4]; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) @@ -4334,97 +3987,89 @@ void dlsch_channel_aver_band(int **dl_ch_estimates_ext, else nre=12; - for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++){ + for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; avg128D = _mm_setzero_si128(); - // print_shorts("avg128D 1",&avg128D); + // print_shorts("avg128D 1",&avg128D); - for (rb=0;rb<nb_rb;rb++) { + for (rb=0; rb<nb_rb; rb++) { /* printf("symbol %d, ant %d, nre*nrb %d, rb %d \n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, nb_rb*nre, rb); print_shorts("aver dl_ch128",&dl_ch128[0]); print_shorts("aver dl_ch128",&dl_ch128[1]); print_shorts("aver dl_ch128",&dl_ch128[2]); avg128D = _mm_add_epi16(avg128D, dl_ch128[0]);*/ //print_shorts("avg128D 2",&avg128D); - avg128D = _mm_add_epi16(avg128D, dl_ch128[1]); - // print_shorts("avg128D 3",&avg128D); + // print_shorts("avg128D 3",&avg128D); if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { dl_ch128+=2; - }else { + } else { avg128D = _mm_add_epi16(avg128D,dl_ch128[2]); - // print_shorts("avg128D 4",&avg128D); + // print_shorts("avg128D 4",&avg128D); dl_ch128+=3; } } - chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].r =(((int16_t*)&avg128D)[0] + - ((int16_t*)&avg128D)[2] + - ((int16_t*)&avg128D)[4] + - ((int16_t*)&avg128D)[6])/(nb_rb*nre); - // printf("symb %d chan_avg re [%d] = %d\n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].r); - - - - chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i =(((int16_t*)&avg128D)[1] + - ((int16_t*)&avg128D)[3] + - ((int16_t*)&avg128D)[5] + - ((int16_t*)&avg128D)[7])/(nb_rb*nre); - // printf("symb %d chan_avg im [%d] = %d\n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i); - + chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].r =(((int16_t *)&avg128D)[0] + + ((int16_t *)&avg128D)[2] + + ((int16_t *)&avg128D)[4] + + ((int16_t *)&avg128D)[6])/(nb_rb*nre); + // printf("symb %d chan_avg re [%d] = %d\n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].r); + chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i =(((int16_t *)&avg128D)[1] + + ((int16_t *)&avg128D)[3] + + ((int16_t *)&avg128D)[5] + + ((int16_t *)&avg128D)[7])/(nb_rb*nre); + // printf("symb %d chan_avg im [%d] = %d\n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i); //printf("symb %d chan_avg im [%d] = %d\n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i); - - chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx] = (((int32_t)chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].i)<<16)|(((int32_t)chan_avg[aatx*frame_parms->nb_antennas_rx + aarx].r) & 0xffff); - //printf("symb %d chan_est_avg [%d] = %d\n", symbol, aatx*frame_parms->nb_antennas_rx + aarx, chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx]); - dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0;rb<nb_rb;rb++) { + for (rb=0; rb<nb_rb; rb++) { dl_ch128[0] = _mm_set1_epi32(chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx]); dl_ch128[1] = _mm_set1_epi32(chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx]); + if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { dl_ch128+=2; - }else { - dl_ch128[2] = _mm_set1_epi32(chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx]); + } else { + dl_ch128[2] = _mm_set1_epi32(chan_est_avg[aatx*frame_parms->nb_antennas_rx + aarx]); dl_ch128+=3; } - } - } - } - - _mm_empty(); - _m_empty(); + } + } + } + _mm_empty(); + _m_empty(); #elif defined(__arm__) #endif - } +} void rxdataF_to_float(int32_t **rxdataF_ext, float complex **rxdataF_f, int n_rx, int length, - int start_point) -{ + int start_point) { short re; int aarx; int16_t imag; int16_t real; for (aarx=0; aarx<n_rx; aarx++) { - for (re=0; re<length; re++){ + for (re=0; re<length; re++) { imag = (int16_t) (rxdataF_ext[aarx][start_point + re] >> 16); real = (int16_t) (rxdataF_ext[aarx][start_point + re] & 0xffff); rxdataF_f[aarx][re] = (float)(real/(32768.0)) + I*(float)(imag/(32768.0)); #ifdef DEBUG_MMSE - if (re==0){ - printf("rxdataF_to_float: aarx = %d, real= %d, imag = %d\n", aarx, real, imag); - //printf("rxdataF_to_float: rxdataF_ext[%d][%d] = %d\n", aarx, start_point + re, rxdataF_ext[aarx][start_point + re]); - //printf("rxdataF_to_float: ant %d, re = %d, rxdataF_f real = %f, rxdataF_f imag = %f \n", aarx, re, creal(rxdataF_f[aarx][re]), cimag(rxdataF_f[aarx][re])); - } + + if (re==0) { + printf("rxdataF_to_float: aarx = %d, real= %d, imag = %d\n", aarx, real, imag); + //printf("rxdataF_to_float: rxdataF_ext[%d][%d] = %d\n", aarx, start_point + re, rxdataF_ext[aarx][start_point + re]); + //printf("rxdataF_to_float: ant %d, re = %d, rxdataF_f real = %f, rxdataF_f imag = %f \n", aarx, re, creal(rxdataF_f[aarx][re]), cimag(rxdataF_f[aarx][re])); + } + #endif } } @@ -4437,66 +4082,68 @@ void chan_est_to_float(int32_t **dl_ch_estimates_ext, int n_tx, int n_rx, int length, - int start_point) -{ + int start_point) { short re; int aatx,aarx; int16_t imag; int16_t real; - for (aatx=0; aatx<n_tx; aatx++){ + for (aatx=0; aatx<n_tx; aatx++) { for (aarx=0; aarx<n_rx; aarx++) { - for (re=0; re<length; re++){ + for (re=0; re<length; re++) { imag = (int16_t) (dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re] >> 16); real = (int16_t) (dl_ch_estimates_ext[aatx*n_rx + aarx][start_point+ re] & 0xffff); dl_ch_estimates_ext_f[aatx*n_rx + aarx][re] = (float)(real/(32768.0)) + I*(float)(imag/(32768.0)); #ifdef DEBUG_MMSE - if (re==0){ + + if (re==0) { printf("ant %d, re = %d, real = %d, imag = %d \n", aatx*n_rx + aarx, re, real, imag); printf("ant %d, re = %d, real = %f, imag = %f \n", aatx*n_rx + aarx, re, creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]), cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])); } + #endif - } + } } } } void float_to_chan_est(int32_t **dl_ch_estimates_ext, - float complex **dl_ch_estimates_ext_f, - int n_tx, - int n_rx, - int length, - int start_point) -{ - + float complex **dl_ch_estimates_ext_f, + int n_tx, + int n_rx, + int length, + int start_point) { short re; int aarx, aatx; int16_t imag; int16_t real; - for (aatx=0; aatx<n_tx; aatx++){ + for (aatx=0; aatx<n_tx; aatx++) { for (aarx=0; aarx<n_rx; aarx++) { - for (re=0; re<length; re++){ + for (re=0; re<length; re++) { if (cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])<-1) - imag = 0x8000; - else if (cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])>=1) - imag = 0x7FFF; - else + imag = 0x8000; + else if (cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])>=1) + imag = 0x7FFF; + else imag = cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])*32768; - if (creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])<-1) - real = 0x8000; - else if (creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])>=1) - real = 0x7FFF; - else - real = creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])*32768; - - dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re] = (((int32_t)imag)<<16)|((int32_t)real & 0xffff); + + if (creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])<-1) + real = 0x8000; + else if (creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])>=1) + real = 0x7FFF; + else + real = creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])*32768; + + dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re] = (((int32_t)imag)<<16)|((int32_t)real & 0xffff); #ifdef DEBUG_MMSE - if (re==0){ + + if (re==0) { printf(" float_to_chan_est: chan est real = %f, chan est imag = %f\n",creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]), cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])); printf("float_to_chan_est: real fixed = %d, imag fixed = %d\n", real, imag); printf("float_to_chan_est: ant %d, re = %d, dl_ch_estimates_ext = %d \n", aatx*n_rx + aarx, re, dl_ch_estimates_ext[aatx*n_rx + aarx][start_point + re]); } + #endif } } @@ -4509,76 +4156,81 @@ void float_to_rxdataF(int32_t **rxdataF_ext, int n_tx, int n_rx, int length, - int start_point) -{ - + int start_point) { short re; int aarx; int16_t imag; int16_t real; for (aarx=0; aarx<n_rx; aarx++) { - for (re=0; re<length; re++){ + for (re=0; re<length; re++) { if (cimag(rxdataF_f[aarx][re])<-1) imag = 0x8000; else if (cimag(rxdataF_f[aarx][re])>=1) imag = 0x7FFF; else imag = cimag(rxdataF_f[aarx][re])*32768; + if (creal(rxdataF_f[aarx][re])<-1) real = 0x8000; else if (creal(rxdataF_f[aarx][re])>=1) real = 0x7FFF; else real = creal(rxdataF_f[aarx][re])*32768; + rxdataF_ext[aarx][start_point + re] = (((int32_t)imag)<<16)|(((int32_t)real) & 0xffff); #ifdef DEBUG_MMSE - if (re==0){ - printf(" float_to_rxdataF: real = %f, imag = %f\n",creal(rxdataF_f[aarx][re]), cimag(rxdataF_f[aarx][re])); - printf("float_to_rxdataF: real fixed = %d, imag fixed = %d\n", real, imag); - printf("float_to_rxdataF: ant %d, re = %d, rxdataF_ext = %d \n", aarx, re, rxdataF_ext[aarx][start_point + re]); - } -#endif + + if (re==0) { + printf(" float_to_rxdataF: real = %f, imag = %f\n",creal(rxdataF_f[aarx][re]), cimag(rxdataF_f[aarx][re])); + printf("float_to_rxdataF: real fixed = %d, imag fixed = %d\n", real, imag); + printf("float_to_rxdataF: ant %d, re = %d, rxdataF_ext = %d \n", aarx, re, rxdataF_ext[aarx][start_point + re]); } + +#endif } + } } -void mult_mmse_rxdataF(float complex** Wmmse, - float complex** rxdataF_ext_f, +void mult_mmse_rxdataF(float complex **Wmmse, + float complex **rxdataF_ext_f, int n_tx, int n_rx, int length, - int start_point) -{ + int start_point) { short re; int aarx, aatx; + float complex *rxdata_re = malloc(n_rx*sizeof(float complex)); + float complex *rxdata_mmse_re = malloc(n_rx*sizeof(float complex)); + float complex *Wmmse_re = malloc(n_tx*n_rx*sizeof(float complex)); - - float complex* rxdata_re = malloc(n_rx*sizeof(float complex)); - float complex* rxdata_mmse_re = malloc(n_rx*sizeof(float complex)); - float complex* Wmmse_re = malloc(n_tx*n_rx*sizeof(float complex)); - - for (re=0;re<length; re++){ - for (aarx=0; aarx<n_rx; aarx++){ + for (re=0; re<length; re++) { + for (aarx=0; aarx<n_rx; aarx++) { rxdata_re[aarx] = rxdataF_ext_f[aarx][re]; #ifdef DEBUG_MMSE + if (re==0) printf("mult_mmse_rxdataF before: rxdata_re[%d] = (%f, %f)\n", aarx, creal(rxdata_re[aarx]), cimag(rxdata_re[aarx])); + #endif - } - for (aatx=0; aatx<n_tx; aatx++){ - for (aarx=0; aarx<n_rx; aarx++){ + } + + for (aatx=0; aatx<n_tx; aatx++) { + for (aarx=0; aarx<n_rx; aarx++) { Wmmse_re[aatx*n_rx + aarx] = Wmmse[aatx*n_rx + aarx][re]; } } + mutl_matrix_matrix_col_based(Wmmse_re, rxdata_re, n_rx, n_tx, n_rx, 1, rxdata_mmse_re); - for (aarx=0; aarx<n_rx; aarx++){ + for (aarx=0; aarx<n_rx; aarx++) { rxdataF_ext_f[aarx][re] = rxdata_mmse_re[aarx]; #ifdef DEBUG_MMSE - if (re==0) + + if (re==0) printf("mult_mmse_rxdataF after: rxdataF_ext_f[%d] = (%f, %f)\n", aarx, creal(rxdataF_ext_f[aarx][re]), cimag(rxdataF_ext_f[aarx][re])); + #endif } } @@ -4588,45 +4240,50 @@ void mult_mmse_rxdataF(float complex** Wmmse, free(Wmmse_re); } -void mult_mmse_chan_est(float complex** Wmmse, - float complex** dl_ch_estimates_ext_f, +void mult_mmse_chan_est(float complex **Wmmse, + float complex **dl_ch_estimates_ext_f, int n_tx, int n_rx, int length, - int start_point) -{ + int start_point) { short re; int aarx, aatx; + float complex *chan_est_re = malloc(n_tx*n_rx*sizeof(float complex)); + float complex *chan_est_mmse_re = malloc(n_tx*n_rx*sizeof(float complex)); + float complex *Wmmse_re = malloc(n_tx*n_rx*sizeof(float complex)); - float complex* chan_est_re = malloc(n_tx*n_rx*sizeof(float complex)); - float complex* chan_est_mmse_re = malloc(n_tx*n_rx*sizeof(float complex)); - float complex* Wmmse_re = malloc(n_tx*n_rx*sizeof(float complex)); - - for (re=0;re<length; re++){ - for (aatx=0; aatx<n_tx; aatx++){ - for (aarx=0; aarx<n_rx; aarx++){ + for (re=0; re<length; re++) { + for (aatx=0; aatx<n_tx; aatx++) { + for (aarx=0; aarx<n_rx; aarx++) { chan_est_re[aatx*n_rx + aarx] = dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]; Wmmse_re[aatx*n_rx + aarx] = Wmmse[aatx*n_rx + aarx][re]; #ifdef DEBUG_MMSE + if (re==0) - printf("mult_mmse_chan_est: chan_est_re[%d] = (%f, %f)\n", aatx*n_rx + aarx, creal(chan_est_re[aatx*n_rx + aarx]), cimag(chan_est_re[aatx*n_rx + aarx])); + printf("mult_mmse_chan_est: chan_est_re[%d] = (%f, %f)\n", aatx*n_rx + aarx, creal(chan_est_re[aatx*n_rx + aarx]), cimag(chan_est_re[aatx*n_rx + aarx])); + #endif } } - mutl_matrix_matrix_col_based(Wmmse_re, chan_est_re, n_rx, n_tx, n_rx, n_tx, chan_est_mmse_re); - for (aatx=0; aatx<n_tx; aatx++){ - for (aarx=0; aarx<n_rx; aarx++){ - dl_ch_estimates_ext_f[aatx*n_rx + aarx][re] = chan_est_mmse_re[aatx*n_rx + aarx]; + + mutl_matrix_matrix_col_based(Wmmse_re, chan_est_re, n_rx, n_tx, n_rx, n_tx, chan_est_mmse_re); + + for (aatx=0; aatx<n_tx; aatx++) { + for (aarx=0; aarx<n_rx; aarx++) { + dl_ch_estimates_ext_f[aatx*n_rx + aarx][re] = chan_est_mmse_re[aatx*n_rx + aarx]; #ifdef DEBUG_MMSE - if (re==0) + + if (re==0) printf("mult_mmse_chan_est: dl_ch_estimates_ext_f[%d][%d] = (%f, %f)\n", aatx*n_rx + aarx, re, creal(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re]), cimag(dl_ch_estimates_ext_f[aatx*n_rx + aarx][re])); + #endif - } } - } - free(Wmmse_re); - free(chan_est_re); - free(chan_est_mmse_re); + } + } + + free(Wmmse_re); + free(chan_est_re); + free(chan_est_mmse_re); } @@ -4642,19 +4299,15 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, uint8_t symbol, unsigned short nb_rb, unsigned int mmse_flag, - MIMO_mode_t mimo_mode){ - + MIMO_mode_t mimo_mode) { #if defined(__x86_64__)||defined(__i386__) - short rb; unsigned char aarx,nre=12,symbol_mod; __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp, avg_0_128D, avg_1_128D; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - //clear average level - // avg_0_128D = _mm_setzero_si128(); - // avg_1_128D = _mm_setzero_si128(); + // avg_0_128D = _mm_setzero_si128(); + // avg_1_128D = _mm_setzero_si128(); avg_0[0] = 0; avg_0[1] = 0; avg_1[0] = 0; @@ -4671,17 +4324,17 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { dl_ch0_128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - avg_0_128D = _mm_setzero_si128(); avg_1_128D = _mm_setzero_si128(); + for (rb=0; rb<nb_rb; rb++) { - // printf("rb %d : \n",rb); - //print_shorts("ch0\n",&dl_ch0_128[0]); - //print_shorts("ch1\n",&dl_ch1_128[0]); + // printf("rb %d : \n",rb); + //print_shorts("ch0\n",&dl_ch0_128[0]); + //print_shorts("ch1\n",&dl_ch1_128[0]); dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[0]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[0]); - if (mmse_flag == 0){ + if (mmse_flag == 0) { if (mimo_mode==LARGE_CDD) prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) @@ -4694,13 +4347,11 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, // mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); - avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); - dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]); - if (mmse_flag == 0){ + if (mmse_flag == 0) { if (mimo_mode==LARGE_CDD) prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) @@ -4713,18 +4364,16 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, // mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); - avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { dl_ch0_128+=2; dl_ch1_128+=2; - } - else { + } else { dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); - if (mmse_flag == 0){ + if (mmse_flag == 0) { if (mimo_mode==LARGE_CDD) prec2A_TM3_128(&dl_ch0_128_tmp,&dl_ch1_128_tmp); else if (mimo_mode==DUALSTREAM_UNIFORM_PRECODING1) @@ -4734,45 +4383,39 @@ void dlsch_channel_level_TM34(int **dl_ch_estimates_ext, else if (mimo_mode==DUALSTREAM_PUSCH_PRECODING) prec2A_TM4_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); } - // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); + // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg_1_128D = _mm_add_epi32(avg_1_128D,_mm_madd_epi16(dl_ch1_128_tmp,dl_ch1_128_tmp)); avg_0_128D = _mm_add_epi32(avg_0_128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); - dl_ch0_128+=3; dl_ch1_128+=3; } } - - avg_0[aarx] = (((int*)&avg_0_128D)[0])/(nb_rb*nre) + - (((int*)&avg_0_128D)[1])/(nb_rb*nre) + - (((int*)&avg_0_128D)[2])/(nb_rb*nre) + - (((int*)&avg_0_128D)[3])/(nb_rb*nre); + avg_0[aarx] = (((int *)&avg_0_128D)[0])/(nb_rb*nre) + + (((int *)&avg_0_128D)[1])/(nb_rb*nre) + + (((int *)&avg_0_128D)[2])/(nb_rb*nre) + + (((int *)&avg_0_128D)[3])/(nb_rb*nre); // printf("From Chan_level aver stream 0 %d =%d\n", aarx, avg_0[aarx]); - - avg_1[aarx] = (((int*)&avg_1_128D)[0])/(nb_rb*nre) + - (((int*)&avg_1_128D)[1])/(nb_rb*nre) + - (((int*)&avg_1_128D)[2])/(nb_rb*nre) + - (((int*)&avg_1_128D)[3])/(nb_rb*nre); - // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]); + avg_1[aarx] = (((int *)&avg_1_128D)[0])/(nb_rb*nre) + + (((int *)&avg_1_128D)[1])/(nb_rb*nre) + + (((int *)&avg_1_128D)[2])/(nb_rb*nre) + + (((int *)&avg_1_128D)[3])/(nb_rb*nre); + // printf("From Chan_level aver stream 1 %d =%d\n", aarx, avg_1[aarx]); } -//avg_0[0] = max(avg_0[0],avg_0[1]); -//avg_1[0] = max(avg_1[0],avg_1[1]); -//avg_0[0]= max(avg_0[0], avg_1[0]); + //avg_0[0] = max(avg_0[0],avg_0[1]); + //avg_1[0] = max(avg_1[0],avg_1[1]); + //avg_0[0]= max(avg_0[0], avg_1[0]); avg_0[0] = avg_0[0] + avg_0[1]; - // printf("From Chan_level aver stream 0 final =%d\n", avg_0[0]); + // printf("From Chan_level aver stream 0 final =%d\n", avg_0[0]); avg_1[0] = avg_1[0] + avg_1[1]; - // printf("From Chan_level aver stream 1 final =%d\n", avg_1[0]); - avg_0[0] = min (avg_0[0], avg_1[0]); - avg_1[0] = avg_0[0]; - + // printf("From Chan_level aver stream 1 final =%d\n", avg_1[0]); + avg_0[0] = min (avg_0[0], avg_1[0]); + avg_1[0] = avg_0[0]; _mm_empty(); _m_empty(); - #elif defined(__arm__) - #endif } @@ -4782,17 +4425,12 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, unsigned char *pmi_ext, int *avg, uint8_t symbol, - unsigned short nb_rb) -{ - + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) - short rb; unsigned char aarx,nre=12,symbol_mod; __m128i *dl_ch0_128,*dl_ch1_128, dl_ch0_128_tmp, dl_ch1_128_tmp,avg128D; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - //clear average level avg128D = _mm_setzero_si128(); avg[0] = 0; @@ -4811,17 +4449,13 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, dl_ch1_128 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { - dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[0]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[0]); - prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); // mmtmpD0 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); - dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[1]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[1]); - prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); // mmtmpD1 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); @@ -4829,52 +4463,41 @@ void dlsch_channel_level_TM56(int **dl_ch_estimates_ext, if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) { dl_ch0_128+=2; dl_ch1_128+=2; - } - else { + } else { dl_ch0_128_tmp = _mm_load_si128(&dl_ch0_128[2]); dl_ch1_128_tmp = _mm_load_si128(&dl_ch1_128[2]); - prec2A_TM56_128(pmi_ext[rb],&dl_ch0_128_tmp,&dl_ch1_128_tmp); // mmtmpD2 = _mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp); avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch0_128_tmp,dl_ch0_128_tmp)); - dl_ch0_128+=3; dl_ch1_128+=3; } } - avg[aarx] = (((int*)&avg128D)[0])/(nb_rb*nre) + - (((int*)&avg128D)[1])/(nb_rb*nre) + - (((int*)&avg128D)[2])/(nb_rb*nre) + - (((int*)&avg128D)[3])/(nb_rb*nre); + avg[aarx] = (((int *)&avg128D)[0])/(nb_rb*nre) + + (((int *)&avg128D)[1])/(nb_rb*nre) + + (((int *)&avg128D)[2])/(nb_rb*nre) + + (((int *)&avg128D)[3])/(nb_rb*nre); } // choose maximum of the 2 effective channels avg[0] = cmax(avg[0],avg[1]); - _mm_empty(); _m_empty(); - #elif defined(__arm__) - - #endif } //compute average channel_level for TM7 void dlsch_channel_level_TM7(int **dl_bf_ch_estimates_ext, - LTE_DL_FRAME_PARMS *frame_parms, - int *avg, - uint8_t symbol, - unsigned short nb_rb) -{ - + LTE_DL_FRAME_PARMS *frame_parms, + int *avg, + uint8_t symbol, + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) - short rb; unsigned char aatx,aarx,nre=12,symbol_mod; __m128i *dl_ch128,avg128D; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) @@ -4882,7 +4505,6 @@ void dlsch_channel_level_TM7(int **dl_bf_ch_estimates_ext, //clear average level avg128D = _mm_setzero_si128(); // 5 is always a symbol with no pilots for both normal and extended prefix - dl_ch128=(__m128i *)&dl_bf_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; for (rb=0; rb<nb_rb; rb++) { @@ -4916,19 +4538,16 @@ void dlsch_channel_level_TM7(int **dl_bf_ch_estimates_ext, else nre=12; - avg[(aatx<<1)+aarx] = (((int*)&avg128D)[0] + - ((int*)&avg128D)[1] + - ((int*)&avg128D)[2] + - ((int*)&avg128D)[3])/(nb_rb*nre); - + avg[(aatx<<1)+aarx] = (((int *)&avg128D)[0] + + ((int *)&avg128D)[1] + + ((int *)&avg128D)[2] + + ((int *)&avg128D)[3])/(nb_rb*nre); // printf("Channel level : %d\n",avg[(aatx<<1)+aarx]); } _mm_empty(); _m_empty(); - #elif defined(__arm__) - #endif } //#define ONE_OVER_2_Q15 16384 @@ -4937,53 +4556,40 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, int **dl_ch_mag, int **dl_ch_magb, unsigned char symbol, - unsigned short nb_rb) -{ - + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) - short *rxF0,*rxF1; __m128i *ch_mag0,*ch_mag1,*ch_mag0b,*ch_mag1b, *rxF0_128; unsigned char rb,re; int jj = (symbol*frame_parms->N_RB_DL*12); uint8_t symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; uint8_t pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0; - rxF0_128 = (__m128i*) &rxdataF_comp[0][jj]; - + rxF0_128 = (__m128i *) &rxdataF_comp[0][jj]; //amp = _mm_set1_epi16(ONE_OVER_2_Q15); - - // printf("Doing alamouti!\n"); - rxF0 = (short*)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y - rxF1 = (short*)&rxdataF_comp[2][jj]; //tx antenna 1 h1*y + rxF0 = (short *)&rxdataF_comp[0][jj]; //tx antenna 0 h0*y + rxF1 = (short *)&rxdataF_comp[2][jj]; //tx antenna 1 h1*y ch_mag0 = (__m128i *)&dl_ch_mag[0][jj]; ch_mag1 = (__m128i *)&dl_ch_mag[2][jj]; ch_mag0b = (__m128i *)&dl_ch_magb[0][jj]; ch_mag1b = (__m128i *)&dl_ch_magb[2][jj]; for (rb=0; rb<nb_rb; rb++) { - for (re=0; re<((pilots==0)?12:8); re+=2) { - // Alamouti RX combining - // printf("Alamouti: symbol %d, rb %d, re %d: rxF0 (%d,%d,%d,%d), rxF1 (%d,%d,%d,%d)\n",symbol,rb,re,rxF0[0],rxF0[1],rxF0[2],rxF0[3],rxF1[0],rxF1[1],rxF1[2],rxF1[3]); rxF0[0] = rxF0[0] + rxF1[2]; rxF0[1] = rxF0[1] - rxF1[3]; - rxF0[2] = rxF0[2] - rxF1[0]; rxF0[3] = rxF0[3] + rxF1[1]; - // printf("Alamouti: rxF0 after (%d,%d,%d,%d)\n",rxF0[0],rxF0[1],rxF0[2],rxF0[3]); rxF0+=4; rxF1+=4; - } // compute levels for 16QAM or 64 QAM llr unit ch_mag0[0] = _mm_adds_epi16(ch_mag0[0],ch_mag1[0]); ch_mag0[1] = _mm_adds_epi16(ch_mag0[1],ch_mag1[1]); - ch_mag0b[0] = _mm_adds_epi16(ch_mag0b[0],ch_mag1b[0]); ch_mag0b[1] = _mm_adds_epi16(ch_mag0b[1],ch_mag1b[1]); @@ -5001,21 +4607,14 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, //rxF0_128[0] = _mm_srai_epi16(rxF0_128[0],1); //rxF0_128[1] = _mm_srai_epi16(rxF0_128[1],1); - - if (pilots==0) { ch_mag0[2] = _mm_adds_epi16(ch_mag0[2],ch_mag1[2]); ch_mag0b[2] = _mm_adds_epi16(ch_mag0b[2],ch_mag1b[2]); - //ch_mag0[2] = _mm_srai_epi16(ch_mag0[2],1); //ch_mag0b[2] = _mm_srai_epi16(ch_mag0b[2],1); - //rxF0_128[2] = _mm_mulhi_epi16(rxF0_128[2],amp); //rxF0_128[2] = _mm_slli_epi16(rxF0_128[2],1); - //rxF0_128[2] = _mm_srai_epi16(rxF0_128[2],1); - - ch_mag0+=3; ch_mag1+=3; ch_mag0b+=3; @@ -5032,9 +4631,7 @@ void dlsch_alamouti(LTE_DL_FRAME_PARMS *frame_parms, _mm_empty(); _m_empty(); - #elif defined(__arm__) - #endif } @@ -5054,18 +4651,11 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, unsigned char subframe, uint32_t high_speed_flag, LTE_DL_FRAME_PARMS *frame_parms) { - - - unsigned short rb,nb_rb=0; unsigned char rb_alloc_ind; unsigned char i,aarx,l,nsymb,skip_half=0,sss_symb,pss_symb=0; int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; - - - unsigned char symbol_mod,pilots=0,j=0,poffset=0; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0; l=symbol; @@ -5083,21 +4673,17 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, poffset=3; for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - if (high_speed_flag == 1) dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; else dl_ch0 = &dl_ch_estimates[aarx][5]; dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; - rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs - - for (rb=0;rb<frame_parms->N_RB_DL;rb++) { - + for (rb=0; rb<frame_parms->N_RB_DL; rb++) { if (rb < 32) rb_alloc_ind = (rb_alloc[0]>>rb) & 1; else if (rb < 64) @@ -5128,7 +4714,6 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, rb_alloc_ind = 0; } - if (frame_parms->frame_type == FDD) { //PSS if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { @@ -5172,25 +4757,21 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, rxF_ext[j]=rxF[i]; // printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); dl_ch0_ext[j++]=dl_ch0[i]; - } } dl_ch0_ext+=10; rxF_ext+=10; } - - } dl_ch0+=12; rxF+=12; - } else { // Odd number of RBs for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) { #ifdef DEBUG_DLSCH_DEMOD - printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); + printf("dlch_ext %u\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); #endif skip_half=0; @@ -5208,7 +4789,6 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (rb_alloc_ind == 1) nb_rb++; - // PBCH if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) { rb_alloc_ind = 0; @@ -5228,6 +4808,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, (l==sss_symb) ) { rb_alloc_ind = 0; } + //SSS if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && @@ -5240,7 +4821,6 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, //PSS in subframe 0/5 if FDD if (frame_parms->frame_type == FDD) { //FDD - if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && @@ -5255,22 +4835,22 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, } if ((frame_parms->frame_type == TDD) && - (subframe==6)){ //TDD Subframe 6 + (subframe==6)) { //TDD Subframe 6 if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { rb_alloc_ind = 0; } + if ((rb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) skip_half=1; else if ((rb==((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb)) skip_half=2; } - if (rb_alloc_ind==1) { - #ifdef DEBUG_DLSCH_DEMOD printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); #endif + if (pilots==0) { // printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); if (skip_half==1) { @@ -5279,9 +4859,10 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, for (i=0; i<6; i++) { rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } + dl_ch0_ext+=6; rxF_ext+=6; } else if (skip_half==2) { @@ -5290,9 +4871,10 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, for (i=0; i<6; i++) { rxF_ext[i]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } + dl_ch0_ext+=6; rxF_ext+=6; } else { @@ -5301,9 +4883,10 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, for (i=0; i<12; i++) { rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } + dl_ch0_ext+=12; rxF_ext+=12; } @@ -5316,11 +4899,12 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (i!=((frame_parms->nushift+poffset)%6)) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i]; } } + rxF_ext+=5; dl_ch0_ext+=5; } else if (skip_half==2) { @@ -5328,7 +4912,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (i!=((frame_parms->nushift+poffset)%6)) { rxF_ext[j]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i+6]; } @@ -5342,10 +4926,9 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, (i!=((frame_parms->nushift+poffset+6)%12))) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i]; - } } @@ -5354,11 +4937,11 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, } } } + dl_ch0+=12; rxF+=12; } // first half loop - // Do middle RB (around DC) if (rb < 32) rb_alloc_ind = (rb_alloc[0]>>rb) & 1; @@ -5371,7 +4954,6 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, else rb_alloc_ind = 0; - if (rb_alloc_ind == 1) nb_rb++; @@ -5402,13 +4984,13 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, rb_alloc_ind = 0; } - // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); // printf("DC rb %d (%p)\n",rb,rxF); if (rb_alloc_ind==1) { #ifdef DEBUG_DLSCH_DEMOD printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); #endif + if (pilots==0) { for (i=0; i<6; i++) { dl_ch0_ext[i]=dl_ch0[i]; @@ -5432,7 +5014,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, dl_ch0_ext[j]=dl_ch0[i]; rxF_ext[j++]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); + printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short *)&rxF_ext[j-1])); #endif } } @@ -5444,7 +5026,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, dl_ch0_ext[j]=dl_ch0[i]; rxF_ext[j++]=rxF[(1+i-6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short*)&rxF_ext[j-1])); + printf("**extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j-1],*(1+(short *)&rxF_ext[j-1])); #endif } } @@ -5461,7 +5043,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, rxF+=7; rb++; - for (;rb<frame_parms->N_RB_DL;rb++) { + for (; rb<frame_parms->N_RB_DL; rb++) { // printf("dlch_ext %d\n",dl_ch0_ext-&dl_ch_estimates_ext[aarx][0]); // printf("rb %d (%p)\n",rb,rxF); skip_half=0; @@ -5484,6 +5066,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if ((subframe==0) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l>=nsymb>>1) && (l<((nsymb>>1) + 4))) { rb_alloc_ind = 0; } + //PBCH subframe 0, symbols nsymb>>1 ... nsymb>>1 + 3 if ((subframe==0) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l>=(nsymb>>1)) && (l<((nsymb>>1) + 4))) skip_half=1; @@ -5494,11 +5077,13 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb) ) { rb_alloc_ind = 0; } + //SSS if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)-3)) && (l==sss_symb)) skip_half=1; else if (((subframe==0)||(subframe==5)) && (rb==((frame_parms->N_RB_DL>>1)+3)) && (l==sss_symb)) skip_half=2; + if (frame_parms->frame_type == FDD) { //PSS if (((subframe==0)||(subframe==5)) && (rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { @@ -5514,7 +5099,6 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, } if ((frame_parms->frame_type == TDD) && - (subframe==6)) { //TDD Subframe 6 if ((rb>((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { rb_alloc_ind = 0; @@ -5530,6 +5114,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, #ifdef DEBUG_DLSCH_DEMOD printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); #endif + /* printf("rb %d\n",rb); for (i=0;i<12;i++) @@ -5544,33 +5129,34 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, for (i=0; i<6; i++) { rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } + dl_ch0_ext+=6; rxF_ext+=6; - } else if (skip_half==2) { memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int)); for (i=0; i<6; i++) { rxF_ext[i]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } + dl_ch0_ext+=6; rxF_ext+=6; - } else { memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); for (i=0; i<12; i++) { rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } + dl_ch0_ext+=12; rxF_ext+=12; } @@ -5583,7 +5169,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (i!=((frame_parms->nushift+poffset)%6)) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i]; } @@ -5596,7 +5182,7 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, if (i!=((frame_parms->nushift+poffset)%6)) { rxF_ext[j]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i+6]; } @@ -5610,11 +5196,12 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, (i!=((frame_parms->nushift+poffset+6)%12))) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i]; } } + dl_ch0_ext+=10; rxF_ext+=10; } @@ -5627,7 +5214,6 @@ unsigned short dlsch_extract_rbs_single(int **rxdataF, } } - return(nb_rb/frame_parms->nb_antennas_rx); } @@ -5643,7 +5229,6 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, uint32_t high_speed_flag, LTE_DL_FRAME_PARMS *frame_parms, MIMO_mode_t mimo_mode) { - int prb,nb_rb=0; int prb_off,prb_off2; int rb_alloc_ind,skip_half=0,sss_symb,pss_symb=0,nsymb,l; @@ -5651,7 +5236,6 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, int32_t *dl_ch0,*dl_ch0p,*dl_ch0_ext,*dl_ch1,*dl_ch1p,*dl_ch1_ext,*rxF,*rxF_ext; int symbol_mod,pilots=0,j=0; unsigned char *pmi_loc; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; // printf("extract_rbs: symbol_mod %d\n",symbol_mod); @@ -5670,7 +5254,6 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, } for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - if (high_speed_flag==1) { dl_ch0 = &dl_ch_estimates[aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; dl_ch1 = &dl_ch_estimates[2+aarx][5+(symbol*(frame_parms->ofdm_symbol_size))]; @@ -5680,7 +5263,6 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, } pmi_loc = pmi_ext; - // pointers to extracted RX signals and channel estimates rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; @@ -5701,8 +5283,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rb_alloc_ind = 0; if (rb_alloc_ind == 1) - nb_rb++; - + nb_rb++; if ((frame_parms->N_RB_DL&1) == 0) { // even number of RBs @@ -5726,8 +5307,6 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb); } - - //PSS in subframe 0/5 if FDD if (frame_parms->frame_type == FDD) { //FDD if (((subframe==0)||(subframe==5)) && @@ -5749,35 +5328,29 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, } if (rb_alloc_ind==1) { // PRB is allocated - - - prb_off = 12*prb; prb_off2 = 1+(12*(prb-(frame_parms->N_RB_DL>>1))); dl_ch0p = dl_ch0+(12*prb); dl_ch1p = dl_ch1+(12*prb); - if (prb<(frame_parms->N_RB_DL>>1)){ + + if (prb<(frame_parms->N_RB_DL>>1)) { rxF = &rxdataF[aarx][prb_off+ frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size))]; - } - else { + } else { rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } - /* - if (mimo_mode <= PUSCH_PRECODING1) - *pmi_loc = (pmi>>((prb>>2)<<1))&3; - else - *pmi_loc=(pmi>>prb)&1;*/ - - *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); + /* + if (mimo_mode <= PUSCH_PRECODING1) + *pmi_loc = (pmi>>((prb>>2)<<1))&3; + else + *pmi_loc=(pmi>>prb)&1;*/ + *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); pmi_loc++; - if (pilots == 0) { - memcpy(dl_ch0_ext,dl_ch0p,12*sizeof(int)); memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int)); memcpy(rxF_ext,rxF,12*sizeof(int)); @@ -5786,6 +5359,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, rxF_ext +=12; } else { // pilots==1 j=0; + for (i=0; i<12; i++) { if ((i!=frame_parms->nushift) && (i!=frame_parms->nushift+3) && @@ -5797,16 +5371,15 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, dl_ch1_ext[j++]=dl_ch1p[i]; } } + dl_ch0_ext+=8; dl_ch1_ext+=8; rxF_ext+=8; } // pilots==1 - } } else { // Odd number of RBs - - // PBCH + // PBCH if ((subframe==0) && (prb>((frame_parms->N_RB_DL>>1)-3)) && (prb<((frame_parms->N_RB_DL>>1)+3)) && @@ -5826,8 +5399,6 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, // printf("symbol %d / rb %d: skipping SSS REs\n",symbol,prb); } - - //PSS in subframe 0/5 if FDD if (frame_parms->frame_type == FDD) { //FDD if (((subframe==0)||(subframe==5)) && @@ -5882,7 +5453,6 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, (((subframe==0)||(subframe==5)))) || //FDD Subframes 0,5 ((frame_parms->frame_type == TDD) && (((subframe==1) || (subframe==6))))) { //TDD Subframes 1,6 - if ((prb==((frame_parms->N_RB_DL>>1)-3)) && (l==pss_symb)) skip_half=1; @@ -5891,31 +5461,30 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, skip_half=2; } - prb_off = 12*prb; prb_off2 = 7+(12*(prb-(frame_parms->N_RB_DL>>1)-1)); dl_ch0p = dl_ch0+(12*prb); dl_ch1p = dl_ch1+(12*prb); - if (prb<=(frame_parms->N_RB_DL>>1)){ + if (prb<=(frame_parms->N_RB_DL>>1)) { rxF = &rxdataF[aarx][prb_off+ frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size))]; - } - else { + } else { rxF = &rxdataF[aarx][prb_off2+ (symbol*(frame_parms->ofdm_symbol_size))]; } + #ifdef DEBUG_DLSCH_DEMOD printf("symbol %d / rb %d: alloc %d skip_half %d (rxF %p, rxF_ext %p) prb_off (%d,%d)\n",symbol,prb,rb_alloc_ind,skip_half,rxF,rxF_ext,prb_off,prb_off2); #endif - /* if (mimo_mode <= PUSCH_PRECODING1) - *pmi_loc = (pmi>>((prb>>2)<<1))&3; - else - *pmi_loc=(pmi>>prb)&1; - // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); -*/ - *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); + /* if (mimo_mode <= PUSCH_PRECODING1) + *pmi_loc = (pmi>>((prb>>2)<<1))&3; + else + *pmi_loc=(pmi>>prb)&1; + // printf("symbol_mod %d (pilots %d) rb %d, sb %d, pmi %d (pmi_loc %p,rxF %p, ch00 %p, ch01 %p, rxF_ext %p dl_ch0_ext %p dl_ch1_ext %p)\n",symbol_mod,pilots,prb,prb>>2,*pmi_loc,pmi_loc,rxF,dl_ch0, dl_ch1, rxF_ext,dl_ch0_ext,dl_ch1_ext); + */ + *pmi_loc = get_pmi(frame_parms->N_RB_DL,mimo_mode,pmi,prb); pmi_loc++; if (prb != (frame_parms->N_RB_DL>>1)) { // This PRB is not around DC @@ -5925,8 +5494,10 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); memcpy(rxF_ext,rxF,6*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD - for (i=0;i<6;i++) - printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + + for (i=0; i<6; i++) + printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); + #endif dl_ch0_ext+=6; dl_ch1_ext+=6; @@ -5936,8 +5507,10 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, memcpy(dl_ch1_ext,dl_ch1p+6,6*sizeof(int32_t)); memcpy(rxF_ext,rxF+6,6*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD - for (i=0;i<6;i++) - printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + + for (i=0; i<6; i++) + printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); + #endif dl_ch0_ext+=6; dl_ch1_ext+=6; @@ -5947,8 +5520,10 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, memcpy(dl_ch1_ext,dl_ch1p,12*sizeof(int32_t)); memcpy(rxF_ext,rxF,12*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD - for (i=0;i<12;i++) - printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + + for (i=0; i<12; i++) + printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); + #endif dl_ch0_ext+=12; dl_ch1_ext+=12; @@ -5963,12 +5538,13 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, (i!=((frame_parms->nushift+3)%6))) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("(pilots,skip1)extract rb %d, re %d (%d)=> (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("(pilots,skip1)extract rb %d, re %d (%d)=> (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j]=dl_ch0p[i]; dl_ch1_ext[j++]=dl_ch1p[i]; } } + dl_ch0_ext+=4; dl_ch1_ext+=4; rxF_ext+=4; @@ -5978,16 +5554,16 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, (i!=((frame_parms->nushift+3)%6))) { rxF_ext[j]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("(pilots,skip2)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("(pilots,skip2)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j]=dl_ch0p[i+6]; dl_ch1_ext[j++]=dl_ch1p[i+6]; } } + dl_ch0_ext+=4; dl_ch1_ext+=4; rxF_ext+=4; - } else { //skip_half==0 for (i=0; i<12; i++) { if ((i!=frame_parms->nushift) && @@ -5996,43 +5572,45 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, (i!=((frame_parms->nushift+9)%12))) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("(pilots)extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("(pilots)extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j] =dl_ch0p[i]; dl_ch1_ext[j++]=dl_ch1p[i]; } } + dl_ch0_ext+=8; dl_ch1_ext+=8; rxF_ext+=8; } //skip_half==0 } //pilots==1 } else { // Do middle RB (around DC) - if (pilots==0) { memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t)); memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); memcpy(rxF_ext,rxF,6*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD + for (i=0; i<6; i++) { - printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); } + #endif rxF_ext+=6; dl_ch0_ext+=6; dl_ch1_ext+=6; dl_ch0p+=6; dl_ch1p+=6; - rxF = &rxdataF[aarx][1+((symbol*(frame_parms->ofdm_symbol_size)))]; - memcpy(dl_ch0_ext,dl_ch0p,6*sizeof(int32_t)); memcpy(dl_ch1_ext,dl_ch1p,6*sizeof(int32_t)); memcpy(rxF_ext,rxF,6*sizeof(int32_t)); #ifdef DEBUG_DLSCH_DEMOD + for (i=0; i<6; i++) { - printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",prb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); } + #endif rxF_ext+=6; dl_ch0_ext+=6; @@ -6047,10 +5625,11 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, dl_ch1_ext[j]=dl_ch1p[i]; rxF_ext[j++]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[i],*(1+(short*)&rxF[i])); + printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[i],*(1+(short *)&rxF[i])); #endif } } + rxF = &rxdataF[aarx][1+symbol*(frame_parms->ofdm_symbol_size)]; for (; i<12; i++) { @@ -6060,7 +5639,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, dl_ch1_ext[j]=dl_ch1p[i]; rxF_ext[j++]=rxF[i-6]; #ifdef DEBUG_DLSCH_DEMOD - printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[1+i-6],*(1+(short*)&rxF[1+i-6])); + printf("(pilots)extract rb %d, re %d (%d) => (%d,%d)\n",prb,i,j,*(short *)&rxF[1+i-6],*(1+(short *)&rxF[1+i-6])); #endif } } @@ -6074,6 +5653,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF, } // if rballoc==1 } // for prb } // for aarx + return(nb_rb/frame_parms->nb_antennas_rx); } @@ -6085,26 +5665,22 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, unsigned char symbol, unsigned char subframe, uint32_t high_speed_flag, - LTE_DL_FRAME_PARMS *frame_parms) -{ - + LTE_DL_FRAME_PARMS *frame_parms) { unsigned short rb,nb_rb=0; unsigned char rb_alloc_ind; unsigned char i,aarx,l,nsymb,skip_half=0,sss_symb,pss_symb=0; int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; - unsigned char symbol_mod,pilots=0,uespec_pilots=0,j=0,poffset=0,uespec_poffset=0; int8_t uespec_nushift = frame_parms->Nid_cell%3; - symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; pilots = ((symbol_mod==0)||(symbol_mod==(4-frame_parms->Ncp))) ? 1 : 0; l=symbol; nsymb = (frame_parms->Ncp==NORMAL) ? 14:12; - if (frame_parms->Ncp==0){ + if (frame_parms->Ncp==0) { if (symbol==3 || symbol==6 || symbol==9 || symbol==12) uespec_pilots = 1; - } else{ + } else { if (symbol==4 || symbol==7 || symbol==10) uespec_pilots = 1; } @@ -6124,20 +5700,17 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, uespec_poffset=2; for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - if (high_speed_flag == 1) dl_ch0 = &dl_bf_ch_estimates[aarx][symbol*(frame_parms->ofdm_symbol_size)]; else dl_ch0 = &dl_bf_ch_estimates[aarx][0]; dl_ch0_ext = &dl_bf_ch_estimates_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; - rxF_ext = &rxdataF_ext[aarx][symbol*(frame_parms->N_RB_DL*12)]; rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + (symbol*(frame_parms->ofdm_symbol_size)))]; if ((frame_parms->N_RB_DL&1) == 0) // even number of RBs for (rb=0; rb<frame_parms->N_RB_DL; rb++) { - if (rb < 32) rb_alloc_ind = (rb_alloc[0]>>rb) & 1; else if (rb < 64) @@ -6149,7 +5722,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, else rb_alloc_ind = 0; - if (rb_alloc_ind == 1) + if (rb_alloc_ind == 1) nb_rb++; // For second half of RBs skip DC carrier @@ -6168,7 +5741,6 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, rb_alloc_ind = 0; } - if (frame_parms->frame_type == FDD) { //PSS if (((subframe==0)||(subframe==5)) && (rb>=((frame_parms->N_RB_DL>>1)-3)) && (rb<((frame_parms->N_RB_DL>>1)+3)) && (l==pss_symb) ) { @@ -6184,7 +5756,6 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, } if (rb_alloc_ind==1) { - /* printf("rb %d\n",rb); for (i=0;i<12;i++) @@ -6213,39 +5784,33 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, dl_ch0_ext+=10; rxF_ext+=10; - } else if (pilots==0 && uespec_pilots==1) { j=0; - - for (i=0; i<12; i++){ - if (frame_parms->Ncp==0){ - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){ - rxF_ext[j] = rxF[i]; + for (i=0; i<12; i++) { + if (frame_parms->Ncp==0) { + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12) { + rxF_ext[j] = rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; } - } else{ - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){ - rxF_ext[j] = rxF[i]; + } else { + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12) { + rxF_ext[j] = rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; } } - - } + } dl_ch0_ext+=9-frame_parms->Ncp; rxF_ext+=9-frame_parms->Ncp; - } else { LOG_E(PHY,"dlsch_extract_rbs_TM7(dl_demodulation.c):pilot or ue spec pilot detection error\n"); exit(-1); } - } dl_ch0+=12; rxF+=12; - } else { // Odd number of RBs for (rb=0; rb<frame_parms->N_RB_DL>>1; rb++) { @@ -6318,7 +5883,6 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, skip_half=2; } - if (rb_alloc_ind==1) { #ifdef DEBUG_DLSCH_DEMOD printf("rb %d/symbol %d pilots %d, uespec_pilots %d, (skip_half %d)\n",rb,l,pilots,uespec_pilots,skip_half); @@ -6326,14 +5890,13 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, if (pilots==0 && uespec_pilots==0) { //printf("Extracting w/o pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); - if (skip_half==1) { memcpy(dl_ch0_ext,dl_ch0,6*sizeof(int)); for (i=0; i<6; i++) { rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } @@ -6345,7 +5908,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, for (i=0; i<6; i++) { rxF_ext[i]=rxF[(i+6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } @@ -6354,12 +5917,13 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, } else { memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); - for (i=0; i<12; i++){ + for (i=0; i<12; i++) { rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",symbol,rb,i,*(short *)&rxF[i],*(1+(short*)&rxF[i])); + printf("extract symbol %d rb %d, re %d => (%d,%d)\n",symbol,rb,i,*(short *)&rxF[i],*(1+(short *)&rxF[i])); #endif } + dl_ch0_ext+=12; rxF_ext+=12; } @@ -6373,7 +5937,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, rxF_ext[j]=rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } @@ -6386,7 +5950,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, rxF_ext[j]=rxF[(i+6)]; dl_ch0_ext[j++]=dl_ch0[i+6]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } @@ -6399,107 +5963,103 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, (i!=((frame_parms->nushift+poffset+6)%12))) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i]; - } } dl_ch0_ext+=10; rxF_ext+=10; } - } else if(pilots==0 && uespec_pilots==1){ + } else if(pilots==0 && uespec_pilots==1) { //printf("Extracting with uespec pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); j=0; if (skip_half==1) { - if (frame_parms->Ncp==0){ + if (frame_parms->Ncp==0) { for (i=0; i<6; i++) { - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){ + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12) { rxF_ext[j]=rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } + dl_ch0_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6); rxF_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6); - - } else{ + } else { for (i=0; i<6; i++) { - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){ + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12) { rxF_ext[j]=rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } + dl_ch0_ext+=4; rxF_ext+=4; } - } else if (skip_half==2) { - if(frame_parms->Ncp==0){ + if(frame_parms->Ncp==0) { for (i=0; i<6; i++) { - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){ + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12) { rxF_ext[j]=rxF[(i+6)]; dl_ch0_ext[j++]=dl_ch0[i+6]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } + dl_ch0_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6); rxF_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6); - } else { for (i=0; i<6; i++) { - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){ + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12) { rxF_ext[j]=rxF[(i+6)]; dl_ch0_ext[j++]=dl_ch0[i+6]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } + dl_ch0_ext+=4; rxF_ext+=4; } - } else { - - for (i=0; i<12; i++){ - if (frame_parms->Ncp==0){ - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){ - rxF_ext[j] = rxF[i]; + for (i=0; i<12; i++) { + if (frame_parms->Ncp==0) { + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12) { + rxF_ext[j] = rxF[i]; dl_ch0_ext[j++] = dl_ch0[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d, j %d => (%d,%d)\n",symbol,rb,i,j-1,*(short *)&dl_ch0[j],*(1+(short*)&dl_ch0[i])); + printf("extract symbol %d, rb %d, re %d, j %d => (%d,%d)\n", + symbol,rb,i,j-1,*(short *)&dl_ch0[j],*(1+(short *)&dl_ch0[i])); #endif } - } else{ - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){ - rxF_ext[j] = rxF[i]; + } else { + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12) { + rxF_ext[j] = rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } - - } + } dl_ch0_ext+=9-frame_parms->Ncp; rxF_ext+=9-frame_parms->Ncp; - } - + } } else { LOG_E(PHY,"dlsch_extract_rbs_TM7(dl_demodulation.c):pilot or ue spec pilot detection error\n"); exit(-1); - } } @@ -6507,7 +6067,6 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, rxF+=12; } // first half loop - // Do middle RB (around DC) if (rb < 32) rb_alloc_ind = (rb_alloc[0]>>rb) & 1; @@ -6556,7 +6115,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, dl_ch0_ext[i]=dl_ch0[i]; rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } @@ -6566,13 +6125,13 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, dl_ch0_ext[i]=dl_ch0[i]; rxF_ext[i]=rxF[(1+i-6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } dl_ch0_ext+=12; rxF_ext+=12; - } else if(pilots==1 && uespec_pilots==0){ // pilots==1 + } else if(pilots==1 && uespec_pilots==0) { // pilots==1 j=0; for (i=0; i<6; i++) { @@ -6580,7 +6139,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, dl_ch0_ext[j]=dl_ch0[i]; rxF_ext[j++]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } @@ -6592,7 +6151,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, dl_ch0_ext[j]=dl_ch0[i]; rxF_ext[j++]=rxF[(1+i-6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } @@ -6602,43 +6161,43 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, } else if(pilots==0 && uespec_pilots==1) { j=0; - for (i=0; i<6; i++) { - if (frame_parms->Ncp==0){ - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){ + for (i=0; i<6; i++) { + if (frame_parms->Ncp==0) { + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12) { dl_ch0_ext[j]=dl_ch0[i]; - rxF_ext[j++] = rxF[i]; + rxF_ext[j++] = rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } else { - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){ + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12) { dl_ch0_ext[j]=dl_ch0[i]; - rxF_ext[j++] = rxF[i]; + rxF_ext[j++] = rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } - } + } rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; for (; i<12; i++) { - if (frame_parms->Ncp==0){ - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){ + if (frame_parms->Ncp==0) { + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12) { dl_ch0_ext[j]=dl_ch0[i]; rxF_ext[j++]=rxF[(1+i-6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } else { - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){ + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12) { dl_ch0_ext[j]=dl_ch0[i]; - rxF_ext[j++] = rxF[(1+i-6)]; + rxF_ext[j++] = rxF[(1+i-6)]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } @@ -6646,9 +6205,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, dl_ch0_ext+=9-frame_parms->Ncp; rxF_ext+=9-frame_parms->Ncp; - - }// symbol_mod==0 - + }// symbol_mod==0 } // rballoc==1 else { rxF = &rxdataF[aarx][((symbol*(frame_parms->ofdm_symbol_size)))]; @@ -6724,8 +6281,9 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, if (rb_alloc_ind==1) { #ifdef DEBUG_DLSCH_DEMOD - printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); + printf("rb %d/symbol %d (skip_half %d)\n",rb,l,skip_half); #endif + /* printf("rb %d\n",rb); for (i=0;i<12;i++) @@ -6740,26 +6298,24 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, for (i=0; i<6; i++) { rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } dl_ch0_ext+=6; rxF_ext+=6; - } else if (skip_half==2) { memcpy(dl_ch0_ext,dl_ch0+6,6*sizeof(int)); for (i=0; i<6; i++) { rxF_ext[i]=rxF[i+6]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } dl_ch0_ext+=6; rxF_ext+=6; - } else { memcpy(dl_ch0_ext,dl_ch0,12*sizeof(int)); //printf("symbol %d, extract rb %d, => (%d,%d)\n",symbol,rb,*(short *)&dl_ch0[j],*(1+(short*)&dl_ch0[i])); @@ -6767,14 +6323,14 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, for (i=0; i<12; i++) { rxF_ext[i]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } dl_ch0_ext+=12; rxF_ext+=12; } - } else if (pilots==1 && uespec_pilots==0){ + } else if (pilots==1 && uespec_pilots==0) { //printf("Extracting with pilots (symbol %d, rb %d, skip_half %d)\n",l,rb,skip_half); j=0; @@ -6784,7 +6340,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, rxF_ext[j]=rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } @@ -6797,7 +6353,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, rxF_ext[j]=rxF[(i+6)]; dl_ch0_ext[j++]=dl_ch0[i+6]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } @@ -6810,7 +6366,7 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, (i!=((frame_parms->nushift+poffset+6)%12))) { rxF_ext[j]=rxF[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short*)&rxF_ext[j])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[j],*(1+(short *)&rxF_ext[j])); #endif dl_ch0_ext[j++]=dl_ch0[i]; } @@ -6823,87 +6379,85 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, j=0; if (skip_half==1) { - if (frame_parms->Ncp==0){ + if (frame_parms->Ncp==0) { for (i=0; i<6; i++) { - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){ + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12) { rxF_ext[j]=rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } + dl_ch0_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6); rxF_ext+=6-(uespec_nushift+uespec_poffset<6)-(uespec_nushift+uespec_poffset+4<6)-((uespec_nushift+uespec_poffset+8)%12<6); - - } else{ + } else { for (i=0; i<6; i++) { - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){ + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12) { rxF_ext[j]=rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } + dl_ch0_ext+=4; rxF_ext+=4; } - } else if (skip_half==2) { - if(frame_parms->Ncp==0){ + if(frame_parms->Ncp==0) { for (i=0; i<6; i++) { - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){ + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12) { rxF_ext[j]=rxF[i+6]; dl_ch0_ext[j++]=dl_ch0[i+6]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } + dl_ch0_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6); rxF_ext+=6-(uespec_nushift+uespec_poffset>6)-(uespec_nushift+uespec_poffset+4>6)-((uespec_nushift+uespec_poffset+8)%12>6); - } else { for (i=0; i<6; i++) { - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){ + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12) { rxF_ext[j]=rxF[(i+6)]; dl_ch0_ext[j++]=dl_ch0[i+6]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } + dl_ch0_ext+=4; rxF_ext+=4; } - } else { - for (i=0; i<12; i++){ - if (frame_parms->Ncp==0){ - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12){ - rxF_ext[j] = rxF[i]; + for (i=0; i<12; i++) { + if (frame_parms->Ncp==0) { + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+4 && i!=(uespec_nushift+uespec_poffset+8)%12) { + rxF_ext[j] = rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } - } else{ - if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12){ - rxF_ext[j] = rxF[i]; + } else { + if (i!=uespec_nushift+uespec_poffset && i!=uespec_nushift+uespec_poffset+3 && i!=uespec_nushift+uespec_poffset+6 && i!=(uespec_nushift+uespec_poffset+9)%12) { + rxF_ext[j] = rxF[i]; dl_ch0_ext[j++]=dl_ch0[i]; #ifdef DEBUG_DLSCH_DEMOD - printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short*)&rxF_ext[i])); + printf("extract rb %d, re %d => (%d,%d)\n",rb,i,*(short *)&rxF_ext[i],*(1+(short *)&rxF_ext[i])); #endif } } - } + } dl_ch0_ext+=9-frame_parms->Ncp; rxF_ext+=9-frame_parms->Ncp; - } - }// pilots=0 } @@ -6915,17 +6469,14 @@ unsigned short dlsch_extract_rbs_TM7(int **rxdataF, _mm_empty(); _m_empty(); - return(nb_rb/frame_parms->nb_antennas_rx); } //============================================================================================== -void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid) -{ +void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid) { #define NSYMB ((ue->frame_parms.Ncp == 0) ? 14 : 12) char fname[32],vname[32]; - sprintf(fname,"dlsch%d_rxF_r%d_ext0.m",eNB_id,round); sprintf(vname,"dl%d_rxF_r%d_ext0",eNB_id,round); LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0], @@ -6943,12 +6494,11 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[0], 12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1); - if (ue->transmission_mode[eNB_id]==7){ + if (ue->transmission_mode[eNB_id]==7) { sprintf(fname,"dlsch%d_bf_ch_r%d.m",eNB_id,round); sprintf(vname,"dl%d_bf_ch_r%d",eNB_id,round); LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_bf_ch_estimates[0],512*NSYMB,1,1); //LOG_M(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0],512,1,1); - sprintf(fname,"dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round); sprintf(vname,"dl%d_bf_ch_r%d_ext00",eNB_id,round); LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_bf_ch_estimates_ext[0], @@ -6958,8 +6508,8 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c if (ue->frame_parms.nb_antennas_rx == 2) { sprintf(fname,"dlsch%d_ch_r%d_ext01.m",eNB_id,round); sprintf(vname,"dl%d_ch_r%d_ext01",eNB_id,round); - LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[1], - 12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1); + LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[1], + 12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1); } if (ue->frame_parms.nb_antenna_ports_eNB == 2) { @@ -6980,7 +6530,6 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c sprintf(vname,"dl%d_rxF_r%d_uespec0",eNB_id,round); LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_uespec_pilots[0], 12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1); - /* LOG_M("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*NSYMB,1,1); LOG_M("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*NSYMB,1,1); @@ -6988,20 +6537,17 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c */ sprintf(fname,"dlsch%d_r%d_rho.m",eNB_id,round); sprintf(vname,"dl_rho_r%d_%d",eNB_id,round); - LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_rho_ext[harq_pid][round][0], 12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1); - sprintf(fname,"dlsch%d_r%d_rho2.m",eNB_id,round); sprintf(vname,"dl_rho2_r%d_%d",eNB_id,round); - LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_rho2_ext[0], 12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1); - sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round); sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round); LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0], 12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1); + if (ue->frame_parms.nb_antenna_ports_eNB == 2) { sprintf(fname,"dlsch%d_rxF_r%d_comp1.m",eNB_id,round); sprintf(vname,"dl%d_rxF_r%d_comp1",eNB_id,round); @@ -7015,12 +6561,11 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c sprintf(fname,"dlsch%d_r%d_mag1.m",eNB_id,round); sprintf(vname,"dl%d_r%d_mag1",eNB_id,round); LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0], - 12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1); + 12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1); sprintf(fname,"dlsch%d_r%d_mag2.m",eNB_id,round); sprintf(vname,"dl%d_r%d_mag2",eNB_id,round); LOG_M(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0], 12*(ue->frame_parms.N_RB_DL)*NSYMB,1,1); - } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c index 55407d8e2dcea9e8016f7bb3ca6be98054f390fb..4c74377ef6f4a323df9d96b46e993beadeac2908 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c @@ -672,7 +672,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, len = (nb_rb*12) - pbch_pss_sss_adjust; } - + LOG_D(PHY,"[p %d : symb %d / FirstSym %d / Length %d]: @LLR Buff %p, @LLR Buff(symb) %p \n", frame_parms->nb_antenna_ports_eNB, symbol, @@ -680,7 +680,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, len, dlsch_llr, llr32); - + qpsk_llr((short *)rxF, (short *)llr32, diff --git a/openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c index aed3ddabc15b6279393c7405961edde780c51cd2..972dd839056a6d854fd61dc8ce8801a3f415985b 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/pch_ue.c @@ -48,7 +48,7 @@ int init_ue_paging_info(PHY_VARS_UE *ue, long defaultPagingCycle, long nB) { else if (Ns==4) ue->PO = (fp->frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1))); else - AssertFatal(1==0,"init_ue_paging_info: Ns is %d\n",Ns); + AssertFatal(1==0,"init_ue_paging_info: Ns is %u\n",Ns); return(0); } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h index 9c48201b003dbb15410aad53e008eac2646b48aa..536bd5f7383c2b143945808407505966556db031 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h @@ -1375,7 +1375,7 @@ void init_ul_hopping(LTE_DL_FRAME_PARMS *frame_parms); @param nB nB from 36.304 (0=4T,1=2T,2=T,3=T/2,4=T/4,5=T/8,6=T/16,7=T/32*/ int init_ue_paging_info(PHY_VARS_UE *ue, long defaultPagingCycle, long nB); -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void init_mpdcch(PHY_VARS_eNB *eNB); #endif diff --git a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c index b62c5c55449cc351fc1540e42d6175e2a2517c18..cc1f762e7046b9836d0c898d6c459afd9f34cb89 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c @@ -80,7 +80,6 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) } } free16(ulsch,sizeof(LTE_UE_ULSCH_t)); - ulsch = NULL; } } diff --git a/openair1/PHY/MODULATION/compute_bf_weights.c b/openair1/PHY/MODULATION/compute_bf_weights.c index 89d76058e6d2b1859124a14408704403fc9f778b..5c132062977ac574295022e232183738016013c9 100644 --- a/openair1/PHY/MODULATION/compute_bf_weights.c +++ b/openair1/PHY/MODULATION/compute_bf_weights.c @@ -22,6 +22,7 @@ int f_read(char *calibF_fname, int nb_ant, int nb_freq, int32_t **tdd_calib_coef } printf("%d\n",(int)tdd_calib_coeffs[0][0]); printf("%d\n",(int)tdd_calib_coeffs[1][599]); + fclose(calibF_fd); } else printf("%s not found, running with defaults\n",calibF_fname); /* TODO: what to return? is this code used at all? */ diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c index b01979431dcf88212604aa71cf0d0470eb177d06..58cd46a73ffa6760b6c363f5ded012f7f590b160 100644 --- a/openair1/PHY/MODULATION/slot_fep.c +++ b/openair1/PHY/MODULATION/slot_fep.c @@ -33,9 +33,7 @@ int slot_fep(PHY_VARS_UE *ue, unsigned char Ns, int sample_offset, int no_prefix, - int reset_freq_est) -{ - + int reset_freq_est) { LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; LTE_UE_COMMON *common_vars = &ue->common_vars; uint8_t eNB_id = 0;//ue_common_vars->eNb_id; @@ -48,43 +46,41 @@ int slot_fep(PHY_VARS_UE *ue, int i; unsigned int frame_length_samples = frame_parms->samples_per_tti * 10; unsigned int rx_offset; - /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id]; - unsigned char harq_pid = dlsch_ue[0]->current_harq_pid; + unsigned char harq_pid = dlsch_ue[0]->current_harq_pid; LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid]; int uespec_pilot[9][1200];*/ - void (*dft)(int16_t *,int16_t *, int); int tmp_dft_in[2048] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs switch (frame_parms->ofdm_symbol_size) { - case 128: - dft = dft128; - break; + case 128: + dft = dft128; + break; - case 256: - dft = dft256; - break; + case 256: + dft = dft256; + break; - case 512: - dft = dft512; - break; + case 512: + dft = dft512; + break; - case 1024: - dft = dft1024; - break; + case 1024: + dft = dft1024; + break; - case 1536: - dft = dft1536; - break; + case 1536: + dft = dft1536; + break; - case 2048: - dft = dft2048; - break; + case 2048: + dft = dft2048; + break; - default: - dft = dft512; - break; + default: + dft = dft512; + break; } if (no_prefix) { @@ -97,7 +93,6 @@ int slot_fep(PHY_VARS_UE *ue, // subframe_offset_F = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1); - if (l<0 || l>=7-frame_parms->Ncp) { printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp); return(-1); @@ -108,17 +103,13 @@ int slot_fep(PHY_VARS_UE *ue, return(-1); } - - for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); - rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET; // Align with 256 bit // rx_offset = rx_offset&0xfffffff8; if (l==0) { - if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((short *)&common_vars->rxdata[aa][frame_length_samples], (short *)&common_vars->rxdata[aa][0], @@ -132,30 +123,29 @@ int slot_fep(PHY_VARS_UE *ue, (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly #if UE_TIMING_TRACE - start_meas(&ue->rx_dft_stats); + start_meas(&ue->rx_dft_stats); #endif - dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); #endif - } } else { rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// + // (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); - #ifdef DEBUG_FEP // if (ue->frame <100) - LOG_I(PHY,"slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol, - nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples); + LOG_I(PHY,"slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", + ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol, + nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples); #endif if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((void *)&common_vars->rxdata[aa][frame_length_samples], (void *)&common_vars->rxdata[aa][0], frame_parms->ofdm_symbol_size*sizeof(int)); + #if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); #endif @@ -167,27 +157,25 @@ int slot_fep(PHY_VARS_UE *ue, dft((int16_t *)tmp_dft_in, (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly - dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } + #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); #endif - - } - #ifdef DEBUG_FEP - // if (ue->frame <100) - printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx, symbol,rx_offset); - #endif + +#ifdef DEBUG_FEP + // if (ue->frame <100) + printf("slot_fep: frame %d: symbol %d rx_offset %u\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx, symbol,rx_offset); +#endif } if (ue->perfect_ce == 0) { if ((l==0) || (l==(4-frame_parms->Ncp))) { for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) { - #ifdef DEBUG_FEP printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l); #endif @@ -212,7 +200,6 @@ int slot_fep(PHY_VARS_UE *ue, } } - // do frequency offset estimation here! // use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1}) #ifdef DEBUG_FEP @@ -220,23 +207,19 @@ int slot_fep(PHY_VARS_UE *ue, #endif if (l==(4-frame_parms->Ncp)) { - #if UE_TIMING_TRACE - start_meas(&ue->dlsch_freq_offset_estimation_stats); + start_meas(&ue->dlsch_freq_offset_estimation_stats); #endif - lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[0], frame_parms, l, &common_vars->freq_offset, - reset_freq_est); + reset_freq_est); #if UE_TIMING_TRACE stop_meas(&ue->dlsch_freq_offset_estimation_stats); #endif - } } - } #ifdef DEBUG_FEP @@ -246,11 +229,10 @@ int slot_fep(PHY_VARS_UE *ue, } int front_end_fft(PHY_VARS_UE *ue, - unsigned char l, - unsigned char Ns, - int sample_offset, - int no_prefix) -{ + unsigned char l, + unsigned char Ns, + int sample_offset, + int no_prefix) { LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; LTE_UE_COMMON *common_vars = &ue->common_vars; unsigned char aa; @@ -262,43 +244,41 @@ int front_end_fft(PHY_VARS_UE *ue, unsigned int frame_length_samples = frame_parms->samples_per_tti * 10; unsigned int rx_offset; uint8_t threadId; - /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id]; unsigned char harq_pid = dlsch_ue[0]->current_harq_pid; LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid]; int uespec_pilot[9][1200];*/ - void (*dft)(int16_t *,int16_t *, int); int tmp_dft_in[2048] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs switch (frame_parms->ofdm_symbol_size) { - case 128: - dft = dft128; - break; + case 128: + dft = dft128; + break; - case 256: - dft = dft256; - break; + case 256: + dft = dft256; + break; - case 512: - dft = dft512; - break; + case 512: + dft = dft512; + break; - case 1024: - dft = dft1024; - break; + case 1024: + dft = dft1024; + break; - case 1536: - dft = dft1536; - break; + case 1536: + dft = dft1536; + break; - case 2048: - dft = dft2048; - break; + case 2048: + dft = dft2048; + break; - default: - dft = dft512; - break; + default: + dft = dft512; + break; } if (no_prefix) { @@ -311,7 +291,6 @@ int front_end_fft(PHY_VARS_UE *ue, // subframe_offset_F = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1); - if (l<0 || l>=7-frame_parms->Ncp) { printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp); return(-1); @@ -322,19 +301,16 @@ int front_end_fft(PHY_VARS_UE *ue, return(-1); } - - threadId = ue->current_thread_id[Ns>>1]; + for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - // change thread index + // change thread index memset(&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); - rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET; // Align with 256 bit // rx_offset = rx_offset&0xfffffff8; if (l==0) { - if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) memcpy((short *)&common_vars->rxdata[aa][frame_length_samples], (short *)&common_vars->rxdata[aa][0], @@ -348,21 +324,19 @@ int front_end_fft(PHY_VARS_UE *ue, (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly start_meas(&ue->rx_dft_stats); - dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); stop_meas(&ue->rx_dft_stats); - } } else { rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// + // (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1); - #ifdef DEBUG_FEP // if (ue->frame <100) - LOG_I(PHY,"slot_fep: frame %d: slot %d, threadId %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", - ue->proc.proc_rxtx[threadId].frame_rx,Ns, threadId,symbol, - nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples); + LOG_I(PHY, + "slot_fep: frame %d: slot %d, threadId %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", + ue->proc.proc_rxtx[threadId].frame_rx,Ns, threadId,symbol, + nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples); #endif if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size)) @@ -379,29 +353,27 @@ int front_end_fft(PHY_VARS_UE *ue, dft((int16_t *)tmp_dft_in, (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly - dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples], (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } stop_meas(&ue->rx_dft_stats); - - } - #ifdef DEBUG_FEP - // if (ue->frame <100) - printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[threadId].frame_rx, symbol,rx_offset); - #endif +#ifdef DEBUG_FEP + // if (ue->frame <100) + printf("slot_fep: frame %d: symbol %d rx_offset %u\n", ue->proc.proc_rxtx[threadId].frame_rx, symbol,rx_offset); +#endif + } + return(0); } int front_end_chanEst(PHY_VARS_UE *ue, - unsigned char l, - unsigned char Ns, - int reset_freq_est) -{ + unsigned char l, + unsigned char Ns, + int reset_freq_est) { LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; LTE_UE_COMMON *common_vars = &ue->common_vars; uint8_t eNB_id = 0;//ue_common_vars->eNb_id; @@ -417,7 +389,6 @@ int front_end_chanEst(PHY_VARS_UE *ue, if (ue->perfect_ce == 0) { if ((l==0) || (l==(4-frame_parms->Ncp))) { for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) { - #ifdef DEBUG_FEP printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l); #endif @@ -438,7 +409,6 @@ int front_end_chanEst(PHY_VARS_UE *ue, } } - // do frequency offset estimation here! // use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1}) #ifdef DEBUG_FEP @@ -451,12 +421,11 @@ int front_end_chanEst(PHY_VARS_UE *ue, frame_parms, l, &common_vars->freq_offset, - reset_freq_est); + reset_freq_est); stop_meas(&ue->dlsch_freq_offset_estimation_stats); - } } - } + return(0); } diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c index 45373ab9e2ac57f768c59f2a80e20123062587fc..b8633b5126c43ce23d34b21e1bf9970b589ded47 100644 --- a/openair1/PHY/TOOLS/lte_dfts.c +++ b/openair1/PHY/TOOLS/lte_dfts.c @@ -9494,7 +9494,7 @@ int main(int argc, char**argv) LOG_M("x24576.m","x24576",x,24576,1,1); int dftsizes[33]={24,36,48,60,72,96,108,120,144,180,192,216,240,288,300,324,360,384,432,480,540,576,600,648,720,768,864,900,960,972,1080,1152,1200}; - void (*dft[33])(int16_t *x,int16_t *y,uint8_t scale) = {dft24,dft36,dft48,dft60,dft72,dft96,dft108,dft120,dft144,dft180,dft192,dft216,dft240,dft288,dft300,dft324,dft360,dft384,dft432,dft480,dft540,dft576,dft600,dft648,dft720,dft768,dft864,dft900,dft960,dft972,dft1080,dft1152,dft1200}; + void (*dft)(int16_t *x,int16_t *y,uint8_t scale)[33] = {dft24,dft36,dft48,dft60,dft72,dft96,dft108,dft120,dft144,dft180,dft192,dft216,dft240,dft288,dft300,dft324,dft360,dft384,dft432,dft480,dft540,dft576,dft600,dft648,dft720,dft768,dft864,dft900,dft960,dft972,dft1080,dft1152,dft1200}; for (int n=0;n<33;n++) { // 4xN-point DFT memset((void*)x,0,dftsizes[n]*8*sizeof(int16_t)); diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c index 8dd41548ab3b62f915b1873acdfe84227fa425fe..5c7322e2e93963ef6a5413bbd0fcc31146892a26 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c +++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c @@ -812,9 +812,6 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, free(bit1); free(bit_pdcch); free(llr_pdcch); - for (arx=0;arx<nb_antennas_rx;arx++) { - free(chest_t_abs[arx]); - } //This is done to avoid plotting old data when TB0 is disabled, and TB1 is mapped onto CW0 /*if (phy_vars_ue->transmission_mode[eNB_id]==3 && phy_vars_ue->transmission_mode[eNB_id]==4){ diff --git a/openair1/PHY/TOOLS/read_F.c b/openair1/PHY/TOOLS/read_F.c index 32ade0dfdb698c69c1ccc0cf757c10e739787822..155b72c851e6ea0d710d507e0fbb45fcada963b5 100644 --- a/openair1/PHY/TOOLS/read_F.c +++ b/openair1/PHY/TOOLS/read_F.c @@ -19,6 +19,7 @@ int f_read(char *calibF_fname, int nb_antM, int nb_freq, int16_t (*calibF_mtx)[n } printf("%d\n",(int)calibF_mtx[0][0]); printf("%d\n",(int)calibF_mtx[1][599]); + fclose(calibF_fd); } else printf("%s not found, running with defaults\n",calibF_fname); } diff --git a/openair1/PHY/TOOLS/smbv.c b/openair1/PHY/TOOLS/smbv.c index e020ca0c5200573c391d2d0235a9d0bfb855b3cb..d3618725478cbec430fe0a986c704fd385773700 100644 --- a/openair1/PHY/TOOLS/smbv.c +++ b/openair1/PHY/TOOLS/smbv.c @@ -64,6 +64,7 @@ int smbv_init_config(const char* fname, uint16_t sequence_length) if (sequence_length>4) { msg("ERROR invalid sequence length: %d, maximum is 4\n", sequence_length); + fclose(f_ptr); return -1; } else slen = sequence_length; @@ -448,13 +449,6 @@ int smbv_send_config (const char* fname, char* smbv_ip) int bytes_sent, status, sockfd; char buf[BUFFER_LENGTH]; - if (fopen(fname,"r")!=NULL) { - msg("Configuration file: %s\n",fname); - } else { - msg("ERROR: can't open SMBV config file: %s\n",fname); - return -1; - } - memset(buf,0,BUFFER_LENGTH); // first, load up address structs with getaddrinfo(): diff --git a/openair1/PHY/TOOLS/time_meas.c b/openair1/PHY/TOOLS/time_meas.c index b37f146b0a8eb9b05f4c871f4e8562d0cc1e3afa..327efbaafae5f3386ad38d5760e91b37d12f281b 100644 --- a/openair1/PHY/TOOLS/time_meas.c +++ b/openair1/PHY/TOOLS/time_meas.c @@ -29,7 +29,6 @@ int opp_enabled = 0; double get_cpu_freq_GHz(void) { - time_stats_t ts = {0}; reset_meas(&ts); ts.trials++; @@ -38,32 +37,40 @@ double get_cpu_freq_GHz(void) { ts.diff = (rdtsc_oai()-ts.in); cpu_freq_GHz = (double)ts.diff/1000000000; printf("CPU Freq is %f \n", cpu_freq_GHz); - return cpu_freq_GHz; + return cpu_freq_GHz; } +int cpumeas(int action) { + switch (action) { + case CPUMEAS_ENABLE: + opp_enabled = 1; + break; + + case CPUMEAS_DISABLE: + opp_enabled = 0; + break; + + case CPUMEAS_GETSTATE: + default: + break; + } -void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name){ - + return opp_enabled; +} +void print_meas_now(time_stats_t *ts, const char *name, FILE *file_name) { if (opp_enabled) { - //static double cpu_freq_GHz = 3.2; //if (cpu_freq_GHz == 0.0) - //cpu_freq_GHz = get_cpu_freq_GHz(); // super slow - + //cpu_freq_GHz = get_cpu_freq_GHz(); // super slow if (ts->trials>0) { - //fprintf(file_name,"Name %25s: Processing %15.3f ms for SF %d, diff_now %15.3f \n", name,(ts->p_time/(cpu_freq_GHz*1000000.0)),subframe,ts->p_time); fprintf(file_name,"%15.3f us, diff_now %15.3f \n",(ts->p_time/(cpu_freq_GHz*1000.0)),(double)ts->p_time); - } } } -void print_meas(time_stats_t *ts, const char* name, time_stats_t * total_exec_time, time_stats_t * sf_exec_time) -{ - +void print_meas(time_stats_t *ts, const char *name, time_stats_t *total_exec_time, time_stats_t *sf_exec_time) { if (opp_enabled) { - static int first_time = 0; static double cpu_freq_GHz = 0.0; @@ -81,7 +88,6 @@ void print_meas(time_stats_t *ts, const char* name, time_stats_t * total_exec_ti if (ts->trials>0) { //printf("%20s: total: %10.3f ms, average: %10.3f us (%10d trials)\n", name, ts->diff/cpu_freq_GHz/1000000.0, ts->diff/ts->trials/cpu_freq_GHz/1000.0, ts->trials); - if ((total_exec_time == NULL) || (sf_exec_time== NULL)) { fprintf(stderr, "%25s: %15.3f us; %15d;\n", name, @@ -98,12 +104,9 @@ void print_meas(time_stats_t *ts, const char* name, time_stats_t * total_exec_ti } } } - } -double get_time_meas_us(time_stats_t *ts) -{ - +double get_time_meas_us(time_stats_t *ts) { static double cpu_freq_GHz = 0.0; if (cpu_freq_GHz == 0.0) diff --git a/openair1/PHY/TOOLS/time_meas.h b/openair1/PHY/TOOLS/time_meas.h index eac057095a42d41ef89efc86a090715f9c09292a..797acef8e724259436248b3d6b85143c25fbc658 100644 --- a/openair1/PHY/TOOLS/time_meas.h +++ b/openair1/PHY/TOOLS/time_meas.h @@ -61,23 +61,21 @@ static inline void start_meas(time_stats_t *ts) __attribute__((always_inline)); static inline void stop_meas(time_stats_t *ts) __attribute__((always_inline)); -void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name); -void print_meas(time_stats_t *ts, const char* name, time_stats_t * total_exec_time, time_stats_t * sf_exec_time); +void print_meas_now(time_stats_t *ts, const char *name, FILE *file_name); +void print_meas(time_stats_t *ts, const char *name, time_stats_t *total_exec_time, time_stats_t *sf_exec_time); double get_time_meas_us(time_stats_t *ts); double get_cpu_freq_GHz(void); #if defined(__i386__) static inline unsigned long long rdtsc_oai(void) __attribute__((always_inline)); -static inline unsigned long long rdtsc_oai(void) -{ +static inline unsigned long long rdtsc_oai(void) { unsigned long long int x; __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); return x; } #elif defined(__x86_64__) static inline unsigned long long rdtsc_oai(void) __attribute__((always_inline)); -static inline unsigned long long rdtsc_oai(void) -{ +static inline unsigned long long rdtsc_oai(void) { unsigned long long a, d; __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); return (d<<32) | a; @@ -85,61 +83,54 @@ static inline unsigned long long rdtsc_oai(void) #elif defined(__arm__) static inline uint32_t rdtsc_oai(void) __attribute__((always_inline)); -static inline uint32_t rdtsc_oai(void) -{ +static inline uint32_t rdtsc_oai(void) { uint32_t r = 0; asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(r) ); return r; } #endif -static inline void start_meas(time_stats_t *ts) -{ - +#define CPUMEAS_DISABLE 0 +#define CPUMEAS_ENABLE 1 +#define CPUMEAS_GETSTATE 2 +int cpumeas(int action); +static inline void start_meas(time_stats_t *ts) { if (opp_enabled) { if (ts->meas_flag==0) { ts->trials++; ts->in = rdtsc_oai(); ts->meas_flag=1; - } - else { + } else { ts->in = rdtsc_oai(); } } } -static inline void stop_meas(time_stats_t *ts) -{ - +static inline void stop_meas(time_stats_t *ts) { if (opp_enabled) { long long out = rdtsc_oai(); - ts->diff += (out-ts->in); /// process duration is the difference between two clock points ts->p_time = (out-ts->in); ts->diff_square += (out-ts->in)*(out-ts->in); - + if ((out-ts->in) > ts->max) ts->max = out-ts->in; - ts->meas_flag=0; + ts->meas_flag=0; } } static inline void reset_meas(time_stats_t *ts) { - ts->trials=0; ts->diff=0; ts->p_time=0; ts->diff_square=0; ts->max=0; ts->meas_flag=0; - } -static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) -{ - +static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) { if (opp_enabled) { dst_ts->trials=src_ts->trials; dst_ts->diff=src_ts->diff; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index cb6d13c285f927201c0f72de84552d2100723af8..e1d78479e7755b8173ecac000a6965b096cf434a 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -312,6 +312,10 @@ typedef struct RU_t_s{ LTE_DL_FRAME_PARMS frame_parms; ///timing offset used in TDD int N_TA_offset; + /// SF extension used in TDD (unit: number of samples at 30.72MHz) (this is an expert option) + int sf_extension; + /// "end of burst delay" used in TDD (unit: number of samples at 30.72MHz) (this is an expert option) + int end_of_burst_delay; /// RF device descriptor openair0_device rfdevice; /// HW configuration @@ -971,6 +975,22 @@ typedef struct PHY_VARS_eNB_s { uint32_t lte_gold_mbsfn_khz_1dot25_table[10][150]; #endif + // PRACH energy detection parameters + /// Detection threshold for LTE PRACH + int prach_DTX_threshold; + /// Detection threshold for LTE-M PRACH per CE-level + int prach_DTX_threshold_emtc[4]; + /// counter to average prach energh over first 100 prach opportunities + int prach_energy_counter; + // PUCCH1 energy detection parameters + int pucch1_DTX_threshold; + // PUCCH1 energy detection parameters for eMTC per CE-level + int pucch1_DTX_threshold_emtc[4]; + // PUCCH1a/b energy detection parameters + int pucch1ab_DTX_threshold; + // PUCCH1a/b energy detection parameters for eMTC per CE-level + int pucch1ab_DTX_threshold_emtc[4]; + uint32_t X_u[64][839]; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint32_t X_u_br[4][64][839]; @@ -1007,8 +1027,7 @@ typedef struct PHY_VARS_eNB_s { /// if ==0 enables phy only test mode int mac_enabled; - /// counter to average prach energh over first 100 prach opportunities - int prach_energy_counter; + // PDSCH Varaibles PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_UE_MAX]; diff --git a/openair1/README.TXT b/openair1/README.TXT index 69912b4ecff0d7d98bd84ed1643ca79f94c0d3ae..98ec8984c425a3683070f42b91f3166f70feacad 100644 --- a/openair1/README.TXT +++ b/openair1/README.TXT @@ -9,7 +9,7 @@ General remarks: every directory contains at least defs.h (for declaration of st | |-- INIT // variables defined in vars.h are initialzed here (memory allocation) | |-- LTE_ESTIMATION // estimation for LTE | |-- LTE_REFSIG // reference signals for LTE (sync and pilot sequences) reference signals from 36-211 -| |-- NR_REFSIG // reference signals for NR (sync and pilot sequences) reference signals from 38-211 +| |-- NR_REFSIG // reference signals for NR (sync and pilot sequences) reference signals from 38-211 | |-- LTE_TRANSPORT // these are the top level routines for different transport and physical channels (for example DL-SCH, PSS) implements a subset of 36-211,36-212 | |-- LTE_UE_TRANSPORT // these are the top level routines for different transport and physical channels (for example DL-SCH, PSS) implements a subset of 36-211,36-212 | |-- NR_TRANSPORT // these are the top level routines for different transport and physical channels (for example DL-SCH, PSS) implements a subset of 38-211,38-212 @@ -27,18 +27,18 @@ General remarks: every directory contains at least defs.h (for declaration of st | |-- spec_defs_top.h | |-- types.h | `-- vars.h -|-- SCHED // schedules the different LTE eNB functions +|-- SCHED // schedules the different LTE eNB functions | |-- defs.h | |-- extern.h | |-- phy_procedures_lte_eNb.c // LTE PHY procedures for eNB (from 36-213) | |-- phy_procedures_lte_common.c // LTE PHY procedures common for UE and eNB (from 36-213) | |-- prach_procedures.c //LTE PRACH procedures (from 36-213) -| |-- ru_procedures.c //RU procedures +| |-- ru_procedures.c //RU procedures | |-- fapi_l1.c //L1 side of the FAPI interface | |-- phy_mac_stub.c //MAC stub that generates channels when used in phy-test-mode | |-- rt_compat.h | `-- vars.h -|-- SCHED_UE // schedules the different LTE UE functions +|-- SCHED_UE // schedules the different LTE UE functions | |-- phy_procedures_lte_ue.c // LTE PHY procedures for UE (from 36-213) | |-- pucch_pc.c // power control for PUCCH | |-- pusch_pc.c // power control for PUSCH @@ -53,7 +53,7 @@ General remarks: every directory contains at least defs.h (for declaration of st | | |-- dlsim.c // PDSCH simulation testbench | | |-- ulsim.c // PUSCH simulation testbench | | |-- pucchsim.c // PUCCH simulation testbench -| |-- RF // RF simulation tools +| |-- RF // RF simulation tools | |-- ETH_TRANSPORT | `-- TOOLS diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index a057b243b9898f8d579ee2c49f2d72b9c163c576..a2754b835ac976e105117838a457d788b21b4c93 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -33,8 +33,7 @@ #include "PHY/defs_eNB.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" #include "SCHED/sched_eNB.h" - -#include "nfapi_interface.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "nfapi_pnf_interface.h" #include "fapi_l1.h" @@ -43,42 +42,37 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req); int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req); -extern uint8_t nfapi_mode; - void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, L1_rxtx_proc_t *proc, - nfapi_dl_config_request_pdu_t *dl_config_pdu) -{ + nfapi_dl_config_request_pdu_t *dl_config_pdu) { int idx = subframe&1; LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[idx]; nfapi_dl_config_dci_dl_pdu *pdu = &dl_config_pdu->dci_dl_pdu; - if (nfapi_mode==2) return; - - LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,subframe, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci); + if (NFAPI_MODE==NFAPI_MODE_VNF) return; + LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populating pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",frame,subframe, pdcch_vars->num_dci, proc->subframe_tx, + idx, pdcch_vars->num_dci); // copy dci configuration into eNB structure fill_dci_and_dlsch(eNB,frame,subframe,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci],pdu); - - LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->subframe_tx, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci); + LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->subframe_tx, pdcch_vars->num_dci, + proc->subframe_tx, idx, pdcch_vars->num_dci); } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, - nfapi_dl_config_request_pdu_t *dl_config_pdu) -{ + nfapi_dl_config_request_pdu_t *dl_config_pdu) { int idx = proc->subframe_tx&1; LTE_eNB_MPDCCH *mpdcch_vars = &eNB->mpdcch_vars[idx]; nfapi_dl_config_mpdcch_pdu *pdu = &dl_config_pdu->mpdcch_pdu; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; LOG_D(PHY,"Frame %d, Subframe %d: MDCI processing\n",proc->frame_tx,proc->subframe_tx); - // copy dci configuration into eNB structure fill_mdci_and_dlsch(eNB,proc,&mpdcch_vars->mdci_alloc[mpdcch_vars->num_dci],pdu); } @@ -86,15 +80,13 @@ void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, #endif void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, - nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) -{ + nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { int idx = subframe&1; LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[idx]; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; //LOG_D(PHY,"%s() SFN/SF:%04d%d Before num_dci:%d\n", __FUNCTION__,frame,subframe,pdcch_vars->num_dci); - // copy dci configuration in to eNB structure fill_dci0(eNB,frame,subframe,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci], &hi_dci0_config_pdu->dci_pdu); } @@ -102,11 +94,11 @@ void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rx void handle_nfapi_hi_dci0_mpdcch_dci_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, - nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) -{ + nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { int idx = proc->subframe_tx&1; LTE_eNB_MPDCCH *pdcch_vars = &eNB->mpdcch_vars[idx]; - if (nfapi_mode==2) return; + + if (NFAPI_MODE==NFAPI_MODE_VNF) return; // copy dci configuration in to eNB structure fill_mpdcch_dci0(eNB,proc,&pdcch_vars->mdci_alloc[pdcch_vars->num_dci], &hi_dci0_config_pdu->mpdcch_dci_pdu); @@ -114,18 +106,16 @@ void handle_nfapi_hi_dci0_mpdcch_dci_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, - nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) -{ + nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { LTE_eNB_PHICH *phich = &eNB->phich_vars[subframe&1]; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; // copy dci configuration in to eNB structure LOG_D(PHY,"Received HI PDU with value %d (rbstart %d,cshift %d)\n", hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value, hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start, hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms); - // DJP - TODO FIXME - transmission power ignored phich->config[phich->num_hi].hi = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value; phich->config[phich->num_hi].first_rb = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start; @@ -136,38 +126,34 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxt void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, - uint8_t *sdu) -{ + uint8_t *sdu) { nfapi_dl_config_bch_pdu_rel8_t *rel8 = &dl_config_pdu->bch_pdu.bch_pdu_rel8; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; AssertFatal(rel8->length == 3, "BCH PDU has length %d != 3\n",rel8->length); - //LOG_D(PHY,"bch_pdu: %x,%x,%x\n",sdu[0],sdu[1],sdu[2]); eNB->pbch_pdu[0] = sdu[2]; eNB->pbch_pdu[1] = sdu[1]; eNB->pbch_pdu[2] = sdu[0]; - // adjust transmit amplitude here based on NFAPI info } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -extern uint32_t localRIV2alloc_LUT6[32]; -extern uint32_t localRIV2alloc_LUT25[512]; -extern uint32_t localRIV2alloc_LUT50_0[1600]; -extern uint32_t localRIV2alloc_LUT50_1[1600]; -extern uint32_t localRIV2alloc_LUT100_0[6000]; -extern uint32_t localRIV2alloc_LUT100_1[6000]; -extern uint32_t localRIV2alloc_LUT100_2[6000]; -extern uint32_t localRIV2alloc_LUT100_3[6000]; + extern uint32_t localRIV2alloc_LUT6[32]; + extern uint32_t localRIV2alloc_LUT25[512]; + extern uint32_t localRIV2alloc_LUT50_0[1600]; + extern uint32_t localRIV2alloc_LUT50_1[1600]; + extern uint32_t localRIV2alloc_LUT100_0[6000]; + extern uint32_t localRIV2alloc_LUT100_1[6000]; + extern uint32_t localRIV2alloc_LUT100_2[6000]; + extern uint32_t localRIV2alloc_LUT100_3[6000]; #endif void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, - uint8_t *sdu) -{ + uint8_t *sdu) { nfapi_dl_config_dlsch_pdu_rel8_t *rel8 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) nfapi_dl_config_dlsch_pdu_rel10_t *rel10 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10; @@ -180,58 +166,62 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro int UE_id; int harq_pid; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE); - if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ){ + + if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ) { LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rel8->rnti,UE_id); return; } + //AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n"); //AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX); - dlsch0 = eNB->dlsch[UE_id][0]; dlsch1 = eNB->dlsch[UE_id][1]; - #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + if ((rel13->pdsch_payload_type < 2) && (rel13->ue_type>0)) dlsch0->harq_ids[proc->frame_tx%2][proc->subframe_tx] = 0; -#endif +#endif harq_pid = dlsch0->harq_ids[proc->frame_tx%2][proc->subframe_tx]; AssertFatal((harq_pid>=0) && (harq_pid<8),"harq_pid %d not in 0...7 frame:%d subframe:%d subframe(TX):%d rnti:%x UE_id:%d dlsch0[harq_ids:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d]\n", - harq_pid, - frame,subframe, - proc->subframe_tx,rel8->rnti,UE_id, - dlsch0->harq_ids[proc->frame_tx%2][0], - dlsch0->harq_ids[proc->frame_tx%2][1], - dlsch0->harq_ids[proc->frame_tx%2][2], - dlsch0->harq_ids[proc->frame_tx%2][3], - dlsch0->harq_ids[proc->frame_tx%2][4], - dlsch0->harq_ids[proc->frame_tx%2][5], - dlsch0->harq_ids[proc->frame_tx%2][6], - dlsch0->harq_ids[proc->frame_tx%2][7], - dlsch0->harq_ids[proc->frame_tx%2][8], - dlsch0->harq_ids[proc->frame_tx%2][9] - ); + harq_pid, + frame,subframe, + proc->subframe_tx,rel8->rnti,UE_id, + dlsch0->harq_ids[proc->frame_tx%2][0], + dlsch0->harq_ids[proc->frame_tx%2][1], + dlsch0->harq_ids[proc->frame_tx%2][2], + dlsch0->harq_ids[proc->frame_tx%2][3], + dlsch0->harq_ids[proc->frame_tx%2][4], + dlsch0->harq_ids[proc->frame_tx%2][5], + dlsch0->harq_ids[proc->frame_tx%2][6], + dlsch0->harq_ids[proc->frame_tx%2][7], + dlsch0->harq_ids[proc->frame_tx%2][8], + dlsch0->harq_ids[proc->frame_tx%2][9] + ); dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch_harq is null\n"); - // compute DL power control parameters eNB->pdsch_config_dedicated[UE_id].p_a = rel8->pa; +#ifdef PHY_TX_THREAD -#ifdef PHY_TX_THREAD - if (dlsch0->active[proc->subframe_tx]){ + if (dlsch0->active[proc->subframe_tx]) { # else - if (dlsch0->active){ + + if (dlsch0->active) { #endif computeRhoA_eNB(rel8->pa, dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off); } + #ifdef PHY_TX_THREAD - if (dlsch1->active[proc->subframe_tx]){ + + if (dlsch1->active[proc->subframe_tx]) { #else - if (dlsch1->active){ + + if (dlsch1->active) { #endif computeRhoA_eNB(rel8->pa, dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off); @@ -241,25 +231,27 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro if (dlsch0_harq->round==0) { //get pointer to SDU if this a new SDU if(sdu == NULL) { - LOG_E(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n", + LOG_E(PHY, + "NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n", frame,subframe, proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start); return; } + //AssertFatal(sdu!=NULL,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n", // frame,subframe, // proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid, // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start); if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d, subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n", - frame,subframe,proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid); + frame,subframe,proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid); + if (codeword_index == 0) dlsch0_harq->pdu = sdu; else dlsch1_harq->pdu = sdu; - } - else { + } else { if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d, subframe %d]: programming dlsch for round %d, rnti %x, UE_id %d, harq_pid %d\n", - frame,subframe,proc->frame_tx,proc->subframe_tx,dlsch0_harq->round, - rel8->rnti,UE_id,harq_pid); + frame,subframe,proc->frame_tx,proc->subframe_tx,dlsch0_harq->round, + rel8->rnti,UE_id,harq_pid); } #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) @@ -273,55 +265,60 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE); AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n"); AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX); - dlsch0 = eNB->dlsch[UE_id][0]; - dlsch0->harq_mask = 1; + dlsch0->harq_mask = 1; dlsch0_harq = dlsch0->harq_processes[0]; dlsch0_harq->pdu = sdu; - if (proc->frame_tx < 200) LOG_D(PHY,"NFAPI: frame %d, subframe %d (TX %d.%d): Programming SI-BR (%d) => %d\n",frame,subframe,proc->frame_tx,proc->subframe_tx,rel13->pdsch_payload_type,UE_id); - + LOG_D(PHY,"NFAPI: frame %d, subframe %d (TX %d.%d): Programming SI-BR (%d) => %d\n",frame,subframe,proc->frame_tx,proc->subframe_tx,rel13->pdsch_payload_type,UE_id); + dlsch0->rnti = 0xFFFF; dlsch0->Kmimo = 1; dlsch0->Mdlharq = 4; dlsch0->Nsoft = 25344; - dlsch0->i0 = rel13->initial_transmission_sf_io; dlsch0_harq->pdsch_start = rel10->pdsch_start; dlsch0->harq_ids[proc->frame_tx%2][proc->subframe_rx] = 0; dlsch0_harq->frame = proc->frame_tx; dlsch0_harq->subframe = proc->subframe_tx; - - #ifdef PHY_TX_THREAD + if (rel13->pdsch_payload_type == 0) dlsch0_harq->sib1_br_flag=1; + #else + if (rel13->pdsch_payload_type == 0) dlsch0->sib1_br_flag=1; + #endif - // configure PDSCH + // configure PDSCH switch (eNB->frame_parms.N_RB_DL) { - case 6: - dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT6[rel8->resource_block_coding]; - break; - case 15: - AssertFatal(1==0,"15 PRBs not supported for now\n"); - break; - case 25: - dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT25[rel8->resource_block_coding]; - break; - case 50: - dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT50_0[rel8->resource_block_coding]; - dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT50_1[rel8->resource_block_coding]; - break; - case 75: - AssertFatal(1==0,"75 PRBs not supported for now\n"); - break; - case 100: - dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT100_0[rel8->resource_block_coding]; - dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT100_1[rel8->resource_block_coding]; - dlsch0_harq->rb_alloc[2] = localRIV2alloc_LUT100_2[rel8->resource_block_coding]; - dlsch0_harq->rb_alloc[3] = localRIV2alloc_LUT100_3[rel8->resource_block_coding]; + case 6: + dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT6[rel8->resource_block_coding]; + break; + + case 15: + AssertFatal(1==0,"15 PRBs not supported for now\n"); + break; + + case 25: + dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT25[rel8->resource_block_coding]; + break; + + case 50: + dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT50_0[rel8->resource_block_coding]; + dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT50_1[rel8->resource_block_coding]; + break; + + case 75: + AssertFatal(1==0,"75 PRBs not supported for now\n"); + break; + + case 100: + dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT100_0[rel8->resource_block_coding]; + dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT100_1[rel8->resource_block_coding]; + dlsch0_harq->rb_alloc[2] = localRIV2alloc_LUT100_2[rel8->resource_block_coding]; + dlsch0_harq->rb_alloc[3] = localRIV2alloc_LUT100_3[rel8->resource_block_coding]; } #ifdef PHY_TX_THREAD @@ -329,7 +326,6 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro #else dlsch0->active = 1; #endif - dlsch0_harq->nb_rb = 6; dlsch0_harq->vrb_type = LOCALIZED; dlsch0_harq->rvidx = rel8->redundancy_version; @@ -342,99 +338,96 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro dlsch0_harq->Qm = rel8->modulation; dlsch0_harq->codeword = 0; dlsch0_harq->pdsch_start = rel10->pdsch_start; - } - else + } else #endif - { + { UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE); AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n"); AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX); - dlsch0 = eNB->dlsch[UE_id][0]; dlsch1 = eNB->dlsch[UE_id][1]; - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) dlsch0->sib1_br_flag=0; dlsch0->i0 = 0xFFFF; #endif - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - LOG_D(PHY,"dlsch->i0:%04x dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", + LOG_D(PHY,"dlsch->i0:%04x dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", #ifdef PHY_TX_THREAD - dlsch0_harq->i0, + dlsch0_harq->i0, #else - dlsch0->i0, + dlsch0->i0, #endif - dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0], - rel8->length - ); + dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, + dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0], + rel8->length + ); #else - LOG_D(PHY,"dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", - dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0], - rel8->length - ); + LOG_D(PHY,"dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", + dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, + dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0], + rel8->length + ); #endif - dlsch0->active = 1; harq_pid = dlsch0->harq_ids[frame%2][proc->subframe_tx]; dlsch0->harq_mask |= (1<<harq_pid); - AssertFatal((harq_pid>=0) && (harq_pid<8),"subframe %d: harq_pid %d not in 0...7\n",proc->subframe_tx,harq_pid); dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch_harq is null\n"); - // compute DL power control parameters - + // compute DL power control parameters - if (dlsch0->active){ + if (dlsch0->active) { computeRhoA_eNB(rel8->pa,dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off); - } - if (dlsch1->active){ + } + + if (dlsch1->active) { computeRhoA_eNB(rel8->pa, dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off); } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - dlsch0_harq->pdsch_start = eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols; -#else - dlsch0_harq->pdsch_start = rel10->pdsch_start; + + if (rel13->ue_type>0) + dlsch0_harq->pdsch_start = rel10->pdsch_start; + else #endif + dlsch0_harq->pdsch_start = eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols; + if (dlsch0_harq->round==0) { //get pointer to SDU if this a new SDU AssertFatal(sdu!=NULL,"NFAPI: frame %d, subframe %d: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d\n", proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index); + if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: frame %d, subframe %d: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n", - proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid); + proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid); + if (codeword_index == 0) dlsch0_harq->pdu = sdu; else dlsch1_harq->pdu = sdu; - } - else { + } else { if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: frame %d, subframe %d: programming dlsch for round %d, rnti %x, UE_id %d, harq_pid %d\n", - proc->frame_tx,proc->subframe_tx,dlsch0_harq->round, - rel8->rnti,UE_id,harq_pid); + proc->frame_tx,proc->subframe_tx,dlsch0_harq->round, + rel8->rnti,UE_id,harq_pid); } - } } -int16_t to_beta_offset_harqack[16]={16,20,25,32,40,50,64,80,101,127,160,248,400,640,1008,8}; +int16_t to_beta_offset_harqack[16]= {16,20,25,32,40,50,64,80,101,127,160,248,400,640,1008,8}; void handle_ulsch_harq_pdu( - PHY_VARS_eNB *eNB, - int UE_id, - nfapi_ul_config_request_pdu_t *ul_config_pdu, - nfapi_ul_config_ulsch_harq_information *harq_information, - uint16_t frame, - uint8_t subframe) -{ + PHY_VARS_eNB *eNB, + int UE_id, + nfapi_ul_config_request_pdu_t *ul_config_pdu, + nfapi_ul_config_ulsch_harq_information *harq_information, + uint16_t frame, + uint8_t subframe) { nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8; - LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id]; LTE_UL_eNB_HARQ_t *ulsch_harq; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; int harq_pid = rel8->harq_process_number; ulsch_harq = ulsch->harq_processes[harq_pid]; @@ -442,30 +435,31 @@ void handle_ulsch_harq_pdu( ulsch_harq->subframe = subframe; ulsch_harq->O_ACK = harq_information->harq_information_rel10.harq_size; ulsch->beta_offset_harqack_times8 = to_beta_offset_harqack[harq_information->harq_information_rel10.delta_offset_harq]; + if (eNB->frame_parms.frame_type == TDD) { if (harq_information->harq_information_rel10.ack_nack_mode==0) //bundling - ulsch->bundling = 1; - } + ulsch->bundling = 1; + } } -uint16_t to_beta_offset_ri[16]={9,13,16,20,25,32,40,50,64,80,101,127,160,0,0,0}; -uint16_t to_beta_offset_cqi[16]={0,0,9,10,11,13,14,16,18,20,23,25,28,32,40,50}; +uint16_t to_beta_offset_ri[16]= {9,13,16,20,25,32,40,50,64,80,101,127,160,0,0,0}; +uint16_t to_beta_offset_cqi[16]= {0,0,9,10,11,13,14,16,18,20,23,25,28,32,40,50}; -void handle_ulsch_cqi_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) -{ +void handle_ulsch_cqi_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) { nfapi_ul_config_cqi_ri_information_rel9_t *rel9 = &ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9; - LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; int harq_pid = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number; LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; ulsch_harq->frame = frame; ulsch_harq->subframe = subframe; ulsch_harq->O_RI = rel9->aperiodic_cqi_pmi_ri_report.cc[0].ri_size; ulsch_harq->Or1 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0]; + if (ulsch_harq->O_RI>1) ulsch_harq->Or2 = rel9->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[1]; + ulsch->beta_offset_ri_times8 = to_beta_offset_ri[rel9->delta_offset_ri]; ulsch->beta_offset_cqi_times8 = to_beta_offset_cqi[rel9->delta_offset_cqi]; LOG_D(PHY,"Filling ulsch_cqi_ri information for frame %d, subframe %d : O_RI %d, Or1 %d, beta_offset_cqi_times8 %d (%d)\n", @@ -473,16 +467,14 @@ void handle_ulsch_cqi_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request rel9->delta_offset_cqi); } -void handle_ulsch_cqi_harq_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) -{ +void handle_ulsch_cqi_harq_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) { nfapi_ul_config_cqi_ri_information_rel9_t *rel9 = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.cqi_ri_information.cqi_ri_information_rel9; - LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id]; int harq_pid = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number; LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid]; nfapi_ul_config_ulsch_harq_information *harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; ulsch_harq->frame = frame; ulsch_harq->subframe = subframe; @@ -497,14 +489,11 @@ void handle_ulsch_cqi_harq_ri_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_re ulsch->beta_offset_cqi_times8 = to_beta_offset_cqi[rel9->delta_offset_cqi]; } -void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_config_harq_information *harq_information) -{ - - if (nfapi_mode==2) return; +void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_config_harq_information *harq_information) { + if (NFAPI_MODE==NFAPI_MODE_VNF) return; if (eNB->frame_parms.frame_type == FDD) { uci->num_pucch_resources = harq_information->harq_information_rel9_fdd.number_of_pucch_resources; - LOG_D(PHY,"Programming UCI HARQ mode %d : size %d in (%d,%d)\n", harq_information->harq_information_rel9_fdd.ack_nack_mode, harq_information->harq_information_rel9_fdd.harq_size, @@ -515,23 +504,20 @@ void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_co uci->pucch_fmt = pucch_format1a; uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; - } - else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) && - (harq_information->harq_information_rel9_fdd.harq_size == 2)) { + } else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) && + (harq_information->harq_information_rel9_fdd.harq_size == 2)) { uci->pucch_fmt = pucch_format1b; uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; - } - else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) && - (harq_information->harq_information_rel9_fdd.harq_size == 2)) { + } else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) && + (harq_information->harq_information_rel9_fdd.harq_size == 2)) { uci->pucch_fmt = pucch_format1b_csA2; uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; uci->n_pucch_1[1][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_1; uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1; - } - else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) && - (harq_information->harq_information_rel9_fdd.harq_size == 3)) { + } else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) && + (harq_information->harq_information_rel9_fdd.harq_size == 3)) { uci->pucch_fmt = pucch_format1b_csA3; uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; @@ -539,9 +525,8 @@ void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_co uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1; uci->n_pucch_1[2][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_2; uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2; - } - else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) && - (harq_information->harq_information_rel9_fdd.harq_size == 4)) { + } else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 1) && + (harq_information->harq_information_rel9_fdd.harq_size == 4)) { uci->pucch_fmt = pucch_format1b_csA4; uci->n_pucch_1[0][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; @@ -549,33 +534,27 @@ void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_co uci->n_pucch_1[1][1] = harq_information->harq_information_rel11.n_pucch_2_1; uci->n_pucch_1[2][0] = harq_information->harq_information_rel9_fdd.n_pucch_1_2; uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2; - } - else if (harq_information->harq_information_rel9_fdd.ack_nack_mode == 2) { + } else if (harq_information->harq_information_rel9_fdd.ack_nack_mode == 2) { uci->pucch_fmt = pucch_format3; uci->n_pucch_3[0] = harq_information->harq_information_rel9_fdd.n_pucch_1_0; uci->n_pucch_3[1] = harq_information->harq_information_rel11.n_pucch_2_0; - } - else AssertFatal(1==0,"unsupported FDD HARQ mode %d size %d\n",harq_information->harq_information_rel9_fdd.ack_nack_mode,harq_information->harq_information_rel9_fdd.harq_size); - } - else { // TDD + } else AssertFatal(1==0,"unsupported FDD HARQ mode %d size %d\n",harq_information->harq_information_rel9_fdd.ack_nack_mode,harq_information->harq_information_rel9_fdd.harq_size); + } else { // TDD uci->num_pucch_resources = harq_information->harq_information_rel10_tdd.number_of_pucch_resources; if (harq_information->harq_information_rel10_tdd.ack_nack_mode == 0) {//bundling - uci->pucch_fmt = harq_information->harq_information_rel10_tdd.harq_size==1 ? pucch_format1a : pucch_format1b; uci->tdd_bundling = 1; uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0; uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; - } - else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && //multiplexing - (uci->num_pucch_resources == 1)) { + } else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && //multiplexing + (uci->num_pucch_resources == 1)) { uci->pucch_fmt = harq_information->harq_information_rel10_tdd.harq_size==1 ? pucch_format1a : pucch_format1b; uci->tdd_bundling = 0; uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0; uci->n_pucch_1[0][1] = harq_information->harq_information_rel11.n_pucch_2_0; - } - else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && //multiplexing M>1 - (uci->num_pucch_resources > 1)) { + } else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && //multiplexing M>1 + (uci->num_pucch_resources > 1)) { uci->pucch_fmt = pucch_format1b; uci->tdd_bundling = 0; uci->n_pucch_1[0][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0; @@ -586,21 +565,24 @@ void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_co uci->n_pucch_1[2][1] = harq_information->harq_information_rel11.n_pucch_2_2; uci->n_pucch_1[3][0] = harq_information->harq_information_rel10_tdd.n_pucch_1_3; uci->n_pucch_1[3][1] = harq_information->harq_information_rel11.n_pucch_2_3; - } - else if (harq_information->harq_information_rel10_tdd.ack_nack_mode == 2) { + } else if (harq_information->harq_information_rel10_tdd.ack_nack_mode == 2) { uci->pucch_fmt = pucch_format3; uci->n_pucch_3[0] = harq_information->harq_information_rel10_tdd.n_pucch_1_0; uci->n_pucch_3[1] = harq_information->harq_information_rel11.n_pucch_2_0; - } - else AssertFatal(1==0,"unsupported HARQ mode %d\n",harq_information->harq_information_rel10_tdd.ack_nack_mode); + } else AssertFatal(1==0,"unsupported HARQ mode %d\n",harq_information->harq_information_rel10_tdd.ack_nack_mode); } } -void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) +void handle_uci_sr_pdu(PHY_VARS_eNB *eNB, + int UE_id, + nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint16_t frame, + uint8_t subframe, + uint8_t srs_active) { LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id]; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; uci->frame = frame; uci->subframe = subframe; @@ -618,14 +600,16 @@ void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t uci->total_repetitions = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel13.total_number_of_repetitions; #endif LOG_D(PHY,"Programming UCI SR rnti %x, pucch1_0 %d for (%d,%d)\n", - uci->rnti,uci->n_pucch_1_0_sr[0],frame,subframe); + uci->rnti, + uci->n_pucch_1_0_sr[0], + frame, + subframe); } -void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) -{ +void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) { LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id]; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; uci->frame = frame; uci->subframe = subframe; @@ -644,11 +628,10 @@ void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_ handle_uci_harq_information(eNB,uci,&ul_config_pdu->uci_sr_harq_pdu.harq_information); } -void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) -{ +void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe,uint8_t srs_active) { LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id]; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; LOG_D(PHY,"Frame %d, Subframe %d: Programming UCI_HARQ process (type %d)\n",frame,subframe,HARQ); uci->frame = frame; @@ -663,18 +646,15 @@ void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu uci->total_repetitions = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions; #endif handle_uci_harq_information(eNB,uci,&ul_config_pdu->uci_harq_pdu.harq_information); - uci->active=1; } -void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) -{ +void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_pdu,uint16_t frame,uint8_t subframe) { int i; - if (nfapi_mode==2) return; - - for (i=0;i<NUMBER_OF_UE_MAX;i++) { + if (NFAPI_MODE==NFAPI_MODE_VNF) return; + for (i=0; i<NUMBER_OF_UE_MAX; i++) { if (eNB->soundingrs_ul_config_dedicated[i].active==1) continue; eNB->soundingrs_ul_config_dedicated[i].active = 1; @@ -689,91 +669,77 @@ void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_p eNB->soundingrs_ul_config_dedicated[i].cyclicShift = ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift; break; } + AssertFatal(i<NUMBER_OF_UE_MAX,"No room for SRS processing\n"); } void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, - uint16_t frame,uint8_t subframe,uint8_t srs_present) -{ + uint16_t frame,uint8_t subframe,uint8_t srs_present) { nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8; int16_t UE_id; - if (nfapi_mode==2) return; + if (NFAPI_MODE==NFAPI_MODE_VNF) return; // check if we have received a dci for this ue and ulsch descriptor is configured if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { + //if (UE_id == find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE)<0) + //for (int i=0;i<16;i++) if (eNB->ulsch[i]->harq_mask>0) LOG_I(PHY,"rnti %x, mask %x\n",eNB->ulsch[i]->rnti,eNB->ulsch[i]->harq_mask >0); AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, "No existing UE ULSCH for rnti %x\n",rel8->rnti); - LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d, modulation %d, rvidx %d\n", UE_id,rel8->rnti,frame,subframe,rel8->modulation_type,rel8->redundancy_version); - + LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d, modulation %d, rvidx %d, first_rb %d, nb_rb %d\n", UE_id,rel8->rnti,frame,subframe,rel8->modulation_type, + rel8->redundancy_version, + rel8->resource_block_start,rel8->number_of_resource_blocks); fill_ulsch(eNB,UE_id,&ul_config_pdu->ulsch_pdu,frame,subframe); - - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) { + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) { AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti); - fill_ulsch(eNB,UE_id,&ul_config_pdu->ulsch_harq_pdu.ulsch_pdu,frame,subframe); handle_ulsch_harq_pdu(eNB, UE_id, ul_config_pdu, - &ul_config_pdu->ulsch_harq_pdu.harq_information, frame, subframe); - - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) { + &ul_config_pdu->ulsch_harq_pdu.harq_information, frame, subframe); + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) { AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti, eNB,SEARCH_EXIST_OR_FREE))>=0, "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti); fill_ulsch(eNB,UE_id,&ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu,frame,subframe); handle_ulsch_cqi_ri_pdu(eNB,UE_id,ul_config_pdu,frame,subframe); - - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) { + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) { AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti, eNB,SEARCH_EXIST_OR_FREE))>=0, "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti); fill_ulsch(eNB,UE_id,&ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu,frame,subframe); handle_ulsch_cqi_harq_ri_pdu(eNB,UE_id,ul_config_pdu,frame,subframe); handle_ulsch_harq_pdu(eNB, UE_id, ul_config_pdu, - &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information, frame, subframe); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { + &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information, frame, subframe); + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { AssertFatal((UE_id = find_uci(ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti, proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0, "No available UE UCI for rnti %x\n",ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti); LOG_D(PHY,"Applying UL UCI_HARQ config for UE %d, rnti %x for frame %d, subframe %d\n", UE_id,ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti,frame,subframe); - handle_uci_harq_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) { + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) { AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE not handled yet\n"); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) { + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) { AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE not handled yet\n"); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) { + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) { AssertFatal(1==0,"NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE not handled yet\n"); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) { + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) { AssertFatal((UE_id = find_uci(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti, proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0, "No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti); handle_uci_sr_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present); - - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) { + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) { AssertFatal((UE_id = find_uci(rel8->rnti,proc->frame_tx,proc->subframe_tx,eNB,SEARCH_EXIST_OR_FREE))>=0, "No available UE UCI for rnti %x\n",ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti); handle_uci_sr_harq_pdu(eNB,UE_id,ul_config_pdu,frame,subframe,srs_present); - } - else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_SRS_PDU_TYPE) { + } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_SRS_PDU_TYPE) { handle_srs_pdu(eNB,ul_config_pdu,frame,subframe); } } -void schedule_response(Sched_Rsp_t *Sched_INFO) -{ +void schedule_response(Sched_Rsp_t *Sched_INFO) { PHY_VARS_eNB *eNB; L1_rxtx_proc_t *proc; // copy data from L2 interface into L1 structures @@ -790,70 +756,57 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) int ul_frame; int harq_pid; LTE_UL_eNB_HARQ_t *ulsch_harq; - AssertFatal(RC.eNB!=NULL,"RC.eNB is null\n"); AssertFatal(RC.eNB[Mod_id]!=NULL,"RC.eNB[%d] is null\n",Mod_id); AssertFatal(RC.eNB[Mod_id][CC_id]!=NULL,"RC.eNB[%d][%d] is null\n",Mod_id,CC_id); - - eNB = RC.eNB[Mod_id][CC_id]; fp = &eNB->frame_parms; proc = &eNB->proc.L1_proc; - /* TODO: check that following line is correct - in the meantime it is disabled */ //if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return; - ul_subframe = pdcch_alloc2ul_subframe(fp,subframe); ul_frame = pdcch_alloc2ul_frame(fp,frame,subframe); - // DJP - subframe assert will fail - not sure why yet // DJP - AssertFatal(proc->subframe_tx == subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe); // DJP - AssertFatal(proc->subframe_tx == subframe, "Current frame %d != NFAPI frame %d\n",proc->frame_tx,frame); - uint8_t number_pdcch_ofdm_symbols = DL_req->dl_config_request_body.number_pdcch_ofdm_symbols; - uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu; uint8_t number_hi_dci0_pdu = HI_DCI0_req->hi_dci0_request_body.number_of_dci+HI_DCI0_req->hi_dci0_request_body.number_of_hi; uint8_t number_ul_pdu = UL_req!=NULL ? UL_req->ul_config_request_body.number_of_pdus : 0; - nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_hi_dci0_request_pdu_t *hi_dci0_req_pdu; nfapi_ul_config_request_pdu_t *ul_config_pdu; - int i; - eNB->pdcch_vars[subframe&1].num_pdcch_symbols = number_pdcch_ofdm_symbols; eNB->pdcch_vars[subframe&1].num_dci = 0; eNB->phich_vars[subframe&1].num_hi = 0; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) eNB->mpdcch_vars[subframe&1].num_dci = 0; #endif - LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%04d%d DL_req:SFN/SF:%04d%d:dl_pdu:%d tx_req:SFN/SF:%04d%d:pdus:%d\n", - frame,subframe, - NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),number_dl_pdu, - NFAPI_SFNSF2SFN(TX_req->sfn_sf),NFAPI_SFNSF2SF(TX_req->sfn_sf),TX_req->tx_request_body.number_of_pdus + frame,subframe, + NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),number_dl_pdu, + NFAPI_SFNSF2SFN(TX_req->sfn_sf),NFAPI_SFNSF2SF(TX_req->sfn_sf),TX_req->tx_request_body.number_of_pdus ); LOG_D(PHY,"NFAPI: hi_dci0:SFN/SF:%04d%d:pdus:%d\n", NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),number_hi_dci0_pdu ); + if(UL_req!=NULL) LOG_D(PHY,"NFAPI: ul_cfg:SFN/SF:%04d%d:pdus:%d num_pdcch_symbols:%d\n", NFAPI_SFNSF2SFN(UL_req->sfn_sf),NFAPI_SFNSF2SF(UL_req->sfn_sf),number_ul_pdu, eNB->pdcch_vars[subframe&1].num_pdcch_symbols); - int do_oai =0; int dont_send =0; + /* TODO: check the following test - in the meantime it is put back as it was before */ //if ((ul_subframe<10)&& // (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is an ul_subframe that can be configured here if (ul_subframe<10) { // This means that there is an ul_subframe that can be configured here LOG_D(PHY,"NFAPI: Clearing dci allocations for potential UL subframe %d\n",ul_subframe); - harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); - // clear DCI allocation maps for new subframe for (i=0; i<NUMBER_OF_UE_MAX; i++) { @@ -864,165 +817,160 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) } } } - for (i=0;i<number_dl_pdu;i++) { + + for (i=0; i<number_dl_pdu; i++) { dl_config_pdu = &DL_req->dl_config_request_body.dl_config_pdu_list[i]; + //LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_config_pdu->pdu_type); switch (dl_config_pdu->pdu_type) { - case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: - handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu); - eNB->pdcch_vars[NFAPI_SFNSF2SF(DL_req->sfn_sf)&1].num_dci++; - //LOG_E(PHY,"Incremented num_dci:%d but already set??? dl_config:num_dci:%d\n", eNB->pdcch_vars[subframe&1].num_dci, number_dci); - do_oai=1; - break; - case NFAPI_DL_CONFIG_BCH_PDU_TYPE: - AssertFatal(dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index<TX_req->tx_request_body.number_of_pdus, - "bch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n", - dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index, - TX_req->tx_request_body.number_of_pdus); - eNB->pbch_configured=1; - do_oai=1; - //LOG_D(PHY,"%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE TX:%d/%d RX:%d/%d TXREQ:%d/%d\n", - //__FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2SFN(TX_req->sfn_sf), NFAPI_SFNSF2SF(TX_req->sfn_sf)); - - - handle_nfapi_bch_pdu(eNB,proc,dl_config_pdu, - TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index].segments[0].segment_data); - break; - case NFAPI_DL_CONFIG_MCH_PDU_TYPE: - // handle_nfapi_mch_dl_pdu(eNB,dl_config_pdu); - break; - case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: - { + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: + handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu); + eNB->pdcch_vars[NFAPI_SFNSF2SF(DL_req->sfn_sf)&1].num_dci++; + //LOG_E(PHY,"Incremented num_dci:%d but already set??? dl_config:num_dci:%d\n", eNB->pdcch_vars[subframe&1].num_dci, number_dci); + do_oai=1; + break; + + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: + AssertFatal(dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index<TX_req->tx_request_body.number_of_pdus, + "bch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n", + dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index, + TX_req->tx_request_body.number_of_pdus); + eNB->pbch_configured=1; + do_oai=1; + //LOG_D(PHY,"%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE TX:%d/%d RX:%d/%d TXREQ:%d/%d\n", + //__FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2SFN(TX_req->sfn_sf), NFAPI_SFNSF2SF(TX_req->sfn_sf)); + handle_nfapi_bch_pdu(eNB,proc,dl_config_pdu, + TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index].segments[0].segment_data); + break; + + case NFAPI_DL_CONFIG_MCH_PDU_TYPE: + // handle_nfapi_mch_dl_pdu(eNB,dl_config_pdu); + break; + + case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: { nfapi_dl_config_dlsch_pdu_rel8_t *dlsch_pdu_rel8 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8; uint16_t pdu_index = dlsch_pdu_rel8->pdu_index; uint16_t tx_pdus = TX_req->tx_request_body.number_of_pdus; uint16_t invalid_pdu = pdu_index == -1; uint8_t *sdu = invalid_pdu ? NULL : pdu_index >= tx_pdus ? NULL : TX_req->tx_request_body.tx_pdu_list[pdu_index].segments[0].segment_data; - - LOG_D(PHY,"%s() [PDU:%d] NFAPI_DL_CONFIG_DLSCH_PDU_TYPE SFN/SF:%04d%d TX:%d/%d RX:%d/%d transport_blocks:%d pdu_index:%d sdu:%p\n", - __FUNCTION__, i, - NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf), - proc->frame_tx, proc->subframe_tx, - proc->frame_rx, proc->subframe_rx, - dlsch_pdu_rel8->transport_blocks, pdu_index, sdu); - - /* - AssertFatal(dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index<TX_req->tx_request_body.number_of_pdus, - "dlsch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n", - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index, - TX_req->tx_request_body.number_of_pdus); - */ - AssertFatal((dlsch_pdu_rel8->transport_blocks<3) && - (dlsch_pdu_rel8->transport_blocks>0), - "dlsch_pdu_rel8->transport_blocks = %d not in [1,2]\n", - dlsch_pdu_rel8->transport_blocks); - if (1)//sdu != NULL) - { - handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu); - } - else - { - dont_send=1; - - LOG_E(MAC,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index, NFAPI_SFNSF2DEC(TX_req->sfn_sf), tx_pdus); + LOG_D(PHY,"%s() [PDU:%d] NFAPI_DL_CONFIG_DLSCH_PDU_TYPE SFN/SF:%04d%d TX:%d/%d RX:%d/%d transport_blocks:%d pdu_index:%d sdu:%p\n", + __FUNCTION__, i, + NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf), + proc->frame_tx, proc->subframe_tx, + proc->frame_rx, proc->subframe_rx, + dlsch_pdu_rel8->transport_blocks, pdu_index, sdu); + /* + AssertFatal(dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index<TX_req->tx_request_body.number_of_pdus, + "dlsch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n", + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index, + TX_req->tx_request_body.number_of_pdus); + */ + AssertFatal((dlsch_pdu_rel8->transport_blocks<3) && + (dlsch_pdu_rel8->transport_blocks>0), + "dlsch_pdu_rel8->transport_blocks = %d not in [1,2]\n", + dlsch_pdu_rel8->transport_blocks); + + if (1) { //sdu != NULL) + handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu); + } else { + dont_send=1; + LOG_E(MAC,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index, + NFAPI_SFNSF2DEC(TX_req->sfn_sf), tx_pdus); + } + + // Send the data first so that the DL_CONFIG can just pluck it out of the buffer + // DJP - OAI was here - moved to bottom + do_oai=1; + /* + if (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == eNB->preamble_list[0].preamble_rel8.rnti) {// is RAR pdu + + LOG_D(PHY,"Frame %d, Subframe %d: Received LTE RAR pdu, programming based on UL Grant\n",frame,subframe); + generate_eNB_ulsch_params_from_rar(eNB, + TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, + frame, + subframe); + + } */ } + break; - // Send the data first so that the DL_CONFIG can just pluck it out of the buffer - // DJP - OAI was here - moved to bottom - do_oai=1; + case NFAPI_DL_CONFIG_PCH_PDU_TYPE: + // handle_nfapi_pch_pdu(eNB,dl_config_pdu); + break; - /* - if (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == eNB->preamble_list[0].preamble_rel8.rnti) {// is RAR pdu + case NFAPI_DL_CONFIG_PRS_PDU_TYPE: + // handle_nfapi_prs_pdu(eNB,dl_config_pdu); + break; - LOG_D(PHY,"Frame %d, Subframe %d: Received LTE RAR pdu, programming based on UL Grant\n",frame,subframe); - generate_eNB_ulsch_params_from_rar(eNB, - TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data, - frame, - subframe); + case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: + // handle_nfapi_csi_rs_pdu(eNB,dl_config_pdu); + break; - } */ - } - break; - case NFAPI_DL_CONFIG_PCH_PDU_TYPE: - // handle_nfapi_pch_pdu(eNB,dl_config_pdu); - break; - case NFAPI_DL_CONFIG_PRS_PDU_TYPE: - // handle_nfapi_prs_pdu(eNB,dl_config_pdu); - break; - case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: - // handle_nfapi_csi_rs_pdu(eNB,dl_config_pdu); - break; - case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: - // handle_nfapi_epdcch_pdu(eNB,dl_config_pdu); - break; + case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: + // handle_nfapi_epdcch_pdu(eNB,dl_config_pdu); + break; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: - handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu); - eNB->mpdcch_vars[subframe&1].num_dci++; - break; -#endif + + case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: + handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu); + eNB->mpdcch_vars[subframe&1].num_dci++; + break; +#endif } } - - if (nfapi_mode && do_oai && !dont_send) { - oai_nfapi_tx_req(Sched_INFO->TX_req); + if ((NFAPI_MODE!=NFAPI_MONOLITHIC) && do_oai && !dont_send) { + oai_nfapi_tx_req(Sched_INFO->TX_req); oai_nfapi_dl_config_req(Sched_INFO->DL_req); // DJP - .dl_config_request_body.dl_config_pdu_list[0]); // DJP - FIXME TODO - yuk - only copes with 1 pdu } - if (nfapi_mode && number_hi_dci0_pdu!=0) { + if ((NFAPI_MODE!=NFAPI_MONOLITHIC) && number_hi_dci0_pdu!=0) { oai_nfapi_hi_dci0_req(HI_DCI0_req); eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci=0; eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_pdcch_symbols=0; } - for (i=0;i<number_hi_dci0_pdu;i++) { - + for (i=0; i<number_hi_dci0_pdu; i++) { hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i]; - LOG_D(PHY,"NFAPI: hi_dci0_pdu %d : type %d\n",i,hi_dci0_req_pdu->pdu_type); switch (hi_dci0_req_pdu->pdu_type) { - - case NFAPI_HI_DCI0_DCI_PDU_TYPE: - - handle_nfapi_hi_dci0_dci_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu); - eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci++; - break; - - case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: - handle_nfapi_hi_dci0_mpdcch_dci_pdu(eNB,proc,hi_dci0_req_pdu); - eNB->mpdcch_vars[subframe&1].num_dci++; - break; - - case NFAPI_HI_DCI0_HI_PDU_TYPE: - handle_nfapi_hi_dci0_hi_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu); - break; + case NFAPI_HI_DCI0_DCI_PDU_TYPE: + handle_nfapi_hi_dci0_dci_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu); + eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci++; + break; + + case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: + handle_nfapi_hi_dci0_mpdcch_dci_pdu(eNB,proc,hi_dci0_req_pdu); + eNB->mpdcch_vars[subframe&1].num_dci++; + break; + + case NFAPI_HI_DCI0_HI_PDU_TYPE: + handle_nfapi_hi_dci0_hi_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu); + break; } } - if (nfapi_mode) { - if (number_ul_pdu>0) - { + if (NFAPI_MODE!=NFAPI_MONOLITHIC) { + if (number_ul_pdu>0) { //LOG_D(PHY, "UL_CONFIG to send to PNF\n"); oai_nfapi_ul_config_req(UL_req); UL_req->ul_config_request_body.number_of_pdus=0; number_ul_pdu=0; } - } - else { - for (i=0;i<number_ul_pdu;i++) { + } else { + for (i=0; i<number_ul_pdu; i++) { ul_config_pdu = &UL_req->ul_config_request_body.ul_config_pdu_list[i]; LOG_D(PHY,"NFAPI: ul_pdu %d : type %d\n",i,ul_config_pdu->pdu_type); AssertFatal(ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE || - ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE - , - "Optional UL_PDU type %d not supported\n",ul_config_pdu->pdu_type); + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE || + ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE + , + "Optional UL_PDU type %d not supported\n",ul_config_pdu->pdu_type); handle_nfapi_ul_pdu(eNB,proc,ul_config_pdu,UL_req->sfn_sf>>4,UL_req->sfn_sf&0xf,UL_req->ul_config_request_body.srs_present); } } @@ -1030,22 +978,18 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) /*Dummy functions*/ -int memcpy_dl_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req) -{ - return 0; +int memcpy_dl_config_req (nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) { + return 0; } -int memcpy_ul_config_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req) -{ - return 0; +int memcpy_ul_config_req (nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) { + return 0; } -int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req) -{ - return 0; +int memcpy_hi_dci0_req (nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) { + return 0; } -int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req) -{ - return 0; +int memcpy_tx_req (nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) { + return 0; } diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 7750f614a576235a854919b64632fcdbcc4552b0..3b3b9336d4e482481680636e0b5fe936e6c42fd6 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -35,7 +35,7 @@ #include "SCHED/sched_eNB.h" #include "SCHED/sched_common_extern.h" #include "PHY/LTE_ESTIMATION/lte_estimation.h" -#include "nfapi_interface.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "fapi_l1.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -45,26 +45,18 @@ #include <time.h> -#if defined(ENABLE_ITTI) #include "intertask_interface.h" -#endif - -extern uint8_t nfapi_mode; -int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) -{ +int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) { uint32_t Nre,sumKr,MPR_x100,Kr,r; uint16_t beta_offset_pusch; - DevAssert( UE_id < NUMBER_OF_UE_MAX+1 ); DevAssert( harq_pid < 8 ); - Nre = eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_initial * - eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12; - + eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12; sumKr = 0; for (r=0; r<eNB->ulsch[UE_id]->harq_processes[harq_pid]->C; r++) { @@ -82,10 +74,8 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t MPR_x100 = 100*sumKr/Nre; // Note: MPR=is the effective spectral efficiency of the PUSCH // FK 20140908 sumKr is only set after the ulsch_encoding - beta_offset_pusch = 8; //(eNB->ulsch[UE_id]->harq_processes[harq_pid]->control_only == 1) ? eNB->ulsch[UE_id]->beta_offset_cqi_times8:8; - DevAssert( UE_id < NUMBER_OF_UE_MAX ); //#warning "This condition happens sometimes. Need more investigation" // navid //DevAssert( MPR_x100/6 < 100 ); @@ -103,9 +93,7 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t } -int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid) -{ - +int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid) { int8_t UE_id; if ((RC.eNB == NULL) || (module_idP > RC.nb_inst) || (CC_id > RC.nb_CC[module_idP])) { @@ -126,30 +114,21 @@ int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rn int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); -lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subframe) -{ - +lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subframe) { return(subframe_select(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe)); - } void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { - - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) MCH_PDU *mch_pduP=NULL; // uint8_t sync_area=255; #endif - int subframe = proc->subframe_tx; - AssertFatal (1 == 0, "pmch not tested for the moment, exiting\n"); - // This is DL-Cell spec pilots in Control region generate_pilots_slot (eNB, eNB->common_vars.txdataF, AMP, subframe << 1, 1); - - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + // if mcch is active, send regardless of the node type: eNB or RN // when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing /* @@ -160,15 +139,15 @@ void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { */ if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0 LOG_D(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n", - eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->mcs, - eNB->dlsch_MCH->harq_processes[0]->TBS>>3); + eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->mcs, + eNB->dlsch_MCH->harq_processes[0]->TBS>>3); else { LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n", - eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->sync_area, - (mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment"); + eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->sync_area, + (mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment"); mch_pduP = NULL; } - + if (mch_pduP) { fill_eNB_dlsch_MCH (eNB, mch_pduP->mcs, 1, 0); // Generate PMCH @@ -181,26 +160,23 @@ void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { } void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { - LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int **txdataF = eNB->common_vars.txdataF; uint8_t *pbch_pdu=&eNB->pbch_pdu[0]; - - //LOG_D(PHY,"common_signal_procedures: frame %d, subframe %d fdd:%s dir:%s\n",frame,subframe,fp->frame_type == FDD?"FDD":"TDD", subframe_select(fp,subframe) == SF_DL?"DL":"UL?"); - + //LOG_D(PHY,"common_signal_procedures: frame %d, subframe %d fdd:%s dir:%s\n",frame,subframe,fp->frame_type == FDD?"FDD":"TDD", subframe_select(fp,subframe) == SF_DL?"DL":"UL?"); // generate Cell-Specific Reference Signals for both slots VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1); if(subframe_select(fp,subframe) == SF_S) generate_pilots_slot(eNB, - txdataF, - AMP, - subframe<<1,1); + txdataF, + AMP, + subframe<<1,1); else generate_pilots_slot(eNB, - txdataF, - AMP, - subframe<<1,0); + txdataF, + AMP, + subframe<<1,0); // check that 2nd slot is for DL if (subframe_select (fp, subframe) == SF_DL) @@ -208,35 +184,32 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX, 0); - // First half of PSS/SSS (FDD, slot 0) if (subframe == 0) { if (fp->frame_type == FDD) { generate_pss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 6 : 5, 0); generate_sss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 5 : 4, 0); - } - - /// First half of SSS (TDD, slot 1) if (fp->frame_type == TDD) { generate_sss (txdataF, AMP, fp, (fp->Ncp == NORMAL) ? 6 : 5, 1); } + // generate PBCH (Physical Broadcast CHannel) info /// generate PBCH if ((frame&3)==0) { //AssertFatal(eNB->pbch_configured==1,"PBCH was not configured by MAC\n"); if (eNB->pbch_configured!=1) return; + eNB->pbch_configured=0; } + T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_BUFFER(pbch_pdu, 3)); - generate_pbch (&eNB->pbch, txdataF, AMP, fp, pbch_pdu, frame & 3); - } else if ((subframe == 1) && (fp->frame_type == TDD)) { generate_pss (txdataF, AMP, fp, 2, 2); } @@ -244,7 +217,6 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { else if ((subframe == 5) && (fp->frame_type == FDD)) { generate_pss (txdataF, AMP, &eNB->frame_parms, (fp->Ncp == NORMAL) ? 6 : 5, 10); generate_sss (txdataF, AMP, &eNB->frame_parms, (fp->Ncp == NORMAL) ? 5 : 4, 10); - } // Second-half of SSS (TDD, slot 11) else if ((subframe == 5) && (fp->frame_type == TDD)) { @@ -254,73 +226,68 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { else if ((subframe == 6) && (fp->frame_type == TDD)) { generate_pss (txdataF, AMP, fp, 2, 12); } - } void pdsch_procedures(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - int harq_pid, - LTE_eNB_DLSCH_t *dlsch, - LTE_eNB_DLSCH_t *dlsch1, - LTE_eNB_UE_stats *ue_stats, - int ra_flag) { - + L1_rxtx_proc_t *proc, + int harq_pid, + LTE_eNB_DLSCH_t *dlsch, + LTE_eNB_DLSCH_t *dlsch1, + LTE_eNB_UE_stats *ue_stats, + int ra_flag) { int frame=proc->frame_tx; int subframe=proc->subframe_tx; LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid]; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - if (dlsch->rnti == 0x02) {//frame < 200) { - - LOG_D(PHY, - "[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d, subframe %d: Generating PDSCH/DLSCH with input size = %"PRIu16", pdsch_start %d, G %d, nb_rb %"PRIu16", rb0 %x, rb1 %x, TBS %"PRIu16", pmi_alloc %"PRIx64", rv %"PRIu8" (round %"PRIu8")\n", - eNB->Mod_id, dlsch->rnti,harq_pid, - frame, subframe, dlsch_harq->TBS/8, dlsch_harq->pdsch_start, - get_G(fp, - dlsch_harq->nb_rb, - dlsch_harq->rb_alloc, - dlsch_harq->Qm, - dlsch_harq->Nl, - dlsch_harq->pdsch_start, - frame, - subframe, - dlsch_harq->mimo_mode==TM7?7:0), - dlsch_harq->nb_rb, - dlsch_harq->rb_alloc[0], - dlsch_harq->rb_alloc[1], - dlsch_harq->TBS, - pmi2hex_2Ar1(dlsch_harq->pmi_alloc), - dlsch_harq->rvidx, - dlsch_harq->round); - } + if (dlsch->rnti != 0xffff) {//frame < 200) { + LOG_D(PHY, + "[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d, subframe %d: Generating PDSCH/DLSCH (type %d) with input size = %"PRIu16", pdsch_start %d, G %d, nb_rb %"PRIu16", rb0 %x, rb1 %x, TBS %"PRIu16", pmi_alloc %"PRIx64", rv %"PRIu8" (round %"PRIu8")\n", + eNB->Mod_id, dlsch->rnti,harq_pid, + frame, subframe, dlsch->ue_type,dlsch_harq->TBS/8, dlsch_harq->pdsch_start, + get_G(fp, + dlsch_harq->nb_rb, + dlsch_harq->rb_alloc, + dlsch_harq->Qm, + dlsch_harq->Nl, + dlsch_harq->pdsch_start, + frame, + subframe, + dlsch_harq->mimo_mode==TM7?7:0), + dlsch_harq->nb_rb, + dlsch_harq->rb_alloc[0], + dlsch_harq->rb_alloc[1], + dlsch_harq->TBS, + pmi2hex_2Ar1(dlsch_harq->pmi_alloc), + dlsch_harq->rvidx, + dlsch_harq->round); + } MSC_LOG_TX_MESSAGE( - MSC_PHY_ENB,MSC_PHY_UE, - NULL,0, - "%05u:%02u PDSCH/DLSCH input size = %"PRIu16", G %d, nb_rb %"PRIu16", TBS %"PRIu16", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")", - frame, subframe, - dlsch_harq->TBS/8, - get_G(fp, - dlsch_harq->nb_rb, - dlsch_harq->rb_alloc, - dlsch_harq->Qm, - dlsch_harq->Nl, - dlsch_harq->pdsch_start, - frame, - subframe, - dlsch_harq->mimo_mode==TM7?7:0), - dlsch_harq->nb_rb, - dlsch_harq->TBS, - pmi2hex_2Ar1(dlsch_harq->pmi_alloc), - dlsch_harq->rvidx, - dlsch_harq->round); - - - + MSC_PHY_ENB,MSC_PHY_UE, + NULL,0, + "%05u:%02u PDSCH/DLSCH input size = %"PRIu16", G %d, nb_rb %"PRIu16", TBS %"PRIu16", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")", + frame, subframe, + dlsch_harq->TBS/8, + get_G(fp, + dlsch_harq->nb_rb, + dlsch_harq->rb_alloc, + dlsch_harq->Qm, + dlsch_harq->Nl, + dlsch_harq->pdsch_start, + frame, + subframe, + dlsch_harq->mimo_mode==TM7?7:0), + dlsch_harq->nb_rb, + dlsch_harq->TBS, + pmi2hex_2Ar1(dlsch_harq->pmi_alloc), + dlsch_harq->rvidx, + dlsch_harq->round); + if (ue_stats) ue_stats->dlsch_sliding_cnt++; - + if (dlsch_harq->round == 0) { if (ue_stats) ue_stats->dlsch_trials[harq_pid][0]++; @@ -333,87 +300,81 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, #endif } + if (dlsch->rnti!=0xffff) LOG_D(PHY,"Generating DLSCH/PDSCH pdu:%p pdsch_start:%d frame:%d subframe:%d nb_rb:%d rb_alloc:%d Qm:%d Nl:%d round:%d\n", + dlsch_harq->pdu,dlsch_harq->pdsch_start,frame,subframe,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0],dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round); - LOG_D(PHY,"Generating DLSCH/PDSCH pdu:%p pdsch_start:%d frame:%d subframe:%d nb_rb:%d rb_alloc:%d Qm:%d Nl:%d round:%d\n", - dlsch_harq->pdu,dlsch_harq->pdsch_start,frame,subframe,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0],dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round); - // 36-212 - if (nfapi_mode == 0 || nfapi_mode == 1) { // monolthic OR PNF - do not need turbo encoding on VNF - - if (dlsch_harq->pdu==NULL){ - LOG_E(PHY,"dlsch_harq->pdu == NULL SFN/SF:%04d%d dlsch[rnti:%x] dlsch_harq[pdu:%p pdsch_start:%d Qm:%d Nl:%d round:%d nb_rb:%d rb_alloc[0]:%d]\n", frame,subframe,dlsch->rnti, dlsch_harq->pdu,dlsch_harq->pdsch_start,dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0]); + // 36-212 + if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { // monolthic OR PNF - do not need turbo encoding on VNF + if (dlsch_harq->pdu==NULL) { + LOG_E(PHY,"dlsch_harq->pdu == NULL SFN/SF:%04d%d dlsch[rnti:%x] dlsch_harq[pdu:%p pdsch_start:%d Qm:%d Nl:%d round:%d nb_rb:%d rb_alloc[0]:%d]\n", frame,subframe,dlsch->rnti, dlsch_harq->pdu, + dlsch_harq->pdsch_start,dlsch_harq->Qm,dlsch_harq->Nl,dlsch_harq->round,dlsch_harq->nb_rb,dlsch_harq->rb_alloc[0]); return; } start_meas(&eNB->dlsch_encoding_stats); - dlsch_encoding_all(eNB, - dlsch_harq->pdu, - dlsch_harq->pdsch_start, - dlsch, - frame, - subframe, - &eNB->dlsch_rate_matching_stats, - &eNB->dlsch_turbo_encoding_stats, - &eNB->dlsch_turbo_encoding_waiting_stats, - &eNB->dlsch_turbo_encoding_main_stats, - &eNB->dlsch_turbo_encoding_wakeup_stats0, - &eNB->dlsch_turbo_encoding_wakeup_stats1, - &eNB->dlsch_interleaving_stats); - + dlsch_harq->pdu, + dlsch_harq->pdsch_start, + dlsch, + frame, + subframe, + &eNB->dlsch_rate_matching_stats, + &eNB->dlsch_turbo_encoding_stats, + &eNB->dlsch_turbo_encoding_waiting_stats, + &eNB->dlsch_turbo_encoding_main_stats, + &eNB->dlsch_turbo_encoding_wakeup_stats0, + &eNB->dlsch_turbo_encoding_wakeup_stats1, + &eNB->dlsch_interleaving_stats); stop_meas(&eNB->dlsch_encoding_stats); - if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) - { - print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr); - } + + if(eNB->dlsch_encoding_stats.p_time>500*3000 && opp_enabled == 1) { + print_meas_now(&eNB->dlsch_encoding_stats,"total coding",stderr); + } + // 36-211 start_meas(&eNB->dlsch_scrambling_stats); dlsch_scrambling(fp, - 0, - dlsch, - harq_pid, - get_G(fp, - dlsch_harq->nb_rb, - dlsch_harq->rb_alloc, - dlsch_harq->Qm, - dlsch_harq->Nl, - dlsch_harq->pdsch_start, - frame,subframe, - 0), - 0, - frame, - subframe<<1); + 0, + dlsch, + harq_pid, + get_G(fp, + dlsch_harq->nb_rb, + dlsch_harq->rb_alloc, + dlsch_harq->Qm, + dlsch_harq->Nl, + dlsch_harq->pdsch_start, + frame,subframe, + 0), + 0, + frame, + subframe<<1); stop_meas(&eNB->dlsch_scrambling_stats); - start_meas(&eNB->dlsch_modulation_stats); - - dlsch_modulation(eNB, - eNB->common_vars.txdataF, - AMP, - frame, - subframe, - dlsch_harq->pdsch_start, - dlsch, - dlsch1); - + eNB->common_vars.txdataF, + AMP, + frame, + subframe, + dlsch_harq->pdsch_start, + dlsch, + dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL); stop_meas(&eNB->dlsch_modulation_stats); } + #ifdef PHY_TX_THREAD dlsch->active[subframe] = 0; #else dlsch->active = 0; #endif dlsch_harq->round++; - LOG_D(PHY,"Generating DLSCH/PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round); } void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - int do_meas) -{ + L1_rxtx_proc_t *proc, + int do_meas) { int frame=proc->frame_tx; int subframe=proc->subframe_tx; uint32_t i,aa; @@ -429,982 +390,951 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; LTE_UL_eNB_HARQ_t *ulsch_harq; - - if ((fp->frame_type == TDD) && (subframe_select (fp, subframe) == SF_UL)) return; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+(eNB->CC_id),1); + if (do_meas==1) start_meas(&eNB->phy_proc_tx); + if (do_meas==1) start_meas(&eNB->dlsch_common_and_dci); // clear the transmit data array for the current subframe for (aa = 0; aa < fp->nb_antenna_ports_eNB; aa++) { memset (&eNB->common_vars.txdataF[aa][subframe * fp->ofdm_symbol_size * (fp->symbols_per_tti)], 0, fp->ofdm_symbol_size * (fp->symbols_per_tti) * sizeof (int32_t)); } - - - if (nfapi_mode == 0 || nfapi_mode == 1) { + + if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { if (is_pmch_subframe(frame,subframe,fp)) { pmch_procedures(eNB,proc); - } - else { + } else { // this is not a pmch subframe, so generate PSS/SSS/PBCH common_signal_procedures(eNB,proc->frame_tx, proc->subframe_tx); } } - - + // clear existing ulsch dci allocations before applying info from MAC (this is table ul_subframe = pdcch_alloc2ul_subframe (fp, subframe); ul_frame = pdcch_alloc2ul_frame (fp, frame, subframe); - - - + // clear previous allocation information for all UEs for (i = 0; i < NUMBER_OF_UE_MAX; i++) { if (eNB->dlsch[i][0]) eNB->dlsch[i][0]->subframe_tx[subframe] = 0; } - - + /* TODO: check the following test - in the meantime it is put back as it was before */ //if ((ul_subframe < 10)&& // (subframe_select(fp,ul_subframe)==SF_UL)) { // This means that there is a potential UL subframe that will be scheduled here if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be scheduled here for (i=0; i<NUMBER_OF_UE_MAX; i++) { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (eNB->ulsch[i] && eNB->ulsch[i]->ue_type >0) harq_pid = 0; - else + else #endif - harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); - + harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); + if (eNB->ulsch[i]) { - ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid]; - - /* Store first_rb and n_DMRS for correct PHICH generation below. - * For PHICH generation we need "old" values of last scheduling - * for this HARQ process. 'generate_eNB_dlsch_params' below will - * overwrite first_rb and n_DMRS and 'generate_phich_top', done - * after 'generate_eNB_dlsch_params', would use the "new" values - * instead of the "old" ones. - * - * This has been tested for FDD only, may be wrong for TDD. - * - * TODO: maybe we should restructure the code to be sure it - * is done correctly. The main concern is if the code - * changes and first_rb and n_DMRS are modified before - * we reach here, then the PHICH processing will be wrong, - * using wrong first_rb and n_DMRS values to compute - * ngroup_PHICH and nseq_PHICH. - * - * TODO: check if that works with TDD. - */ - ulsch_harq->previous_first_rb = ulsch_harq->first_rb; - ulsch_harq->previous_n_DMRS = ulsch_harq->n_DMRS; - + ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid]; + /* Store first_rb and n_DMRS for correct PHICH generation below. + * For PHICH generation we need "old" values of last scheduling + * for this HARQ process. 'generate_eNB_dlsch_params' below will + * overwrite first_rb and n_DMRS and 'generate_phich_top', done + * after 'generate_eNB_dlsch_params', would use the "new" values + * instead of the "old" ones. + * + * This has been tested for FDD only, may be wrong for TDD. + * + * TODO: maybe we should restructure the code to be sure it + * is done correctly. The main concern is if the code + * changes and first_rb and n_DMRS are modified before + * we reach here, then the PHICH processing will be wrong, + * using wrong first_rb and n_DMRS values to compute + * ngroup_PHICH and nseq_PHICH. + * + * TODO: check if that works with TDD. + */ + ulsch_harq->previous_first_rb = ulsch_harq->first_rb; + ulsch_harq->previous_n_DMRS = ulsch_harq->n_DMRS; } } } - - + num_pdcch_symbols = eNB->pdcch_vars[subframe&1].num_pdcch_symbols; num_dci = eNB->pdcch_vars[subframe&1].num_dci; LOG_D(PHY,"num_pdcch_symbols %"PRIu8",number dci %"PRIu8"\n",num_pdcch_symbols, num_dci); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO,num_pdcch_symbols); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME (VCD_SIGNAL_DUMPER_VARIABLES_DCI_INFO, (frame * 10) + subframe); - + if (num_dci > 0) LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %"PRIu8") num_pdcch_symbols:%d\n",eNB->Mod_id,frame, subframe, num_dci, num_pdcch_symbols); - - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1); - - if (nfapi_mode == 0 || nfapi_mode == 1) { + + if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { generate_dci_top(num_pdcch_symbols, - num_dci, - &eNB->pdcch_vars[subframe&1].dci_alloc[0], - 0, - AMP, - fp, - eNB->common_vars.txdataF, - subframe); - + num_dci, + &eNB->pdcch_vars[subframe&1].dci_alloc[0], + 0, + AMP, + fp, + eNB->common_vars.txdataF, + subframe); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) num_mdci = eNB->mpdcch_vars[subframe &1].num_dci; + if (num_mdci > 0) { - LOG_I (PHY, "[eNB %" PRIu8 "] Frame %d, subframe %d: Calling generate_mdci_top (mpdcch) (num_dci %" PRIu8 ")\n", eNB->Mod_id, frame, subframe, num_mdci); - + LOG_D (PHY, "[eNB %" PRIu8 "] Frame %d, subframe %d: Calling generate_mdci_top (mpdcch) (num_dci %" PRIu8 ")\n", eNB->Mod_id, frame, subframe, num_mdci); generate_mdci_top (eNB, frame, subframe, AMP, eNB->common_vars.txdataF); - } + #endif } if (do_meas==1) stop_meas(&eNB->dlsch_common_and_dci); + if (do_meas==1) start_meas(&eNB->dlsch_ue_specific); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); // Now scan UE specific DLSCH LTE_eNB_DLSCH_t *dlsch0,*dlsch1; + for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { - dlsch0 = eNB->dlsch[(uint8_t)UE_id][0]; - dlsch1 = eNB->dlsch[(uint8_t)UE_id][1]; - + dlsch0 = eNB->dlsch[(uint8_t)UE_id][0]; + dlsch1 = eNB->dlsch[(uint8_t)UE_id][1]; + if ((dlsch0)&&(dlsch0->rnti>0)&& #ifdef PHY_TX_THREAD - (dlsch0->active[subframe] == 1) + (dlsch0->active[subframe] == 1) #else - (dlsch0->active == 1) + (dlsch0->active == 1) #endif - ){ - + ) { // get harq_pid harq_pid = dlsch0->harq_ids[frame%2][subframe]; AssertFatal(harq_pid>=0,"harq_pid is negative\n"); - - if (harq_pid>=8) - { - LOG_E(PHY,"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x\n", harq_pid,UE_id,frame,subframe,dlsch0->rnti); - } - else - { - // generate pdsch - - pdsch_procedures(eNB, - proc, - harq_pid, - dlsch0, - dlsch1, - &eNB->UE_stats[(uint32_t)UE_id], - 0); - } - - - } - - - else if ((dlsch0)&&(dlsch0->rnti>0)&& + + if (harq_pid>=8) { +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + + if (dlsch0->ue_type==0) +#endif + LOG_E(PHY,"harq_pid:%d corrupt must be 0-7 UE_id:%d frame:%d subframe:%d rnti:%x [ %1d.%1d.%1d.%1d.%1d.%1d.%1d.%1d\n", harq_pid,UE_id,frame,subframe,dlsch0->rnti, + dlsch0->harq_ids[frame%2][0], + dlsch0->harq_ids[frame%2][1], + dlsch0->harq_ids[frame%2][2], + dlsch0->harq_ids[frame%2][3], + dlsch0->harq_ids[frame%2][4], + dlsch0->harq_ids[frame%2][5], + dlsch0->harq_ids[frame%2][6], + dlsch0->harq_ids[frame%2][7]); + } else { + // generate pdsch + pdsch_procedures(eNB, + proc, + harq_pid, + dlsch0, + dlsch1, + &eNB->UE_stats[(uint32_t)UE_id], + 0); + } + } else if ((dlsch0)&&(dlsch0->rnti>0)&& #ifdef PHY_TX_THREAD - (dlsch0->active[subframe] == 0) + (dlsch0->active[subframe] == 0) #else - (dlsch0->active == 0) + (dlsch0->active == 0) #endif - ){ + ) { // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later) dlsch0->subframe_tx[subframe]=0; } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); - } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PHICH,1); generate_phich_top(eNB, - proc, - AMP); + proc, + AMP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PHICH,0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+(eNB->CC_id),0); + if (do_meas==1) stop_meas(&eNB->dlsch_ue_specific); + if (do_meas==1) stop_meas(&eNB->phy_proc_tx); - } void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; - int i; - + if (is_srs_occasion_common (fp, frame, subframe)) { - - // Do SRS processing + // Do SRS processing // check if there is SRS and we have to use shortened format // TODO: check for exceptions in transmission of SRS together with ACK/NACK for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (eNB->soundingrs_ul_config_dedicated[i].active == 1) { - - - if (lte_srs_channel_estimation (fp, &eNB->common_vars, &eNB->srs_vars[i], &eNB->soundingrs_ul_config_dedicated[i], subframe, 0 /*eNB_id */ )) { - LOG_E (PHY, "problem processing SRS\n"); - } - eNB->soundingrs_ul_config_dedicated[i].active = 0; + if (lte_srs_channel_estimation (fp, &eNB->common_vars, &eNB->srs_vars[i], &eNB->soundingrs_ul_config_dedicated[i], subframe, 0 /*eNB_id */ )) { + LOG_E (PHY, "problem processing SRS\n"); + } + + eNB->soundingrs_ul_config_dedicated[i].active = 0; } } } } void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat) { - pthread_mutex_lock(&eNB->UL_INFO_mutex); nfapi_sr_indication_t *sr_ind = &eNB->UL_INFO.sr_ind; nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body; nfapi_sr_indication_pdu_t *pdu = &sr_ind_body->sr_pdu_list[sr_ind_body->number_of_srs]; - sr_ind->sfn_sf = frame<<4|subframe; sr_ind->header.message_id = NFAPI_RX_SR_INDICATION; - sr_ind_body->tl.tag = NFAPI_SR_INDICATION_BODY_TAG; - pdu->instance_length = 0; // don't know what to do with this // pdu->rx_ue_information.handle = handle; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; - int SNRtimes10 = dB_fixed_times10(stat) - 300;//(10*eNB->measurements.n0_power_dB[0]); - - - pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; - + if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0; else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi=255; else pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5; + pdu->ul_cqi_information.channel = 0; - sr_ind_body->number_of_srs++; pthread_mutex_unlock(&eNB->UL_INFO_mutex); } -void uci_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) +//----------------------------------------------------------------------------- +/* + * Main handler of PUCCH received + */ +void +uci_procedures(PHY_VARS_eNB *eNB, + L1_rxtx_proc_t *proc) +//----------------------------------------------------------------------------- { - LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; - uint8_t SR_payload = 0,pucch_b0b1[4][2]= {{0,0},{0,0},{0,0},{0,0}},harq_ack[4]={0,0,0,0}; - int32_t metric[4]={0,0,0,0},metric_SR=0,max_metric=0; + uint8_t SR_payload = 0; + uint8_t pucch_b0b1[4][2] = {{0,0},{0,0},{0,0},{0,0}}; + uint8_t harq_ack[4] = {0,0,0,0}; + uint16_t tdd_multiplexing_mask = 0; + int32_t metric[4] = {0,0,0,0}; + int32_t metric_SR = 0; + int32_t max_metric = 0; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; - int i; - LTE_eNB_UCI *uci; - uint16_t tdd_multiplexing_mask=0; - - for (i=0;i<NUMBER_OF_UE_MAX;i++) { - - - uci = &eNB->uci_vars[i]; + LTE_eNB_UCI *uci = NULL; + LTE_DL_FRAME_PARMS *fp = &(eNB->frame_parms); + + for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { + uci = &(eNB->uci_vars[i]); + if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) { + LOG_D(PHY,"Frame %d, subframe %d: Running uci procedures (type %d) for %d \n", + frame, + subframe, + uci->type, + i); - LOG_D (PHY, "Frame %d, subframe %d: Running uci procedures (type %d) for %d \n", frame, subframe, uci->type, i); uci->active = 0; - + // Null out PUCCH PRBs for noise measurement switch (fp->N_RB_UL) { - case 6: - eNB->rb_mask_ul[0] |= (0x1 | (1 << 5)); //position 5 - break; - case 15: - eNB->rb_mask_ul[0] |= (0x1 | (1 << 14)); // position 14 - break; - case 25: - eNB->rb_mask_ul[0] |= (0x1 | (1 << 24)); // position 24 - break; - case 50: - eNB->rb_mask_ul[0] |= 0x1; - eNB->rb_mask_ul[1] |= (1 << 17); // position 49 (49-32) - break; - case 75: - eNB->rb_mask_ul[0] |= 0x1; - eNB->rb_mask_ul[2] |= (1 << 10); // position 74 (74-64) - break; - case 100: - eNB->rb_mask_ul[0] |= 0x1; - eNB->rb_mask_ul[3] |= (1 << 3); // position 99 (99-96) - break; - default: - LOG_E (PHY, "Unknown number for N_RB_UL %d\n", fp->N_RB_UL); - break; + case 6: + eNB->rb_mask_ul[0] |= (0x1 | (1 << 5)); // position 5 + break; + case 15: + eNB->rb_mask_ul[0] |= (0x1 | (1 << 14)); // position 14 + break; + case 25: + eNB->rb_mask_ul[0] |= (0x1 | (1 << 24)); // position 24 + break; + case 50: + eNB->rb_mask_ul[0] |= 0x1; + eNB->rb_mask_ul[1] |= (1 << 17); // position 49 (49-32) + break; + case 75: + eNB->rb_mask_ul[0] |= 0x1; + eNB->rb_mask_ul[2] |= (1 << 10); // position 74 (74-64) + break; + case 100: + eNB->rb_mask_ul[0] |= 0x1; + eNB->rb_mask_ul[3] |= (1 << 3); // position 99 (99-96) + break; + default: + LOG_E(PHY,"Unknown number for N_RB_UL %d\n", fp->N_RB_UL); + break; } + SR_payload = 0; + switch (uci->type) { - case SR: - case HARQ_SR: - - metric_SR = rx_pucch(eNB, - uci->pucch_fmt, - i, - uci->n_pucch_1_0_sr[0], - 0, // n2_pucch - uci->srs_active, // shortened format - &SR_payload, - frame, - subframe, - PUCCH1_THRES); - LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR is %d (uci.type %d SR n1pucch is %d)\n", - eNB->Mod_id, - uci->rnti, - frame, - subframe, - SR_payload, - uci->type, - uci->n_pucch_1_0_sr[0]); - if (uci->type == SR) { - if (SR_payload == 1) { - fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR); - break; - } - else { - break; - } - } - case HARQ: - if (fp->frame_type == FDD) { - LOG_D(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n", - frame,subframe,i, - uci->pucch_fmt,uci->type, - uci->frame,uci->subframe,uci->n_pucch_1[0][0], - SR_payload); - - metric[0] = rx_pucch(eNB, - uci->pucch_fmt, - i, - uci->n_pucch_1[0][0], - 0, //n2_pucch - uci->srs_active, // shortened format - pucch_b0b1[0], - frame, - subframe, - PUCCH1a_THRES); - - - /* cancel SR detection if reception on n1_pucch0 is better than on SR PUCCH resource index, otherwise send it up to MAC */ - if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0; - else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR); - - if (uci->type==HARQ_SR && metric[0] <= metric_SR) { - /* when transmitting ACK/NACK on SR PUCCH resource index, SR payload is always 1 */ - SR_payload = 1; - - metric[0]=rx_pucch(eNB, - uci->pucch_fmt, - i, - uci->n_pucch_1_0_sr[0], - 0, //n2_pucch - uci->srs_active, // shortened format - pucch_b0b1[0], - frame, - subframe, - PUCCH1a_THRES); - } - - - LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n", - eNB->Mod_id, - uci->rnti, - frame,subframe, - pucch_b0b1[0][0],metric[0]); - - uci->stat = metric[0]; - fill_uci_harq_indication(eNB,uci,frame,subframe,pucch_b0b1[0],0,0xffff); - - } - else { // frame_type == TDD - LOG_D(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n", - frame,subframe,i, - uci->pucch_fmt,uci->type, - uci->frame,uci->subframe,uci->n_pucch_1[0][0], - SR_payload); + case SR: + case HARQ_SR: { + int pucch1_thres = (uci->ue_type == 0) ? eNB->pucch1_DTX_threshold : eNB->pucch1_DTX_threshold_emtc[0]; + metric_SR = rx_pucch(eNB, + uci->pucch_fmt, + i, + uci->n_pucch_1_0_sr[0], + 0, // n2_pucch + uci->srs_active, // shortened format + &SR_payload, + frame, + subframe, + pucch1_thres +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,uci->ue_type +#endif + ); + LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR is %d (uci.type %d SR n1pucch is %d)\n", + eNB->Mod_id, + uci->rnti, + frame, + subframe, + SR_payload, + uci->type, + uci->n_pucch_1_0_sr[0]); + + if (uci->type == SR) { + if (SR_payload == 1) { + fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR); + break; + } else { + break; + } + } + } + + case HARQ: { + int pucch1ab_thres = (uci->ue_type == 0) ? eNB->pucch1ab_DTX_threshold : eNB->pucch1ab_DTX_threshold_emtc[0]; + + if (fp->frame_type == FDD) { + LOG_D(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n", + frame,subframe,i, + uci->pucch_fmt,uci->type, + uci->frame,uci->subframe,uci->n_pucch_1[0][0], + SR_payload); + metric[0] = rx_pucch(eNB, + uci->pucch_fmt, + i, + uci->n_pucch_1[0][0], + 0, //n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[0], + frame, + subframe, + pucch1ab_thres +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,uci->ue_type +#endif + ); + + //dump_ulsch(eNB,frame,subframe,0,0); exit(-1); + + /* cancel SR detection if reception on n1_pucch0 is better than on SR PUCCH resource index, otherwise send it up to MAC */ + if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0; + else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR); + + if (uci->type==HARQ_SR && metric[0] <= metric_SR) { + /* when transmitting ACK/NACK on SR PUCCH resource index, SR payload is always 1 */ + SR_payload = 1; + metric[0]=rx_pucch(eNB, + uci->pucch_fmt, + i, + uci->n_pucch_1_0_sr[0], + 0, //n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[0], + frame, + subframe, + pucch1ab_thres +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,uci->ue_type +#endif + ); + } + + LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n", + eNB->Mod_id, + uci->rnti, + frame,subframe, + pucch_b0b1[0][0],metric[0]); + uci->stat = metric[0]; + fill_uci_harq_indication(eNB,uci,frame,subframe,pucch_b0b1[0],0,0xffff); + } else { // frame_type == TDD + LOG_D(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n", + frame,subframe,i, + uci->pucch_fmt,uci->type, + uci->frame,uci->subframe,uci->n_pucch_1[0][0], + SR_payload); #if 1 - metric[0] = rx_pucch(eNB, - uci->pucch_fmt, - i, - uci->n_pucch_1[0][0], - 0, //n2_pucch - uci->srs_active, // shortened format - pucch_b0b1[0], - frame, - subframe, - PUCCH1a_THRES); - if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0; - else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR); - - if (uci->type==HARQ_SR && metric[0] <= metric_SR) { - SR_payload = 1; - metric[0] = rx_pucch(eNB, - pucch_format1b, - i, - uci->n_pucch_1_0_sr[0], - 0, //n2_pucch - uci->srs_active, // shortened format - pucch_b0b1[0], - frame, - subframe, - PUCCH1a_THRES); - } + metric[0] = rx_pucch(eNB, + uci->pucch_fmt, + i, + uci->n_pucch_1[0][0], + 0, //n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[0], + frame, + subframe, + pucch1ab_thres +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,uci->ue_type +#endif + ); + + if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0; + else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR); + + if (uci->type==HARQ_SR && metric[0] <= metric_SR) { + SR_payload = 1; + metric[0] = rx_pucch(eNB, + pucch_format1b, + i, + uci->n_pucch_1_0_sr[0], + 0, //n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[0], + frame, + subframe, + pucch1ab_thres +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,uci->ue_type +#endif + ); + } + #else - // if SR was detected, use the n1_pucch from SR - if (SR_payload==1) { + + // if SR was detected, use the n1_pucch from SR + if (SR_payload==1) { #ifdef DEBUG_PHY_PROC - LOG_D (PHY, "[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n", eNB->Mod_id, - eNB->dlsch[UE_id][0]->rnti, frame, subframe, n1_pucch0, n1_pucch1, n1_pucch2, n1_pucch3, format); + LOG_D (PHY, "[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n", eNB->Mod_id, + eNB->dlsch[UE_id][0]->rnti, frame, subframe, n1_pucch0, n1_pucch1, n1_pucch2, n1_pucch3, format); #endif - - metric[0] = rx_pucch (eNB, pucch_format1b, i, uci->n_pucch_1_0_sr[0], 0, //n2_pucch - uci->srs_active, // shortened format - pucch_b0b1[0], frame, subframe, PUCCH1a_THRES + metric[0] = rx_pucch (eNB, pucch_format1b, i, uci->n_pucch_1_0_sr[0], 0, //n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[0], frame, subframe, + pucch1ab_thres #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,uci->ue_type + ,uci->ue_type #endif - ); - } else { //using assigned pucch resources + ); + } else { //using assigned pucch resources #ifdef DEBUG_PHY_PROC - LOG_D (PHY, "[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK M=%d (%d,%d,%d,%d) format %d\n", eNB->Mod_id, - eNB->dlsch[UE_id][0]->rnti, - frame, subframe, uci->num_pucch_resources, uci->n_pucch_1[res][0], uci->n_pucch_1[res][1], uci->n_pucch_1[res][2], uci->n_pucch_1[res][3], uci->pucch_fmt); + LOG_D (PHY, "[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK M=%d (%d,%d,%d,%d) format %d\n", eNB->Mod_id, + eNB->dlsch[UE_id][0]->rnti, + frame, subframe, uci->num_pucch_resources, uci->n_pucch_1[res][0], uci->n_pucch_1[res][1], uci->n_pucch_1[res][2], uci->n_pucch_1[res][3], uci->pucch_fmt); #endif - for (res = 0; res < uci->num_pucch_resources; res++) - metric[res] = rx_pucch (eNB, uci->pucch_fmt, i, uci->n_pucch_1[res][0], 0, // n2_pucch - uci->srs_active, // shortened format - pucch_b0b1[res], frame, subframe, PUCCH1a_THRES + + for (res = 0; res < uci->num_pucch_resources; res++) + metric[res] = rx_pucch (eNB, uci->pucch_fmt, i, uci->n_pucch_1[res][0], 0, // n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[res], frame, subframe, + pucch1ab_thres #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,uci->ue_type -#endif - ); - for (res=0;res<uci->num_pucch_resources;res++) - metric[res] = rx_pucch(eNB, - uci->pucch_fmt, - i, - uci->n_pucch_1[res][0], - 0, // n2_pucch - uci->srs_active, // shortened format - pucch_b0b1[res], - frame, - subframe, - PUCCH1a_THRES, + ,uci->ue_type +#endif + ); + + for (res=0; res<uci->num_pucch_resources; res++) + metric[res] = rx_pucch(eNB, + uci->pucch_fmt, + i, + uci->n_pucch_1[res][0], + 0, // n2_pucch + uci->srs_active, // shortened format + pucch_b0b1[res], + frame, + subframe, + pucch1ab_thres #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,uci->ue_type -#endif - ); - } + ,uci->ue_type +#endif + ); + } + #ifdef DEBUG_PHY_PROC - LOG_D(PHY,"RNTI %x type %d SR_payload %d Frame %d Subframe %d pucch_b0b1[0][0] %d pucch_b0b1[0][1] %d pucch_b0b1[1][0] %d pucch_b0b1[1][1] %d \n", - uci->rnti,uci->type,SR_payload,frame,subframe,pucch_b0b1[0][0],pucch_b0b1[0][1],pucch_b0b1[1][0],pucch_b0b1[1][1]); + LOG_D(PHY,"RNTI %x type %d SR_payload %d Frame %d Subframe %d pucch_b0b1[0][0] %d pucch_b0b1[0][1] %d pucch_b0b1[1][0] %d pucch_b0b1[1][1] %d \n", + uci->rnti,uci->type,SR_payload,frame,subframe,pucch_b0b1[0][0],pucch_b0b1[0][1],pucch_b0b1[1][0],pucch_b0b1[1][1]); #endif #endif - if (SR_payload == 1) { // this implements Table 7.3.1 from 36.213 - if (pucch_b0b1[0][0] == 4) { // there isn't a likely transmission - harq_ack[0] = 4; // DTX - } - else if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1) { // 1/4/7 ACKs - harq_ack[0] = 1; - } - else if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] != 1) { // 2/5/8 ACKs - harq_ack[0] = 2; - } - else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] == 1) { // 3/6/9 ACKs - harq_ack[0] = 3; - } - else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1) { // 0 ACKs, or at least one DL assignment missed - harq_ack[0] = 0; - } - uci->stat = metric[0]; - fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,2,0xffff); // special_bundling mode - } - else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==2)){ // multiplexing + no SR, implement Table 10.1.3-5 (Rel14) for multiplexing with M=2 - if (pucch_b0b1[0][0] == 4 || - pucch_b0b1[1][0] == 4) { // there isn't a likely transmission - harq_ack[0] = 4; // DTX - harq_ack[1] = 6; // NACK/DTX - } - else { - if (metric[1]>metric[0]) { - if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1){ - harq_ack[0] = 1; // ACK - harq_ack[1] = 1; // ACK - tdd_multiplexing_mask = 0x3; - } - else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1){ - harq_ack[0] = 6; // NACK/DTX - harq_ack[1] = 1; // ACK - tdd_multiplexing_mask = 0x2; - } - else { - harq_ack[0] = 4; // DTX - harq_ack[1] = 4; // DTX - } - } - else { - if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1){ - harq_ack[0] = 1; // ACK - harq_ack[1] = 6; // NACK/DTX - tdd_multiplexing_mask = 0x1; - } - else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1){ - harq_ack[0] = 2; // NACK - harq_ack[1] = 6; // NACK/DTX - } - else { - harq_ack[0] = 4; // DTX - harq_ack[1] = 4; // DTX - } - } - } - uci->stat = max(metric[0],metric[1]); - fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode - } //else if ((uci->tdd_bundling == 0) && (res==2)) - else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==3)){ // multiplexing + no SR, implement Table 10.1.3-6 (Rel14) for multiplexing with M=3 - - if (harq_ack[0] == 4 || - harq_ack[1] == 4 || - harq_ack[2] == 4) { // there isn't a likely transmission - harq_ack[0] = 4; // DTX - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 6; // NACK/DTX - max_metric = 0; - } - else { - - max_metric = max(metric[0],max(metric[1],metric[2])); - - if (metric[0]==max_metric) { - if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1){ - harq_ack[0] = 1; // ACK - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 6; // NACK/DTX - tdd_multiplexing_mask = 0x1; - } - else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1){ - harq_ack[0] = 2; // NACK - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 6; // NACK/DTX - } - else { - harq_ack[0] = 4; // DTX - harq_ack[1] = 4; // DTX - harq_ack[2] = 4; // DTX - } - } // if (metric[0]==max_metric) { - else if (metric[1]==max_metric) { - - if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1){ - harq_ack[0] = 1; // ACK - harq_ack[1] = 1; // ACK - harq_ack[2] = 6; // NACK/DTX - tdd_multiplexing_mask = 0x3; - } - else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1 ) { - harq_ack[0] = 6; // NACK/DTX - harq_ack[1] = 1; // ACK - harq_ack[2] = 6; // NACK/DTX - tdd_multiplexing_mask = 0x2; - } - else { - harq_ack[0] = 4; // DTX - harq_ack[1] = 4; // DTX - harq_ack[2] = 4; // DTX - } - } // if (metric[1]==max_metric) { - else { - if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1){ - harq_ack[0] = 1; // ACK - harq_ack[1] = 1; // ACK - harq_ack[2] = 1; // ACK - tdd_multiplexing_mask = 0x7; - } - else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) { - harq_ack[0] = 1; // ACK - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 1; // ACK - tdd_multiplexing_mask = 0x5; - } - else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) { - harq_ack[0] = 6; // NACK/DTX - harq_ack[1] = 1; // ACK - harq_ack[2] = 1; // ACK - tdd_multiplexing_mask = 0x6; - } - else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) { - harq_ack[0] = 6; // NACK/DTX - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 1; // ACK - tdd_multiplexing_mask = 0x4; - } - } - uci->stat = max_metric; - fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode - } - } //else if ((uci->tdd_bundling == 0) && (res==3)) - else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==4)){ // multiplexing + no SR, implement Table 10.1.3-7 (Rel14) for multiplexing with M=4 - if (pucch_b0b1[0][0] == 4 || - pucch_b0b1[1][0] == 4 || - pucch_b0b1[2][0] == 4 || - pucch_b0b1[3][0] == 4) { // there isn't a likely transmission - harq_ack[0] = 4; // DTX - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 6; // NACK/DTX - harq_ack[3] = 6; // NACK/DTX - max_metric = 0; - } else { - - max_metric = max(metric[0],max(metric[1],max(metric[2],metric[3]))); - - if (metric[0]==max_metric) { - if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] != 1){ - harq_ack[0] = 2; // NACK - harq_ack[1] = 4; // DTX - harq_ack[2] = 4; // DTX - harq_ack[3] = 4; // DTX - } - else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] == 1){ - harq_ack[0] = 1; // ACK - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 6; // NACK/DTX - harq_ack[3] = 1; // ACK - tdd_multiplexing_mask = 0x9; - } - else if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1){ - harq_ack[0] = 1; // ACK - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 6; // NACK/DTX - harq_ack[3] = 6; // NACK/DTX - tdd_multiplexing_mask = 0x1; - } - else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1){ - harq_ack[0] = 2; // NACK - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 6; // NACK/DTX - harq_ack[3] = 6; // NACK/DTX - } - - } - else if (metric[1]==max_metric) { - if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] == 1){ - harq_ack[0] = 1; // ACK - harq_ack[1] = 1; // ACK - harq_ack[2] = 1; // ACK - harq_ack[3] = 1; // ACK - tdd_multiplexing_mask = 0xF; - } - else if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1 ) { - harq_ack[0] = 1; // ACK - harq_ack[1] = 1; // ACK - harq_ack[2] = 6; // NACK/DTX - harq_ack[3] = 6; // NACK/DTX - tdd_multiplexing_mask = 0x3; - } - else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] != 1 ) { - harq_ack[0] = 6; // NACK/DTX - harq_ack[1] = 1; // ACK - harq_ack[2] = 1; // ACK - harq_ack[3] = 1; // ACK - tdd_multiplexing_mask = 0xE; - } - else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1 ) { - harq_ack[0] = 6; // NACK/DTX - harq_ack[1] = 1; // ACK - harq_ack[2] = 6; // NACK/DTX - harq_ack[3] = 6; // NACK/DTX - tdd_multiplexing_mask = 0x2; - } - } - else if (metric[2]==max_metric) { - if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1){ - harq_ack[0] = 1; // ACK - harq_ack[1] = 1; // ACK - harq_ack[2] = 1; // ACK - harq_ack[3] = 6; // NACK/DTX - tdd_multiplexing_mask = 0x7; - } - else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) { - harq_ack[0] = 1; // ACK - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 1; // ACK - harq_ack[3] = 6; // NACK/DTX - tdd_multiplexing_mask = 0x5; - } - else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) { - harq_ack[0] = 4; // NACK/DTX - harq_ack[1] = 1; // ACK - harq_ack[2] = 1; // ACK - harq_ack[3] = 4; // NACK/DTX - tdd_multiplexing_mask = 0x6; - } - else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) { - harq_ack[0] = 4; // NACK/DTX - harq_ack[1] = 4; // NACK/DTX - harq_ack[2] = 1; // ACK - harq_ack[3] = 4; // NACK/DTX - tdd_multiplexing_mask = 0x4; - } - } - else { // max_metric[3]=max_metric - if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1){ - harq_ack[0] = 1; // ACK - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 1; // ACK - harq_ack[3] = 1; // ACK - tdd_multiplexing_mask = 0xD; - } - else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) { - harq_ack[0] = 6; // NACK/DTX - harq_ack[1] = 1; // ACK - harq_ack[2] = 6; // NACK/DTX - harq_ack[3] = 1; // ACK - tdd_multiplexing_mask = 0xA; - } - else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) { - harq_ack[0] = 6; // NACK/DTX - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 1; // ACK - harq_ack[3] = 1; // ACK - tdd_multiplexing_mask = 0xC; - } - else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) { - harq_ack[0] = 6; // NACK/DTX - harq_ack[1] = 6; // NACK/DTX - harq_ack[2] = 6; // NACK/DTX - harq_ack[3] = 1; // ACK - tdd_multiplexing_mask = 0x8; - } - } - } - uci->stat = max_metric; - fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode - } // else if ((uci->tdd_bundling == 0) && (res==4)) - else { // bundling - harq_ack[0] = pucch_b0b1[0][0]; - harq_ack[1] = pucch_b0b1[0][1]; - uci->stat = metric[0]; - LOG_D(PHY,"bundling: (%d,%d), metric %d\n",harq_ack[0],harq_ack[1],uci->stat); - fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,0,0xffff); // special_bundling mode - } - + + if (SR_payload == 1) { // this implements Table 7.3.1 from 36.213 + if (pucch_b0b1[0][0] == 4) { // there isn't a likely transmission + harq_ack[0] = 4; // DTX + } else if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1) { // 1/4/7 ACKs + harq_ack[0] = 1; + } else if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] != 1) { // 2/5/8 ACKs + harq_ack[0] = 2; + } else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] == 1) { // 3/6/9 ACKs + harq_ack[0] = 3; + } else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1) { // 0 ACKs, or at least one DL assignment missed + harq_ack[0] = 0; + } + + uci->stat = metric[0]; + fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,2,0xffff); // special_bundling mode + } else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==2)) { // multiplexing + no SR, implement Table 10.1.3-5 (Rel14) for multiplexing with M=2 + if (pucch_b0b1[0][0] == 4 || + pucch_b0b1[1][0] == 4) { // there isn't a likely transmission + harq_ack[0] = 4; // DTX + harq_ack[1] = 6; // NACK/DTX + } else { + if (metric[1]>metric[0]) { + if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + tdd_multiplexing_mask = 0x3; + } else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + tdd_multiplexing_mask = 0x2; + } else { + harq_ack[0] = 4; // DTX + harq_ack[1] = 4; // DTX + } + } else { + if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x1; + } else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1) { + harq_ack[0] = 2; // NACK + harq_ack[1] = 6; // NACK/DTX + } else { + harq_ack[0] = 4; // DTX + harq_ack[1] = 4; // DTX + } + } + } + + uci->stat = max(metric[0],metric[1]); + fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode + } //else if ((uci->tdd_bundling == 0) && (res==2)) + else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==3)) { // multiplexing + no SR, implement Table 10.1.3-6 (Rel14) for multiplexing with M=3 + if (harq_ack[0] == 4 || + harq_ack[1] == 4 || + harq_ack[2] == 4) { // there isn't a likely transmission + harq_ack[0] = 4; // DTX + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + max_metric = 0; + } else { + max_metric = max(metric[0],max(metric[1],metric[2])); + + if (metric[0]==max_metric) { + if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x1; + } else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1) { + harq_ack[0] = 2; // NACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + } else { + harq_ack[0] = 4; // DTX + harq_ack[1] = 4; // DTX + harq_ack[2] = 4; // DTX + } + } // if (metric[0]==max_metric) { + else if (metric[1]==max_metric) { + if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + harq_ack[2] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x3; + } else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x2; + } else { + harq_ack[0] = 4; // DTX + harq_ack[1] = 4; // DTX + harq_ack[2] = 4; // DTX + } + } // if (metric[1]==max_metric) { + else { + if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + tdd_multiplexing_mask = 0x7; + } else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 1; // ACK + tdd_multiplexing_mask = 0x5; + } else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + tdd_multiplexing_mask = 0x6; + } else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 1; // ACK + tdd_multiplexing_mask = 0x4; + } + } + + uci->stat = max_metric; + fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode + } + } //else if ((uci->tdd_bundling == 0) && (res==3)) + else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==4)) { // multiplexing + no SR, implement Table 10.1.3-7 (Rel14) for multiplexing with M=4 + if (pucch_b0b1[0][0] == 4 || + pucch_b0b1[1][0] == 4 || + pucch_b0b1[2][0] == 4 || + pucch_b0b1[3][0] == 4) { // there isn't a likely transmission + harq_ack[0] = 4; // DTX + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 6; // NACK/DTX + max_metric = 0; + } else { + max_metric = max(metric[0],max(metric[1],max(metric[2],metric[3]))); + + if (metric[0]==max_metric) { + if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] != 1) { + harq_ack[0] = 2; // NACK + harq_ack[1] = 4; // DTX + harq_ack[2] = 4; // DTX + harq_ack[3] = 4; // DTX + } else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] == 1) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0x9; + } else if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x1; + } else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1) { + harq_ack[0] = 2; // NACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 6; // NACK/DTX + } + } else if (metric[1]==max_metric) { + if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] == 1) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0xF; + } else if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1 ) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x3; + } else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] != 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0xE; + } else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x2; + } + } else if (metric[2]==max_metric) { + if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + harq_ack[3] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x7; + } else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 1; // ACK + harq_ack[3] = 6; // NACK/DTX + tdd_multiplexing_mask = 0x5; + } else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) { + harq_ack[0] = 4; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 1; // ACK + harq_ack[3] = 4; // NACK/DTX + tdd_multiplexing_mask = 0x6; + } else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 4; // NACK/DTX + harq_ack[1] = 4; // NACK/DTX + harq_ack[2] = 1; // ACK + harq_ack[3] = 4; // NACK/DTX + tdd_multiplexing_mask = 0x4; + } + } else { // max_metric[3]=max_metric + if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] == 1) { + harq_ack[0] = 1; // ACK + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 1; // ACK + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0xD; + } else if (pucch_b0b1[2][0] == 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 1; // ACK + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0xA; + } else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] == 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 1; // ACK + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0xC; + } else if (pucch_b0b1[2][0] != 1 && pucch_b0b1[2][1] != 1 ) { + harq_ack[0] = 6; // NACK/DTX + harq_ack[1] = 6; // NACK/DTX + harq_ack[2] = 6; // NACK/DTX + harq_ack[3] = 1; // ACK + tdd_multiplexing_mask = 0x8; + } + } + } + + uci->stat = max_metric; + fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode + } // else if ((uci->tdd_bundling == 0) && (res==4)) + else { // bundling + harq_ack[0] = pucch_b0b1[0][0]; + harq_ack[1] = pucch_b0b1[0][1]; + uci->stat = metric[0]; + LOG_D(PHY,"bundling: (%d,%d), metric %d\n",harq_ack[0],harq_ack[1],uci->stat); + fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,0,0xffff); // special_bundling mode + } + #ifdef DEBUG_PHY_PROC - LOG_D (PHY, "[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, (%d,%d)\n", eNB->Mod_id, - eNB->dlsch[UE_id][0]->rnti, frame, subframe, metric0, metric1, pucch_b0b1[0], pucch_b0b1[1]); + LOG_D (PHY, "[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, (%d,%d)\n", eNB->Mod_id, + eNB->dlsch[UE_id][0]->rnti, frame, subframe, metric0, metric1, pucch_b0b1[0], pucch_b0b1[1]); #endif - } - break; - default: - AssertFatal (1 == 0, "Unsupported UCI type %d\n", uci->type); - break; - } - - if (SR_payload == 1) { - LOG_D (PHY, "[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n", eNB->Mod_id, uci->rnti, frame, subframe); - - if (eNB->first_sr[i] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4 - eNB->first_sr[i] = 0; - eNB->dlsch[i][0]->harq_processes[0]->round = 0; - eNB->dlsch[i][0]->harq_processes[0]->status = SCH_IDLE; - LOG_D (PHY, "[eNB %d][SR %x] Frame %d subframe %d First SR\n", eNB->Mod_id, eNB->ulsch[i]->rnti, frame, subframe); - } + } + + break; + + default: + AssertFatal (1 == 0, "Unsupported UCI type %d\n", uci->type); + break; + } + + if (SR_payload == 1) { + LOG_D (PHY, "[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n", eNB->Mod_id, uci->rnti, frame, subframe); + + if (eNB->first_sr[i] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4 + eNB->first_sr[i] = 0; + eNB->dlsch[i][0]->harq_processes[0]->round = 0; + eNB->dlsch[i][0]->harq_processes[0]->status = SCH_IDLE; + LOG_D (PHY, "[eNB %d][SR %x] Frame %d subframe %d First SR\n", eNB->Mod_id, eNB->ulsch[i]->rnti, frame, subframe); + } + } } - } - } + } // end if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) { + } // end loop for (int i = 0; i < NUMBER_OF_UE_MAX; i++) { } -void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) -{ +void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { uint32_t ret=0,i; uint32_t harq_pid; uint8_t nPRS; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; LTE_eNB_ULSCH_t *ulsch; LTE_UL_eNB_HARQ_t *ulsch_harq; - const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; - - harq_pid = subframe2harq_pid(&eNB->frame_parms,frame,subframe); + uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe); - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { ulsch = eNB->ulsch[i]; + if (ulsch->ue_type > 0) harq_pid = 0; - + else harq_pid=harq_pid0; + ulsch_harq = ulsch->harq_processes[harq_pid]; - + if (ulsch->rnti>0) LOG_D(PHY,"eNB->ulsch[%d]->harq_processes[harq_pid:%d] SFN/SF:%04d%d: PUSCH procedures, UE %d/%x ulsch_harq[status:%d SFN/SF:%04d%d handled:%d]\n", - i, harq_pid, frame,subframe,i,ulsch->rnti, - ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->handled); - + i, harq_pid, frame,subframe,i,ulsch->rnti, + ulsch_harq->status, ulsch_harq->frame, ulsch_harq->subframe, ulsch_harq->handled); + if ((ulsch) && - (ulsch->rnti>0) && - (ulsch_harq->status == ACTIVE) && - (ulsch_harq->frame == frame) && - (ulsch_harq->subframe == subframe) && - (ulsch_harq->handled == 0)) { - + (ulsch->rnti>0) && + (ulsch_harq->status == ACTIVE) && + (ulsch_harq->frame == frame) && + (ulsch_harq->subframe == subframe) && + (ulsch_harq->handled == 0)) { // UE has ULSCH scheduling for (int rb=0; - rb<=ulsch_harq->nb_rb; - rb++) { - int rb2 = rb+ulsch_harq->first_rb; - eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); + rb<=ulsch_harq->nb_rb; + rb++) { + int rb2 = rb+ulsch_harq->first_rb; + eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); } - + LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d \n", eNB->Mod_id, frame, subframe, i); - nPRS = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]; - ulsch->cyclicShift = (ulsch_harq->n_DMRS2 + - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + - nPRS)%12; - AssertFatal(ulsch_harq->TBS>0,"illegal TBS %d\n",ulsch_harq->TBS); + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + + nPRS)%12; + AssertFatal(ulsch_harq->TBS>0,"illegal TBS %d\n",ulsch_harq->TBS); LOG_D(PHY, - "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, Qm %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, ), O_ACK %d, beta_cqi %d \n", - eNB->Mod_id,harq_pid,frame,subframe, - ulsch_harq->dci_alloc, - ulsch_harq->rar_alloc, - ulsch_harq->round, - ulsch_harq->first_rb, - ulsch_harq->nb_rb, - ulsch_harq->Qm, - ulsch_harq->TBS, - ulsch_harq->rvidx, - ulsch->cyclicShift, - ulsch_harq->n_DMRS2, - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift, - ulsch_harq->O_ACK, - ulsch->beta_offset_cqi_times8); - + "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, Qm %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, ), O_ACK %d, beta_cqi %d \n", + eNB->Mod_id,harq_pid,frame,subframe, + ulsch_harq->dci_alloc, + ulsch_harq->rar_alloc, + ulsch_harq->round, + ulsch_harq->first_rb, + ulsch_harq->nb_rb, + ulsch_harq->Qm, + ulsch_harq->TBS, + ulsch_harq->rvidx, + ulsch->cyclicShift, + ulsch_harq->n_DMRS2, + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift, + ulsch_harq->O_ACK, + ulsch->beta_offset_cqi_times8); start_meas(&eNB->ulsch_demodulation_stats); - rx_ulsch(eNB,proc, i); - stop_meas(&eNB->ulsch_demodulation_stats); - start_meas(&eNB->ulsch_decoding_stats); - ret = ulsch_decoding(eNB,proc, - i, - 0, // control_only_flag - ulsch_harq->V_UL_DAI, - ulsch_harq->nb_rb>20 ? 1 : 0); - + i, + 0, // control_only_flag + ulsch_harq->V_UL_DAI, + ulsch_harq->nb_rb>20 ? 1 : 0); stop_meas(&eNB->ulsch_decoding_stats); - - LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d ulsch_harq->cqi_crc_status:%d ackBits:%d ulsch_decoding_stats[t:%lld max:%lld]\n", - eNB->Mod_id,harq_pid, - frame,subframe, - ulsch->rnti, - dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]), - dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]), - 30,//eNB->measurements.n0_power_dB[0], - 30,//eNB->measurements.n0_power_dB[1], - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1], - ret, - ulsch_harq->cqi_crc_status, - ulsch_harq->O_ACK, - eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max); - + LOG_D(PHY, + "[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d ulsch_harq->cqi_crc_status:%d ackBits:%d ulsch_decoding_stats[t:%lld max:%lld]\n", + eNB->Mod_id,harq_pid, + frame,subframe, + ulsch->rnti, + dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]), + dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]), + 30,//eNB->measurements.n0_power_dB[0], + 30,//eNB->measurements.n0_power_dB[1], + ulsch_harq->o_ACK[0], + ulsch_harq->o_ACK[1], + ret, + ulsch_harq->cqi_crc_status, + ulsch_harq->O_ACK, + eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max); //compute the expected ULSCH RX power (for the stats) ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered - - if (RC.mac != NULL) { /* ulsim dose not use RC.mac context. */ - if (ulsch_harq->cqi_crc_status == 1) { + + if (RC.mac != NULL) { /* ulsim does not use RC.mac context. */ + if (ulsch_harq->cqi_crc_status == 1) { #ifdef DEBUG_PHY_PROC - //if (((frame%10) == 0) || (frame < 50)) - print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL); + //if (((frame%10) == 0) || (frame < 50)) + print_CQI(ulsch_harq->o,ulsch_harq->uci_format,0,fp->N_RB_DL); #endif - fill_ulsch_cqi_indication(eNB,frame,subframe,ulsch_harq,ulsch->rnti); - RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe)); - } else { - if(RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag & (1 << subframe) ){ - RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe)); - RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_timer=30; - LOG_D(PHY,"Frame %d,Subframe %d, We're supposed to get a cqi here. Set cqi_req_timer to 30.\n",frame,subframe); - } - } + fill_ulsch_cqi_indication(eNB,frame,subframe,ulsch_harq,ulsch->rnti); + RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe)); + } else { + if(RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag & (1 << subframe) ) { + RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe)); + RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_timer=30; + LOG_D(PHY,"Frame %d,Subframe %d, We're supposed to get a cqi here. Set cqi_req_timer to 30.\n",frame,subframe); + } + } } - + if (ret == (1+MAX_TURBO_ITERATIONS)) { - T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(ulsch->rnti), - T_INT(harq_pid)); - - fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC - fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC - - LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", - eNB->Mod_id,harq_pid, - frame,subframe, i, - ulsch_harq->round, - ulsch->Mlimit, - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1]); - - if (ulsch_harq->round >= 3) { - ulsch_harq->status = SCH_IDLE; - ulsch_harq->handled = 0; - ulsch->harq_mask &= ~(1 << harq_pid); - ulsch_harq->round = 0; - } - - MSC_LOG_RX_DISCARDED_MESSAGE( - MSC_PHY_ENB,MSC_PHY_UE, - NULL,0, - "%05u:%02u ULSCH received rnti %x harq id %u round %d", - frame,subframe, - ulsch->rnti,harq_pid, - ulsch_harq->round-1 - ); - - /* Mark the HARQ process to release it later if max transmission reached - * (see below). - * MAC does not send the max transmission count, we have to deal with it - * locally in PHY. - */ - ulsch_harq->handled = 1; + T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(ulsch->rnti), + T_INT(harq_pid)); + fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC + fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC + LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", + eNB->Mod_id,harq_pid, + frame,subframe, i, + ulsch_harq->round, + ulsch->Mlimit, + ulsch_harq->o_ACK[0], + ulsch_harq->o_ACK[1]); + + if (ulsch_harq->round >= 3) { + ulsch_harq->status = SCH_IDLE; + ulsch_harq->handled = 0; + ulsch->harq_mask &= ~(1 << harq_pid); + ulsch_harq->round = 0; + } + + MSC_LOG_RX_DISCARDED_MESSAGE( + MSC_PHY_ENB,MSC_PHY_UE, + NULL,0, + "%05u:%02u ULSCH received rnti %x harq id %u round %d", + frame,subframe, + ulsch->rnti,harq_pid, + ulsch_harq->round-1 + ); + /* Mark the HARQ process to release it later if max transmission reached + * (see below). + * MAC does not send the max transmission count, we have to deal with it + * locally in PHY. + */ + ulsch_harq->handled = 1; } // ulsch in error else { - fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC - fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC - ulsch_harq->status = SCH_IDLE; - ulsch->harq_mask &= ~(1 << harq_pid); - - T (T_ENB_PHY_ULSCH_UE_ACK, T_INT (eNB->Mod_id), T_INT (frame), T_INT (subframe), T_INT (ulsch->rnti), T_INT (harq_pid)); - - MSC_LOG_RX_MESSAGE( - MSC_PHY_ENB,MSC_PHY_UE, - NULL,0, - "%05u:%02u ULSCH received rnti %x harq id %u", - frame,subframe, - ulsch->rnti,harq_pid - ); - - + fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC + fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC + ulsch_harq->status = SCH_IDLE; + ulsch->harq_mask &= ~(1 << harq_pid); + T (T_ENB_PHY_ULSCH_UE_ACK, T_INT (eNB->Mod_id), T_INT (frame), T_INT (subframe), T_INT (ulsch->rnti), T_INT (harq_pid)); + MSC_LOG_RX_MESSAGE( + MSC_PHY_ENB,MSC_PHY_UE, + NULL,0, + "%05u:%02u ULSCH received rnti %x harq id %u", + frame,subframe, + ulsch->rnti,harq_pid + ); #ifdef DEBUG_PHY_PROC #ifdef DEBUG_ULSCH - LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe, - harq_pid,ulsch_harq->TBS>>3); - - for (j=0; j<ulsch_harq->TBS>>3; j++) - LOG_T(PHY,"%x.",ulsch->harq_processes[harq_pid]->b[j]); - - LOG_T(PHY,"\n"); + LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe, + harq_pid,ulsch_harq->TBS>>3); + + for (j=0; j<ulsch_harq->TBS>>3; j++) + LOG_T(PHY,"%x.",ulsch->harq_processes[harq_pid]->b[j]); + + LOG_T(PHY,"\n"); #endif #endif } // ulsch not in error - + if (ulsch_harq->O_ACK>0) fill_ulsch_harq_indication(eNB,ulsch_harq,ulsch->rnti,frame,subframe,ulsch->bundling); - + LOG_D(PHY,"[eNB %d] Frame %d subframe %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n", - eNB->Mod_id,frame,subframe, - harq_pid, - i, - ret, - ulsch_harq->cqi_crc_status, - ulsch_harq->o_ACK[0], - ulsch_harq->o_ACK[1], - eNB->UE_stats[i].ulsch_errors[harq_pid], - eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]); + eNB->Mod_id,frame,subframe, + harq_pid, + i, + ret, + ulsch_harq->cqi_crc_status, + ulsch_harq->o_ACK[0], + ulsch_harq->o_ACK[1], + eNB->UE_stats[i].ulsch_errors[harq_pid], + eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]); } // if ((ulsch) && // (ulsch->rnti>0) && // (ulsch_harq->status == ACTIVE)) else if ((ulsch) && - (ulsch->rnti>0) && - (ulsch_harq->status == ACTIVE) && - (ulsch_harq->frame == frame) && - (ulsch_harq->subframe == subframe) && - (ulsch_harq->handled == 1)) { + (ulsch->rnti>0) && + (ulsch_harq->status == ACTIVE) && + (ulsch_harq->frame == frame) && + (ulsch_harq->subframe == subframe) && + (ulsch_harq->handled == 1)) { // this harq process is stale, kill it, this 1024 frames later (10s), consider reducing that ulsch_harq->status = SCH_IDLE; ulsch_harq->handled = 0; @@ -1419,26 +1349,18 @@ extern int oai_exit; extern void *td_thread (void *); void init_td_thread(PHY_VARS_eNB *eNB) { - L1_proc_t *proc = &eNB->proc; - proc->tdp.eNB = eNB; proc->instance_cnt_td = -1; - - pthread_attr_init( &proc->attr_td); + pthread_attr_init( &proc->attr_td); pthread_mutex_init( &proc->mutex_td, NULL); pthread_cond_init( &proc->cond_td, NULL); - - pthread_create(&proc->pthread_td, &proc->attr_td, td_thread, (void*)&proc->tdp); - + pthread_create(&proc->pthread_td, &proc->attr_td, td_thread, (void *)&proc->tdp); } void kill_td_thread(PHY_VARS_eNB *eNB) { - L1_proc_t *proc = &eNB->proc; - proc->instance_cnt_td = 0; pthread_cond_signal(&proc->cond_td); - pthread_join(proc->pthread_td, NULL); pthread_mutex_destroy( &proc->mutex_td ); pthread_cond_destroy( &proc->cond_td ); @@ -1447,26 +1369,22 @@ void kill_td_thread(PHY_VARS_eNB *eNB) { extern void *te_thread (void *); void init_te_thread(PHY_VARS_eNB *eNB) { - L1_proc_t *proc = &eNB->proc; - for(int i=0; i<3 ;i++){ + for(int i=0; i<3 ; i++) { proc->tep[i].eNB = eNB; proc->tep[i].instance_cnt_te = -1; - pthread_mutex_init( &proc->tep[i].mutex_te, NULL); pthread_cond_init( &proc->tep[i].cond_te, NULL); pthread_attr_init( &proc->tep[i].attr_te); - LOG_I(PHY,"Creating te_thread %d\n",i); - pthread_create(&proc->tep[i].pthread_te, &proc->tep[i].attr_te, te_thread, (void*)&proc->tep[i]); + pthread_create(&proc->tep[i].pthread_te, &proc->tep[i].attr_te, te_thread, (void *)&proc->tep[i]); } } void kill_te_thread(PHY_VARS_eNB *eNB) { - L1_proc_t *proc = &eNB->proc; - for(int i=0; i<3 ;i++){ + for(int i=0; i<3 ; i++) { proc->tep[i].instance_cnt_te = 0; pthread_cond_signal(&proc->tep[i].cond_te); pthread_join(proc->tep[i].pthread_te, NULL); @@ -1477,74 +1395,76 @@ void kill_te_thread(PHY_VARS_eNB *eNB) { void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) { nfapi_rx_indication_pdu_t *pdu; - int timing_advance_update; int sync_pos; - uint32_t harq_pid; - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (eNB->ulsch[UE_id]->ue_type > 0) harq_pid = 0; else #endif - { - harq_pid = subframe2harq_pid (&eNB->frame_parms, - frame, subframe); - } - + { + harq_pid = subframe2harq_pid (&eNB->frame_parms, + frame, subframe); + } + pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rx_ind.sfn_sf = frame<<4| subframe; eNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; - pdu = &eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; - // pdu->rx_ue_information.handle = eNB->ulsch[UE_id]->handle; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = eNB->ulsch[UE_id]->rnti; pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3; pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->b; + pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->b; // estimate timing advance for MAC sync_pos = lte_est_timing_advance_pusch(eNB,UE_id); timing_advance_update = sync_pos; // - eNB->frame_parms.nb_prefix_samples/4; //to check - // if (timing_advance_update > 10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);} // if (timing_advance_update < -10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);} switch (eNB->frame_parms.N_RB_DL) { - case 6: /* nothing to do */ - break; - case 15: - timing_advance_update /= 2; - break; - case 25: - timing_advance_update /= 4; - break; - case 50: - timing_advance_update /= 8; - break; - case 75: - timing_advance_update /= 12; - break; - case 100: - timing_advance_update /= 16; - break; - default: - abort (); + case 6: /* nothing to do */ + break; + + case 15: + timing_advance_update /= 2; + break; + + case 25: + timing_advance_update /= 4; + break; + + case 50: + timing_advance_update /= 8; + break; + + case 75: + timing_advance_update /= 12; + break; + + case 100: + timing_advance_update /= 16; + break; + + default: + abort (); } + // 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; + pdu->rx_indication_rel8.timing_advance = timing_advance_update; - // estimate UL_CQI for MAC (from antenna port 0 only) int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 300;//(10*eNB->measurements.n0_power_dB[0]); - if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi = 0; @@ -1552,101 +1472,140 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) { pdu->rx_indication_rel8.ul_cqi = 255; else pdu->rx_indication_rel8.ul_cqi = (640 + SNRtimes10) / 5; - + LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n", - harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance, - timing_advance_update); - + harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance, + timing_advance_update); eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++; eNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | subframe; pthread_mutex_unlock(&eNB->UL_INFO_mutex); } -/* release the harq if its round is >= 'after_rounds' */ -static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int after_rounds) { - - LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; - LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; +//----------------------------------------------------------------------------- +/* + * Release the harq process if its round is >= 'after_rounds' + */ +static void do_release_harq(PHY_VARS_eNB *eNB, + int UE_id, + int tb, + uint16_t frame, + uint8_t subframe, + uint16_t mask, + int after_rounds) +//----------------------------------------------------------------------------- +{ + LTE_eNB_DLSCH_t *dlsch0 = NULL; + LTE_eNB_DLSCH_t *dlsch1 = NULL; + LTE_DL_eNB_HARQ_t *dlsch0_harq = NULL; + LTE_DL_eNB_HARQ_t *dlsch1_harq = NULL; int harq_pid; - int subframe_tx,frame_tx; - int M,m; - AssertFatal (UE_id != -1, "no existing dlsch context\n"); - AssertFatal (UE_id < NUMBER_OF_UE_MAX, "returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n", UE_id, NUMBER_OF_UE_MAX); + int subframe_tx; + int frame_tx; + + AssertFatal(UE_id != -1, "No existing dlsch context\n"); + AssertFatal(UE_id < NUMBER_OF_UE_MAX, "Returned UE_id %d >= %d (NUMBER_OF_UE_MAX)\n", UE_id, NUMBER_OF_UE_MAX); + dlsch0 = eNB->dlsch[UE_id][0]; dlsch1 = eNB->dlsch[UE_id][1]; - - if (eNB->frame_parms.frame_type == FDD) { - subframe_tx = (subframe+6)%10; - frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms,frame,subframe,subframe_tx); - harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; // or just use 0 for fdd? - - AssertFatal((harq_pid>=0) && (harq_pid<10),"harq_pid %d not in 0...9\n",harq_pid); - dlsch0_harq = dlsch0->harq_processes[harq_pid]; - dlsch1_harq = dlsch1->harq_processes[harq_pid]; - AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); + + if (eNB->frame_parms.frame_type == FDD) { + subframe_tx = (subframe + 6) % 10; + frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms, + frame, + subframe, + subframe_tx); + + harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; + + AssertFatal((harq_pid >= 0) && (harq_pid < 8),"harq_pid %d not in 0...7\n", harq_pid); + + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + AssertFatal(dlsch0_harq != NULL, "dlsch0_harq is null\n"); + #if T_TRACER + if (after_rounds != -1) { - T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(dlsch0->rnti), T_INT(harq_pid)); + T(T_ENB_PHY_DLSCH_UE_NACK, + T_INT(0), + T_INT(frame), + T_INT(subframe), + T_INT(dlsch0->rnti), + T_INT(harq_pid)); } else { - T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(dlsch0->rnti), T_INT(harq_pid)); + T(T_ENB_PHY_DLSCH_UE_ACK, + T_INT(0), + T_INT(frame), + T_INT(subframe), + T_INT(dlsch0->rnti), + T_INT(harq_pid)); } + #endif - + if (dlsch0_harq->round >= after_rounds) { dlsch0_harq->status = SCH_IDLE; - /*if ((dlsch1_harq == NULL)|| - ((dlsch1_harq!=NULL)&& - (dlsch1_harq->status == SCH_IDLE)))*/ - dlsch0->harq_mask &= ~(1<<harq_pid); + dlsch0->harq_mask &= ~(1 << harq_pid); } - LOG_D(PHY,"Frame %d, subframe %d: Releasing harq %d for UE %x\n",frame,subframe,harq_pid,dlsch0->rnti); - - } - else { // release all processes in the bundle that was acked, based on mask - // This is at most 4 for multiplexing and 9 for bundling/special bundling - M=ul_ACK_subframe2_M(&eNB->frame_parms, - subframe); - - for (m=0; m<M; m++) { + + } else { + /* Release all processes in the bundle that was acked, based on mask */ + /* This is at most 4 for multiplexing and 9 for bundling/special bundling */ + int M = ul_ACK_subframe2_M(&eNB->frame_parms, subframe); + + for (int m=0; m < M; m++) { subframe_tx = ul_ACK_subframe2_dl_subframe(&eNB->frame_parms, - subframe, - m); - frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms,frame,subframe,subframe_tx); - if (((1<<m)&mask) > 0) { - harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; - if ((harq_pid>=0) && (harq_pid<dlsch0->Mdlharq)) { - dlsch0_harq = dlsch0->harq_processes[harq_pid]; - dlsch1_harq = dlsch1->harq_processes[harq_pid]; - AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); - + subframe, + m); + + frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms, + frame, + subframe, + subframe_tx); + + if (((1 << m) & mask) > 0) { + harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; + + if ((harq_pid >= 0) && (harq_pid < dlsch0->Mdlharq)) { + dlsch0_harq = dlsch0->harq_processes[harq_pid]; + dlsch1_harq = dlsch1->harq_processes[harq_pid]; + + AssertFatal(dlsch0_harq != NULL, "Dlsch0_harq is null\n"); + #if T_TRACER - if (after_rounds != -1) { - T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(dlsch0->rnti), T_INT(harq_pid)); - } else { - T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe), - T_INT(dlsch0->rnti), T_INT(harq_pid)); - } + if (after_rounds != -1) { + T(T_ENB_PHY_DLSCH_UE_NACK, + T_INT(0), + T_INT(frame), + T_INT(subframe), + T_INT(dlsch0->rnti), + T_INT(harq_pid)); + } else { + T(T_ENB_PHY_DLSCH_UE_ACK, + T_INT(0), + T_INT(frame), + T_INT(subframe), + T_INT(dlsch0->rnti), + T_INT(harq_pid)); + } #endif - if (dlsch0_harq->round >= after_rounds) { - dlsch0_harq->status = SCH_IDLE; - if ((dlsch1_harq == NULL)|| - ((dlsch1_harq!=NULL)&& - (dlsch1_harq->status == SCH_IDLE))) - dlsch0->harq_mask &= ~(1<<harq_pid); - } - } - - } - } - } + if (dlsch0_harq->round >= after_rounds) { + dlsch0_harq->status = SCH_IDLE; + + if ((dlsch1_harq == NULL) || ((dlsch1_harq != NULL) && (dlsch1_harq->status == SCH_IDLE))) { + dlsch0->harq_mask &= ~(1 << harq_pid); + } + } + } // end if ((harq_pid >= 0) && (harq_pid < dlsch0->Mdlharq)) + } // end if (((1 << m) & mask) > 0) + } // end for (int m=0; m < M; m++) + } // end if TDD } static void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8_t subframe,uint16_t mask, int is_ack) { - /* Maximum number of DL transmissions = 4. + /* + * Maximum number of DL transmissions = 4. * TODO: get the value from configuration. * If is_ack is true then we release immediately. The value -1 can be used for that. */ @@ -1654,121 +1613,118 @@ static void release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,uint8 } int getM(PHY_VARS_eNB *eNB,int frame,int subframe) { - int M,Mtx=0; LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; int harq_pid; int subframe_tx,frame_tx; int m; - M=ul_ACK_subframe2_M(&eNB->frame_parms, - subframe); - + subframe); + for (m=0; m<M; m++) { subframe_tx = ul_ACK_subframe2_dl_subframe(&eNB->frame_parms, - subframe, - m); + subframe, + m); frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms,frame, - subframe,subframe_tx); + subframe,subframe_tx); + + if (dlsch0 == NULL || dlsch1 == NULL) { + LOG_E(PHY, "dlsch0 and/or dlsch1 NULL, getM frame %i, subframe %i\n",frame,subframe); + return Mtx; + } + harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; - + if (harq_pid>=0 && harq_pid<10) { dlsch0_harq = dlsch0->harq_processes[harq_pid]; dlsch1_harq = dlsch1->harq_processes[harq_pid]; AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n"); + if (dlsch0_harq->status == ACTIVE|| - (dlsch1_harq!=NULL && dlsch1_harq->status == ACTIVE)) Mtx ++; + (dlsch1_harq!=NULL && dlsch1_harq->status == ACTIVE)) Mtx ++; } } + return (Mtx); } -void fill_ulsch_cqi_indication (PHY_VARS_eNB * eNB, uint16_t frame, uint8_t subframe, LTE_UL_eNB_HARQ_t * ulsch_harq, uint16_t rnti) { - +void fill_ulsch_cqi_indication (PHY_VARS_eNB *eNB, uint16_t frame, uint8_t subframe, LTE_UL_eNB_HARQ_t *ulsch_harq, uint16_t rnti) { pthread_mutex_lock (&eNB->UL_INFO_mutex); nfapi_cqi_indication_pdu_t *pdu = &eNB->UL_INFO.cqi_ind.cqi_pdu_list[eNB->UL_INFO.cqi_ind.number_of_cqis]; nfapi_cqi_indication_raw_pdu_t *raw_pdu = &eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list[eNB->UL_INFO.cqi_ind.number_of_cqis]; - pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; + if (ulsch_harq->cqi_crc_status != 1) pdu->cqi_indication_rel9.data_offset = 0; else pdu->cqi_indication_rel9.data_offset = 1; // fill in after all cqi_indications have been generated when non-zero - - // by default set O to rank 1 value + // by default set O to rank 1 value pdu->cqi_indication_rel9.tl.tag = NFAPI_CQI_INDICATION_REL9_TAG; pdu->cqi_indication_rel9.length = (ulsch_harq->Or1>>3) + ((ulsch_harq->Or1&7) > 0 ? 1 : 0); pdu->cqi_indication_rel9.ri[0] = 0; + // if we have RI bits, set them and if rank2 overwrite O if (ulsch_harq->O_RI > 0) { pdu->cqi_indication_rel9.ri[0] = ulsch_harq->o_RI[0]; + if (ulsch_harq->o_RI[0] == 2) pdu->cqi_indication_rel9.length = (ulsch_harq->Or2 >> 3) + ((ulsch_harq->Or2 & 7) > 0 ? 1 : 0); + pdu->cqi_indication_rel9.timing_advance = 0; } - + pdu->cqi_indication_rel9.number_of_cc_reported = 1; pdu->ul_cqi_information.channel = 1; // PUSCH memcpy ((void *) raw_pdu->pdu, ulsch_harq->o, pdu->cqi_indication_rel9.length); eNB->UL_INFO.cqi_ind.number_of_cqis++; LOG_D(PHY,"eNB->UL_INFO.cqi_ind.number_of_cqis:%d\n", eNB->UL_INFO.cqi_ind.number_of_cqis); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - -} - -void fill_ulsch_harq_indication (PHY_VARS_eNB * eNB, LTE_UL_eNB_HARQ_t * ulsch_harq, uint16_t rnti, int frame, int subframe, int bundling) { +} +void fill_ulsch_harq_indication (PHY_VARS_eNB *eNB, LTE_UL_eNB_HARQ_t *ulsch_harq, uint16_t rnti, int frame, int subframe, int bundling) { int UE_id = find_dlsch(rnti,eNB,SEARCH_EXIST); - if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ){ + + if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ) { LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rnti,UE_id); return; } + //AssertFatal(UE_id>=0,"UE_id doesn't exist\n"); - pthread_mutex_lock(&eNB->UL_INFO_mutex); nfapi_harq_indication_pdu_t *pdu = &eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs]; int M; int i; - eNB->UL_INFO.harq_ind.header.message_id = NFAPI_HARQ_INDICATION; eNB->UL_INFO.harq_ind.sfn_sf = frame<<4|subframe; - eNB->UL_INFO.harq_ind.harq_indication_body.tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; - pdu->instance_length = 0; // don't know what to do with this // pdu->rx_ue_information.handle = handle; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; - + if (eNB->frame_parms.frame_type == FDD) { pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; pdu->harq_indication_fdd_rel13.mode = 0; pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK; - + for (i = 0; i < ulsch_harq->O_ACK; i++) { AssertFatal (ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n", i, ulsch_harq->o_ACK[i]); - pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 2 - ulsch_harq->o_ACK[i]; // release DLSCH if needed - release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1); - } } else { // TDD M = ul_ACK_subframe2_M (&eNB->frame_parms, subframe); - pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; pdu->harq_indication_tdd_rel13.mode = 1-bundling; pdu->harq_indication_tdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK; - + for (i = 0; i < ulsch_harq->O_ACK; i++) { AssertFatal (ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n", i, ulsch_harq->o_ACK[i]); - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 2-ulsch_harq->o_ACK[i]; // release DLSCH if needed /* TODO: review this code, it's most certainly wrong. @@ -1776,77 +1732,70 @@ void fill_ulsch_harq_indication (PHY_VARS_eNB * eNB, LTE_UL_eNB_HARQ_t * ulsch_h * Basically, call release_harq with 1 as last argument when ACK and 0 when NACK. */ release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1); + if (M==1 && ulsch_harq->O_ACK==1 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1); else if (M==1 && ulsch_harq->O_ACK==2 && ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff, ulsch_harq->o_ACK[i] == 1); else if (M>1 && ulsch_harq->o_ACK[i] == 1) { - // spatial bundling - release_harq(eNB,UE_id,0,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1); - release_harq(eNB,UE_id,1,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1); + // spatial bundling + release_harq(eNB,UE_id,0,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1); + release_harq(eNB,UE_id,1,frame,subframe,1<<i, ulsch_harq->o_ACK[i] == 1); } } } //LOG_E(PHY,"eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs:%d\n", eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs); eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs++; - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - } -void fill_uci_harq_indication (PHY_VARS_eNB * eNB, LTE_eNB_UCI * uci, int frame, int subframe, uint8_t * harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask) { - +void fill_uci_harq_indication (PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask) { int UE_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST); + //AssertFatal(UE_id>=0,"UE_id doesn't exist rnti:%x\n", uci->rnti); if (UE_id < 0) { LOG_E(PHY,"SFN/SF:%04d%d Unable to find rnti:%x do not send HARQ\n", frame, subframe, uci->rnti); return; } - + pthread_mutex_lock(&eNB->UL_INFO_mutex); - nfapi_harq_indication_t *ind = &eNB->UL_INFO.harq_ind; nfapi_harq_indication_body_t *body = &ind->harq_indication_body; nfapi_harq_indication_pdu_t *pdu = &body->harq_pdu_list[eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs]; - ind->sfn_sf = frame<<4|subframe; ind->header.message_id = NFAPI_HARQ_INDICATION; - body->tl.tag = NFAPI_HARQ_INDICATION_BODY_TAG; - pdu->instance_length = 0; // don't know what to do with this // pdu->rx_ue_information.handle = handle; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = uci->rnti; - // estimate UL_CQI for MAC (from antenna port 0 only) pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; int SNRtimes10 = dB_fixed_times10(uci->stat) - 300;//(10*eNB->measurements.n0_power_dB[0]); - + if (SNRtimes10 < -100) LOG_I (PHY, "uci->stat %d \n", uci->stat); - + if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi = 0; else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi = 255; else pdu->ul_cqi_information.ul_cqi = (640 + SNRtimes10) / 5; + pdu->ul_cqi_information.channel = 0; - + if (eNB->frame_parms.frame_type == FDD) { if (uci->pucch_fmt == pucch_format1a) { pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; - pdu->harq_indication_fdd_rel13.mode = 0; + pdu->harq_indication_fdd_rel13.mode = 0; pdu->harq_indication_fdd_rel13.number_of_ack_nack = 1; - AssertFatal (harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n", harq_ack[0]); pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0]; // release DLSCH if needed release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); - } - else if (uci->pucch_fmt == pucch_format1b) { + } else if (uci->pucch_fmt == pucch_format1b) { pdu->harq_indication_fdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_FDD_REL13_TAG; - pdu->harq_indication_fdd_rel13.mode = 0; + pdu->harq_indication_fdd_rel13.mode = 0; pdu->harq_indication_fdd_rel13.number_of_ack_nack = 2; AssertFatal (harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n", harq_ack[0]); AssertFatal (harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n", harq_ack[1]); @@ -1855,202 +1804,197 @@ void fill_uci_harq_indication (PHY_VARS_eNB * eNB, LTE_eNB_UCI * uci, int frame, // release DLSCH if needed release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1); - } - else AssertFatal(1==0,"only format 1a/b for now, received %d\n",uci->pucch_fmt); - } - else { // TDD + } else AssertFatal(1==0,"only format 1a/b for now, received %d\n",uci->pucch_fmt); + } else { // TDD AssertFatal (tdd_mapping_mode == 0 || tdd_mapping_mode == 1 || tdd_mapping_mode == 2, "Illegal tdd_mapping_mode %d\n", tdd_mapping_mode); pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; - pdu->harq_indication_tdd_rel13.mode = tdd_mapping_mode; - LOG_D(PHY,"%s(eNB, uci_harq format %d, rnti:%04x, frame:%d, subframe:%d, tdd_mapping_mode:%d) harq_ack[0]:%d harq_ack[1]:%d\n", __FUNCTION__, uci->pucch_fmt,uci->rnti, frame, subframe, tdd_mapping_mode,harq_ack[0],harq_ack[1]); + pdu->harq_indication_tdd_rel13.mode = tdd_mapping_mode; + LOG_D(PHY,"%s(eNB, uci_harq format %d, rnti:%04x, frame:%d, subframe:%d, tdd_mapping_mode:%d) harq_ack[0]:%d harq_ack[1]:%d\n", __FUNCTION__, uci->pucch_fmt,uci->rnti, frame, subframe, + tdd_mapping_mode,harq_ack[0],harq_ack[1]); + switch (tdd_mapping_mode) { - case 0: // bundling - - if (uci->pucch_fmt == pucch_format1a) { - pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; - pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; - LOG_D(PHY,"bundling, pucch1a, number of ack nack %d\n",pdu->harq_indication_tdd_rel13.number_of_ack_nack); - AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; - // release all bundled DLSCH if needed - release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); - } - else if (uci->pucch_fmt == pucch_format1b) { - pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2; - AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]); - AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]); - pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; - pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1]; - // release all DLSCH if needed - release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); - release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1); - } - break; - case 1: // multiplexing - AssertFatal (uci->pucch_fmt == pucch_format1b, "uci->pucch_format %d is not format1b\n", uci->pucch_fmt); - - if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1a) { - pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; - pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; - AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); - pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; - // release all DLSCH if needed - release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); - } - else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) { - pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; - pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2; - AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]); - AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]); - pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; - pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1]; - // release all DLSCH if needed - release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); - release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1); - } - else { // num_pucch_resources (M) > 1 - pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; - pdu->harq_indication_tdd_rel13.number_of_ack_nack = uci->num_pucch_resources; - - pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; - pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1]; - if (uci->num_pucch_resources == 3) pdu->harq_indication_tdd_rel13.harq_data[2].multiplex.value_0 = harq_ack[2]; - if (uci->num_pucch_resources == 4) pdu->harq_indication_tdd_rel13.harq_data[3].multiplex.value_0 = harq_ack[3]; - // spatial-bundling in this case so release both HARQ if necessary - release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */); - release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */); - } - break; - case 2: // special bundling (SR collision) - pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; - pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; - pdu->harq_indication_tdd_rel13.mode = 0; - int tdd_config5_sf2scheds=0; - if (eNB->frame_parms.tdd_config==5) tdd_config5_sf2scheds = getM(eNB,frame,subframe); - - switch (harq_ack[0]) { - case 0: - case 4: - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; - /* TODO: release_harq here? this whole code looks suspicious */ - break; - case 1: // check if M=1,4,7 - if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 || - tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) { - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; - release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1); - release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1); - }else{ - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; - } - break; - case 2: // check if M=2,5,8 - if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 || - tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) { - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; - release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1); - release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1); - }else{ - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; - } - break; - case 3: // check if M=3,6,9 - if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 || - tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) { - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; - release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1); - release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1); - }else{ - pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; - } - break; - } - break; - + case 0: // bundling + if (uci->pucch_fmt == pucch_format1a) { + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; + LOG_D(PHY,"bundling, pucch1a, number of ack nack %d\n",pdu->harq_indication_tdd_rel13.number_of_ack_nack); + AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; + // release all bundled DLSCH if needed + release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); + } else if (uci->pucch_fmt == pucch_format1b) { + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2; + AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]); + AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]); + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = harq_ack[0]; + pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = harq_ack[1]; + // release all DLSCH if needed + release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1); + } + + break; + + case 1: // multiplexing + AssertFatal (uci->pucch_fmt == pucch_format1b, "uci->pucch_format %d is not format1b\n", uci->pucch_fmt); + + if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1a) { + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; + AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[0] == 4, "harq_ack[0] is %d, should be 1,2 or 4\n",harq_ack[0]); + pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; + // release all DLSCH if needed + release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); + } else if (uci->num_pucch_resources == 1 && uci->pucch_fmt == pucch_format1b) { + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 2; + AssertFatal(harq_ack[0] == 1 || harq_ack[0] == 2 || harq_ack[1] == 4, "harq_ack[0] is %d, should be 0,1 or 4\n",harq_ack[0]); + AssertFatal(harq_ack[1] == 1 || harq_ack[1] == 2 || harq_ack[1] == 4, "harq_ack[1] is %d, should be 0,1 or 4\n",harq_ack[1]); + pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; + pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1]; + // release all DLSCH if needed + release_harq(eNB,UE_id,0,frame,subframe,0xffff, harq_ack[0] == 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, harq_ack[1] == 1); + } else { // num_pucch_resources (M) > 1 + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.number_of_ack_nack = uci->num_pucch_resources; + pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = harq_ack[0]; + pdu->harq_indication_tdd_rel13.harq_data[1].multiplex.value_0 = harq_ack[1]; + + if (uci->num_pucch_resources == 3) pdu->harq_indication_tdd_rel13.harq_data[2].multiplex.value_0 = harq_ack[2]; + + if (uci->num_pucch_resources == 4) pdu->harq_indication_tdd_rel13.harq_data[3].multiplex.value_0 = harq_ack[3]; + + // spatial-bundling in this case so release both HARQ if necessary + release_harq(eNB,UE_id,0,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */); + release_harq(eNB,UE_id,1,frame,subframe,tdd_multiplexing_mask, 1 /* force release? previous code was unconditional */); + } + + break; + + case 2: // special bundling (SR collision) + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; + pdu->harq_indication_tdd_rel13.mode = 0; + int tdd_config5_sf2scheds=0; + + if (eNB->frame_parms.tdd_config==5) tdd_config5_sf2scheds = getM(eNB,frame,subframe); + + switch (harq_ack[0]) { + case 0: + case 4: + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; + /* TODO: release_harq here? this whole code looks suspicious */ + break; + + case 1: // check if M=1,4,7 + if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 || + tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) { + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; + release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1); + } else { + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; + } + + break; + + case 2: // check if M=2,5,8 + if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 || + tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) { + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; + release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1); + } else { + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; + } + + break; + + case 3: // check if M=3,6,9 + if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 || + tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) { + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; + release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1); + release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1); + } else { + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0; + } + + break; + } + + break; } } //TDD - - + eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs++; LOG_D(PHY,"Incremented eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs:%d\n", eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); } -void fill_crc_indication (PHY_VARS_eNB * eNB, int UE_id, int frame, int subframe, uint8_t crc_flag) { - +void fill_crc_indication (PHY_VARS_eNB *eNB, int UE_id, int frame, int subframe, uint8_t crc_flag) { pthread_mutex_lock(&eNB->UL_INFO_mutex); nfapi_crc_indication_pdu_t *pdu = &eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs]; - eNB->UL_INFO.crc_ind.sfn_sf = frame<<4 | subframe; eNB->UL_INFO.crc_ind.header.message_id = NFAPI_CRC_INDICATION; eNB->UL_INFO.crc_ind.crc_indication_body.tl.tag = NFAPI_CRC_INDICATION_BODY_TAG; - pdu->instance_length = 0; // don't know what to do with this // pdu->rx_ue_information.handle = handle; - pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = eNB->ulsch[UE_id]->rnti; pdu->crc_indication_rel8.tl.tag = NFAPI_CRC_INDICATION_REL8_TAG; pdu->crc_indication_rel8.crc_flag = crc_flag; - eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs++; - //LOG_D(PHY, "%s() rnti:%04x crcs:%d crc_flag:%d\n", __FUNCTION__, pdu->rx_ue_information.rnti, eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, crc_flag); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); } -void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) -{ +void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { //RX processing for ue-specific resources (i LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; - /* TODO: use correct rxdata */ T (T_ENB_PHY_INPUT_SIGNAL, T_INT (eNB->Mod_id), T_INT (frame), T_INT (subframe), T_INT (0), T_BUFFER (&eNB->RU_list[0]->common.rxdata[0][subframe * eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti * 4)); - + if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return; - + T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 1 ); - LOG_D (PHY, "[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n", eNB->Mod_id, frame, subframe); - eNB->rb_mask_ul[0] = 0; eNB->rb_mask_ul[1] = 0; eNB->rb_mask_ul[2] = 0; eNB->rb_mask_ul[3] = 0; - // Fix me here, these should be locked eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0; eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs = 0; // Call SRS first since all others depend on presence of SRS or lack thereof srs_procedures (eNB, proc); - eNB->first_run_I0_measurements = 0; - uci_procedures (eNB, proc); - - if (nfapi_mode == 0 || nfapi_mode == 1) { // If PNF or monolithic + + if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { // If PNF or monolithic pusch_procedures(eNB,proc); } lte_eNB_I0_measurements (eNB, subframe, 0, eNB->first_run_I0_measurements); - int min_I0=1000,max_I0=0; - if ((frame==0) && (subframe==4)) { - for (int i=0;i<eNB->frame_parms.N_RB_UL;i++) { + + if ((frame==0) && (subframe==4)) { + for (int i=0; i<eNB->frame_parms.N_RB_UL; i++) { if (i==(eNB->frame_parms.N_RB_UL>>1) - 1) i+=2; - + if (eNB->measurements.n0_subband_power_tot_dB[i]<min_I0) min_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; + if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0) max_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; - } + LOG_I (PHY, "max_I0 %d, min_I0 %d\n", max_I0, min_I0); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); } diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index ee16a4f5807a13429564024f47dd79b30b4f084d..18fc1e5313b3e958f1007e02a88dee6c66ac09cb 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -37,6 +37,7 @@ #include "fapi_l1.h" #include "nfapi_pnf.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -46,91 +47,86 @@ #include <time.h> #if defined(ENABLE_ITTI) -# include "intertask_interface.h" + #include "intertask_interface.h" #endif -extern uint32_t nfapi_mode; extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void prach_procedures(PHY_VARS_eNB *eNB #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - int br_flag + , + int br_flag #endif - ) { + ) { uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4]; uint16_t i; int frame,subframe; - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (br_flag==1) { subframe = eNB->proc.subframe_prach_br; frame = eNB->proc.frame_prach_br; pthread_mutex_lock(&eNB->UL_INFO_mutex); eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles=0; pthread_mutex_unlock(&eNB->UL_INFO_mutex); - } - else + } else #endif - { - pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles=0; - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - subframe = eNB->proc.subframe_prach; - frame = eNB->proc.frame_prach; - } + { + pthread_mutex_lock(&eNB->UL_INFO_mutex); + eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles=0; + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + subframe = eNB->proc.subframe_prach; + frame = eNB->proc.frame_prach; + } + RU_t *ru; int aa=0; int ru_aa; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1); - - - for (i=0;i<eNB->num_RU;i++) { + for (i=0; i<eNB->num_RU; i++) { ru=eNB->RU_list[i]; - for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) { + + for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) { eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa]; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int ce_level; if (br_flag==1) - for (ce_level=0;ce_level<4;ce_level++) eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa]; + for (ce_level=0; ce_level<4; ce_level++) eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[i]->prach_rxsigF_br[ce_level][ru_aa]; + #endif } } + // run PRACH detection for CE-level 0 only for now when br_flag is set rx_prach(eNB, - eNB->RU_list[0], - &max_preamble[0], - &max_preamble_energy[0], - &max_preamble_delay[0], - frame, - 0 + eNB->RU_list[0], + &max_preamble[0], + &max_preamble_energy[0], + &max_preamble_delay[0], + frame, + 0 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,br_flag + ,br_flag #endif - ); - - LOG_D(PHY,"[RAPROC] Frame %d, subframe %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n", - frame,subframe, + ); + LOG_D(PHY,"[RAPROC] Frame %d, subframe %d : BR %d Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n", + frame,subframe,br_flag, max_preamble[0], max_preamble_energy[0]/10, max_preamble_delay[0], - eNB->prach_energy_counter); - + eNB->prach_energy_counter); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (br_flag==1) { int prach_mask; - prach_mask = is_prach_subframe (&eNB->frame_parms, eNB->proc.frame_prach_br, eNB->proc.subframe_prach_br); - eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br; int ind = 0; int ce_level = 0; - /* Save for later, it doesn't work + /* Save for later, it doesn't work for (int ind=0,ce_level=0;ce_level<4;ce_level++) { if ((eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[ce_level]==1)&& @@ -141,9 +137,8 @@ void prach_procedures(PHY_VARS_eNB *eNB */ if (eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[0] == 1) { - if ((eNB->prach_energy_counter == 100) && (max_preamble_energy[0] > eNB->measurements.prach_I0 + 200)) { + if ((eNB->prach_energy_counter == 100) && (max_preamble_energy[0] > eNB->measurements.prach_I0 + eNB->prach_DTX_threshold_emtc[0])) { eNB->UL_INFO.rach_ind_br.rach_indication_body.number_of_preambles++; - eNB->preamble_list_br[ind].preamble_rel8.timing_advance = max_preamble_delay[ind]; // eNB->preamble_list_br[ind].preamble_rel8.preamble = max_preamble[ind]; // note: fid is implicitly 0 here, this is the rule for eMTC RA-RNTI from 36.321, Section 5.1.4 @@ -158,69 +153,61 @@ void prach_procedures(PHY_VARS_eNB *eNB eNB->preamble_list_br[ind].preamble_rel8.preamble, eNB->preamble_list_br[ind].preamble_rel8.rnti, eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type); } } - /* - ind++; - } - } */// ce_level - } - else -#endif - { - if ((eNB->prach_energy_counter == 100) && - (max_preamble_energy[0] > eNB->measurements.prach_I0+100)) { - - LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", - eNB->Mod_id, - eNB->CC_id, - frame, - subframe, - max_preamble[0], - max_preamble_energy[0]/10, - max_preamble_energy[0]%10, - max_preamble_delay[0]); - - T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), - T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0])); - - pthread_mutex_lock(&eNB->UL_INFO_mutex); - - eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 1; - eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = &eNB->preamble_list[0]; - eNB->UL_INFO.rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; - eNB->UL_INFO.rach_ind.header.message_id = NFAPI_RACH_INDICATION; - eNB->UL_INFO.rach_ind.sfn_sf = frame<<4 | subframe; - - eNB->preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; - eNB->preamble_list[0].preamble_rel8.timing_advance = max_preamble_delay[0]; - eNB->preamble_list[0].preamble_rel8.preamble = max_preamble[0]; - eNB->preamble_list[0].preamble_rel8.rnti = 1+subframe; // note: fid is implicitly 0 here - eNB->preamble_list[0].preamble_rel13.rach_resource_type = 0; - eNB->preamble_list[0].instance_length = 0; //don't know exactly what this is - - if (nfapi_mode == 1) { // If NFAPI PNF then we need to send the message to the VNF - - LOG_D(PHY,"Filling NFAPI indication for RACH : SFN_SF:%d TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", - NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), - eNB->preamble_list[0].preamble_rel8.timing_advance, - eNB->preamble_list[0].preamble_rel8.preamble, - eNB->preamble_list[0].preamble_rel8.rnti, - eNB->preamble_list[0].preamble_rel13.rach_resource_type); - - oai_nfapi_rach_ind(&eNB->UL_INFO.rach_ind); - - eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 0; - } - - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - - } // max_preamble_energy > prach_I0 + 100 - else { - eNB->measurements.prach_I0 = ((eNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); - if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",eNB->measurements.prach_I0/10,eNB->measurements.prach_I0%10); - if (eNB->prach_energy_counter < 100) eNB->prach_energy_counter++; + /* + ind++; + } + } */// ce_level + } else +#endif + { + if ((eNB->prach_energy_counter == 100) && + (max_preamble_energy[0] > eNB->measurements.prach_I0+eNB->prach_DTX_threshold)) { + LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", + eNB->Mod_id, + eNB->CC_id, + frame, + subframe, + max_preamble[0], + max_preamble_energy[0]/10, + max_preamble_energy[0]%10, + max_preamble_delay[0]); + T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), + T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0])); + pthread_mutex_lock(&eNB->UL_INFO_mutex); + eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 1; + eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = &eNB->preamble_list[0]; + eNB->UL_INFO.rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; + eNB->UL_INFO.rach_ind.header.message_id = NFAPI_RACH_INDICATION; + eNB->UL_INFO.rach_ind.sfn_sf = frame<<4 | subframe; + eNB->preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; + eNB->preamble_list[0].preamble_rel8.timing_advance = max_preamble_delay[0]; + eNB->preamble_list[0].preamble_rel8.preamble = max_preamble[0]; + eNB->preamble_list[0].preamble_rel8.rnti = 1+subframe; // note: fid is implicitly 0 here + eNB->preamble_list[0].preamble_rel13.rach_resource_type = 0; + eNB->preamble_list[0].instance_length = 0; //don't know exactly what this is + + if (NFAPI_MODE==NFAPI_MODE_PNF) { // If NFAPI PNF then we need to send the message to the VNF + LOG_D(PHY,"Filling NFAPI indication for RACH : SFN_SF:%d TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", + NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), + eNB->preamble_list[0].preamble_rel8.timing_advance, + eNB->preamble_list[0].preamble_rel8.preamble, + eNB->preamble_list[0].preamble_rel8.rnti, + eNB->preamble_list[0].preamble_rel13.rach_resource_type); + oai_nfapi_rach_ind(&eNB->UL_INFO.rach_ind); + eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 0; } - } // else br_flag + + pthread_mutex_unlock(&eNB->UL_INFO_mutex); + } // max_preamble_energy > prach_I0 + 100 + else { + eNB->measurements.prach_I0 = ((eNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); + + if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",eNB->measurements.prach_I0/10,eNB->measurements.prach_I0%10); + + if (eNB->prach_energy_counter < 100) eNB->prach_energy_counter++; + } + } // else br_flag VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 0e0705cf2fd31b91d247dfdb473929b6507105d8..d71c4f5c7552f84b1ed521ccc639feade26dff1f 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -1518,15 +1518,19 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1; } + if (ue->ulsch[eNB_id]->o_ACK[0]) { + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } else { + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { if(ue->ulsch[eNB_id]->o_ACK[0]) { LOG_I(PHY,"PUSCH ACK\n"); - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); } else { LOG_I(PHY,"PUSCH NACK\n"); - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); } LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", @@ -1901,16 +1905,6 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin uint8_t isShortenPucch = (pSoundingrs_ul_config_dedicated->srsCellSubframe && frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission); bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode; - if ((frame_parms->frame_type==FDD) || - (bundling_flag==bundling) || - ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe_tx!=2)||(subframe_tx!=7)))) { - format = pucch_format1a; - // LOG_D(PHY,"[UE] PUCCH 1a\n"); - } else { - format = pucch_format1b; - // LOG_D(PHY,"[UE] PUCCH 1b\n"); - } - // Part - I // Collect feedback that should be transmitted at this subframe // - SR @@ -2046,14 +2040,12 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin } } - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - if(pucch_payload[0]) { - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); - } else { - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); - } + if (pucch_payload[0]) { + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } else { + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); } generate_pucch1x(ue->common_vars.txdataF, @@ -2774,18 +2766,21 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint CBA_RNTI, eNB_id, 0)==0)) { + int harq_pid = subframe2harq_pid(&ue->frame_parms, + pdcch_alloc2ul_frame(&ue->frame_parms,proc->frame_rx,proc->subframe_rx), + pdcch_alloc2ul_subframe(&ue->frame_parms,proc->subframe_rx)); + T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx), + T_INT(dci_alloc_rx[i].rnti), + T_INT(harq_pid), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS)); if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_USEDINLOG_VAR(int8_t,harq_pid) = subframe2harq_pid(&ue->frame_parms, pdcch_alloc2ul_frame(&ue->frame_parms,proc->frame_rx,proc->subframe_rx), pdcch_alloc2ul_subframe(&ue->frame_parms,proc->subframe_rx)); - T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx), - T_INT(dci_alloc_rx[i].rnti), - T_INT(harq_pid), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS)); LOG_D(PHY,"[UE %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); } } @@ -3085,7 +3080,7 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC int i_mod,eNB_id_i,dual_stream_UE; int first_symbol_flag=0; - if (dlsch0->active == 0) + if (dlsch0 && dlsch0->active == 0) return; for (m=s0; m<=s1; m++) { @@ -4313,7 +4308,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr ue->dlsch_ra[eNB_id]->active = 0; } - if (LOG_DEBUGFLAG(UE_TIMING) + if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); LOG_I(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } diff --git a/openair1/SCHED_UE/pusch_pc.c b/openair1/SCHED_UE/pusch_pc.c index fa38d42c60ab1ddc56505391168221a708d9eaf8..503d73005f25adcc5bd7afe8b8d2fe61ff0af2ea 100644 --- a/openair1/SCHED_UE/pusch_pc.c +++ b/openair1/SCHED_UE/pusch_pc.c @@ -36,12 +36,10 @@ #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #include "PHY/phy_extern_ue.h" #include "PHY/LTE_ESTIMATION/lte_estimation.h" +#include "nfapi/oai_integration/vendor_ext.h" -extern uint8_t nfapi_mode; - -int16_t get_hundred_times_delta_IF(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t harq_pid) -{ +int16_t get_hundred_times_delta_IF(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t harq_pid) { uint32_t Nre = 2*ue->ulsch[eNB_id]->harq_processes[harq_pid]->Nsymb_initial * ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb*12; @@ -51,9 +49,8 @@ int16_t get_hundred_times_delta_IF(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t harq_p uint32_t MPR_x100 = 100*ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/Nre; // Note: MPR=is the effective spectral efficiency of the PUSCH // FK 20140908 sumKr is only set after the ulsch_encoding - uint16_t beta_offset_pusch = (ue->ulsch[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? - ue->ulsch[eNB_id]->beta_offset_cqi_times8:8; + ue->ulsch[eNB_id]->beta_offset_cqi_times8:8; if (ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled == 1) { // This is the formula from Section 5.1.1.1 in 36.213 10*log10(deltaIF_PUSCH = (2^(MPR*Ks)-1)*beta_offset_pusch) @@ -67,34 +64,24 @@ int16_t get_hundred_times_delta_IF(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t harq_p uint8_t alpha_lut[8] = {0,40,50,60,70,80,90,100}; -void pusch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag) -{ - - +void pusch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag) { uint8_t harq_pid = subframe2harq_pid(&ue->frame_parms, proc->frame_tx, proc->subframe_tx); - uint8_t nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb; int16_t PL; - - // P_pusch = 10*log10(nb_rb + P_opusch(j)+ alpha(u)*PL + delta_TF(i) + f(i)) // // P_opusch(0) = P_oPTR + deltaP_Msg3 if PUSCH is transporting Msg3 // else // P_opusch(0) = PO_NOMINAL_PUSCH(j) + P_O_UE_PUSCH(j) PL = get_PL(ue->Mod_id,ue->CC_id,eNB_id); - ue->ulsch[eNB_id]->Po_PUSCH = (hundred_times_log10_NPRB[nb_rb-1]+ - get_hundred_times_delta_IF(ue,eNB_id,harq_pid) + - 100*ue->ulsch[eNB_id]->f_pusch)/100; + get_hundred_times_delta_IF(ue,eNB_id,harq_pid) + + 100*ue->ulsch[eNB_id]->f_pusch)/100; if(ue->ulsch_Msg3_active[eNB_id] == 1) { // Msg3 PUSCH - ue->ulsch[eNB_id]->Po_PUSCH += (get_Po_NOMINAL_PUSCH(ue->Mod_id,0) + PL); - - LOG_I(PHY,"[UE %d][RAPROC] frame %d, subframe %d: Msg3 Po_PUSCH %d dBm (%d,%d,100*PL=%d,%d,%d)\n", ue->Mod_id,proc->frame_tx,proc->subframe_tx,ue->ulsch[eNB_id]->Po_PUSCH, 100*get_Po_NOMINAL_PUSCH(ue->Mod_id,0), @@ -104,10 +91,9 @@ void pusch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_ 100*ue->ulsch[eNB_id]->f_pusch); } else if (j==0) { // SPS PUSCH } else if (j==1) { // Normal PUSCH - ue->ulsch[eNB_id]->Po_PUSCH += ((alpha_lut[ue->frame_parms.ul_power_control_config_common.alpha]*PL)/100); ue->ulsch[eNB_id]->Po_PUSCH += ue->frame_parms.ul_power_control_config_common.p0_NominalPUSCH; - ue->ulsch[eNB_id]->PHR = ue->tx_power_max_dBm-ue->ulsch[eNB_id]->Po_PUSCH; + ue->ulsch[eNB_id]->PHR = ue->tx_power_max_dBm-ue->ulsch[eNB_id]->Po_PUSCH; if (ue->ulsch[eNB_id]->PHR < -23) ue->ulsch[eNB_id]->PHR = -23; @@ -126,13 +112,11 @@ void pusch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_ get_hundred_times_delta_IF(ue,eNB_id,harq_pid)/100.0, ue->ulsch[eNB_id]->f_pusch); } - } -int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id,uint8_t eNB_index) -{ - if(nfapi_mode!=3) - return PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->PHR; - else - return 40; // For nfapi_mode=3 consider ideal conditions +int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id,uint8_t eNB_index) { + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) + return PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->PHR; + else + return 40; // l1l2 simulator => ideal conditions } diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c index 5af873acd5830358bcc609fe8207048fe460e580..df9114336fcebaf8dcf54604bff864297b7843d0 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -39,13 +39,14 @@ #include <fcntl.h> #include <errno.h> #include "platform_constants.h" -#ifdef UE_NAS_USE_TUN + #include <sys/ioctl.h> #include <sys/socket.h> #include <linux/if.h> #include <linux/if_tun.h> #include "openairinterface5g_limits.h" -#endif + +#include "pdcp.h" char nl_rx_buf[NL_MAX_PAYLOAD]; @@ -54,20 +55,15 @@ struct nlmsghdr *nas_nlh_tx = NULL; struct nlmsghdr *nas_nlh_rx = NULL; struct iovec nas_iov_tx; struct iovec nas_iov_rx = {nl_rx_buf, sizeof(nl_rx_buf)}; -#ifdef UE_NAS_USE_TUN -int nas_sock_fd[NUMBER_OF_UE_MAX]; -#else -int nas_sock_fd; -#endif + +int nas_sock_fd[MAX_MOBILES_PER_ENB]; + struct msghdr nas_msg_tx; struct msghdr nas_msg_rx; #define GRAAL_NETLINK_ID 31 -#ifdef UE_NAS_USE_TUN - -static int tun_alloc(char *dev) -{ +static int tun_alloc(char *dev) { struct ifreq ifr; int fd, err; @@ -77,66 +73,58 @@ static int tun_alloc(char *dev) } memset(&ifr, 0, sizeof(ifr)); - /* Flags: IFF_TUN - TUN device (no Ethernet headers) * IFF_TAP - TAP device * * IFF_NO_PI - Do not provide packet information */ ifr.ifr_flags = IFF_TUN | IFF_NO_PI; + if( *dev ) - strncpy(ifr.ifr_name, dev, IFNAMSIZ); + strncpy(ifr.ifr_name, dev, IFNAMSIZ); - if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ - close(fd); - return err; + if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) { + close(fd); + return err; } + strcpy(dev, ifr.ifr_name); return fd; } -int netlink_init(void) -{ - int i; +int netlink_init_tun(char *ifprefix, int num_if) { int ret; - char ifname[64]; - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - sprintf(ifname, "oip%d", i+1); + + for (int i = 0; i < num_if; i++) { + sprintf(ifname, "oaitun_%.3s%d",ifprefix,i+1); nas_sock_fd[i] = tun_alloc(ifname); if (nas_sock_fd[i] == -1) { - printf("[NETLINK] Error opening socket %d (%d:%s)\n",nas_sock_fd[i],errno, strerror(errno)); + printf("[NETLINK] Error opening socket %s (%d:%s)\n",ifname,errno, strerror(errno)); exit(1); } - printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd[i]); - -#if !defined(PDCP_USE_NETLINK_QUEUES) + printf("[NETLINK]Opened socket %s with fd %d\n",ifname,nas_sock_fd[i]); ret = fcntl(nas_sock_fd[i],F_SETFL,O_NONBLOCK); if (ret == -1) { printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno)); -#if defined(LINK_ENB_PDCP_TO_IP_DRIVER) - exit(1); -#endif - } -#endif + if (LINK_ENB_PDCP_TO_IP_DRIVER) { + exit(1); + } + } memset(&nas_src_addr, 0, sizeof(nas_src_addr)); nas_src_addr.nl_family = AF_NETLINK; nas_src_addr.nl_pid = 1;//getpid(); /* self pid */ nas_src_addr.nl_groups = 0; /* not in mcast groups */ - ret = bind(nas_sock_fd[i], (struct sockaddr*)&nas_src_addr, sizeof(nas_src_addr)); - - - + ret = bind(nas_sock_fd[i], (struct sockaddr *)&nas_src_addr, sizeof(nas_src_addr)); memset(&nas_dest_addr, 0, sizeof(nas_dest_addr)); nas_dest_addr.nl_family = AF_NETLINK; nas_dest_addr.nl_pid = 0; /* For Linux Kernel */ nas_dest_addr.nl_groups = 0; /* unicast */ - // TX PART nas_nlh_tx=(struct nlmsghdr *)malloc(NLMSG_SPACE(NL_MAX_PAYLOAD)); memset(nas_nlh_tx, 0, NLMSG_SPACE(NL_MAX_PAYLOAD)); @@ -144,7 +132,6 @@ int netlink_init(void) nas_nlh_tx->nlmsg_len = NLMSG_SPACE(NL_MAX_PAYLOAD); nas_nlh_tx->nlmsg_pid = 1;//getpid(); /* self pid */ nas_nlh_tx->nlmsg_flags = 0; - nas_iov_tx.iov_base = (void *)nas_nlh_tx; nas_iov_tx.iov_len = nas_nlh_tx->nlmsg_len; memset(&nas_msg_tx,0,sizeof(nas_msg_tx)); @@ -152,62 +139,50 @@ int netlink_init(void) nas_msg_tx.msg_namelen = sizeof(nas_dest_addr); nas_msg_tx.msg_iov = &nas_iov_tx; nas_msg_tx.msg_iovlen = 1; - - // RX PART memset(&nas_msg_rx,0,sizeof(nas_msg_rx)); nas_msg_rx.msg_name = (void *)&nas_src_addr; nas_msg_rx.msg_namelen = sizeof(nas_src_addr); nas_msg_rx.msg_iov = &nas_iov_rx; nas_msg_rx.msg_iovlen = 1; - } + } /* for */ return 1; } -#else /* UE_NAS_USE_TUN */ -int netlink_init(void) -{ +int netlink_init(void) { int ret; + nas_sock_fd[0] = socket(PF_NETLINK, SOCK_RAW,GRAAL_NETLINK_ID); + if (nas_sock_fd[0] == -1) { + printf("[NETLINK] Error opening socket %d (%d:%s)\n",nas_sock_fd[0],errno, strerror(errno)); - nas_sock_fd = socket(PF_NETLINK, SOCK_RAW,GRAAL_NETLINK_ID); - - if (nas_sock_fd == -1) { - printf("[NETLINK] Error opening socket %d (%d:%s)\n",nas_sock_fd,errno, strerror(errno)); -#if defined(LINK_ENB_PDCP_TO_IP_DRIVER) - exit(1); -#endif + if (LINK_ENB_PDCP_TO_IP_DRIVER) { + exit(1); + } } - printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd); - -#if !defined(PDCP_USE_NETLINK_QUEUES) - ret = fcntl(nas_sock_fd,F_SETFL,O_NONBLOCK); + printf("[NETLINK]Opened socket with fd %d\n",nas_sock_fd[0]); + ret = fcntl(nas_sock_fd[0],F_SETFL,O_NONBLOCK); if (ret == -1) { printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno)); -#if defined(LINK_ENB_PDCP_TO_IP_DRIVER) - exit(1); -#endif - } -#endif + if (LINK_ENB_PDCP_TO_IP_DRIVER) { + exit(1); + } + } memset(&nas_src_addr, 0, sizeof(nas_src_addr)); nas_src_addr.nl_family = AF_NETLINK; nas_src_addr.nl_pid = 1;//getpid(); /* self pid */ nas_src_addr.nl_groups = 0; /* not in mcast groups */ - ret = bind(nas_sock_fd, (struct sockaddr*)&nas_src_addr, sizeof(nas_src_addr)); - - - + ret = bind(nas_sock_fd[0], (struct sockaddr *)&nas_src_addr, sizeof(nas_src_addr)); memset(&nas_dest_addr, 0, sizeof(nas_dest_addr)); nas_dest_addr.nl_family = AF_NETLINK; nas_dest_addr.nl_pid = 0; /* For Linux Kernel */ nas_dest_addr.nl_groups = 0; /* unicast */ - // TX PART nas_nlh_tx=(struct nlmsghdr *)malloc(NLMSG_SPACE(NL_MAX_PAYLOAD)); memset(nas_nlh_tx, 0, NLMSG_SPACE(NL_MAX_PAYLOAD)); @@ -215,7 +190,6 @@ int netlink_init(void) nas_nlh_tx->nlmsg_len = NLMSG_SPACE(NL_MAX_PAYLOAD); nas_nlh_tx->nlmsg_pid = 1;//getpid(); /* self pid */ nas_nlh_tx->nlmsg_flags = 0; - nas_iov_tx.iov_base = (void *)nas_nlh_tx; nas_iov_tx.iov_len = nas_nlh_tx->nlmsg_len; memset(&nas_msg_tx,0,sizeof(nas_msg_tx)); @@ -223,16 +197,12 @@ int netlink_init(void) nas_msg_tx.msg_namelen = sizeof(nas_dest_addr); nas_msg_tx.msg_iov = &nas_iov_tx; nas_msg_tx.msg_iovlen = 1; - - // RX PART memset(&nas_msg_rx,0,sizeof(nas_msg_rx)); nas_msg_rx.msg_name = (void *)&nas_src_addr; nas_msg_rx.msg_namelen = sizeof(nas_src_addr); nas_msg_rx.msg_iov = &nas_iov_rx; nas_msg_rx.msg_iovlen = 1; - - return(nas_sock_fd); + return(nas_sock_fd[0]); } -#endif /* UE_NAS_USE_TUN */ diff --git a/openair1/SIMULATION/ETH_TRANSPORT/proto.h b/openair1/SIMULATION/ETH_TRANSPORT/proto.h index 25b3265757d74b9ff471021211afefc31c7790e0..ff677d1580696f2f92a4ef07f38984ad77137968 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/proto.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/proto.h @@ -34,7 +34,7 @@ #define EMU_PROTO_H_ void init_bypass (void); -void bypass_init ( unsigned int (*tx_handlerP) (unsigned char,char*, unsigned int*, unsigned int*),unsigned int (*rx_handlerP) (unsigned char,char*,unsigned int)); +void bypass_init ( unsigned int (*tx_handlerP) (unsigned char,char *, unsigned int *, unsigned int *),unsigned int (*rx_handlerP) (unsigned char,char *,unsigned int)); int bypass_rx_data(unsigned int frame, unsigned int last_slot, unsigned int next_slot, uint8_t is_master); void bypass_signal_mac_phy(unsigned int frame, unsigned int last_slot, @@ -43,7 +43,7 @@ void bypass_tx_data (emu_transport_info_t Type, unsigned int frame, unsigned int void emulation_tx_rx(void); -unsigned int emul_tx_handler(unsigned char Mode,char *Tx_buffer,unsigned int* Nbytes,unsigned int *Nb_flows); +unsigned int emul_tx_handler(unsigned char Mode,char *Tx_buffer,unsigned int *Nbytes,unsigned int *Nb_flows); unsigned int emul_rx_handler(unsigned char Mode,char *rx_buffer, unsigned int Nbytes); unsigned int emul_rx_data(void); @@ -62,5 +62,6 @@ int multicast_link_read_data_from_sock(uint8_t eNB_flag); void clear_eNB_transport_info(uint8_t); void clear_UE_transport_info(uint8_t); int netlink_init(void); +int netlink_init_tun(char *ifsuffix, int num_if); #endif /* EMU_PROTO_H_ */ diff --git a/openair1/SIMULATION/LTE_PHY/common_sim.h b/openair1/SIMULATION/LTE_PHY/common_sim.h index e9ad4dc888f8573874d8aa1f8d4bf271978d8196..ff8406b0c1a4cab7f759a7aa1573f20752b050ad 100644 --- a/openair1/SIMULATION/LTE_PHY/common_sim.h +++ b/openair1/SIMULATION/LTE_PHY/common_sim.h @@ -25,7 +25,7 @@ void dumpVarArray(varArray_t *input) { printf("\n"); } void sumUpStats(time_stats_t * res, time_stats_t * src, int lastActive) { - reset_meas(res); + reset_meas(res); for (int i=0; i<RX_NB_TH; i++) { res->diff+=src[i].diff; res->diff_square+=src[i].diff_square; @@ -36,7 +36,7 @@ void sumUpStats(time_stats_t * res, time_stats_t * src, int lastActive) { res->p_time=src[lastActive].p_time; } void sumUpStatsSlot(time_stats_t *res, time_stats_t src[RX_NB_TH][2], int lastActive) { - reset_meas(res); + reset_meas(res); for (int i=0; i<RX_NB_TH; i++) { res->diff+=src[i][0].diff+src[i][1].diff; res->diff_square+=src[i][0].diff_square+src[i][1].diff_square; @@ -94,7 +94,7 @@ void logDistribution(FILE* fd, time_stats_t *ptr, varArray_t *sortedList, int dr squareRoot(ptr), (double)ptr->max, *(double*)dataArray(sortedList), median(sortedList),q1(sortedList),q3(sortedList), - dropped); + dropped); } struct option * parse_oai_options(paramdef_t *options) { @@ -125,7 +125,7 @@ struct option * parse_oai_options(paramdef_t *options) { case TYPE_UINT16: *options[i].u16ptr=options[i].defintval; break; - + default: printf("not parsed type for default value %s\n", options[i].optname ); exit(1); @@ -155,11 +155,11 @@ void display_options_values(paramdef_t *options, int verbose) { case TYPE_UINT8: sprintf(varText,"%d",(int)*ptr->u8ptr); break; - + case TYPE_UINT16: sprintf(varText,"%d",(int)*ptr->u16ptr); break; - + default: printf("not decoded type\n"); exit(1); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index b557df3c92653bfcf7a47a90b807022af4d6b959..084d5b5cefefbde2c014d760d78f50d8f530a5f8 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -66,7 +66,7 @@ #include "SCHED_UE/sched_UE.h" #include "common/config/config_load_configmodule.h" #include "PHY/INIT/phy_init.h" - +#include "nfapi/oai_integration/vendor_ext.h" void feptx_ofdm(RU_t *ru); void feptx_prec(RU_t *ru); @@ -89,14 +89,11 @@ THREAD_STRUCT thread_struct; int emulate_rf = 0; -void handler(int sig) -{ +void handler(int sig) { void *array[10]; size_t size; - // get void*'s for all entries on the stack size = backtrace(array, 10); - // print out all the frames to stderr fprintf(stderr, "Error: signal %d:\n", sig); backtrace_symbols_fd(array, size, 2); @@ -114,17 +111,13 @@ uint64_t DLSCH_alloc_pdu_1[2]; #define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2) //#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13 //#define DLSCH_RB_ALLOC 0x0001 -void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms) -{ - +void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms) { int aa, slot_offset, slot_offset_F; - slot_offset_F = (next_slot)*(frame_parms->ofdm_symbol_size)*((frame_parms->Ncp==1) ? 6 : 7); slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1); for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) { // printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc()); - if (frame_parms->Ncp == 1) PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input &txdata[aa][slot_offset], // output @@ -138,15 +131,11 @@ void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_ 7, frame_parms); } - - } - } void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4], - double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) { - + double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) { int i,u; int aa,aarx,aatx; double channelx,channely; @@ -157,19 +146,18 @@ void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { for (aa=0; aa<ru->frame_parms.nb_antennas_tx; aa++) { if (awgn_flag == 0) { - s_re[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); - s_im[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + s_re[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); + s_im[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); } else { - for (aarx=0; aarx<UE->frame_parms.nb_antennas_rx; aarx++) { - if (aa==0) { - r_re[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); - r_im[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); - } else { - r_re[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); - r_im[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); - } - - } + for (aarx=0; aarx<UE->frame_parms.nb_antennas_rx; aarx++) { + if (aa==0) { + r_re[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + } else { + r_re[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + } + } } } } @@ -177,27 +165,26 @@ void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, // Multipath channel if (awgn_flag == 0) { multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im, - 2*UE->frame_parms.samples_per_tti,hold_channel); + 2*UE->frame_parms.samples_per_tti,hold_channel); // printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset); if(abstx==1 && num_rounds>1) if(round==0 && hold_channel==0) { - random_channel(eNB2UE[1],0); - random_channel(eNB2UE[2],0); - random_channel(eNB2UE[3],0); + random_channel(eNB2UE[1],0); + random_channel(eNB2UE[2],0); + random_channel(eNB2UE[3],0); } if (UE->perfect_ce==1) { // fill in perfect channel estimates freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1); /* - LOG_M("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); - LOG_M("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL + 1,1,8); + LOG_M("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); + LOG_M("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL + 1,1,8); */ } } - if(abstx) { if (trials==0 && round==0) { // calculate freq domain representation to compute SINR @@ -206,51 +193,51 @@ void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, fprintf(csv_fd,"%f,",SNR); for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { - for (aarx=0; aarx<eNB2UE[0]->nb_rx; aarx++) { - for (aatx=0; aatx<eNB2UE[0]->nb_tx; aatx++) { - channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x; - channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y; - fprintf(csv_fd,"%e+i*(%e),",channelx,channely); - } - } + for (aarx=0; aarx<eNB2UE[0]->nb_rx; aarx++) { + for (aatx=0; aatx<eNB2UE[0]->nb_tx; aatx++) { + channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x; + channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } } if(num_rounds>1) { - freq_channel(eNB2UE[1], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - - for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { - for (aarx=0; aarx<eNB2UE[1]->nb_rx; aarx++) { - for (aatx=0; aatx<eNB2UE[1]->nb_tx; aatx++) { - channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x; - channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y; - fprintf(csv_fd,"%e+i*(%e),",channelx,channely); - } - } - } - - freq_channel(eNB2UE[2], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - - for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { - for (aarx=0; aarx<eNB2UE[2]->nb_rx; aarx++) { - for (aatx=0; aatx<eNB2UE[2]->nb_tx; aatx++) { - channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x; - channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y; - fprintf(csv_fd,"%e+i*(%e),",channelx,channely); - } - } - } - - freq_channel(eNB2UE[3], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - - for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { - for (aarx=0; aarx<eNB2UE[3]->nb_rx; aarx++) { - for (aatx=0; aatx<eNB2UE[3]->nb_tx; aatx++) { - channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x; - channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y; - fprintf(csv_fd,"%e+i*(%e),",channelx,channely); - } - } - } + freq_channel(eNB2UE[1], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); + + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { + for (aarx=0; aarx<eNB2UE[1]->nb_rx; aarx++) { + for (aatx=0; aatx<eNB2UE[1]->nb_tx; aatx++) { + channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x; + channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + + freq_channel(eNB2UE[2], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); + + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { + for (aarx=0; aarx<eNB2UE[2]->nb_rx; aarx++) { + for (aatx=0; aatx<eNB2UE[2]->nb_tx; aatx++) { + channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x; + channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } + + freq_channel(eNB2UE[3], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); + + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { + for (aarx=0; aarx<eNB2UE[3]->nb_rx; aarx++) { + for (aatx=0; aatx<eNB2UE[3]->nb_tx; aatx++) { + channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x; + channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y; + fprintf(csv_fd,"%e+i*(%e),",channelx,channely); + } + } + } } } } @@ -264,25 +251,23 @@ void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { for (aa=0; aa<UE->frame_parms.nb_antennas_rx; aa++) { //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); - ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = - (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = - (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = + (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = + (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); } } } uint16_t fill_tx_req(nfapi_tx_request_body_t *tx_req_body, - uint16_t absSF, - uint16_t pdu_length, - uint16_t pdu_index, - uint8_t *pdu) -{ + uint16_t absSF, + uint16_t pdu_length, + uint16_t pdu_index, + uint8_t *pdu) { nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; LOG_D(MAC, "Filling TX_req %d for pdu length %d\n", - tx_req_body->number_of_pdus, pdu_length); - + tx_req_body->number_of_pdus, pdu_length); TX_req->pdu_length = pdu_length; TX_req->pdu_index = pdu_index; TX_req->num_segments = 1; @@ -290,40 +275,37 @@ fill_tx_req(nfapi_tx_request_body_t *tx_req_body, TX_req->segments[0].segment_data = pdu; tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; tx_req_body->number_of_pdus++; - return (((absSF / 10) << 4) + (absSF % 10)); } void -fill_dlsch_config(nfapi_dl_config_request_body_t * dl_req, - uint16_t length, - uint16_t pdu_index, - uint16_t rnti, - uint8_t resource_allocation_type, - uint8_t virtual_resource_block_assignment_flag, - uint16_t resource_block_coding, - uint8_t modulation, - uint8_t redundancy_version, - uint8_t transport_blocks, - uint8_t transport_block_to_codeword_swap_flag, - uint8_t transmission_scheme, - uint8_t number_of_layers, - uint8_t number_of_subbands, - // uint8_t codebook_index, - uint8_t ue_category_capacity, - uint8_t pa, - uint8_t delta_power_offset_index, - uint8_t ngap, - uint8_t nprb, - uint8_t transmission_mode, - uint8_t num_bf_prb_per_subband, - uint8_t num_bf_vector) -{ +fill_dlsch_config(nfapi_dl_config_request_body_t *dl_req, + uint16_t length, + uint16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint8_t virtual_resource_block_assignment_flag, + uint16_t resource_block_coding, + uint8_t modulation, + uint8_t redundancy_version, + uint8_t transport_blocks, + uint8_t transport_block_to_codeword_swap_flag, + uint8_t transmission_scheme, + uint8_t number_of_layers, + uint8_t number_of_subbands, + // uint8_t codebook_index, + uint8_t ue_category_capacity, + uint8_t pa, + uint8_t delta_power_offset_index, + uint8_t ngap, + uint8_t nprb, + uint8_t transmission_mode, + uint8_t num_bf_prb_per_subband, + uint8_t num_bf_vector) { nfapi_dl_config_request_pdu_t *dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - + sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; @@ -354,159 +336,132 @@ fill_dlsch_config(nfapi_dl_config_request_body_t * dl_req, } void fill_DCI(PHY_VARS_eNB *eNB, - int frame, - int subframe, - Sched_Rsp_t *sched_resp, - uint8_t input_buffer[NUMBER_OF_UE_MAX][20000], - int n_rnti, - int n_users, - int transmission_mode, - int retrans, - int common_flag, - int NB_RB, - int DLSCH_RB_ALLOC, - int TPC, - int mcs1, - int mcs2, - int ndi, - int rv, - int pa, - int *num_common_dci, - int *num_ue_spec_dci, - int *num_dci) { - + int frame, + int subframe, + Sched_Rsp_t *sched_resp, + uint8_t input_buffer[NUMBER_OF_UE_MAX][20000], + int n_rnti, + int n_users, + int transmission_mode, + int retrans, + int common_flag, + int NB_RB, + int DLSCH_RB_ALLOC, + int TPC, + int mcs1, + int mcs2, + int ndi, + int rv, + int pa, + int *num_common_dci, + int *num_ue_spec_dci, + int *num_dci) { int k; - nfapi_dl_config_request_body_t *dl_req=&sched_resp->DL_req->dl_config_request_body; nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_tx_request_body_t *TX_req=&sched_resp->TX_req->tx_request_body; int NB_RB4TBS = common_flag == 0 ? NB_RB : (2+TPC); - dl_req->number_dci=0; dl_req->number_pdu=0; TX_req->number_of_pdus=0; for(k=0; k<n_users; k++) { switch(transmission_mode) { - case 1: - - case 2: - - case 7: - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = (common_flag == 0) ? NFAPI_DL_DCI_FORMAT_1 : NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = (common_flag == 0) ? n_rnti+k : SI_RNTI; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (common_flag ==0 ) ? 1: 2; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = TPC; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = (common_flag == 0) ? ndi : 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = (common_flag == 0) ? DLSCH_RB_ALLOC : computeRIV(eNB->frame_parms.N_RB_DL,0,NB_RB); - //deactivate second codeword - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = 0; - - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - AssertFatal(TPC>=0 && TPC<2, "TPC should be 0 or 1\n"); - - fill_dlsch_config(dl_req, - get_TBS_DL(mcs1,NB_RB4TBS), - (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */ - (common_flag == 0) ? n_rnti : SI_RNTI, - 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - DLSCH_RB_ALLOC, // resource_block_coding, - get_Qm(mcs1), - rv, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - transmission_mode == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - pa, // pa - 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - transmission_mode, - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - fill_tx_req(TX_req, - (frame * 10) + subframe, - get_TBS_DL(mcs1,NB_RB4TBS), - 0, - input_buffer[k]); - - - break; - - case 3: - if (common_flag == 0) { - - if (eNB->frame_parms.nb_antennas_tx == 2) { - - if (eNB->frame_parms.frame_type == TDD) { - - } - else { - - } - } - } - break; - - case 4: - if (common_flag == 0) { - - if (eNB->frame_parms.nb_antennas_tx == 2) { - - if (eNB->frame_parms.frame_type == TDD) { - - - } - - else { - - } - } else if (eNB->frame_parms.nb_antennas_tx == 4) { + case 1: + case 2: + case 7: + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = (common_flag == 0) ? NFAPI_DL_DCI_FORMAT_1 : NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = (common_flag == 0) ? n_rnti+k : SI_RNTI; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (common_flag ==0 ) ? 1: 2; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = TPC; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = (common_flag == 0) ? ndi : 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = (common_flag == 0) ? DLSCH_RB_ALLOC : computeRIV(eNB->frame_parms.N_RB_DL,0,NB_RB); + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = 0; + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + AssertFatal(TPC>=0 && TPC<2, "TPC should be 0 or 1\n"); + fill_dlsch_config(dl_req, + get_TBS_DL(mcs1,NB_RB4TBS), + (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */ + (common_flag == 0) ? n_rnti : SI_RNTI, + 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + DLSCH_RB_ALLOC, // resource_block_coding, + get_Qm(mcs1), + rv, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + transmission_mode == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + pa, // pa + 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + transmission_mode, + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + fill_tx_req(TX_req, + (frame * 10) + subframe, + get_TBS_DL(mcs1,NB_RB4TBS), + 0, + input_buffer[k]); + break; - } + case 3: + if (common_flag == 0) { + if (eNB->frame_parms.nb_antennas_tx == 2) { + if (eNB->frame_parms.frame_type == TDD) { + } else { + } + } + } - } - else { + break; + case 4: + if (common_flag == 0) { + if (eNB->frame_parms.nb_antennas_tx == 2) { + if (eNB->frame_parms.frame_type == TDD) { + } else { + } + } else if (eNB->frame_parms.nb_antennas_tx == 4) { + } + } else { } break; case 5: case 6: - break; - default: - printf("Unsupported Transmission Mode %d!!!\n",transmission_mode); - exit(-1); - break; + default: + printf("Unsupported Transmission Mode %d!!!\n",transmission_mode); + exit(-1); + break; } } + *num_dci = dl_req->number_dci; *num_ue_spec_dci = dl_req->number_dci; *num_common_dci = 0; @@ -516,7 +471,7 @@ int n_users = 1; int subframe=7; int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1; uint16_t n_rnti=0x1234; -int nfapi_mode=0; + int abstx=0; int Nid_cell=0; int N_RB_DL=25; @@ -541,46 +496,33 @@ int verbose=0, help=0; double SNR,snr0=-2.0,snr1,rate = 0; int print_perf=0; -int main(int argc, char **argv) -{ - +int main(int argc, char **argv) { int k,i,j,aa; int re; - int s,Kr,Kr_bytes; - - LTE_DL_FRAME_PARMS *frame_parms; double s_re0[30720*2],s_im0[30720*2],r_re0[30720*2],r_im0[30720*2]; double s_re1[30720*2],s_im1[30720*2],r_re1[30720*2],r_im1[30720*2]; - double *s_re[2]={s_re0,s_re1}; - double *s_im[2]={s_im0,s_im1}; - double *r_re[2]={r_re0,r_re1}; - double *r_im[2]={r_im0,r_im1}; - - + double *s_re[2]= {s_re0,s_re1}; + double *s_im[2]= {s_im0,s_im1}; + double *r_re[2]= {r_re0,r_re1}; + double *r_im[2]= {r_im0,r_im1}; uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2; - int eNB_id = 0; unsigned char round; unsigned char i_mod = 2; int NB_RB; - SCM_t channel_model=Rayleigh1; // unsigned char *input_data,*decoded_output; - DCI_ALLOC_t da; DCI_ALLOC_t *dci_alloc = &da; - unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0; - unsigned int tx_lev=0,tx_lev_dB=0,trials; unsigned int errs[4],errs2[4],round_trials[4],dci_errors[4];//,num_layers; memset(errs,0,4*sizeof(unsigned int)); memset(errs2,0,4*sizeof(unsigned int)); memset(round_trials,0,4*sizeof(unsigned int)); memset(dci_errors,0,4*sizeof(unsigned int)); - //int re_allocated; char fname[32],vname[32]; FILE *bler_fd; @@ -589,25 +531,20 @@ int main(int argc, char **argv) char time_meas_fname[256]; // FILE *tikz_fd; // char tikz_fname[256]; - FILE *input_trch_fd=NULL; unsigned char input_trch_file=0; FILE *input_fd=NULL; unsigned char input_file=0; - channel_desc_t *eNB2UE[4]; //uint8_t num_pdcch_symbols_2=0; //char stats_buffer[4096]; //int len; - //int u; int n=0; //int iii; - int ch_realization; //int pmi_feedback=0; int hold_channel=0; - // void *data; // int ii; // int bler; @@ -617,23 +554,18 @@ int main(int argc, char **argv) frame_t frame_type = FDD; FD_lte_phy_scope_ue *form_ue = NULL; char title[255]; - int numCCE=0; //int dci_length_bytes=0,dci_length=0; //double channel_bandwidth = 5.0, sampling_rate=7.68; int common_flag=0,TPC=0; - double cpu_freq_GHz; // time_stats_t ts;//,sts,usts; int avg_iter,iter_trials; int rballocset=0; int test_passed=0; - double effective_rate=0.0; char channel_model_input[10]="I"; - int TB0_active = 1; - // LTE_DL_UE_HARQ_t *dlsch0_ue_harq; // LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; uint8_t Kmimo; @@ -642,15 +574,13 @@ int main(int argc, char **argv) int sf; int CCE_table[800]; opp_enabled=1; // to enable the time meas - FILE *csv_fd=NULL; char csv_fname[FILENAME_MAX]; int DLSCH_RB_ALLOC = 0; - int dci_received; PHY_VARS_eNB *eNB; RU_t *ru; - PHY_VARS_UE *UE; + PHY_VARS_UE *UE=NULL; nfapi_dl_config_request_t DL_req; nfapi_ul_config_request_t UL_req; nfapi_hi_dci0_request_t HI_DCI0_req; @@ -659,42 +589,40 @@ int main(int argc, char **argv) nfapi_tx_request_t TX_req; Sched_Rsp_t sched_resp; int pa=dB0; - #if defined(__arm__) FILE *proc_fd = NULL; char buf[64]; - + memset(buf,0,sizeof(buf)); proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r"); + if(!proc_fd) - printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq"); + printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq"); else { - while(fgets(buf, 63, proc_fd)) - printf("%s", buf); + while(fgets(buf, 63, proc_fd)) + printf("%s", buf); } + fclose(proc_fd); cpu_freq_GHz = ((double)atof(buf))/1e6; #else cpu_freq_GHz = get_cpu_freq_GHz(); #endif printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); - memset((void*)&sched_resp,0,sizeof(sched_resp)); + memset((void *)&sched_resp,0,sizeof(sched_resp)); sched_resp.DL_req = &DL_req; sched_resp.UL_req = &UL_req; sched_resp.HI_DCI0_req = &HI_DCI0_req; sched_resp.TX_req = &TX_req; - memset((void*)&DL_req,0,sizeof(DL_req)); - memset((void*)&UL_req,0,sizeof(UL_req)); - memset((void*)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); - memset((void*)&TX_req,0,sizeof(TX_req)); - + memset((void *)&DL_req,0,sizeof(DL_req)); + memset((void *)&UL_req,0,sizeof(UL_req)); + memset((void *)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); + memset((void *)&TX_req,0,sizeof(TX_req)); DL_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdu_list; TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; set_parallel_conf("PARALLEL_SINGLE_THREAD"); cpuf = cpu_freq_GHz; - //signal(SIGSEGV, handler); //signal(SIGABRT, handler); - // default parameters n_frames = 1000; snr0 = 0; @@ -748,13 +676,8 @@ int main(int argc, char **argv) { "help", "display help and exit", PARAMFLAG_BOOL, iptr:&help, defintval:0, TYPE_INT, 0 }, { "", "",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, }; - - - struct option * long_options = parse_oai_options(options); - - + struct option *long_options = parse_oai_options(options); int option_index; - int res; while ((res=getopt_long_only(argc, argv, "", long_options, &option_index)) == 0) { @@ -769,16 +692,16 @@ int main(int argc, char **argv) case TYPE_DOUBLE: *(double *)options[option_index].dblptr=atof(optarg); break; - - case TYPE_UINT8: - *(uint8_t *)options[option_index].dblptr=atoi(optarg); - break; - - case TYPE_UINT16: - *(uint16_t *)options[option_index].dblptr=atoi(optarg); - break; - - default: + + case TYPE_UINT8: + *(uint8_t *)options[option_index].dblptr=atoi(optarg); + break; + + case TYPE_UINT16: + *(uint16_t *)options[option_index].dblptr=atoi(optarg); + break; + + default: printf("not decoded type.\n"); exit(1); } @@ -787,51 +710,51 @@ int main(int argc, char **argv) } switch (long_options[option_index].name[0]) { - case 'a': - awgn_flag = 1; - channel_model = AWGN; - break; + case 'a': + awgn_flag = 1; + channel_model = AWGN; + break; - case 'D': - frame_type=TDD; - break; + case 'D': + frame_type=TDD; + break; - case 'e': - num_rounds=1; - common_flag = 1; - TPC = atoi(optarg); - break; + case 'e': + num_rounds=1; + common_flag = 1; + TPC = atoi(optarg); + break; - case 'i': - input_fd = fopen(optarg,"r"); - input_file=1; - dci_flag = 1; - break; + case 'i': + input_fd = fopen(optarg,"r"); + input_file=1; + dci_flag = 1; + break; - case 'I': - input_trch_fd = fopen(optarg,"r"); - input_trch_file=1; - break; + case 'I': + input_trch_fd = fopen(optarg,"r"); + input_trch_file=1; + break; - case 't': - mcs_i = atoi(optarg); - i_mod = get_Qm(mcs_i); - break; + case 't': + mcs_i = atoi(optarg); + i_mod = get_Qm(mcs_i); + break; - case 'r': - DLSCH_RB_ALLOC = atoi(optarg); - rballocset = 1; - break; + case 'r': + DLSCH_RB_ALLOC = atoi(optarg); + rballocset = 1; + break; - case 'g': - strncpy(channel_model_input,optarg,9); - struct tmp { - char opt; - int m; - int M; - } - tmp[]= { - {'A',SCM_A,2}, + case 'g': + strncpy(channel_model_input,optarg,9); + struct tmp { + char opt; + int m; + int M; + } + tmp[]= { + {'A',SCM_A,2}, {'B',SCM_B,3}, {'C',SCM_C,4}, {'D',SCM_D,5}, @@ -858,96 +781,101 @@ int main(int argc, char **argv) AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); break; - case 'u': - dual_stream_UE=1; - UE->use_ia_receiver = 1; + case 'u': + dual_stream_UE=1; - if ((n_tx_port!=2) || (transmission_mode!=5)) { - printf("IA receiver only supported for TM5!"); - exit(-1); - } + if (UE != NULL) + UE->use_ia_receiver = 1; + else { + printf("UE is NULL\n"); + exit(-1); + } - break; + if ((n_tx_port!=2) || (transmission_mode!=5)) { + printf("IA receiver only supported for TM5!"); + exit(-1); + } - case 'v': - i_mod = atoi(optarg); + break; - if (i_mod!=2 && i_mod!=4 && i_mod!=6) { - printf("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); - exit(-1); - } + case 'v': + i_mod = atoi(optarg); - break; + if (i_mod!=2 && i_mod!=4 && i_mod!=6) { + printf("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); + exit(-1); + } - case 'q': - n_tx_port=atoi(optarg); + break; - if ((n_tx_port==0) || ((n_tx_port>2))) { - printf("Unsupported number of cell specific antennas ports %d\n",n_tx_port); - exit(-1); - } + case 'q': + n_tx_port=atoi(optarg); - break; + if ((n_tx_port==0) || ((n_tx_port>2))) { + printf("Unsupported number of cell specific antennas ports %d\n",n_tx_port); + exit(-1); + } + break; - case 'x': - transmission_mode=atoi(optarg); + case 'x': + transmission_mode=atoi(optarg); + + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=3) && + (transmission_mode!=4) && + (transmission_mode!=5) && + (transmission_mode!=6) && + (transmission_mode!=7)) { + printf("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } - if ((transmission_mode!=1) && - (transmission_mode!=2) && - (transmission_mode!=3) && - (transmission_mode!=4) && - (transmission_mode!=5) && - (transmission_mode!=6) && - (transmission_mode!=7)) { - printf("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } + if (transmission_mode>1 && transmission_mode<7) { + n_tx_port = 2; + } - if (transmission_mode>1 && transmission_mode<7) { - n_tx_port = 2; - } + break; - break; + case 'y': + n_tx_phy=atoi(optarg); - case 'y': - n_tx_phy=atoi(optarg); + if (n_tx_phy < n_tx_port) { + printf("n_tx_phy mush not be smaller than n_tx_port"); + exit(-1); + } - if (n_tx_phy < n_tx_port) { - printf("n_tx_phy mush not be smaller than n_tx_port"); - exit(-1); - } + if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) { + printf("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode); + exit(-1); + } - if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) { - printf("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode); - exit(-1); - } + if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) { + printf("Physical number of antennas not supported for TM7.\n"); + exit(-1); + } - if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) { - printf("Physical number of antennas not supported for TM7.\n"); - exit(-1); - } + break; - break; + case 'z': + n_rx=atoi(optarg); - case 'z': - n_rx=atoi(optarg); + if ((n_rx==0) || (n_rx>2)) { + printf("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } - if ((n_rx==0) || (n_rx>2)) { - printf("Unsupported number of rx antennas %d\n",n_rx); - exit(-1); - } + break; - break; + case 'Q': + set_parallel_conf(optarg); + break; - case 'Q': - set_parallel_conf(optarg); - break; - - default: - printf("Wrong option: %s\n",long_options[option_index].name); - exit(1); - break; + default: + printf("Wrong option: %s\n",long_options[option_index].name); + exit(1); + break; } } @@ -957,18 +885,19 @@ int main(int argc, char **argv) } if (help || verbose ) - display_options_values(options, true); + display_options_values(options, true); + if (help) exit(0); - + if (thread_struct.parallel_conf != PARALLEL_SINGLE_THREAD) set_worker_conf("WORKER_ENABLE"); if (transmission_mode>1) pa=dBm3; - printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa); + printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa); AssertFatal(load_configmodule(argc,argv, CONFIG_ENABLECMDLINEONLY) != NULL, - "cannot load configuration module, exiting\n"); + "cannot load configuration module, exiting\n"); logInit(); set_glog_onlinelog(true); // enable these lines if you need debug info @@ -981,29 +910,33 @@ int main(int argc, char **argv) if (common_flag == 0) { switch (N_RB_DL) { - case 6: - if (rballocset==0) DLSCH_RB_ALLOC = 0x3f; - num_pdcch_symbols = 3; - break; - - case 25: - if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff; - break; - - case 50: - if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff; - break; - - case 100: - if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff; - break; + case 6: + if (rballocset==0) DLSCH_RB_ALLOC = 0x3f; + + num_pdcch_symbols = 3; + break; + + case 25: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff; + + break; + + case 50: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff; + + break; + + case 100: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff; + + break; } - + NB_RB = conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); - } - else { + } else { if (rballocset==0) NB_RB = 8; else NB_RB = DLSCH_RB_ALLOC; + AssertFatal(NB_RB <= N_RB_DL,"illegal NB_RB %d\n",NB_RB); } @@ -1014,10 +947,15 @@ int main(int argc, char **argv) fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); if (!dual_stream_UE==0) { - UE->use_ia_receiver = 1; - fl_set_button(form_ue->button_0,1); - fl_set_object_label(form_ue->button_0, "IA Receiver ON"); - fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN); + if (UE) { + UE->use_ia_receiver = 1; + fl_set_button(form_ue->button_0,1); + fl_set_object_label(form_ue->button_0, "IA Receiver ON"); + fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN); + } else { + printf("UE is NULL\n"); + exit(-1); + } } } @@ -1025,42 +963,44 @@ int main(int argc, char **argv) n_users = 2; printf("dual_stream_UE=%d\n", dual_stream_UE); } + RC.nb_L1_inst = 1; RC.nb_RU = 1; - lte_param_init(&eNB,&UE,&ru, - n_tx_port, - n_tx_phy, - 1, + n_tx_port, + n_tx_phy, + 1, n_rx, - transmission_mode, - extended_prefix_flag, - frame_type, - Nid_cell, - tdd_config, - N_RB_DL, - pa, - threequarter_fs, - osf, - perfect_ce); - RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); + transmission_mode, + extended_prefix_flag, + frame_type, + Nid_cell, + tdd_config, + N_RB_DL, + pa, + threequarter_fs, + osf, + perfect_ce); + RC.eNB = (PHY_VARS_eNB ** *)malloc(sizeof(PHY_VARS_eNB **)); RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); RC.ru = (RU_t **)malloc(sizeof(RC.ru)); RC.eNB[0][0] = eNB; RC.ru[0] = ru; printf("lte_param_init done\n"); + if ((transmission_mode==1) || (transmission_mode==7)) { for (aa=0; aa<ru->nb_tx; aa++) - for (re=0; re<ru->frame_parms.ofdm_symbol_size; re++) - ru->beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; + for (re=0; re<ru->frame_parms.ofdm_symbol_size; re++) + ru->beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; } if (transmission_mode<7) - ru->do_precoding=0; + ru->do_precoding=0; else - ru->do_precoding=1; + ru->do_precoding=1; eNB->mac_enabled=1; + if(get_thread_worker_conf() == WORKER_ENABLE) { extern void init_td_thread(PHY_VARS_eNB *); extern void init_te_thread(PHY_VARS_eNB *); @@ -1069,27 +1009,21 @@ int main(int argc, char **argv) } // callback functions required for phy_procedures_tx - // eNB_id_i = UE->n_connected_eNB; - printf("Setting mcs1 = %d\n",mcs1); printf("Setting mcs2 = %d\n",mcs2); printf("NPRB = %d\n",NB_RB); printf("n_frames = %d\n",n_frames); printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag); - snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - uint8_t input_buffer[NUMBER_OF_UE_MAX][20000]; - for (i=0;i<n_users;i++) - for (j=0;j<20000;j++) input_buffer[i][j] = (uint8_t)((taus())&255); + for (i=0; i<n_users; i++) + for (j=0; j<20000; j++) input_buffer[i][j] = (uint8_t)((taus())&255); frame_parms = &eNB->frame_parms; - nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12; - printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model); printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d\n", SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8); @@ -1100,10 +1034,12 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d.csv",transmission_mode,channel_model,n_rx,mcs1); bler_fd = fopen(bler_fname,"w"); + if (bler_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",bler_fname); exit(-1); } + fprintf(bler_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); if (test_perf != 0) { @@ -1117,6 +1053,7 @@ int main(int argc, char **argv) N_RB_DL,mcs1,n_tx_phy,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode); //mkdir(dirname,0777); time_meas_fd = fopen(time_meas_fname,"w"); + if (time_meas_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",time_meas_fname); exit(-1); @@ -1127,11 +1064,13 @@ int main(int argc, char **argv) // CSV file sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d.m",transmission_mode,dual_stream_UE,mcs1,channel_model,n_frames,num_rounds); csv_fd = fopen(csv_fname,"w"); - fprintf(csv_fd,"data_all%d=[",mcs1); + if (csv_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",csv_fname); exit(-1); } + + fprintf(csv_fd,"data_all%d=[",mcs1); } /* @@ -1230,38 +1169,35 @@ int main(int argc, char **argv) break; } */ - - UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti; UE->n_connected_eNB = 1; - printf("Allocating %dx%d eNB->UE channel descriptor\n",eNB->frame_parms.nb_antennas_tx,UE->frame_parms.nb_antennas_rx); eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), forgetting_factor, rx_sample_offset, 0); - reset_meas(&eNB2UE[0]->random_channel); reset_meas(&eNB2UE[0]->interp_time); + if(num_rounds>1) { for(n=1; n<4; n++) { eNB2UE[n] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), - forgetting_factor, + N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + forgetting_factor, rx_sample_offset, 0); reset_meas(&eNB2UE[n]->random_channel); reset_meas(&eNB2UE[n]->interp_time); } } - + if (eNB2UE[0]==NULL) { printf("Problem generating channel model. Exiting.\n"); exit(-1); @@ -1273,20 +1209,23 @@ int main(int argc, char **argv) Kmimo=1; switch (ue_category) { - case 1: - Nsoft = 250368; - break; - case 2: - case 3: - Nsoft = 1237248; - break; - case 4: - Nsoft = 1827072; - break; - default: - printf("Unsupported UE category %d\n",ue_category); - exit(-1); - break; + case 1: + Nsoft = 250368; + break; + + case 2: + case 3: + Nsoft = 1237248; + break; + + case 4: + Nsoft = 1827072; + break; + + default: + printf("Unsupported UE category %d\n",ue_category); + exit(-1); + break; } for (k=0; k<NUMBER_OF_UE_MAX; k++) { @@ -1321,15 +1260,13 @@ int main(int argc, char **argv) } } - UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - UE->dlsch_ra[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); - UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); - + UE->dlsch_SI[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->dlsch_ra[0] = new_ue_dlsch(1,1,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0); + UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); // structure for SIC at UE UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { - eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); if (n_users>1) @@ -1344,38 +1281,33 @@ int main(int argc, char **argv) L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc; if (input_fd==NULL) { - DL_req.dl_config_request_body.number_pdcch_ofdm_symbols = num_pdcch_symbols; DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; // UE specific DCI fill_DCI(eNB, - proc_eNB->frame_tx,subframe, - &sched_resp, - input_buffer, - n_rnti, - n_users, - transmission_mode, - 0, - common_flag, - NB_RB, - DLSCH_RB_ALLOC, - TPC, - mcs1, - mcs2, - 1, - 0, - pa, - &num_common_dci, - &num_ue_spec_dci, - &num_dci); - + proc_eNB->frame_tx,subframe, + &sched_resp, + input_buffer, + n_rnti, + n_users, + transmission_mode, + 0, + common_flag, + NB_RB, + DLSCH_RB_ALLOC, + TPC, + mcs1, + mcs2, + 1, + 0, + pa, + &num_common_dci, + &num_ue_spec_dci, + &num_dci); numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe)); if (n_frames==1) printf("num_pdcch_symbols %d, numCCE %d, num_dci %d/%d/%d\n",num_pdcch_symbols,numCCE, num_dci,num_ue_spec_dci,num_common_dci); - - - } snr_step = input_snr_step; @@ -1401,13 +1333,11 @@ int main(int argc, char **argv) round_trials[1] = 0; round_trials[2] = 0; round_trials[3] = 0; - dci_errors[0]=0; dci_errors[1]=0; dci_errors[2]=0; dci_errors[3]=0; // avg_ber = 0; - round=0; avg_iter = 0; iter_trials=0; @@ -1422,15 +1352,17 @@ int main(int argc, char **argv) reset_meas(&eNB->dlsch_turbo_encoding_stats); reset_meas(&eNB->dlsch_common_and_dci); reset_meas(&eNB->dlsch_ue_specific); + for (int i=0; i<RX_NB_TH; i++) { - reset_meas(&UE->phy_proc_rx[i]); // total UE rx - reset_meas(&UE->ue_front_end_stat[i]); + reset_meas(&UE->phy_proc_rx[i]); // total UE rx + reset_meas(&UE->ue_front_end_stat[i]); reset_meas(&UE->pdsch_procedures_stat[i]); - reset_meas(&UE->dlsch_procedures_stat[i]); - reset_meas(&UE->dlsch_decoding_stats[i]); - reset_meas(&UE->dlsch_llr_stats_parallelization[i][0]); - reset_meas(&UE->dlsch_llr_stats_parallelization[i][1]); + reset_meas(&UE->dlsch_procedures_stat[i]); + reset_meas(&UE->dlsch_decoding_stats[i]); + reset_meas(&UE->dlsch_llr_stats_parallelization[i][0]); + reset_meas(&UE->dlsch_llr_stats_parallelization[i][1]); } + reset_meas(&UE->ofdm_demod_stats); reset_meas(&UE->crnti_procedures_stats); reset_meas(&UE->dlsch_channel_estimation_stats); @@ -1449,7 +1381,7 @@ int main(int argc, char **argv) reset_meas(&UE->dlsch_tc_intl1_stats); reset_meas(&UE->dlsch_tc_intl2_stats); // initialization - // initialization + // initialization varArray_t *table_tx=initVarArray(1000,sizeof(double)); varArray_t *table_tx_ifft=initVarArray(1000,sizeof(double)); varArray_t *table_tx_mod=initVarArray(1000,sizeof(double)); @@ -1466,17 +1398,16 @@ int main(int argc, char **argv) varArray_t *table_rx_dec=initVarArray(1000,sizeof(double)); for (trials = 0; trials<n_frames; trials++) { - //printf("Trial %d\n",trials); + //printf("Trial %d\n",trials); fflush(stdout); round=0; - //if (trials%100==0) eNB2UE[0]->first_run = 1; - UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack = 0; - UE->dlsch[UE->current_thread_id[subframe]][eNB_id][1]->harq_ack[subframe].ack = 0; + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack = 0; + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][1]->harq_ack[subframe].ack = 0; while ((round < num_rounds) && (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 0)) { - // printf("Trial %d, round %d\n",trials,round); + // printf("Trial %d, round %d\n",trials,round); round_trials[round]++; //if(transmission_mode>=5) @@ -1492,7 +1423,7 @@ int main(int argc, char **argv) } else hold_channel = 0;//(round==0) ? 0 : 1; - //PMI_FEEDBACK: + //PMI_FEEDBACK: // printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { @@ -1500,91 +1431,73 @@ int main(int argc, char **argv) } if (input_fd==NULL) { - - // Simulate HARQ procedures!!! - memset(CCE_table,0,800*sizeof(int)); - if (/*common_flag == 0*/ 1) { + memset(CCE_table,0,800*sizeof(int)); - num_dci=0; - num_common_dci=0; - num_ue_spec_dci=0; + if (/*common_flag == 0*/ 1) { + num_dci=0; + num_common_dci=0; + num_ue_spec_dci=0; if (round == 0) { // First round TB0_active = 1; - eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3; - DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; - TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; - fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,0,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, - mcs1,mcs2,!(trials&1),round&3,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); - } - else { - DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; - TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; - fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,1,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, - (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); - } - } - - proc_eNB->subframe_tx = subframe; - sched_resp.subframe=subframe; - sched_resp.frame=proc_eNB->frame_tx; - - eNB->abstraction_flag=0; - schedule_response(&sched_resp); - phy_procedures_eNB_TX(eNB,proc_eNB,1); - - if (uncoded_ber_bit == NULL) { - // this is for user 0 only - printf("nb_rb %d, rb_alloc %x, mcs %d\n", - eNB->dlsch[0][0]->harq_processes[0]->nb_rb, - eNB->dlsch[0][0]->harq_processes[0]->rb_alloc[0], - eNB->dlsch[0][0]->harq_processes[0]->mcs); - - coded_bits_per_codeword = get_G(&eNB->frame_parms, - eNB->dlsch[0][0]->harq_processes[0]->nb_rb, - eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, - get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), - eNB->dlsch[0][0]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0, - subframe, - transmission_mode>=7?transmission_mode:0); - - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); - printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); - } - - start_meas(&eNB->ofdm_mod_stats); - - ru->proc.subframe_tx=subframe; - memcpy((void*)&ru->frame_parms,(void*)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); - feptx_prec(ru); - feptx_ofdm(ru); - - stop_meas(&eNB->ofdm_mod_stats); - - - - // generate next subframe for channel estimation - - DL_req.dl_config_request_body.number_dci=0; - DL_req.dl_config_request_body.number_pdu=0; - TX_req.tx_request_body.number_of_pdus=0; - proc_eNB->subframe_tx = subframe+1; - sched_resp.subframe=subframe+1; - schedule_response(&sched_resp); - phy_procedures_eNB_TX(eNB,proc_eNB,0); - - - ru->proc.subframe_tx=(subframe+1)%10; - feptx_prec(ru); - feptx_ofdm(ru); - + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,0,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, + mcs1,mcs2,!(trials&1),round&3,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); + } else { + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,1,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, + (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); + } + } - proc_eNB->frame_tx++; + proc_eNB->subframe_tx = subframe; + sched_resp.subframe=subframe; + sched_resp.frame=proc_eNB->frame_tx; + eNB->abstraction_flag=0; + schedule_response(&sched_resp); + phy_procedures_eNB_TX(eNB,proc_eNB,1); + + if (uncoded_ber_bit == NULL) { + // this is for user 0 only + printf("nb_rb %d, rb_alloc %x, mcs %d\n", + eNB->dlsch[0][0]->harq_processes[0]->nb_rb, + eNB->dlsch[0][0]->harq_processes[0]->rb_alloc[0], + eNB->dlsch[0][0]->harq_processes[0]->mcs); + coded_bits_per_codeword = get_G(&eNB->frame_parms, + eNB->dlsch[0][0]->harq_processes[0]->nb_rb, + eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, + get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), + eNB->dlsch[0][0]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0, + subframe, + transmission_mode>=7?transmission_mode:0); + uncoded_ber_bit = (short *) malloc(sizeof(short)*coded_bits_per_codeword); + printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); + } + start_meas(&eNB->ofdm_mod_stats); + ru->proc.subframe_tx=subframe; + memcpy((void *)&ru->frame_parms,(void *)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + feptx_prec(ru); + feptx_ofdm(ru); + stop_meas(&eNB->ofdm_mod_stats); + // generate next subframe for channel estimation + DL_req.dl_config_request_body.number_dci=0; + DL_req.dl_config_request_body.number_pdu=0; + TX_req.tx_request_body.number_of_pdus=0; + proc_eNB->subframe_tx = subframe+1; + sched_resp.subframe=subframe+1; + schedule_response(&sched_resp); + phy_procedures_eNB_TX(eNB,proc_eNB,0); + ru->proc.subframe_tx=(subframe+1)%10; + feptx_prec(ru); + feptx_ofdm(ru); + proc_eNB->frame_tx++; tx_lev = 0; for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { @@ -1595,176 +1508,153 @@ int main(int argc, char **argv) tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - - if (n_frames==1) { - printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); - + printf("tx_lev = %u (%u dB)\n",tx_lev,tx_lev_dB); LOG_M("txsig0.m","txs0", &ru->common.txdata[0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1); if (transmission_mode<7) { - LOG_M("txsigF0.m","txsF0x", &ru->common.txdataF_BF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + LOG_M("txsigF0.m","txsF0x", &ru->common.txdataF_BF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); } else if (transmission_mode == 7) { LOG_M("txsigF0.m","txsF0", &ru->common.txdataF_BF[5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); LOG_M("txsigF0_BF.m","txsF0_BF", &ru->common.txdataF_BF[0][0],eNB->frame_parms.ofdm_symbol_size,1,1); } } - } - - DL_channel(ru,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd); - - - UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]]; - proc->subframe_rx = subframe; - UE->UE_mode[0] = PUSCH; - - // first symbol has to be done separately in one-shot mode - slot_fep(UE, - 0, - (proc->subframe_rx<<1), - UE->rx_offset, - 0, - 0); - - if (n_frames==1) printf("Running phy_procedures_UE_RX\n"); - - if (dci_flag==0) { - memcpy(dci_alloc,eNB->pdcch_vars[subframe&1].dci_alloc,num_dci*sizeof(DCI_ALLOC_t)); - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols; - if (n_frames==1) - printf("bypassing PDCCH/DCI detection\n"); - if (generate_ue_dlsch_params_from_dci(proc->frame_rx, - proc->subframe_rx, - (void *)&dci_alloc[0].dci_pdu, - common_flag == 0 ? n_rnti : SI_RNTI, - dci_alloc[0].format, - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], - UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], - UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0], - &UE->frame_parms, - UE->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - UE->transmission_mode[eNB_id]<7?0:UE->transmission_mode[eNB_id], - 0)==0) { - - dump_dci(&UE->frame_parms, &dci_alloc[0]); - - //UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][0]->active = 1; - //UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][1]->active = 1; - - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols; - - UE->dlsch_received[eNB_id]++; - } else { - LOG_E(PHY,"Problem in DCI!\n"); - } - } - - dci_received = UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received; - - phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx); - - dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received; - - if (dci_flag && (dci_received == 0)) { - printf("DCI not received\n"); - dci_errors[round]++; - - LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); - LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - - LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); - LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); - - LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); - LOG_M("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); - - - exit(-1); + } - } + DL_channel(ru,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd); + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]]; + proc->subframe_rx = subframe; + UE->UE_mode[0] = PUSCH; + // first symbol has to be done separately in one-shot mode + slot_fep(UE, + 0, + (proc->subframe_rx<<1), + UE->rx_offset, + 0, + 0); - int bit_errors=0; - if ((test_perf ==0 ) && (n_frames==1)) { + if (n_frames==1) printf("Running phy_procedures_UE_RX\n"); - dlsch_unscrambling(&eNB->frame_parms, - 0, - UE->dlsch[UE->current_thread_id[subframe]][0][0], - coded_bits_per_codeword, - UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0], - 0, - subframe<<1); - for (i=0;i<coded_bits_per_codeword;i++) - if ((eNB->dlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)|| - (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) { - uncoded_ber_bit[bit_errors++] = 1; - printf("error in pos %d : %d => %d\n",i, - eNB->dlsch[0][0]->harq_processes[0]->e[i], - UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); - } - else { - /* - printf("no error in pos %d : %d => %d\n",i, - eNB->dlsch[0][0]->harq_processes[0]->e[i], - UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); - */ - } - - LOG_M("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); - LOG_M("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); - - if (eNB->frame_parms.nb_antennas_tx>1) - LOG_M("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8); - - //common vars - LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); - - LOG_M("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); - - if (UE->frame_parms.nb_antennas_rx>1) { - LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1); - LOG_M("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); - } - - LOG_M("dlsch00_r0.m","dl00_r0", - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), - UE->frame_parms.ofdm_symbol_size*nsymb,1,1); - - if (UE->frame_parms.nb_antennas_rx>1) - LOG_M("dlsch01_r0.m","dl01_r0", - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]), - UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + if (dci_flag==0) { + memcpy(dci_alloc,eNB->pdcch_vars[subframe&1].dci_alloc,num_dci*sizeof(DCI_ALLOC_t)); + UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols; - if (eNB->frame_parms.nb_antennas_tx>1) - LOG_M("dlsch10_r0.m","dl10_r0", - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]), - UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + if (n_frames==1) + printf("bypassing PDCCH/DCI detection\n"); + + if (generate_ue_dlsch_params_from_dci(proc->frame_rx, + proc->subframe_rx, + (void *)&dci_alloc[0].dci_pdu, + common_flag == 0 ? n_rnti : SI_RNTI, + dci_alloc[0].format, + UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], + UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], + UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0], + &UE->frame_parms, + UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + UE->transmission_mode[eNB_id]<7?0:UE->transmission_mode[eNB_id], + 0)==0) { + dump_dci(&UE->frame_parms, &dci_alloc[0]); + //UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][0]->active = 1; + //UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][1]->active = 1; + UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols; + UE->dlsch_received[eNB_id]++; + } else { + LOG_E(PHY,"Problem in DCI!\n"); + } + } - if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) - LOG_M("dlsch11_r0.m","dl11_r0", - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]), - UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + dci_received = UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received; + phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx); + dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received; + + if (dci_flag && (dci_received == 0)) { + printf("DCI not received\n"); + dci_errors[round]++; + LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); + LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); + LOG_M("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + exit(-1); + } - //pdsch_vars - printf("coded_bits_per_codeword %d\n",coded_bits_per_codeword); + int bit_errors=0; + + if ((test_perf ==0 ) && (n_frames==1)) { + dlsch_unscrambling(&eNB->frame_parms, + 0, + UE->dlsch[UE->current_thread_id[subframe]][0][0], + coded_bits_per_codeword, + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0], + 0, + subframe<<1); + + for (i=0; i<coded_bits_per_codeword; i++) + if ((eNB->dlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)|| + (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) { + uncoded_ber_bit[bit_errors++] = 1; + printf("error in pos %d : %d => %d\n",i, + eNB->dlsch[0][0]->harq_processes[0]->e[i], + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); + } else { + /* + printf("no error in pos %d : %d => %d\n",i, + eNB->dlsch[0][0]->harq_processes[0]->e[i], + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); + */ + } - dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid); + LOG_M("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); + LOG_M("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); - LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + if (eNB->frame_parms.nb_antennas_tx>1) + LOG_M("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8); - //pdcch_vars - LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); - LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + //common vars + LOG_M("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); + LOG_M("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); - LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); - LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); + if (UE->frame_parms.nb_antennas_rx>1) { + LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1); + LOG_M("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + } - } + LOG_M("dlsch00_r0.m","dl00_r0", + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + + if (UE->frame_parms.nb_antennas_rx>1) + LOG_M("dlsch01_r0.m","dl01_r0", + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + + if (eNB->frame_parms.nb_antennas_tx>1) + LOG_M("dlsch10_r0.m","dl10_r0", + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + + if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) + LOG_M("dlsch11_r0.m","dl11_r0", + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + + //pdsch_vars + printf("coded_bits_per_codeword %u\n",coded_bits_per_codeword); + dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid); + LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); + //pdcch_vars + LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); + } if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 1) { - avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt; iter_trials++; @@ -1773,18 +1663,13 @@ int main(int argc, char **argv) UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; - - - } // DLSCH received ok - else { + } // DLSCH received ok + else { errs[round]++; - avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt-1; iter_trials++; if (n_frames==1) { - - //if ((n_frames==1) || (SNR>=30)) { printf("DLSCH errors found (round %d), uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword); @@ -1795,11 +1680,11 @@ int main(int argc, char **argv) Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; - printf("Decoded_output (Segment %d):\n",s); for (i=0; i<Kr_bytes; i++) - printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i],UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i], + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); } sprintf(fname,"rxsig0_r%d.m",round); @@ -1807,7 +1692,6 @@ int main(int argc, char **argv) LOG_M(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); sprintf(fname,"rxsigF0_r%d.m",round); sprintf(vname,"rxs0F_r%d",round); - LOG_M(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); if (UE->frame_parms.nb_antennas_rx>1) { @@ -1822,67 +1706,63 @@ int main(int argc, char **argv) sprintf(fname,"dlsch00_r%d.m",round); sprintf(vname,"dl00_r%d",round); LOG_M(fname,vname, - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), - UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); if (UE->frame_parms.nb_antennas_rx>1) { sprintf(fname,"dlsch01_r%d.m",round); sprintf(vname,"dl01_r%d",round); LOG_M(fname,vname, - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]), - UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); } if (eNB->frame_parms.nb_antennas_tx>1) { sprintf(fname,"dlsch10_r%d.m",round); sprintf(vname,"dl10_r%d",round); LOG_M(fname,vname, - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]), - UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); } if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) { sprintf(fname,"dlsch11_r%d.m",round); sprintf(vname,"dl11_r%d",round); LOG_M(fname,vname, - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]), - UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); } //pdsch_vars dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid); - - //LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); //LOG_M("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); //LOG_M("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4); //LOG_M("dlsch_w.m","w",UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0); - //pdcch_vars - LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); - LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - - LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); - LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); + //pdcch_vars + LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); + LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); if (round == 3) exit(-1); } // printf("round %d errors %d/%d\n",round,errs[round],trials); - round++; // UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++; } - if (xforms==1) { - phy_scope_UE(form_ue, - UE, - eNB_id, - 0,// UE_id - subframe); - } + if (xforms==1) { + phy_scope_UE(form_ue, + UE, + eNB_id, + 0,// UE_id + subframe); + } - UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++; - } //round + UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++; + } //round // printf("\n"); @@ -1899,40 +1779,34 @@ int main(int argc, char **argv) UE->total_TBS_last[eNB_id] = UE->total_TBS[eNB_id]; } - - - /* calculate the total processing time for each packet, * get the max, min, and number of packets that exceed t>2000us */ - double t_tx = inMicroS(eNB->phy_proc_tx.p_time); + double t_tx = inMicroS(eNB->phy_proc_tx.p_time); double t_tx_ifft = inMicroS(eNB->ofdm_mod_stats.p_time); double t_rx = inMicroS(UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time); - sumUpStats(&phy_proc_rx_tot, UE->phy_proc_rx, UE->current_thread_id[subframe]); - sumUpStats(&ue_front_end_tot, UE->ue_front_end_stat, UE->current_thread_id[subframe]); - sumUpStats(&pdsch_procedures_tot, UE->pdsch_procedures_stat, UE->current_thread_id[subframe]); - sumUpStats(&dlsch_procedures_tot, UE->dlsch_procedures_stat, UE->current_thread_id[subframe]); - sumUpStats(&dlsch_decoding_tot, UE->dlsch_decoding_stats, UE->current_thread_id[subframe]); - sumUpStatsSlot(&dlsch_llr_tot, UE->dlsch_llr_stats_parallelization, UE->current_thread_id[subframe]); - - - double t_rx_fft = inMicroS(UE->ofdm_demod_stats.p_time); + sumUpStats(&phy_proc_rx_tot, UE->phy_proc_rx, UE->current_thread_id[subframe]); + sumUpStats(&ue_front_end_tot, UE->ue_front_end_stat, UE->current_thread_id[subframe]); + sumUpStats(&pdsch_procedures_tot, UE->pdsch_procedures_stat, UE->current_thread_id[subframe]); + sumUpStats(&dlsch_procedures_tot, UE->dlsch_procedures_stat, UE->current_thread_id[subframe]); + sumUpStats(&dlsch_decoding_tot, UE->dlsch_decoding_stats, UE->current_thread_id[subframe]); + sumUpStatsSlot(&dlsch_llr_tot, UE->dlsch_llr_stats_parallelization, UE->current_thread_id[subframe]); + double t_rx_fft = inMicroS(UE->ofdm_demod_stats.p_time); double t_rx_demod = inMicroS(UE->dlsch_rx_pdcch_stats.p_time); double t_rx_dec = inMicroS(UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time); if (t_tx > 2000 )// 2ms is too much time for a subframe n_tx_dropped++; - + if (t_rx > 2000 ) n_rx_dropped++; - - appendVarArray(table_tx, &t_tx); + + appendVarArray(table_tx, &t_tx); appendVarArray(table_tx_ifft, &t_tx_ifft); appendVarArray(table_rx, &t_rx ); appendVarArray(table_rx_fft, &t_rx_fft ); appendVarArray(table_rx_demod, &t_rx_demod ); appendVarArray(table_rx_dec, &t_rx_dec ); - } //trials // round_trials[0]: number of code word : goodput the protocol @@ -1953,12 +1827,10 @@ int main(int argc, char **argv) } effective_rate = 1.0-((double)(errs[0]+errs[1]+errs[2]+errs[3])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); - printf("\n**********************SNR = %f dB (tx_lev %f)**************************\n", SNR, (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12))); - - printf("Errors (%d(%d)/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e), dci_errors %d/%d, Pe = %e => effective rate %f, normalized delay %f (%f)\n", + printf("Errors (%u(%u)/%u %u/%u %u/%u %u/%u), Pe = (%e,%e,%e,%e), dci_errors %u/%u, Pe = %e => effective rate %f, normalized delay %f (%f)\n", errs[0], errs2[0], round_trials[0], @@ -1982,39 +1854,37 @@ int main(int argc, char **argv) (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/ (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); - double timeBase=1/(1000*cpu_freq_GHz); + if (print_perf==1) { printf("\neNB TX function statistics (per 1ms subframe)\n"); - printDistribution(&eNB->phy_proc_tx,table_tx,"PHY proc tx"); - printStatIndent(&eNB->dlsch_common_and_dci,"DL common channels and dci time"); - printStatIndent(&eNB->dlsch_ue_specific,"DL per ue part time"); - printStatIndent2(&eNB->dlsch_encoding_stats,"DLSCH encoding time"); - printStatIndent3(&eNB->dlsch_rate_matching_stats,"DLSCH rate matching time"); - printStatIndent3(&eNB->dlsch_turbo_encoding_stats,"DLSCH turbo encoding time"); - printStatIndent3(&eNB->dlsch_interleaving_stats,"DLSCH interleaving time"); - printStatIndent2(&eNB->dlsch_scrambling_stats, "DLSCH scrambling time"); - printStatIndent2(&eNB->dlsch_modulation_stats, "DLSCH modulation time"); - printDistribution(&eNB->ofdm_mod_stats,table_tx_ifft,"OFDM_mod (idft) time"); - + printDistribution(&eNB->phy_proc_tx,table_tx,"PHY proc tx"); + printStatIndent(&eNB->dlsch_common_and_dci,"DL common channels and dci time"); + printStatIndent(&eNB->dlsch_ue_specific,"DL per ue part time"); + printStatIndent2(&eNB->dlsch_encoding_stats,"DLSCH encoding time"); + printStatIndent3(&eNB->dlsch_rate_matching_stats,"DLSCH rate matching time"); + printStatIndent3(&eNB->dlsch_turbo_encoding_stats,"DLSCH turbo encoding time"); + printStatIndent3(&eNB->dlsch_interleaving_stats,"DLSCH interleaving time"); + printStatIndent2(&eNB->dlsch_scrambling_stats, "DLSCH scrambling time"); + printStatIndent2(&eNB->dlsch_modulation_stats, "DLSCH modulation time"); + printDistribution(&eNB->ofdm_mod_stats,table_tx_ifft,"OFDM_mod (idft) time"); printf("\nUE RX function statistics (per 1ms subframe)\n"); - printDistribution(&phy_proc_rx_tot, table_rx,"Total PHY proc rx"); - printStatIndent(&ue_front_end_tot,"Front end processing"); - printStatIndent(&dlsch_llr_tot,"rx_pdsch processing"); - printStatIndent2(&pdsch_procedures_tot,"pdsch processing"); - printStatIndent2(&dlsch_procedures_tot,"dlsch processing"); - printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing"); - printStatIndent(&UE->ofdm_demod_stats,"ofdm demodulation"); - printStatIndent(&UE->dlsch_channel_estimation_stats,"DLSCH channel estimation time"); - printStatIndent(&UE->dlsch_freq_offset_estimation_stats,"DLSCH frequency offset estimation time"); - printStatIndent(&dlsch_decoding_tot, "DLSCH Decoding time "); - printStatIndent(&UE->dlsch_unscrambling_stats,"DLSCH unscrambling time"); + printDistribution(&phy_proc_rx_tot, table_rx,"Total PHY proc rx"); + printStatIndent(&ue_front_end_tot,"Front end processing"); + printStatIndent(&dlsch_llr_tot,"rx_pdsch processing"); + printStatIndent2(&pdsch_procedures_tot,"pdsch processing"); + printStatIndent2(&dlsch_procedures_tot,"dlsch processing"); + printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing"); + printStatIndent(&UE->ofdm_demod_stats,"ofdm demodulation"); + printStatIndent(&UE->dlsch_channel_estimation_stats,"DLSCH channel estimation time"); + printStatIndent(&UE->dlsch_freq_offset_estimation_stats,"DLSCH frequency offset estimation time"); + printStatIndent(&dlsch_decoding_tot, "DLSCH Decoding time "); + printStatIndent(&UE->dlsch_unscrambling_stats,"DLSCH unscrambling time"); printStatIndent(&UE->dlsch_rate_unmatching_stats,"DLSCH Rate Unmatching"); - printf("|__ DLSCH Turbo Decoding(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, - + printf("|__ DLSCH Turbo Decoding(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, UE->dlsch_tc_intl1_stats.trials/(double)UE->dlsch_tc_init_stats.trials, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials*timeBase, (int)((double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials), @@ -2026,11 +1896,10 @@ int main(int argc, char **argv) printStatIndent2(&UE->dlsch_tc_ext_stats,"ext"); printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver"); printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC"); - } if ((transmission_mode != 3) && (transmission_mode != 4)) { - fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", + fprintf(bler_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u\n", SNR, mcs1, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -2045,7 +1914,7 @@ int main(int argc, char **argv) round_trials[3], dci_errors[0]); } else { - fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u\n", SNR, mcs1,mcs2, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -2062,7 +1931,6 @@ int main(int argc, char **argv) dci_errors[0]); } - if(abstx) { //ABSTRACTION blerr[0] = (double)errs[0]/(round_trials[0]); @@ -2079,7 +1947,7 @@ int main(int argc, char **argv) if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); if ((transmission_mode != 3) && (transmission_mode != 4)) { - fprintf(time_meas_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", + fprintf(time_meas_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u;", SNR, mcs1, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -2093,9 +1961,8 @@ int main(int argc, char **argv) errs[3], round_trials[3], dci_errors[0]); - //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); - fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", + fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%u;%u;%e;%f;%f;", SNR, mcs1, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -2122,7 +1989,7 @@ int main(int argc, char **argv) (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); } else { - fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", + fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u;", SNR, mcs1,mcs2, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -2137,9 +2004,8 @@ int main(int argc, char **argv) errs[3], round_trials[3], dci_errors[0]); - //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); - fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", + fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%u;%u;%e;%f;%f;", SNR, mcs1,mcs2, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -2199,49 +2065,45 @@ int main(int argc, char **argv) fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;",squareRoot(&UE->phy_proc_tx), t_tx_max, t_tx_min, median(table_tx), q1(table_tx), q3(table_tx), n_tx_dropped); //fprintf(time_meas_fd,"IFFT;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", - squareRoot(&eNB->ofdm_mod_stats), + squareRoot(&eNB->ofdm_mod_stats), median(table_tx_ifft),q1(table_tx_ifft),q3(table_tx_ifft)); //fprintf(time_meas_fd,"MOD;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", - squareRoot(&eNB->dlsch_modulation_stats), + squareRoot(&eNB->dlsch_modulation_stats), median(table_tx_mod), q1(table_tx_mod), q3(table_tx_mod)); //fprintf(time_meas_fd,"ENC;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", - squareRoot(&eNB->dlsch_encoding_stats), + squareRoot(&eNB->dlsch_encoding_stats), median(table_tx_enc),q1(table_tx_enc),q3(table_tx_enc)); //fprintf(time_meas_fd,"eNB_PROC_RX_STD;eNB_PROC_RX_MAX;eNB_PROC_RX_MIN;eNB_PROC_RX_MED;eNB_PROC_RX_Q1;eNB_PROC_RX_Q3;eNB_PROC_RX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", - squareRoot(&phy_proc_rx_tot), t_rx_max, t_rx_min, + squareRoot(&phy_proc_rx_tot), t_rx_max, t_rx_min, median(table_rx), q1(table_rx), q3(table_rx), n_rx_dropped); //fprintf(time_meas_fd,"FFT;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", - squareRoot(&UE->ofdm_demod_stats), + squareRoot(&UE->ofdm_demod_stats), median(table_rx_fft), q1(table_rx_fft), q3(table_rx_fft)); //fprintf(time_meas_fd,"DEMOD;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", - squareRoot(&UE->dlsch_demodulation_stats), + squareRoot(&UE->dlsch_demodulation_stats), median(table_rx_demod), q1(table_rx_demod), q3(table_rx_demod)); //fprintf(time_meas_fd,"DEC;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f\n", - squareRoot(&UE->dlsch_decoding_stats[subframe]), + squareRoot(&UE->dlsch_decoding_stats[subframe]), median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec)); - printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); - test_passed = 1; + test_passed = 1; break; } else if (test_perf !=0 ) { printf("[continue] effective rate : %f (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate); - test_passed = 0; + test_passed = 0; } if (((double)errs[0]/(round_trials[0]))<(10.0/n_frames)) break; }// SNR - - } //ch_realization - fclose(bler_fd); if (test_perf !=0) @@ -2265,7 +2127,6 @@ int main(int argc, char **argv) free(uncoded_ber_bit); uncoded_ber_bit = NULL; - printf("Freeing dlsch structures\n"); for (i=0; i<2; i++) { @@ -2280,5 +2141,7 @@ int main(int argc, char **argv) else return(0); } - - +/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */ +uint64_t get_softmodem_optmask(void) { + return 0; +} diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c index 570c13c0b64f0abec0a817b1cfc1223583fffb61..5973f80b55a59f662490e960cb5f295e3ae2267b 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c @@ -68,14 +68,11 @@ double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ -void handler(int sig) -{ +void handler(int sig) { void *array[10]; size_t size; - // get void*'s for all entries on the stack size = backtrace(array, 10); - // print out all the frames to stderr fprintf(stderr, "Error: signal %d:\n", sig); backtrace_symbols_fd(array, size, 2); @@ -94,28 +91,21 @@ uint64_t DLSCH_alloc_pdu_1[2]; //#define DLSCH_RB_ALLOC 0x1fbf // igore DC component,RB13 //#define DLSCH_RB_ALLOC 0x0001 -int main(int argc, char **argv) -{ - +int main(int argc, char **argv) { int c; int k,i,j,aa,aarx,aatx; int re; - int s,Kr,Kr_bytes; - double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1,rate; double snr_step=1,input_snr_step=1, snr_int=30; - LTE_DL_FRAME_PARMS *frame_parms; double **s_re,**s_im,**r_re,**r_im; double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel double iqim=0.0; - uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=1; uint16_t Nid_cell=0; int32_t **cell_spec_bf_weights; int32_t *ue_spec_bf_weights; - int eNB_id = 0, eNB_id_i = 1; unsigned char mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0,round,dci_flag=0; unsigned char i_mod = 2; @@ -124,15 +114,12 @@ int main(int argc, char **argv) uint16_t tdd_config=3; uint16_t n_rnti=0x1234; int n_users = 1; - SCM_t channel_model=Rayleigh1; // unsigned char *input_data,*decoded_output; - unsigned char *input_buffer0[2],*input_buffer1[2]; unsigned short input_buffer_length0,input_buffer_length1; unsigned int ret; unsigned int coded_bits_per_codeword=0,nsymb,dci_cnt,tbs=0; - unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[4]= {0,0,0,0},errs2[4]= {0,0,0,0},round_trials[4]= {0,0,0,0},dci_errors=0,dlsch_active=0;//,num_layers; int re_allocated; char fname[32],vname[32]; @@ -142,23 +129,17 @@ int main(int argc, char **argv) char time_meas_fname[256]; // FILE *tikz_fd; // char tikz_fname[256]; - FILE *input_trch_fd=NULL; unsigned char input_trch_file=0; FILE *input_fd=NULL; unsigned char input_file=0; // char input_val_str[50],input_val_str2[50]; - char input_trch_val[16]; double channelx,channely; - unsigned char pbch_pdu[6]; - DCI_ALLOC_t dci_alloc[8],dci_alloc_rx[8]; int num_common_dci=0,num_ue_spec_dci=0,num_dci=0; - // FILE *rx_frame_file; - int n_frames; int n_ch_rlz = 1; channel_desc_t *eNB2UE[4]; @@ -178,7 +159,6 @@ int main(int argc, char **argv) int ch_realization; int pmi_feedback=0; int hold_channel=0; - // void *data; // int ii; // int bler; @@ -194,7 +174,6 @@ int main(int argc, char **argv) int dci_length_bytes=0,dci_length=0; //double channel_bandwidth = 5.0, sampling_rate=7.68; int common_flag=0,TPC=0; - double cpu_freq_GHz; // time_stats_t ts;//,sts,usts; int avg_iter,iter_trials; @@ -203,50 +182,40 @@ int main(int argc, char **argv) int test_perf=0; int dump_table=0; int llr8_flag=0; - double effective_rate=0.0; char channel_model_input[10]="I"; - int TB0_active = 1; uint32_t perfect_ce = 0; - // LTE_DL_UE_HARQ_t *dlsch0_ue_harq; // LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; uint8_t Kmimo; uint8_t ue_category=4; uint32_t Nsoft; - - - int CCE_table[800]; - int threequarter_fs=0; - opp_enabled=1; // to enable the time meas - #if defined(__arm__) FILE *proc_fd = NULL; char buf[64]; - proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r"); - if(!proc_fd) - printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq"); - else { - while(fgets(buf, 63, proc_fd)) - printf("%s", buf); + + if(!proc_fd) { + printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq"); + exit(-1); + } else { + while(fgets(buf, 63, proc_fd)) + printf("%s", buf); } + fclose(proc_fd); cpu_freq_GHz = ((double)atof(buf))/1e6; #else cpu_freq_GHz = get_cpu_freq_GHz(); #endif printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); - //signal(SIGSEGV, handler); //signal(SIGABRT, handler); - logInit(); - // default parameters n_frames = 1000; snr0 = 0; @@ -255,362 +224,363 @@ int main(int argc, char **argv) while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:p:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XY")) != -1) { switch (c) { - case 'a': - awgn_flag = 1; - channel_model = AWGN; - break; - - case 'A': - abstx = 1; - break; - - case 'b': - tdd_config=atoi(optarg); - break; - - case 'B': - N_RB_DL=atoi(optarg); - break; - - case 'c': - num_pdcch_symbols=atoi(optarg); - break; - - case 'C': - Nid_cell = atoi(optarg); - break; - - case 'd': - dci_flag = 1; - break; - - case 'D': - frame_type=TDD; - break; - - case 'e': - num_rounds=1; - common_flag = 1; - TPC = atoi(optarg); - break; - - case 'E': - threequarter_fs=1; - break; - - case 'f': - input_snr_step= atof(optarg); - break; - - case 'F': - forgetting_factor = atof(optarg); - break; - - case 'i': - input_fd = fopen(optarg,"r"); - input_file=1; - dci_flag = 1; - break; - - case 'I': - input_trch_fd = fopen(optarg,"r"); - input_trch_file=1; - break; - - case 'L': - llr8_flag=1; - break; - - case 'l': - offset_mumimo_llr_drange_fix=atoi(optarg); - break; - - case 'm': - mcs1 = atoi(optarg); - break; + case 'a': + awgn_flag = 1; + channel_model = AWGN; + break; - case 'M': - mcs2 = atoi(optarg); - break; + case 'A': + abstx = 1; + break; - case 'O': - test_perf=atoi(optarg); - //print_perf =1; - break; + case 'b': + tdd_config=atoi(optarg); + break; - case 't': - mcs_i = atoi(optarg); - i_mod = get_Qm(mcs_i); - break; + case 'B': + N_RB_DL=atoi(optarg); + break; - case 'n': - n_frames = atoi(optarg); - break; + case 'c': + num_pdcch_symbols=atoi(optarg); + break; - case 'o': - rx_sample_offset = atoi(optarg); - break; + case 'C': + Nid_cell = atoi(optarg); + break; - case 'r': - DLSCH_RB_ALLOC = atoi(optarg); - rballocset = 1; - break; + case 'd': + dci_flag = 1; + break; - case 's': - snr0 = atof(optarg); - break; + case 'D': + frame_type=TDD; + break; - case 'w': - snr_int = atof(optarg); - break; + case 'e': + num_rounds=1; + common_flag = 1; + TPC = atoi(optarg); + break; - case 'N': - n_ch_rlz= atof(optarg); - break; + case 'E': + threequarter_fs=1; + break; - case 'p': - extended_prefix_flag=1; - break; + case 'f': + input_snr_step= atof(optarg); + break; - case 'g': - memcpy(channel_model_input,optarg,10); + case 'F': + forgetting_factor = atof(optarg); + break; - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; + case 'i': + input_fd = fopen(optarg,"r"); + input_file=1; + dci_flag = 1; break; - case 'B': - channel_model=SCM_B; + case 'I': + input_trch_fd = fopen(optarg,"r"); + input_trch_file=1; break; - case 'C': - channel_model=SCM_C; + case 'L': + llr8_flag=1; break; - case 'D': - channel_model=SCM_D; + case 'l': + offset_mumimo_llr_drange_fix=atoi(optarg); break; - case 'E': - channel_model=EPA; + case 'm': + mcs1 = atoi(optarg); break; - case 'F': - channel_model=EVA; + case 'M': + mcs2 = atoi(optarg); break; - case 'G': - channel_model=ETU; + case 'O': + test_perf=atoi(optarg); + //print_perf =1; break; - case 'H': - channel_model=Rayleigh8; + case 't': + mcs_i = atoi(optarg); + i_mod = get_Qm(mcs_i); break; - case 'I': - channel_model=Rayleigh1; + case 'n': + n_frames = atoi(optarg); break; - case 'J': - channel_model=Rayleigh1_corr; + case 'o': + rx_sample_offset = atoi(optarg); break; - case 'K': - channel_model=Rayleigh1_anticorr; + case 'r': + DLSCH_RB_ALLOC = atoi(optarg); + rballocset = 1; break; - case 'L': - channel_model=Rice8; + case 's': + snr0 = atof(optarg); break; - case 'M': - channel_model=Rice1; + case 'w': + snr_int = atof(optarg); break; case 'N': - channel_model=AWGN; + n_ch_rlz= atof(optarg); break; - default: - msg("Unsupported channel model!\n"); - exit(-1); - } - break; + case 'p': + extended_prefix_flag=1; + break; - case 'R': - num_rounds=atoi(optarg); - break; + case 'g': + memcpy(channel_model_input,optarg,10); - case 'S': - subframe=atoi(optarg); - break; + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; - case 'T': - n_rnti=atoi(optarg); - break; + case 'B': + channel_model=SCM_B; + break; - case 'u': - dual_stream_UE=1; - UE->use_ia_receiver = 1; + case 'C': + channel_model=SCM_C; + break; - if ((n_tx_port!=2) || (transmission_mode!=5)) { - msg("IA receiver only supported for TM5!"); - exit(-1); - } + case 'D': + channel_model=SCM_D; + break; - break; + case 'E': + channel_model=EPA; + break; - case 'v': - i_mod = atoi(optarg); + case 'F': + channel_model=EVA; + break; - if (i_mod!=2 && i_mod!=4 && i_mod!=6) { - msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); - exit(-1); - } + case 'G': + channel_model=ETU; + break; - break; + case 'H': + channel_model=Rayleigh8; + break; - case 'P': - print_perf=1; - break; + case 'I': + channel_model=Rayleigh1; + break; - case 'q': - n_tx_port=atoi(optarg); + case 'J': + channel_model=Rayleigh1_corr; + break; - if ((n_tx_port==0) || ((n_tx_port>2))) { - msg("Unsupported number of cell specific antennas ports %d\n",n_tx_port); - exit(-1); - } + case 'K': + channel_model=Rayleigh1_anticorr; + break; - break; + case 'L': + channel_model=Rice8; + break; + case 'M': + channel_model=Rice1; + break; - case 'x': - transmission_mode=atoi(optarg); + case 'N': + channel_model=AWGN; + break; - if ((transmission_mode!=1) && - (transmission_mode!=2) && - (transmission_mode!=3) && - (transmission_mode!=4) && - (transmission_mode!=5) && - (transmission_mode!=6) && - (transmission_mode!=7)) { - msg("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } + default: + msg("Unsupported channel model!\n"); + exit(-1); + } - if (transmission_mode>1 && transmission_mode<7) { - n_tx_port = 2; - } + break; - break; + case 'R': + num_rounds=atoi(optarg); + break; + + case 'S': + subframe=atoi(optarg); + break; - case 'y': - n_tx_phy=atoi(optarg); - - if (transmission_mode>1&&transmission_mode<7) { - if(n_tx_phy==1) { - msg("n_tx_phy must be >1 for transmission_mode %d\n",transmission_mode); + case 'T': + n_rnti=atoi(optarg); + break; + + case 'u': + dual_stream_UE=1; + UE->use_ia_receiver = 1; + + if ((n_tx_port!=2) || (transmission_mode!=5)) { + msg("IA receiver only supported for TM5!"); exit(-1); - } - } + } - if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) { - msg("Physical number of antennas not supported for TM7.\n"); - exit(-1); - } + break; - break; + case 'v': + i_mod = atoi(optarg); - case 'X': - xforms=1; - break; + if (i_mod!=2 && i_mod!=4 && i_mod!=6) { + msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); + exit(-1); + } - case 'Y': - perfect_ce=1; - break; + break; - case 'z': - n_rx=atoi(optarg); + case 'P': + print_perf=1; + break; - if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); - exit(-1); - } + case 'q': + n_tx_port=atoi(optarg); - break; + if ((n_tx_port==0) || ((n_tx_port>2))) { + msg("Unsupported number of cell specific antennas ports %d\n",n_tx_port); + exit(-1); + } - case 'Z': - dump_table=1; - break; + break; + case 'x': + transmission_mode=atoi(optarg); + + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=3) && + (transmission_mode!=4) && + (transmission_mode!=5) && + (transmission_mode!=6) && + (transmission_mode!=7)) { + msg("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } + if (transmission_mode>1 && transmission_mode<7) { + n_tx_port = 2; + } - case 'h': - default: - printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6,7) -y TXant -z RXant -I trch_file\n",argv[0]); - printf("-h This message\n"); - printf("-a Use AWGN channel and not multipath\n"); - printf("-c Number of PDCCH symbols\n"); - printf("-m MCS1 for TB 1\n"); - printf("-M MCS2 for TB 2\n"); - printf("-d Transmit the DCI and compute its error statistics and the overall throughput\n"); - printf("-p Use extended prefix mode\n"); - printf("-n Number of frames to simulate\n"); - printf("-o Sample offset for receiver\n"); - printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step); - printf("-f step size of SNR, default value is 1.\n"); - printf("-r ressource block allocation (see section 7.1.6.3 in 36.213\n"); - printf("-g [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')\n"); - printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n"); - printf("-x Transmission mode (1,2,6,7 for the moment)\n"); - printf("-q Number of TX antennas ports used in eNB\n"); - printf("-y Number of physical TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-t MCS of interfering UE\n"); - printf("-R Number of HARQ rounds (fixed)\n"); - printf("-A Turns on calibration mode for abstraction.\n"); - printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n"); - printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n"); - printf("-I Input filename for TrCH data (binary)\n"); - printf("-u Enables the Interference Aware Receiver for TM5 (default is normal receiver)\n"); - exit(1); - break; + break; + + case 'y': + n_tx_phy=atoi(optarg); + + if (transmission_mode>1&&transmission_mode<7) { + if(n_tx_phy==1) { + msg("n_tx_phy must be >1 for transmission_mode %d\n",transmission_mode); + exit(-1); + } + } + + if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) { + msg("Physical number of antennas not supported for TM7.\n"); + exit(-1); + } + + break; + + case 'X': + xforms=1; + break; + + case 'Y': + perfect_ce=1; + break; + + case 'z': + n_rx=atoi(optarg); + + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } + + break; + + case 'Z': + dump_table=1; + break; + + case 'h': + default: + printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6,7) -y TXant -z RXant -I trch_file\n",argv[0]); + printf("-h This message\n"); + printf("-a Use AWGN channel and not multipath\n"); + printf("-c Number of PDCCH symbols\n"); + printf("-m MCS1 for TB 1\n"); + printf("-M MCS2 for TB 2\n"); + printf("-d Transmit the DCI and compute its error statistics and the overall throughput\n"); + printf("-p Use extended prefix mode\n"); + printf("-n Number of frames to simulate\n"); + printf("-o Sample offset for receiver\n"); + printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step); + printf("-f step size of SNR, default value is 1.\n"); + printf("-r ressource block allocation (see section 7.1.6.3 in 36.213\n"); + printf("-g [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')\n"); + printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n"); + printf("-x Transmission mode (1,2,6,7 for the moment)\n"); + printf("-q Number of TX antennas ports used in eNB\n"); + printf("-y Number of physical TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-t MCS of interfering UE\n"); + printf("-R Number of HARQ rounds (fixed)\n"); + printf("-A Turns on calibration mode for abstraction.\n"); + printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n"); + printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n"); + printf("-I Input filename for TrCH data (binary)\n"); + printf("-u Enables the Interference Aware Receiver for TM5 (default is normal receiver)\n"); + exit(1); + break; } } if (common_flag == 0) { switch (N_RB_DL) { - case 6: - if (rballocset==0) DLSCH_RB_ALLOC = 0x3f; - num_pdcch_symbols = 3; - break; + case 6: + if (rballocset==0) DLSCH_RB_ALLOC = 0x3f; - case 25: - if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff; - break; + num_pdcch_symbols = 3; + break; - case 50: - if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff; - break; + case 25: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff; - case 100: - if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff; - break; + break; + + case 50: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff; + + break; + + case 100: + if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff; + + break; } NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); } else NB_RB = 4; - if (xforms==1) { fl_initialize (&argc, argv, NULL, 0, 0); form_ue = create_lte_phy_scope_ue(); sprintf (title, "LTE PHY SCOPE eNB"); fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - + if (!dual_stream_UE==0) { UE->use_ia_receiver = 1; fl_set_button(form_ue->button_0,1); @@ -625,9 +595,7 @@ int main(int argc, char **argv) } lte_param_init(n_tx_port,n_tx_phy,n_rx,transmission_mode,extended_prefix_flag,frame_type,Nid_cell,tdd_config,N_RB_DL,threequarter_fs,osf,perfect_ce); - frame_parms = &eNB->frame_parms; - /* cell_spec_bf_weights = eNB->common_vars.beam_weights[0][0]; for(aa=0;aa<n_tx_phy;aa++) { @@ -641,35 +609,27 @@ int main(int argc, char **argv) else if (n_tx_phy==64) cell_spec_bf_weights[aa][re] = 0x00007fff>>4; } - } + } if (transmission_mode==7){ lte_gold_ue_spec_port5(eNB->lte_gold_uespec_port5_table[0],Nid_cell,n_rnti); lte_gold_ue_spec_port5(UE->lte_gold_uespec_port5_table,Nid_cell,n_rnti); }*/ - - eNB_id_i = UE->n_connected_eNB; - printf("Setting mcs1 = %d\n",mcs1); printf("Setting mcs2 = %d\n",mcs2); printf("NPRB = %d\n",NB_RB); printf("n_frames = %d\n",n_frames); printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag); - snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - - - s_re = malloc(n_tx_phy*sizeof(double*)); - s_im = malloc(n_tx_phy*sizeof(double*)); - r_re = malloc(2*sizeof(double*)); - r_im = malloc(2*sizeof(double*)); + s_re = malloc(n_tx_phy*sizeof(double *)); + s_im = malloc(n_tx_phy*sizeof(double *)); + r_re = malloc(2*sizeof(double *)); + r_im = malloc(2*sizeof(double *)); // r_re0 = malloc(2*sizeof(double*)); // r_im0 = malloc(2*sizeof(double*)); - nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12; - printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model); printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d\n", SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8); @@ -680,10 +640,12 @@ int main(int argc, char **argv) sprintf(bler_fname,"bler_tm%d_chan%d_perfce%d_ntx%d_nrx%d_mcs%d.csv",transmission_mode,channel_model,perfect_ce,n_tx_phy,n_rx,mcs1); bler_fd = fopen(bler_fname,"w"); + if (bler_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",bler_fname); exit(-1); } + fprintf(bler_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); if (test_perf != 0) { @@ -697,6 +659,7 @@ int main(int argc, char **argv) N_RB_DL,mcs1,n_tx_phy,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode); //mkdir(dirname,0777); time_meas_fd = fopen(time_meas_fname,"w"); + if (time_meas_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",time_meas_fname); exit(-1); @@ -707,11 +670,11 @@ int main(int argc, char **argv) // CSV file sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d.m",transmission_mode,dual_stream_UE,mcs1,channel_model,n_frames,num_rounds); csv_fd = fopen(csv_fname,"w"); - fprintf(csv_fd,"data_all%d=[",mcs1); if (csv_fd==NULL) { fprintf(stderr,"Cannot create file %s!\n",csv_fname); exit(-1); } + fprintf(csv_fd,"data_all%d=[",mcs1); } /* @@ -811,7 +774,7 @@ int main(int argc, char **argv) } */ - for (i=0; i<n_tx_phy; i++){ + for (i=0; i<n_tx_phy; i++) { s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); } @@ -825,9 +788,7 @@ int main(int argc, char **argv) // bzero(r_im0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); } - UE->pdcch_vars[0]->crnti = n_rnti; - // Fill in UL_alloc UL_alloc_pdu.type = 0; UL_alloc_pdu.hopping = 0; @@ -836,14 +797,12 @@ int main(int argc, char **argv) UL_alloc_pdu.ndi = 1; UL_alloc_pdu.TPC = 0; UL_alloc_pdu.cqi_req = 1; - CCCH_alloc_pdu.type = 0; CCCH_alloc_pdu.vrb_type = 0; CCCH_alloc_pdu.rballoc = CCCH_RB_ALLOC; CCCH_alloc_pdu.ndi = 1; CCCH_alloc_pdu.mcs = 1; CCCH_alloc_pdu.harq_pid = 0; - DLSCH_alloc_pdu2_1E[0].rah = 0; DLSCH_alloc_pdu2_1E[0].rballoc = DLSCH_RB_ALLOC; DLSCH_alloc_pdu2_1E[0].TPC = 0; @@ -856,7 +815,6 @@ int main(int argc, char **argv) // Forget second codeword DLSCH_alloc_pdu2_1E[0].tpmi = (transmission_mode>=5 ? 5 : 0); // precoding DLSCH_alloc_pdu2_1E[0].dl_power_off = (transmission_mode==5 ? 0 : 1); - DLSCH_alloc_pdu2_1E[1].rah = 0; DLSCH_alloc_pdu2_1E[1].rballoc = DLSCH_RB_ALLOC; DLSCH_alloc_pdu2_1E[1].TPC = 0; @@ -869,12 +827,11 @@ int main(int argc, char **argv) // Forget second codeword DLSCH_alloc_pdu2_1E[1].tpmi = (transmission_mode>=5 ? 5 : 0) ; // precoding DLSCH_alloc_pdu2_1E[1].dl_power_off = (transmission_mode==5 ? 0 : 1); - eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), forgetting_factor, rx_sample_offset, 0); @@ -884,9 +841,9 @@ int main(int argc, char **argv) eNB2UE[n] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), - forgetting_factor, + N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + forgetting_factor, rx_sample_offset, 0); } @@ -902,20 +859,23 @@ int main(int argc, char **argv) Kmimo=1; switch (ue_category) { - case 1: - Nsoft = 250368; - break; - case 2: - case 3: - Nsoft = 1237248; - break; - case 4: - Nsoft = 1827072; - break; - default: - printf("Unsupported UE category %d\n",ue_category); - exit(-1); - break; + case 1: + Nsoft = 250368; + break; + + case 2: + case 3: + Nsoft = 1237248; + break; + + case 4: + Nsoft = 1827072; + break; + + default: + printf("Unsupported UE category %d\n",ue_category); + exit(-1); + break; } for (k=0; k<n_users; k++) { @@ -927,12 +887,12 @@ int main(int argc, char **argv) printf("Can't get eNB dlsch structures\n"); exit(-1); } else { - // this initilisation may should be moved to another place - for (j=0; j<4; j++) { - for (aa=0; aa<n_tx_phy; aa++) { + // this initilisation may should be moved to another place + for (j=0; j<4; j++) { + for (aa=0; aa<n_tx_phy; aa++) { ue_spec_bf_weights = eNB->dlsch[k][i]->ue_spec_bf_weights[j][aa]; - for (re=0;re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES;re++) { + for (re=0; re<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) { if (n_tx_phy==1 || n_tx_phy==2) ue_spec_bf_weights[re] = 0x00007fff; else if (n_tx_phy==4 || n_tx_phy==8) @@ -942,10 +902,8 @@ int main(int argc, char **argv) else if (n_tx_phy==64) ue_spec_bf_weights[re] = 0x00007fff>>4; } - } - } - + } } eNB->dlsch[k][i]->rnti = n_rnti+k; @@ -967,7 +925,6 @@ int main(int argc, char **argv) UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) { - eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff); if (n_users>1) @@ -984,8 +941,6 @@ int main(int argc, char **argv) //read_calibration_matrix(calib_fname, nb_ant, nb_freq, eNB->common_vars.tdd_calib_coeffs[0]); if (input_fd==NULL) { - - /* // common DCI memcpy(&dci_alloc[num_dci].dci_pdu[0],&CCCH_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t)); @@ -999,955 +954,917 @@ int main(int argc, char **argv) // UE specific DCI for(k=0; k<n_users; k++) { switch(transmission_mode) { - case 1: - case 2: - case 7: - if (common_flag == 0) { - - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t); - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_TDD_t); - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1_10MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_TDD_t); - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1_20MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_TDD_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t); - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_FDD_t); - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_FDD_t); - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_FDD_t); - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; + case 1: + case 2: + case 7: + if (common_flag == 0) { + if (eNB->frame_parms.frame_type == TDD) { + switch (eNB->frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1_1_5MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t); + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 25: + dci_length = sizeof_DCI1_5MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_5MHz_TDD_t); + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 50: + dci_length = sizeof_DCI1_10MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_10MHz_TDD_t); + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 100: + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1_20MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_20MHz_TDD_t); + break; + } + } else { + switch (eNB->frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t); + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 25: + dci_length = sizeof_DCI1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_5MHz_FDD_t); + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 50: + dci_length = sizeof_DCI1_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_10MHz_FDD_t); + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 100: + dci_length = sizeof_DCI1_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_20MHz_FDD_t); + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + } } - } - - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = n_rnti+k; - dci_alloc[num_dci].format = format1; - dci_alloc[num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format1, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode<7?0:transmission_mode); - - /*if (transmission_mode == 7) - eNB->dlsch[0][0]->harq_processes[0]->mimo_mode = TM7; //Xiwen: to check about harq_pid*/ - - num_dci++; - num_ue_spec_dci++; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = n_rnti+k; + dci_alloc[num_dci].format = format1; + dci_alloc[num_dci].search_space = DCI_UE_SPACE; + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format1, + eNB->dlsch[0], + &eNB->frame_parms, + eNB->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + eNB->UE_stats[0].DL_pmi_single, + transmission_mode<7?0:transmission_mode); + /*if (transmission_mode == 7) + eNB->dlsch[0][0]->harq_processes[0]->mimo_mode = TM7; //Xiwen: to check about harq_pid*/ + num_dci++; + num_ue_spec_dci++; } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; + if (eNB->frame_parms.frame_type == TDD) { + switch (eNB->frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 25: + dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; + break; + + case 50: + dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 100: + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + break; + } + } else { + switch (eNB->frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 25: + dci_length = sizeof_DCI1A_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 50: + dci_length = sizeof_DCI1A_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 100: + dci_length = sizeof_DCI1A_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + } } + + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = SI_RNTI; + dci_alloc[num_dci].format = format1A; + dci_alloc[num_dci].firstCCE = 0; + dci_alloc[num_dci].search_space = DCI_COMMON_SPACE; + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + SI_RNTI, + format1A, + eNB->dlsch[0], + &eNB->frame_parms, + eNB->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + eNB->UE_stats[0].DL_pmi_single, + 0); + num_common_dci++; + num_dci++; } - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = SI_RNTI; - dci_alloc[num_dci].format = format1A; - dci_alloc[num_dci].firstCCE = 0; - dci_alloc[num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + break; - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - 0); + case 3: + if (common_flag == 0) { + if (eNB->frame_parms.nb_antennas_tx == 2) { + if (eNB->frame_parms.frame_type == TDD) { + switch (eNB->frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - num_common_dci++; - num_dci++; + case 25: + dci_length = sizeof_DCI2A_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - } - - break; + case 50: + dci_length = sizeof_DCI2A_10MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - case 3: - if (common_flag == 0) { + case 100: + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); + break; + } + } else { + switch (eNB->frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - if (eNB->frame_parms.nb_antennas_tx == 2) { + case 25: + dci_length = sizeof_DCI2A_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - if (eNB->frame_parms.frame_type == TDD) { + case 50: + dci_length = sizeof_DCI2A_10MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 25: - dci_length = sizeof_DCI2A_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 50: - dci_length = sizeof_DCI2A_10MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 100: - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); - break; + case 100: + dci_length = sizeof_DCI2A_20MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + } } + } else if (eNB->frame_parms.nb_antennas_tx == 4) { } - else { + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = n_rnti+k; + dci_alloc[num_dci].format = format2A; + dci_alloc[num_dci].search_space = DCI_UE_SPACE; + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format2A, + eNB->dlsch[0], + &eNB->frame_parms, + eNB->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + eNB->UE_stats[0].DL_pmi_single, + 0); + num_dci++; + num_ue_spec_dci++; + } else { + if (eNB->frame_parms.frame_type == TDD) { + switch (eNB->frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 25: + dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; + break; + + case 50: + dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 100: + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + break; + } + } else { switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 25: - dci_length = sizeof_DCI2A_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 50: - dci_length = sizeof_DCI2A_10MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 100: - dci_length = sizeof_DCI2A_20MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; + case 6: + dci_length = sizeof_DCI1A_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 25: + dci_length = sizeof_DCI1A_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 50: + dci_length = sizeof_DCI1A_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 100: + dci_length = sizeof_DCI1A_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; } } - } else if (eNB->frame_parms.nb_antennas_tx == 4) { + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = SI_RNTI; + dci_alloc[num_dci].format = format1A; + dci_alloc[num_dci].firstCCE = 0; + dci_alloc[num_dci].search_space = DCI_COMMON_SPACE; + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + SI_RNTI, + format1A, + eNB->dlsch[0], + &eNB->frame_parms, + eNB->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + eNB->UE_stats[0].DL_pmi_single, + 0); + num_common_dci++; + num_dci++; } - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = n_rnti+k; - dci_alloc[num_dci].format = format2A; - dci_alloc[num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); - - printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format2A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - 0); - - num_dci++; - num_ue_spec_dci++; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } + printf("Generated DCI format 2A (Transmission Mode 3)\n"); + break; - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = SI_RNTI; - dci_alloc[num_dci].format = format1A; - dci_alloc[num_dci].firstCCE = 0; - dci_alloc[num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + case 4: + if (common_flag == 0) { + if (eNB->frame_parms.nb_antennas_tx == 2) { + if (eNB->frame_parms.frame_type == TDD) { + switch (eNB->frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - 0); + case 25: + dci_length = sizeof_DCI2_5MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - num_common_dci++; - num_dci++; + case 50: + dci_length = sizeof_DCI2_10MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t); + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - } + case 100: + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + dci_length = sizeof_DCI2_20MHz_2A_TDD_t; + dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); + break; + } + } else { + switch (eNB->frame_parms.N_RB_DL) { + case 6: + dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - printf("Generated DCI format 2A (Transmission Mode 3)\n"); - break; + case 25: + dci_length = sizeof_DCI2_5MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t); + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - case 4: - if (common_flag == 0) { + case 50: + dci_length = sizeof_DCI2_10MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t); + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; - if (eNB->frame_parms.nb_antennas_tx == 2) { + case 100: + dci_length = sizeof_DCI2_20MHz_2A_FDD_t; + dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t); + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; + ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; + break; + } + } + } else if (eNB->frame_parms.nb_antennas_tx == 4) { + } + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = n_rnti+k; + dci_alloc[num_dci].format = format2; + dci_alloc[num_dci].search_space = DCI_UE_SPACE; + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + n_rnti+k, + format2, + eNB->dlsch[0], + &eNB->frame_parms, + eNB->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + eNB->UE_stats[0].DL_pmi_single, + 0); + num_dci++; + num_ue_spec_dci++; + } else { if (eNB->frame_parms.frame_type == TDD) { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 25: - dci_length = sizeof_DCI2_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 50: - dci_length = sizeof_DCI2_10MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t); - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 100: - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - dci_length = sizeof_DCI2_20MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); - break; + case 6: + dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 25: + dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; + break; + + case 50: + dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 100: + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; + dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + break; } - } - - else { + } else { switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 25: - dci_length = sizeof_DCI2_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t); - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 50: - dci_length = sizeof_DCI2_10MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t); - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; - - case 100: - dci_length = sizeof_DCI2_20MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t); - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = 1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = 1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = 0; - break; + case 6: + dci_length = sizeof_DCI1A_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 25: + dci_length = sizeof_DCI1A_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 50: + dci_length = sizeof_DCI1A_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; + + case 100: + dci_length = sizeof_DCI1A_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; + ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; + break; } } - } else if (eNB->frame_parms.nb_antennas_tx == 4) { + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); + dci_alloc[num_dci].dci_length = dci_length; + dci_alloc[num_dci].L = 1; + dci_alloc[num_dci].rnti = SI_RNTI; + dci_alloc[num_dci].format = format1A; + dci_alloc[num_dci].firstCCE = 0; + dci_alloc[num_dci].search_space = DCI_COMMON_SPACE; + dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); + printf("Generating dlsch params for user %d\n",k); + generate_eNB_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + SI_RNTI, + format1A, + eNB->dlsch[0], + &eNB->frame_parms, + eNB->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + eNB->UE_stats[0].DL_pmi_single, + 0); + num_common_dci++; + num_dci++; } - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; + break; + + case 5: + case 6: + memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + dci_alloc[num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; dci_alloc[num_dci].L = 1; dci_alloc[num_dci].rnti = n_rnti+k; - dci_alloc[num_dci].format = format2; + dci_alloc[num_dci].format = format1E_2A_M10PRB; + dci_alloc[num_dci].firstCCE = 4*k; dci_alloc[num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); - printf("Generating dlsch params for user %d\n",k); generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], + subframe, + &DLSCH_alloc_pdu2_1E[k], n_rnti+k, - format2, - eNB->dlsch[0], + format1E_2A_M10PRB, + eNB->dlsch[k], &eNB->frame_parms, eNB->pdsch_config_dedicated, SI_RNTI, 0, P_RNTI, - eNB->UE_stats[0].DL_pmi_single, + eNB->UE_stats[k].DL_pmi_single, 0); - - num_dci++; - num_ue_spec_dci++; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 1; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } - - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[num_dci].dci_length = dci_length; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = SI_RNTI; - dci_alloc[num_dci].format = format1A; - dci_alloc[num_dci].firstCCE = 0; - dci_alloc[num_dci].search_space = DCI_COMMON_SPACE; dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - 0); - - num_common_dci++; + num_ue_spec_dci++; num_dci++; + break; - } - - break; - - case 5: - case 6: - memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - dci_alloc[num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; - dci_alloc[num_dci].L = 1; - dci_alloc[num_dci].rnti = n_rnti+k; - dci_alloc[num_dci].format = format1E_2A_M10PRB; - dci_alloc[num_dci].firstCCE = 4*k; - dci_alloc[num_dci].search_space = DCI_UE_SPACE; - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu2_1E[k], - n_rnti+k, - format1E_2A_M10PRB, - eNB->dlsch[k], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[k].DL_pmi_single, - 0); - - dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]); - num_ue_spec_dci++; - num_dci++; - - break; - - default: - printf("Unsupported Transmission Mode!!!"); - exit(-1); - break; + default: + printf("Unsupported Transmission Mode!!!"); + exit(-1); + break; } - - - /* memcpy(&dci_alloc[1].dci_pdu[0],&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD0_t)); dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_0_t; @@ -1966,13 +1883,12 @@ int main(int argc, char **argv) memset(CCE_table,0,800*sizeof(int)); for (i=num_common_dci; i<num_dci; i++) { - dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table, - 1<<dci_alloc[i].L, - numCCE, - (dci_alloc[i].rnti==SI_RNTI)? 1 : 0, - dci_alloc[i].rnti, - subframe); + 1<<dci_alloc[i].L, + numCCE, + (dci_alloc[i].rnti==SI_RNTI)? 1 : 0, + dci_alloc[i].rnti, + subframe); if (n_frames==1) printf("dci %d: rnti %x, format %d : nCCE %d/%d\n",i,dci_alloc[i].rnti, dci_alloc[i].format, @@ -1980,7 +1896,6 @@ int main(int argc, char **argv) } for (k=0; k<n_users; k++) { - input_buffer_length0 = eNB->dlsch[k][0]->harq_processes[0]->TBS/8; input_buffer0[k] = (unsigned char *)malloc(input_buffer_length0+4); memset(input_buffer0[k],0,input_buffer_length0+4); @@ -1997,13 +1912,11 @@ int main(int argc, char **argv) for (i=0; i<input_buffer_length1; i++) { input_buffer1[k][i]= (unsigned char)(taus()&0xff); } - } - - else { + } else { i=0; while ((!feof(input_trch_fd)) && (i<input_buffer_length0<<3)) { - ret=fscanf(input_trch_fd,"%s",input_trch_val); + ret=fscanf(input_trch_fd,"%15s",input_trch_val); if (input_trch_val[0] == '1') input_buffer0[k][i>>3]+=(1<<(7-(i&7))); @@ -2030,12 +1943,10 @@ int main(int argc, char **argv) eNB->dlsch[0][0]->harq_processes[0]->Nl, num_pdcch_symbols, 0, - subframe, - (transmission_mode<7?0:transmission_mode)); - - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + subframe, + (transmission_mode<7?0:transmission_mode)); + uncoded_ber_bit = (short *) malloc(sizeof(short)*coded_bits_per_codeword); printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); - snr_step = input_snr_step; UE->high_speed_flag = 0; //1 UE->ch_est_alpha=0; @@ -2059,10 +1970,8 @@ int main(int argc, char **argv) round_trials[1] = 0; round_trials[2] = 0; round_trials[3] = 0; - dci_errors=0; // avg_ber = 0; - round=0; avg_iter = 0; iter_trials=0; @@ -2075,7 +1984,6 @@ int main(int argc, char **argv) reset_meas(&eNB->dlsch_interleaving_stats); reset_meas(&eNB->dlsch_rate_matching_stats); reset_meas(&eNB->dlsch_turbo_encoding_stats); - reset_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // total UE rx reset_meas(&UE->ofdm_demod_stats); reset_meas(&UE->dlsch_channel_estimation_stats); @@ -2101,7 +2009,6 @@ int main(int argc, char **argv) initialize(&time_vector_tx_mod); struct list time_vector_tx_enc; initialize(&time_vector_tx_enc); - struct list time_vector_rx; initialize(&time_vector_rx); struct list time_vector_rx_fft; @@ -2115,14 +2022,12 @@ int main(int argc, char **argv) // printf("Trial %d\n",trials); fflush(stdout); round=0; - //if (trials%100==0) eNB2UE[0]->first_run = 1; - ret = UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations+1; while ((round < num_rounds) && (ret > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations)) { - //printf("Trial %d, round %d\n",trials,round); + //printf("Trial %d, round %d\n",trials,round); round_trials[round]++; if(transmission_mode>=5&&transmission_mode<7) @@ -2140,31 +2045,30 @@ int main(int argc, char **argv) PMI_FEEDBACK: - //make sure dlsim is called with perfect channel estimation option (for freq_channel) - //fill drs_ch_estimates with data from eNB2UE->chF - for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) { - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - for (i=0; i<frame_parms->N_RB_DL*12; i++) { - for (l=0; l<frame_parms->symbols_per_tti; l++) { - ((int16_t *) eNB->pusch_vars[0]->drs_ch_estimates[0][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size)*2]=(int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); - //printf("x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP); - ((int16_t *) eNB->pusch_vars[0]->drs_ch_estimates[0][(aa<<1)+aarx])[2*i+1+(l*frame_parms->ofdm_symbol_size)*2]=(int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); - } - } - } - } - - estimate_DLCSI_from_ULCSI(eNB->dlsch[0][0]->calib_dl_ch_estimates, - &eNB->pusch_vars[0]->drs_ch_estimates[0][0/*position of second DMRS*/], - eNB->common_vars.tdd_calib_coeffs[0], - frame_parms->nb_antennas_tx, - frame_parms->N_RB_DL*12); - - compute_BF_weights(eNB->dlsch[0][0]->ue_spec_bf_weights[0], - eNB->dlsch[0][0]->calib_dl_ch_estimates, - MRT, - frame_parms->nb_antennas_tx, - frame_parms->N_RB_DL*12); + //make sure dlsim is called with perfect channel estimation option (for freq_channel) + //fill drs_ch_estimates with data from eNB2UE->chF + for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) { + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + for (i=0; i<frame_parms->N_RB_DL*12; i++) { + for (l=0; l<frame_parms->symbols_per_tti; l++) { + ((int16_t *) eNB->pusch_vars[0]->drs_ch_estimates[0][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size)*2]=(int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); + //printf("x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP); + ((int16_t *) eNB->pusch_vars[0]->drs_ch_estimates[0][(aa<<1)+aarx])[2*i+1+(l*frame_parms->ofdm_symbol_size)*2]=(int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); + } + } + } + } + + estimate_DLCSI_from_ULCSI(eNB->dlsch[0][0]->calib_dl_ch_estimates, + &eNB->pusch_vars[0]->drs_ch_estimates[0][0/*position of second DMRS*/], + eNB->common_vars.tdd_calib_coeffs[0], + frame_parms->nb_antennas_tx, + frame_parms->N_RB_DL*12); + compute_BF_weights(eNB->dlsch[0][0]->ue_spec_bf_weights[0], + eNB->dlsch[0][0]->calib_dl_ch_estimates, + MRT, + frame_parms->nb_antennas_tx, + frame_parms->N_RB_DL*12); //printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); for (aa=0; aa<NB_ANTENNA_PORTS_ENB; aa++) { @@ -2172,397 +2076,390 @@ PMI_FEEDBACK: } if (input_fd==NULL) { - start_meas(&eNB->phy_proc_tx); // Simulate HARQ procedures!!! if (common_flag == 0) { - if (round == 0) { // First round TB0_active = 1; - eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3; if (eNB->frame_parms.frame_type == TDD) { - switch (transmission_mode) { - case 1: - case 2: - case 7: - switch (eNB->frame_parms.N_RB_DL) { - case 6: - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t)); - break; - - case 25: - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t)); - break; - - case 50: - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t)); - break; - - case 100: - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t)); - break; - } - - break; + case 1: + case 2: + case 7: + switch (eNB->frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t)); + break; + + case 25: + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t)); + break; + + case 50: + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t)); + break; + + case 100: + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t)); + break; + } - case 3: - switch (eNB->frame_parms.N_RB_DL) { - case 6: - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); break; - case 25: - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); - break; + case 3: + switch (eNB->frame_parms.N_RB_DL) { + case 6: + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); + break; + + case 25: + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); + break; + + case 50: + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); + break; + + case 100: + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); + break; + } - case 50: - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); break; - case 100: - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); + case 5: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); break; - } - - break; - - case 5: - DLSCH_alloc_pdu2_1E[0].ndi = trials&1; - DLSCH_alloc_pdu2_1E[0].rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - break; - } } else { // FDD switch (transmission_mode) { - case 1: - case 2: - case 7: - switch (eNB->frame_parms.N_RB_DL) { - case 6: - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t)); - break; - - case 25: - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t)); - break; - - case 50: - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t)); - break; - - case 100: - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t)); - break; - } + case 1: + case 2: + case 7: + switch (eNB->frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t)); + break; + + case 25: + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t)); + break; + + case 50: + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t)); + break; + + case 100: + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t)); + break; + } - break; - case 3: - switch (eNB->frame_parms.N_RB_DL) { - case 6: - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t)); break; - case 25: - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t)); - break; + case 3: + switch (eNB->frame_parms.N_RB_DL) { + case 6: + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t)); + break; + + case 25: + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t)); + break; + + case 50: + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t)); + break; + + case 100: + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t)); + break; + } - case 50: - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t)); break; - case 100: - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t)); + case 5: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = 0; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); break; - } - - break; - - case 5: - DLSCH_alloc_pdu2_1E[0].ndi = trials&1; - DLSCH_alloc_pdu2_1E[0].rv = 0; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - break; } - } } else { eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3; if (eNB->frame_parms.frame_type == TDD) { - - switch (transmission_mode) { - case 1: - case 2: - case 7: - switch (eNB->frame_parms.N_RB_DL) { - case 6: - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t)); - break; - - case 25: - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t)); - break; - - case 50: - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t)); - break; - - case 100: - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t)); - break; - } - - break; - - case 3: - switch (eNB->frame_parms.N_RB_DL) { - case 6: - if (TB0_active==1) { - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } else { // deactivate TB0 - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + case 1: + case 2: + case 7: + switch (eNB->frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t)); + break; + + case 25: + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t)); + break; + + case 50: + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t)); + break; + + case 100: + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t)); + break; } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); break; - case 25: - if (TB0_active==1) { - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } else { // deactivate TB0 - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + case 3: + switch (eNB->frame_parms.N_RB_DL) { + case 6: + if (TB0_active==1) { + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } else { // deactivate TB0 + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); - break; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t)); + break; + + case 25: + if (TB0_active==1) { + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } else { // deactivate TB0 + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } - case 50: - if (TB0_active==1) { - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } else { // deactivate TB0 - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t)); + break; + + case 50: + if (TB0_active==1) { + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } else { // deactivate TB0 + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); - break; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t)); + break; + + case 100: + if (TB0_active==1) { + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } else { // deactivate TB0 + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } - case 100: - if (TB0_active==1) { - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } else { // deactivate TB0 - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); + break; } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t)); break; - } - break; - - case 5: - DLSCH_alloc_pdu2_1E[0].ndi = trials&1; - DLSCH_alloc_pdu2_1E[0].rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - break; + case 5: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + break; } } else { switch (transmission_mode) { - case 1: - case 2: - case 7: - switch (eNB->frame_parms.N_RB_DL) { - case 6: - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t)); - break; - - case 25: - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t)); - break; - - case 50: - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t)); - break; - - case 100: - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t)); - break; - } - - break; - - case 3: - switch (eNB->frame_parms.N_RB_DL) { - case 6: - if (TB0_active==1) { - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } else { // deactivate TB0 - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + case 1: + case 2: + case 7: + switch (eNB->frame_parms.N_RB_DL) { + case 6: + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3;; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t)); + break; + + case 25: + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t)); + break; + + case 50: + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t)); + break; + + case 100: + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi = trials&1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t)); + break; } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t)); break; - case 25: - if (TB0_active==1) { - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } else { // deactivate TB0 - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + case 3: + switch (eNB->frame_parms.N_RB_DL) { + case 6: + if (TB0_active==1) { + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } else { // deactivate TB0 + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t)); - break; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t)); + break; + + case 25: + if (TB0_active==1) { + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } else { // deactivate TB0 + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } - case 50: - if (TB0_active==1) { - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } else { // deactivate TB0 - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t)); + break; + + case 50: + if (TB0_active==1) { + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } else { // deactivate TB0 + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t)); - break; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t)); + break; + + case 100: + if (TB0_active==1) { + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } else { // deactivate TB0 + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; + ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + } - case 100: - if (TB0_active==1) { - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1 = trials&1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = round&3; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; - } else { // deactivate TB0 - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1 = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1 = 1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2 = trials&1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2 = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t)); + break; } - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t)); break; - } - - break; - case 5: - DLSCH_alloc_pdu2_1E[0].ndi = trials&1; - DLSCH_alloc_pdu2_1E[0].rv = round&3; - memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - break; + case 5: + DLSCH_alloc_pdu2_1E[0].ndi = trials&1; + DLSCH_alloc_pdu2_1E[0].rv = round&3; + memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); + break; } } } } - + num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci + num_common_dci, dci_alloc, 0, @@ -2570,7 +2467,7 @@ PMI_FEEDBACK: &eNB->frame_parms, eNB->common_vars.txdataF[eNB_id], subframe); - + if (num_pdcch_symbols_2 > num_pdcch_symbols) { msg("Error: given num_pdcch_symbols not big enough (%d > %d)\n",num_pdcch_symbols_2,num_pdcch_symbols); exit(-1); @@ -2585,9 +2482,8 @@ PMI_FEEDBACK: eNB->dlsch[k][cw]->harq_processes[0]->Nl, num_pdcch_symbols, 0, - subframe, - (transmission_mode<7?0:transmission_mode)); - + subframe, + (transmission_mode<7?0:transmission_mode)); #ifdef TBS_FIX // This is for MESH operation!!! tbs = (double)3*TBStable[get_I_TBS(eNB->dlsch[k][cw]->harq_processes[0]->mcs)][eNB->dlsch[k][cw]->nb_rb-1]/4; #else @@ -2596,7 +2492,7 @@ PMI_FEEDBACK: rate = (double)tbs/(double)coded_bits_per_codeword; if ((SNR==snr0) && (trials==0) && (round==0)) - printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %d, TBS %d, mod %d, pdcch_sym %d, ndi %d)\n", + printf("User %d, cw %d: Rate = %f (%f bits/dim) (G %u, TBS %u, mod %d, pdcch_sym %d, ndi %d)\n", k,cw,rate,rate*get_Qm(eNB->dlsch[k][0]->harq_processes[0]->mcs), coded_bits_per_codeword, tbs, @@ -2621,11 +2517,10 @@ PMI_FEEDBACK: */ } - start_meas(&eNB->dlsch_encoding_stats); if (dlsch_encoding(eNB, - ((cw==0) ? input_buffer0[k] : input_buffer1[k]), + ((cw==0) ? input_buffer0[k] : input_buffer1[k]), num_pdcch_symbols, eNB->dlsch[k][cw], 0,subframe, @@ -2649,7 +2544,6 @@ PMI_FEEDBACK: } */ stop_meas(&eNB->dlsch_encoding_stats); - eNB->dlsch[k][cw]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI; start_meas(&eNB->dlsch_scrambling_stats); dlsch_scrambling(&eNB->frame_parms, @@ -2674,19 +2568,18 @@ PMI_FEEDBACK: } } } - + start_meas(&eNB->dlsch_modulation_stats); re_allocated = dlsch_modulation(eNB, - eNB->common_vars.txdataF[eNB_id], + eNB->common_vars.txdataF[eNB_id], AMP, frame, subframe, num_pdcch_symbols, eNB->dlsch[k][0], - eNB->dlsch[k][1]); + eNB->dlsch[k][1]); /* avoid gcc warnings */ (void)re_allocated; - stop_meas(&eNB->dlsch_modulation_stats); /* if (trials==0 && round==0) @@ -2694,174 +2587,172 @@ PMI_FEEDBACK: */ } //n_users - generate_pilots(eNB, eNB->common_vars.txdataF[eNB_id], AMP, LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); -/* - //PSS/SSS - if (eNB->frame_parms.frame_type == FDD) { - generate_pss(eNB->common_vars.txdataF[0], - AMP, - &eNB->frame_parms, - (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5, - 0); - generate_sss(eNB->common_vars.txdataF[0], - AMP, - &eNB->frame_parms, - (eNB->frame_parms.Ncp==NORMAL) ? 5 : 4, - 0); - generate_pss(eNB->common_vars.txdataF[0], - AMP, - &eNB->frame_parms, - (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5, - 10); - generate_sss(eNB->common_vars.txdataF[0], - AMP, - &eNB->frame_parms, - (eNB->frame_parms.Ncp==NORMAL) ? 5 : 4, - 10); - } - else if (eNB->frame_parms.frame_type == TDD) { - generate_sss(eNB->common_vars.txdataF[0], - AMP, - &eNB->frame_parms, - (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5, - 1); - generate_pss(eNB->common_vars.txdataF[0], - AMP, - &eNB->frame_parms, - 2, - 2); - generate_sss(eNB->common_vars.txdataF[0], - AMP, - &eNB->frame_parms, - (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5, - 11); - generate_pss(eNB->common_vars.txdataF[0], - AMP, - &eNB->frame_parms, - 2, - 12); - } + /* + //PSS/SSS + if (eNB->frame_parms.frame_type == FDD) { + generate_pss(eNB->common_vars.txdataF[0], + AMP, + &eNB->frame_parms, + (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5, + 0); + generate_sss(eNB->common_vars.txdataF[0], + AMP, + &eNB->frame_parms, + (eNB->frame_parms.Ncp==NORMAL) ? 5 : 4, + 0); + generate_pss(eNB->common_vars.txdataF[0], + AMP, + &eNB->frame_parms, + (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5, + 10); + generate_sss(eNB->common_vars.txdataF[0], + AMP, + &eNB->frame_parms, + (eNB->frame_parms.Ncp==NORMAL) ? 5 : 4, + 10); + } + else if (eNB->frame_parms.frame_type == TDD) { + generate_sss(eNB->common_vars.txdataF[0], + AMP, + &eNB->frame_parms, + (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5, + 1); + generate_pss(eNB->common_vars.txdataF[0], + AMP, + &eNB->frame_parms, + 2, + 2); + generate_sss(eNB->common_vars.txdataF[0], + AMP, + &eNB->frame_parms, + (eNB->frame_parms.Ncp==NORMAL) ? 6 : 5, + 11); + generate_pss(eNB->common_vars.txdataF[0], + AMP, + &eNB->frame_parms, + 2, + 12); + } - //PBCH - pbch_pdu[2] = 0; + //PBCH + pbch_pdu[2] = 0; - // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators - switch (eNB->frame_parms.N_RB_DL) { - case 6: - pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5); - break; - - case 15: - pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5); - break; - - case 25: - pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5); - break; - - case 50: - pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5); - break; - - case 75: - pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5); - break; - - case 100: - pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5); - break; - - default: - // FIXME if we get here, this should be flagged as an error, right? - pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5); - break; - } + // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators + switch (eNB->frame_parms.N_RB_DL) { + case 6: + pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5); + break; - pbch_pdu[2] = (pbch_pdu[2]&0xef) | - ((eNB->frame_parms.phich_config_common.phich_duration << 4)&0x10); + case 15: + pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5); + break; - switch (eNB->frame_parms.phich_config_common.phich_resource) { - case oneSixth: - pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2); - break; + case 25: + pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5); + break; - case half: - pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2); - break; + case 50: + pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5); + break; - case one: - pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2); - break; + case 75: + pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5); + break; - case two: - pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2); - break; + case 100: + pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5); + break; - default: - // unreachable - break; - + default: + // FIXME if we get here, this should be flagged as an error, right? + pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5); + break; + } - pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((0>>8)&0x3); - pbch_pdu[1] = 0&0xfc; - pbch_pdu[0] = 0; - } + pbch_pdu[2] = (pbch_pdu[2]&0xef) | + ((eNB->frame_parms.phich_config_common.phich_duration << 4)&0x10); + + switch (eNB->frame_parms.phich_config_common.phich_resource) { + case oneSixth: + pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2); + break; + + case half: + pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2); + break; + + case one: + pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2); + break; + + case two: + pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2); + break; + + default: + // unreachable + break; - generate_pbch(&eNB->lte_eNB_pbch, - eNB->common_vars.txdataF[0], - AMP, - &eNB->frame_parms, - pbch_pdu, - 0&3); -*/ + pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((0>>8)&0x3); + pbch_pdu[1] = 0&0xfc; + pbch_pdu[0] = 0; + } + + generate_pbch(&eNB->lte_eNB_pbch, + eNB->common_vars.txdataF[0], + AMP, + &eNB->frame_parms, + pbch_pdu, + 0&3); + */ start_meas(&eNB->ofdm_mod_stats); -/* - for(i=0;i<20;i++){ - - do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], - eNB->common_vars.txdata[eNB_id], - i, - &eNB->frame_parms); - } + /* + for(i=0;i<20;i++){ -*/ - do_OFDM_mod_symbol(&eNB->common_vars, - eNB_id, - (subframe*2), - &eNB->frame_parms); + do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], + eNB->common_vars.txdata[eNB_id], + i, + &eNB->frame_parms); + } + */ do_OFDM_mod_symbol(&eNB->common_vars, - eNB_id, - (subframe*2)+1, - &eNB->frame_parms); - + eNB_id, + (subframe*2), + &eNB->frame_parms); + do_OFDM_mod_symbol(&eNB->common_vars, + eNB_id, + (subframe*2)+1, + &eNB->frame_parms); stop_meas(&eNB->ofdm_mod_stats); stop_meas(&eNB->phy_proc_tx); - /* do_OFDM_mod_l(&eNB->common_vars, - eNB_id, - (subframe*2)+2, - &eNB->frame_parms); */ + /* do_OFDM_mod_l(&eNB->common_vars, + eNB_id, + (subframe*2)+2, + &eNB->frame_parms); */ if (n_frames==1) { if (transmission_mode<7) LOG_M("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size], - nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); else if (transmission_mode==7) LOG_M("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size], - nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + LOG_M("txsigF0_BF.m","txsF0_BF", &eNB->common_vars.txdataF_BF[eNB_id][0][0], - eNB->frame_parms.ofdm_symbol_size,1,1); + eNB->frame_parms.ofdm_symbol_size,1,1); if (eNB->frame_parms.nb_antennas_tx>1)// to be updated LOG_M("txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size], - nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); } + tx_lev = 0; for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { @@ -2873,7 +2764,7 @@ PMI_FEEDBACK: tx_lev_dB = (unsigned int) dB_fixed(tx_lev); if (n_frames==1) { - printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); + printf("tx_lev = %u (%u dB)\n",tx_lev,tx_lev_dB); LOG_M("txsig0.m","txs0", &eNB->common_vars.txdata[eNB_id][0][subframe*eNB->frame_parms.samples_per_tti],eNB->frame_parms.samples_per_tti,1,1); // LOG_M("txsig0.m","txs0",&eNB->common_vars.txdata[eNB_id][0][0*eNB->frame_parms.samples_per_tti],eNB->frame_parms.samples_per_tti*10,1,1); } @@ -2920,7 +2811,6 @@ PMI_FEEDBACK: r_re[aarx][i] += (double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]; r_im[aarx][i] += (double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]; } - } } } @@ -2938,16 +2828,16 @@ PMI_FEEDBACK: random_channel(eNB2UE[2],0); random_channel(eNB2UE[3],0); } - - if (UE->perfect_ce==1) { - // fill in perfect channel estimates - freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1); - /* - LOG_M("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); - LOG_M("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL + 1,1,8); - */ - } - } + + if (UE->perfect_ce==1) { + // fill in perfect channel estimates + freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1); + /* + LOG_M("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8); + LOG_M("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL + 1,1,8); + */ + } + } if(abstx) { if (trials==0 && round==0) { @@ -3017,17 +2907,16 @@ PMI_FEEDBACK: for (i=0; i<2*frame_parms->samples_per_tti; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { // printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); - ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = + ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = + ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); //((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = (short) r_re[aa][i]; - //((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = (short) r_im[aa][i]; + //((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = (short) r_im[aa][i]; //printf("rxdata[%d][%d]=> %d, %d\n",aa,subframe*UE->frame_parms.samples_per_tti+i,r_re[aa][i],r_im[aa][i]); } } - // lte_sync_time_init(eNB->frame_parms,common_vars); // lte_sync_time(common_vars->rxdata, eNB->frame_parms); // lte_sync_time_free(); @@ -3064,12 +2953,11 @@ PMI_FEEDBACK: pilot2 = 6; pilot3 = 9; } - start_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // Inner receiver scheduling for 3 slots - + for (Ns=(2*subframe); Ns<((2*subframe)+3); Ns++) { for (l=0; l<pilot2; l++) { if (n_frames==1) @@ -3087,14 +2975,13 @@ PMI_FEEDBACK: no_prefix if 1 prefix is removed by HW */ - start_meas(&UE->ofdm_demod_stats); slot_fep(UE, l, Ns%20, 0, 0, - 0); + 0); stop_meas(&UE->ofdm_demod_stats); if (UE->perfect_ce==1) { @@ -3103,26 +2990,27 @@ PMI_FEEDBACK: for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (i=0; i<frame_parms->N_RB_DL*12; i++) { - ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)( - eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); + ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size + +LTE_CE_FILTER_LENGTH)*2]=(int16_t)( + eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); //printf("x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP); - ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)( - eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); + ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size + +LTE_CE_FILTER_LENGTH)*2]=(int16_t)( + eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); - if (transmission_mode == 7){ - //this should include the BF weights! Will not work for a random channel + if (transmission_mode == 7) { + //this should include the BF weights! Will not work for a random channel if (UE->high_speed_flag==0) { ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(int16_t)( - eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); + eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=(int16_t)( - eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); + eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); //printf("**,x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP); } else { ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)( - eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); + eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)( - eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); - + eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); } } } @@ -3133,10 +3021,13 @@ PMI_FEEDBACK: for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) { for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { for (i=0; i<frame_parms->N_RB_DL*12; i++) { - ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); - ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2; + ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size + +LTE_CE_FILTER_LENGTH)*2]=(short)(AMP); + ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size + +LTE_CE_FILTER_LENGTH)*2]=0/2; + if (transmission_mode == 7) { - if (UE->high_speed_flag==0){ + if (UE->high_speed_flag==0) { ((int16_t *) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(short)(AMP); ((int16_t *) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=0/2; } else { @@ -3150,7 +3041,6 @@ PMI_FEEDBACK: } } - if ((Ns==((2*subframe))) && (l==0)) { lte_ue_measurements(UE, subframe*UE->frame_parms.samples_per_tti, @@ -3186,12 +3076,9 @@ PMI_FEEDBACK: goto PMI_FEEDBACK; } } - } - if ((Ns==(2*subframe)) && (l==pilot1)) {// process symbols 0,1,2 - if (dci_flag == 1) { UE->UE_mode[0] = PUSCH; start_meas(&UE->dlsch_rx_pdcch_stats); @@ -3207,7 +3094,6 @@ PMI_FEEDBACK: stop_meas(&UE->dlsch_rx_pdcch_stats); // overwrite number of pdcch symbols UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; - dci_cnt = dci_decoding_procedure(UE, dci_alloc_rx,1, eNB_id, @@ -3224,7 +3110,7 @@ PMI_FEEDBACK: //round_trials[0]++; if (n_frames==1) - printf("DCI error trial %d errs[0] %d\n",trials,errs[0]); + printf("DCI error trial %u errs[0] %u\n",trials,errs[0]); } // for (i=1;i<=round;i++) @@ -3238,7 +3124,7 @@ PMI_FEEDBACK: if ((dci_alloc_rx[i].rnti == n_rnti) && (generate_ue_dlsch_params_from_dci(0, - subframe, + subframe, dci_alloc_rx[i].dci_pdu, dci_alloc_rx[i].rnti, dci_alloc_rx[i].format, @@ -3259,18 +3145,16 @@ PMI_FEEDBACK: UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->Nl, UE->pdcch_vars[0]->num_pdcch_symbols, 0, - subframe, - (transmission_mode<7?0:transmission_mode)); - /*if (transmission_mode==7 && common_flag==0) - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->mimo_mode = TM7; */ - + subframe, + (transmission_mode<7?0:transmission_mode)); + /*if (transmission_mode==7 && common_flag==0) + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->mimo_mode = TM7; */ /* rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs)][UE->dlsch[UE->current_thread_id[subframe]][0][0]->nb_rb-1]/(coded_bits_per_codeword); rate*=get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs); */ - printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword, + printf("num_pdcch_symbols %d, G %u, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword, UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->TBS); - dlsch_active = 1; } else { dlsch_active = 0; @@ -3282,7 +3166,7 @@ PMI_FEEDBACK: round=5; if (n_frames==1) - printf("DCI misdetection trial %d\n",trials); + printf("DCI misdetection trial %u\n",trials); } @@ -3293,86 +3177,84 @@ PMI_FEEDBACK: } } // if dci_flag==1 else { //dci_flag == 0 - UE->pdcch_vars[0]->crnti = n_rnti; UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols; if (round == 0) UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx=1; switch (transmission_mode) { - case 1: - case 2: - case 7: - generate_ue_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - (common_flag==0)? C_RNTI : SI_RNTI, - (common_flag==0)? format1 : format1A, - UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id], - UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id], - UE->dlsch[UE->current_thread_id[subframe]][0], - &UE->frame_parms, - UE->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - transmission_mode<7?0:transmission_mode); - /*if(transmission_mode==7 && common_flag==0) - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->mimo_mode = TM7;*/ - break; - - case 3: - // printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx); - generate_ue_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - (common_flag==0)? C_RNTI : SI_RNTI, - (common_flag==0)? format2A : format1A, - UE->dlsch[UE->current_thread_id[subframe]][0], - &UE->frame_parms, - UE->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - 0); - // printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx); - break; + case 1: + case 2: + case 7: + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + (common_flag==0)? C_RNTI : SI_RNTI, + (common_flag==0)? format1 : format1A, + UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id], + UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id], + UE->dlsch[UE->current_thread_id[subframe]][0], + &UE->frame_parms, + UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + transmission_mode<7?0:transmission_mode); + /*if(transmission_mode==7 && common_flag==0) + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->mimo_mode = TM7;*/ + break; - case 4: - generate_ue_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - (common_flag==0)? C_RNTI : SI_RNTI, - (common_flag==0)? format2 : format1A, - UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id], - UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id], - UE->dlsch[UE->current_thread_id[subframe]][0], - &UE->frame_parms, - UE->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - 0); - break; + case 3: + // printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx); + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + (common_flag==0)? C_RNTI : SI_RNTI, + (common_flag==0)? format2A : format1A, + UE->dlsch[UE->current_thread_id[subframe]][0], + &UE->frame_parms, + UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + 0); + // printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx); + break; - case 5: - case 6: - generate_ue_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu2_1E[0], - C_RNTI, - format1E_2A_M10PRB, - ue->pdcch_vars[UE->current_thread_id[subframe]][eNB_id], - ue->pdsch_vars[UE->current_thread_id[subframe]][eNB_id], - UE->dlsch[UE->current_thread_id[subframe]][0], - &UE->frame_parms, - UE->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - 0); - break; + case 4: + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu_1[0], + (common_flag==0)? C_RNTI : SI_RNTI, + (common_flag==0)? format2 : format1A, + UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id], + UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id], + UE->dlsch[UE->current_thread_id[subframe]][0], + &UE->frame_parms, + UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + 0); + break; + case 5: + case 6: + generate_ue_dlsch_params_from_dci(0, + subframe, + &DLSCH_alloc_pdu2_1E[0], + C_RNTI, + format1E_2A_M10PRB, + ue->pdcch_vars[UE->current_thread_id[subframe]][eNB_id], + ue->pdsch_vars[UE->current_thread_id[subframe]][eNB_id], + UE->dlsch[UE->current_thread_id[subframe]][0], + &UE->frame_parms, + UE->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + 0); + break; } dlsch_active = 1; @@ -3380,21 +3262,19 @@ PMI_FEEDBACK: } if (dlsch_active == 1) { - - if (transmission_mode==7) { - if (UE->frame_parms.Ncp==0) { - if ((Ns==(2*subframe) && ((l==3) || (l==6))) || - (Ns==(1+2*subframe) && ((l==2) || (l==5)))) { - if (perfect_ce==0) - lte_dl_bf_channel_estimation(UE,eNB_id,0,Ns,5,l+7*(Ns%2==1)); - } - } else { - msg("Beamforming channel estimation not supported yet for TM7 extented CP.\n"); - } - } + if (transmission_mode==7) { + if (UE->frame_parms.Ncp==0) { + if ((Ns==(2*subframe) && ((l==3) || (l==6))) || + (Ns==(1+2*subframe) && ((l==2) || (l==5)))) { + if (perfect_ce==0) + lte_dl_bf_channel_estimation(UE,eNB_id,0,Ns,5,l+7*(Ns%2==1)); + } + } else { + msg("Beamforming channel estimation not supported yet for TM7 extented CP.\n"); + } + } if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix) - if ((transmission_mode == 5) && (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->dl_power_off==0) && (UE->use_ia_receiver ==1)) { @@ -3403,7 +3283,6 @@ PMI_FEEDBACK: dual_stream_UE = 0; } - start_meas(&UE->dlsch_llr_stats); for (m=UE->pdcch_vars[0]->num_pdcch_symbols; @@ -3480,7 +3359,6 @@ PMI_FEEDBACK: stop_meas(&UE->dlsch_llr_stats); } - if (test_perf ==0 ) { if ((n_frames==1) && (Ns==(2+(2*subframe))) && (l==0)) { LOG_M("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); @@ -3500,36 +3378,33 @@ PMI_FEEDBACK: } LOG_M("dlsch00_r0.m","dl00_r0", - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), - UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); if (UE->frame_parms.nb_antennas_rx>1) LOG_M("dlsch01_r0.m","dl01_r0", - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]), - UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); if (eNB->frame_parms.nb_antennas_tx>1) LOG_M("dlsch10_r0.m","dl10_r0", - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]), - UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) LOG_M("dlsch11_r0.m","dl11_r0", - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]), - UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); //pdsch_vars dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round); //dump_dlsch2(UE,eNB_id_i,coded_bits_per_codeword); LOG_M("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4); - //pdcch_vars LOG_M("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); LOG_M("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1); LOG_M("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4); - } } } @@ -3557,21 +3432,17 @@ PMI_FEEDBACK: eNB->dlsch[0][cw]->harq_processes[0]->Nl, num_pdcch_symbols, 0, - subframe, - (transmission_mode<7?0:transmission_mode)); - + subframe, + (transmission_mode<7?0:transmission_mode)); UE->dlsch[UE->current_thread_id[subframe]][0][cw]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][cw]->current_harq_pid]->G = coded_bits_per_codeword; - - - // calculate uncoded BLER uncoded_ber=0; - for (i=0;i<coded_bits_per_codeword;i++) + + for (i=0; i<coded_bits_per_codeword; i++) if (eNB->dlsch[0][0]->harq_processes[0]->e[i] != (UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]<0)) { uncoded_ber_bit[i] = 1; uncoded_ber++; - } - else + } else uncoded_ber_bit[i] = 0; uncoded_ber/=coded_bits_per_codeword; @@ -3579,7 +3450,6 @@ PMI_FEEDBACK: if (n_frames==1) LOG_M("uncoded_ber_bit.m","uncoded_ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); - start_meas(&UE->dlsch_unscrambling_stats); dlsch_unscrambling(&UE->frame_parms, @@ -3590,7 +3460,6 @@ PMI_FEEDBACK: 0, subframe<<1); stop_meas(&UE->dlsch_unscrambling_stats); - start_meas(&UE->dlsch_decoding_stats); ret = dlsch_decoding(UE, UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[cw], @@ -3610,12 +3479,9 @@ PMI_FEEDBACK: } } - stop_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); - if (ret <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations) { - avg_iter += ret; iter_trials++; @@ -3625,7 +3491,8 @@ PMI_FEEDBACK: UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; - if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) { //try to decode second stream using SIC + if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode == + LARGE_CDD) { //try to decode second stream using SIC /* for (round = 0 ; round < UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round ; round++) { // re-encoding of first stream @@ -3667,12 +3534,11 @@ PMI_FEEDBACK: } } else { errs[round]++; - avg_iter += ret-1; iter_trials++; if (n_frames==1) { - //if ((n_frames==1) || (SNR>=30)) + //if ((n_frames==1) || (SNR>=30)) printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); for (s=0; s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) { @@ -3682,11 +3548,11 @@ PMI_FEEDBACK: Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus; Kr_bytes = Kr>>3; - printf("Decoded_output (Segment %d):\n",s); for (i=0; i<Kr_bytes; i++) - printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i],UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); + printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i], + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]); } sprintf(fname,"rxsig0_r%d.m",round); @@ -3695,7 +3561,7 @@ PMI_FEEDBACK: sprintf(fname,"rxsigF0_r%d.m",round); sprintf(vname,"rxs0F_r%d",round); LOG_M(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1); - + if (UE->frame_parms.nb_antennas_rx>1) { sprintf(fname,"rxsig1_r%d.m",round); sprintf(vname,"rxs1_r%d.m",round); @@ -3708,31 +3574,31 @@ PMI_FEEDBACK: sprintf(fname,"dlsch00_r%d.m",round); sprintf(vname,"dl00_r%d",round); LOG_M(fname,vname, - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), - UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]), + UE->frame_parms.ofdm_symbol_size*nsymb,1,1); if (UE->frame_parms.nb_antennas_rx>1) { sprintf(fname,"dlsch01_r%d.m",round); sprintf(vname,"dl01_r%d",round); LOG_M(fname,vname, - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]), - UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); } if (eNB->frame_parms.nb_antennas_tx>1) { sprintf(fname,"dlsch10_r%d.m",round); sprintf(vname,"dl10_r%d",round); LOG_M(fname,vname, - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]), - UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); } if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1)) { sprintf(fname,"dlsch11_r%d.m",round); sprintf(vname,"dl11_r%d",round); LOG_M(fname,vname, - &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]), - UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); + &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]), + UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); } //pdsch_vars @@ -3748,19 +3614,17 @@ PMI_FEEDBACK: } // printf("round %d errors %d/%d\n",round,errs[round],trials); - round++; // UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++; } - if (xforms==1) { - phy_scope_UE(form_ue, - UE, - eNB_id, - 0,// UE_id - subframe); - } - + if (xforms==1) { + phy_scope_UE(form_ue, + UE, + eNB_id, + 0,// UE_id + subframe); + } } //round // printf("\n"); @@ -3778,9 +3642,7 @@ PMI_FEEDBACK: UE->total_TBS_last[eNB_id] = UE->total_TBS[eNB_id]; } - UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++; - /* calculate the total processing time for each packet, * get the max, min, and number of packets that exceed t>2000us */ @@ -3788,8 +3650,6 @@ PMI_FEEDBACK: double t_tx_ifft = (double)eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; double t_tx_mod = (double)eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; - - double t_rx = (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0; double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; @@ -3817,13 +3677,10 @@ PMI_FEEDBACK: push_front(&time_vector_tx_ifft, t_tx_ifft); push_front(&time_vector_tx_mod, t_tx_mod); push_front(&time_vector_tx_enc, t_tx_enc); - push_front(&time_vector_rx, t_rx); push_front(&time_vector_rx_fft, t_rx_fft); push_front(&time_vector_rx_demod, t_rx_demod); push_front(&time_vector_rx_dec, t_rx_dec); - - } //trials // round_trials[0]: number of code word : goodput the protocol @@ -3835,7 +3692,6 @@ PMI_FEEDBACK: totable(table_tx_mod, &time_vector_tx_mod); double table_tx_enc[time_vector_tx_enc.size]; totable(table_tx_enc, &time_vector_tx_enc); - double table_rx[time_vector_rx.size]; totable(table_rx, &time_vector_rx); double table_rx_fft[time_vector_rx_fft.size]; @@ -3844,8 +3700,6 @@ PMI_FEEDBACK: totable(table_rx_demod, &time_vector_rx_demod); double table_rx_dec[time_vector_rx_dec.size]; totable(table_rx_dec, &time_vector_rx_dec); - - // sort table qsort (table_tx, time_vector_tx.size, sizeof(double), &compare); qsort (table_rx, time_vector_rx.size, sizeof(double), &compare); @@ -3859,53 +3713,41 @@ PMI_FEEDBACK: double tx_median = table_tx[time_vector_tx.size/2]; double tx_q1 = table_tx[time_vector_tx.size/4]; double tx_q3 = table_tx[3*time_vector_tx.size/4]; - double tx_ifft_median = table_tx_ifft[time_vector_tx_ifft.size/2]; double tx_ifft_q1 = table_tx_ifft[time_vector_tx_ifft.size/4]; double tx_ifft_q3 = table_tx_ifft[3*time_vector_tx_ifft.size/4]; - double tx_mod_median = table_tx_mod[time_vector_tx_mod.size/2]; double tx_mod_q1 = table_tx_mod[time_vector_tx_mod.size/4]; double tx_mod_q3 = table_tx_mod[3*time_vector_tx_mod.size/4]; - double tx_enc_median = table_tx_enc[time_vector_tx_enc.size/2]; double tx_enc_q1 = table_tx_enc[time_vector_tx_enc.size/4]; double tx_enc_q3 = table_tx_enc[3*time_vector_tx_enc.size/4]; - double rx_median = table_rx[time_vector_rx.size/2]; double rx_q1 = table_rx[time_vector_rx.size/4]; double rx_q3 = table_rx[3*time_vector_rx.size/4]; - double rx_fft_median = table_rx_fft[time_vector_rx_fft.size/2]; double rx_fft_q1 = table_rx_fft[time_vector_rx_fft.size/4]; double rx_fft_q3 = table_rx_fft[3*time_vector_rx_fft.size/4]; - double rx_demod_median = table_rx_demod[time_vector_rx_demod.size/2]; double rx_demod_q1 = table_rx_demod[time_vector_rx_demod.size/4]; double rx_demod_q3 = table_rx_demod[3*time_vector_rx_demod.size/4]; - double rx_dec_median = table_rx_dec[time_vector_rx_dec.size/2]; double rx_dec_q1 = table_rx_dec[time_vector_rx_dec.size/4]; double rx_dec_q3 = table_rx_dec[3*time_vector_rx_dec.size/4]; - double std_phy_proc_tx=0; double std_phy_proc_tx_ifft=0; double std_phy_proc_tx_mod=0; double std_phy_proc_tx_enc=0; - double std_phy_proc_rx=0; double std_phy_proc_rx_fft=0; double std_phy_proc_rx_demod=0; double std_phy_proc_rx_dec=0; - effective_rate = ((double)(round_trials[0]-dci_errors)/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); - printf("\n**********************SNR = %f dB (tx_lev %f, sigma2_dB %f)**************************\n", SNR, (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12)), sigma2_dB); - - printf("Errors (%d(%d)/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e), dci_errors %d/%d, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f)\n", + printf("Errors (%u(%u)/%u %u/%u %u/%u %u/%u), Pe = (%e,%e,%e,%e), dci_errors %u/%u, Pe = %e => effective rate %f (%2.1f%%,%f, %f), normalized delay %f (%f)\n", errs[0], errs2[0], round_trials[0], @@ -3962,11 +3804,12 @@ PMI_FEEDBACK: printf("|__ DLSCH sub-block interleaving time :%f us (%d trials)\n", ((double)eNB->dlsch_interleaving_stats.trials/eNB->dlsch_encoding_stats.trials)*(double) eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials); - printf("\n\nUE RX function statistics (per 1ms subframe)\n\n"); std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2)); - printf("Total PHY proc rx :%f us (%d trials)\n",(double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0, + 2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double) + UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2)); + printf("Total PHY proc rx :%f us (%d trials)\n", + (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0, UE->phy_proc_rx[UE->current_thread_id[subframe]].trials*2/3); printf("|__Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); @@ -4001,7 +3844,8 @@ PMI_FEEDBACK: printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); printf(" |__ init %f us (cycles/iter %f, %d trials)\n", (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, @@ -4034,7 +3878,7 @@ PMI_FEEDBACK: } if ((transmission_mode != 3) && (transmission_mode != 4)) { - fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", + fprintf(bler_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u\n", SNR, mcs1, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -4049,7 +3893,7 @@ PMI_FEEDBACK: round_trials[3], dci_errors); } else { - fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n", + fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u\n", SNR, mcs1,mcs2, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -4066,7 +3910,6 @@ PMI_FEEDBACK: dci_errors); } - if(abstx) { //ABSTRACTION blerr[0] = (double)errs[0]/(round_trials[0]); @@ -4083,7 +3926,7 @@ PMI_FEEDBACK: if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n"); if ((transmission_mode != 3) && (transmission_mode != 4)) { - fprintf(time_meas_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", + fprintf(time_meas_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u;", SNR, mcs1, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -4097,9 +3940,8 @@ PMI_FEEDBACK: errs[3], round_trials[3], dci_errors); - //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); - fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", + fprintf(time_meas_fd,"%f;%d;%d;%f; %2.1f%%;%f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%u;%u;%e;%f;%f;", SNR, mcs1, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -4126,7 +3968,7 @@ PMI_FEEDBACK: (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); } else { - fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;", + fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;%u;", SNR, mcs1,mcs2, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -4141,9 +3983,8 @@ PMI_FEEDBACK: errs[3], round_trials[3], dci_errors); - //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; DL_DECOD_ITER; err0; trials0; err1; trials1; err2; trials2; err3; trials3; PE; dci_err;PE;ND;\n"); - fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%d;%d;%e;%f;%f;", + fprintf(time_meas_fd,"%f;%d;%d;%d;%d;%f;%2.1f;%f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%u;%u;%e;%f;%f;", SNR, mcs1,mcs2, eNB->dlsch[0][0]->harq_processes[0]->TBS, @@ -4201,30 +4042,20 @@ PMI_FEEDBACK: ); //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); - //fprintf(time_meas_fd,"IFFT;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - //fprintf(time_meas_fd,"MOD;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - //fprintf(time_meas_fd,"ENC;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - - //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); - //fprintf(time_meas_fd,"FFT;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); - //fprintf(time_meas_fd,"DEMOD;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3); - //fprintf(time_meas_fd,"DEC;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); - - /* fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;", eNB->phy_proc_tx.trials, @@ -4248,11 +4079,8 @@ PMI_FEEDBACK: if (((double)errs[0]/(round_trials[0]))<(10.0/n_frames)) break; }// SNR - - } //ch_realization - fclose(bler_fd); if (test_perf !=0) @@ -4293,10 +4121,9 @@ PMI_FEEDBACK: free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]); } - printf("Freeing channel I/O\n"); - for (i=0; i<n_tx_phy; i++){ + for (i=0; i<n_tx_phy; i++) { free(s_re[i]); free(s_im[i]); } @@ -4306,16 +4133,12 @@ PMI_FEEDBACK: free(r_im[i]); } - free(s_re); free(s_im); free(r_re); free(r_im); - // lte_sync_time_free(); - // printf("[MUMIMO] mcs %d, mcsi %d, offset %d, bler %f\n",mcs,mcs_i,offset_mumimo_llr_drange_fix,((double)errs[0])/((double)round_trials[0])); - return(0); } diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c index 9910c97af838db34ec814a0019c3b9e036f622c6..65415e7c68b97633eff7557dfe51ffba935f70f5 100644 --- a/openair1/SIMULATION/LTE_PHY/mbmssim.c +++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c @@ -36,7 +36,7 @@ #include "LAYER2/MAC/vars.h" #ifdef XFORMS -#include "PHY/TOOLS/lte_phy_scope.h" + #include "PHY/TOOLS/lte_phy_scope.h" #endif //XFORMS @@ -52,11 +52,8 @@ double cpuf; DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu2_1E[2]; #define UL_RB_ALLOC 0x1ff; #define CCCH_RB_ALLOC computeRIV(eNB->frame_parms.N_RB_UL,0,2) -int main(int argc, char **argv) -{ - +int main(int argc, char **argv) { char c; - int i,l,l2,aa,aarx,k; double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1=0.0; uint8_t snr1set=0; @@ -64,48 +61,34 @@ int main(int argc, char **argv) int **txdata; double s_re0[2*30720],s_im0[2*30720],s_re1[2*30720],s_im1[2*30720]; double r_re0[2*30720],r_im0[2*30720],r_re1[2*30720],r_im1[2*30720]; - double *s_re[2]={s_re0,s_re1},*s_im[2]={s_im0,s_im1},*r_re[2]={r_re0,r_re1},*r_im[2]={r_im0,r_im1}; + double *s_re[2]= {s_re0,s_re1},*s_im[2]= {s_im0,s_im1},*r_re[2]= {r_re0,r_re1},*r_im[2]= {r_im0,r_im1}; double iqim = 0.0; int subframe=1; char fname[40];//, vname[40]; uint8_t transmission_mode = 1,n_tx=1,n_rx=2; uint16_t Nid_cell=0; - FILE *fd; - int eNB_id = 0; unsigned char mcs=0,awgn_flag=0,round; - int n_frames=1; channel_desc_t *eNB2UE; uint32_t nsymb,tx_lev,tx_lev_dB; uint8_t extended_prefix_flag=1; LTE_DL_FRAME_PARMS *frame_parms; int hold_channel=0; - - uint16_t NB_RB=25; - int tdd_config=3; - SCM_t channel_model=MBSFN; - - unsigned char *input_buffer; unsigned short input_buffer_length; unsigned int ret; - unsigned int trials,errs[4]= {0,0,0,0}; //,round_trials[4]={0,0,0,0}; - uint8_t N_RB_DL=25,osf=1; uint32_t perfect_ce = 0; - lte_frame_type_t frame_type = FDD; - uint32_t Nsoft = 1827072; - /* -#ifdef XFORMS + #ifdef XFORMS FD_lte_phy_scope_ue *form_ue; char title[255]; @@ -113,114 +96,110 @@ int main(int argc, char **argv) form_ue = create_lte_phy_scope_ue(); sprintf (title, "LTE DL SCOPE UE"); fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); -#endif + #endif */ - cpuf = get_cpu_freq_GHz(); - logInit(); number_of_cards = 1; while ((c = getopt (argc, argv, "ahA:Cp:n:s:S:t:x:y:z:N:F:R:O:dm:i:Y")) != -1) { switch (c) { - case 'a': - awgn_flag=1; - break; - - case 'd': - frame_type = 0; - break; - - case 'n': - n_frames = atoi(optarg); - break; - - case 'm': - mcs=atoi(optarg); - break; - - case 's': - snr0 = atof(optarg); - msg("Setting SNR0 to %f\n",snr0); - break; - - case 'i': - input_snr_step = atof(optarg); - break; - - case 'S': - snr1 = atof(optarg); - snr1set=1; - msg("Setting SNR1 to %f\n",snr1); - break; - - case 'p': // subframe no; - subframe=atoi(optarg); - break; - - case 'z': - n_rx=atoi(optarg); - - if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); - exit(-1); - } - - break; - - case 'N': - Nid_cell = atoi(optarg); - break; - - case 'R': - N_RB_DL = atoi(optarg); + case 'a': + awgn_flag=1; + break; + + case 'd': + frame_type = 0; + break; + + case 'n': + n_frames = atoi(optarg); + break; + + case 'm': + mcs=atoi(optarg); + break; + + case 's': + snr0 = atof(optarg); + msg("Setting SNR0 to %f\n",snr0); + break; + + case 'i': + input_snr_step = atof(optarg); + break; + + case 'S': + snr1 = atof(optarg); + snr1set=1; + msg("Setting SNR1 to %f\n",snr1); + break; + + case 'p': // subframe no; + subframe=atoi(optarg); + break; + + case 'z': + n_rx=atoi(optarg); + + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } - if ((N_RB_DL!=6) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=100)) { - printf("Unsupported Bandwidth %d\n",N_RB_DL); - exit(-1); - } + break; - break; + case 'N': + Nid_cell = atoi(optarg); + break; - case 'O': - osf = atoi(optarg); - break; + case 'R': + N_RB_DL = atoi(optarg); - case 'Y': - perfect_ce = 1; - break; + if ((N_RB_DL!=6) && (N_RB_DL!=25) && (N_RB_DL!=50) && (N_RB_DL!=100)) { + printf("Unsupported Bandwidth %d\n",N_RB_DL); + exit(-1); + } - default: - case 'h': - printf("%s -h(elp) -p(subframe) -N cell_id -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -i snr increment -z RXant \n",argv[0]); - printf("-h This message\n"); - printf("-a Use AWGN Channel\n"); - printf("-p Use extended prefix mode\n"); - printf("-d Use TDD\n"); - printf("-n Number of frames to simulate\n"); - printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); - printf("-S Ending SNR, runs from SNR0 to SNR1\n"); - printf("-t Delay spread for multipath channel\n"); - printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); - printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); - printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); - printf("-N Nid_cell\n"); - printf("-R N_RB_DL\n"); - printf("-O oversampling factor (1,2,4,8,16)\n"); - printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); - printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); - printf("-f Output filename (.txt format) for Pe/SNR results\n"); - printf("-F Input filename (.txt format) for RX conformance testing\n"); - exit (-1); - break; + break; + + case 'O': + osf = atoi(optarg); + break; + + case 'Y': + perfect_ce = 1; + break; + + default: + case 'h': + printf("%s -h(elp) -p(subframe) -N cell_id -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -i snr increment -z RXant \n",argv[0]); + printf("-h This message\n"); + printf("-a Use AWGN Channel\n"); + printf("-p Use extended prefix mode\n"); + printf("-d Use TDD\n"); + printf("-n Number of frames to simulate\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-t Delay spread for multipath channel\n"); + printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-N Nid_cell\n"); + printf("-R N_RB_DL\n"); + printf("-O oversampling factor (1,2,4,8,16)\n"); + printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); + printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); + printf("-f Output filename (.txt format) for Pe/SNR results\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + exit (-1); + break; } } - - if (awgn_flag == 1) channel_model = AWGN; @@ -229,7 +208,6 @@ int main(int argc, char **argv) if ((subframe == 0) || (subframe == 5) || // TDD and FDD SFn 0,5; ((frame_type == FDD) && ((subframe == 4) || (subframe == 9))) || // FDD SFn 4,9; ((frame_type == TDD ) && ((subframe<3) || (subframe==6)))) { // TDD SFn 1,2,6; - printf("Illegal subframe %d for eMBMS transmission (frame_type %d)\n",subframe,frame_type); exit(-1); } @@ -239,16 +217,16 @@ int main(int argc, char **argv) lte_param_init(n_tx, n_tx, - n_rx, - transmission_mode, - extended_prefix_flag, - frame_type, - Nid_cell, - tdd_config, - N_RB_DL, - 0, - osf, - perfect_ce); + n_rx, + transmission_mode, + extended_prefix_flag, + frame_type, + Nid_cell, + tdd_config, + N_RB_DL, + 0, + osf, + perfect_ce); if (snr1set==0) { if (n_frames==1) @@ -258,7 +236,6 @@ int main(int argc, char **argv) } printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - frame_parms = &eNB->frame_parms; if (awgn_flag == 0) @@ -270,7 +247,6 @@ int main(int argc, char **argv) printf("Cannot open %s, check permissions\n",fname); exit(-1); } - if (awgn_flag==0) fprintf(fd,"SNR_%d_%d=[];errs_mch_%d_%d=[];mch_trials_%d_%d=[];\n", @@ -284,23 +260,18 @@ int main(int argc, char **argv) mcs,N_RB_DL); fflush(fd); - txdata = eNB->common_vars.txdata[0]; - nsymb = 12; - printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d, AWGN %d\n",NUMBER_OF_OFDM_CARRIERS, frame_parms->Ncp,frame_parms->samples_per_tti,nsymb,awgn_flag); - eNB2UE = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), 0, 0, 0); - // Create transport channel structures for 2 transport blocks (MIMO) eNB->dlsch_MCH = new_eNB_dlsch(1,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); @@ -310,7 +281,6 @@ int main(int argc, char **argv) } UE->dlsch_MCH[0] = new_ue_dlsch(1,8,Nsoft,MAX_TURBO_ITERATIONS_MBSFN,N_RB_DL,0); - eNB->frame_parms.num_MBSFN_config = 1; eNB->frame_parms.MBSFN_config[0].radioframeAllocationPeriod = 0; eNB->frame_parms.MBSFN_config[0].radioframeAllocationOffset = 0; @@ -321,7 +291,6 @@ int main(int argc, char **argv) UE->frame_parms.MBSFN_config[0].radioframeAllocationOffset = 0; UE->frame_parms.MBSFN_config[0].fourFrames_flag = 0; UE->frame_parms.MBSFN_config[0].mbsfn_SubframeConfig=0xff; // activate all possible subframes - fill_eNB_dlsch_MCH(eNB,mcs,1,0); fill_UE_dlsch_MCH(UE,mcs,1,0,0); @@ -333,7 +302,6 @@ int main(int argc, char **argv) exit(-1); } - input_buffer_length = eNB->dlsch_MCH->harq_processes[0]->TBS/8; input_buffer = (unsigned char *)malloc(input_buffer_length+4); memset(input_buffer,0,input_buffer_length+4); @@ -342,14 +310,12 @@ int main(int argc, char **argv) input_buffer[i]= (unsigned char)(taus()&0xff); } - snr_step = input_snr_step; for (SNR=snr0; SNR<snr1; SNR+=snr_step) { UE->proc.proc_rxtx[0].frame_tx=0; eNB->proc.proc_rxtx[0].frame_tx=0; eNB->proc.proc_rxtx[0].subframe_tx=subframe; - errs[0]=0; errs[1]=0; errs[2]=0; @@ -365,14 +331,11 @@ int main(int argc, char **argv) // printf("Trial %d\n",trials); fflush(stdout); round=0; - //if (trials%100==0) //eNB2UE[0]->first_run = 1; eNB2UE->first_run = 1; memset(&eNB->common_vars.txdataF[0][0][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); generate_mch(eNB,&eNB->proc.proc_rxtx[0],input_buffer); - - PHY_ofdm_mod(eNB->common_vars.txdataF[0][0], // input, txdata[0], // output frame_parms->ofdm_symbol_size, @@ -382,7 +345,7 @@ int main(int argc, char **argv) if (n_frames==1) { LOG_M("txsigF0.m","txsF0", &eNB->common_vars.txdataF[0][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size], - nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); //if (eNB->frame_parms.nb_antennas_tx>1) //LOG_M("txsigF1.m","txsF1", &eNB->lte_eNB_common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); } @@ -400,11 +363,9 @@ int main(int argc, char **argv) if (n_frames==1) { printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); // LOG_M("txsig0.m","txs0", &eNB->common_vars.txdata[0][0][subframe* eNB->frame_parms.samples_per_tti], - // eNB->frame_parms.samples_per_tti,1,1); } - for (i=0; i<2*frame_parms->samples_per_tti; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); @@ -415,7 +376,6 @@ int main(int argc, char **argv) //Multipath channel multipath_channel(eNB2UE,s_re,s_im,r_re,r_im, 2*frame_parms->samples_per_tti,hold_channel); - //AWGN sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(NB_RB*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); @@ -426,67 +386,70 @@ int main(int argc, char **argv) for (i=0; i<2*frame_parms->samples_per_tti; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); - ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = + ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = + ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] = (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); } } for (l=2; l<12; l++) { - slot_fep_mbsfn(UE, l, subframe%10, 0, 0); - if (UE->perfect_ce==1) { - // fill in perfect channel estimates - freq_channel(eNB2UE,UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1); - for(k=0; k<NUMBER_OF_eNB_MAX; k++) { - for(aa=0; aa<frame_parms->nb_antennas_tx; aa++) { - for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - for (i=0; i<frame_parms->N_RB_DL*12; i++) { - ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP); - ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP); - } - } - } - } - } - - if (l==6) - for (l2=2;l2<7;l2++) - rx_pmch(UE, - 0, - subframe%10, - l2); - if (l==6) - for (l2=2;l2<7;l2++) - rx_pmch(UE, - 0, - subframe%10, - l2); - if (l==11) - for (l2=7;l2<12;l2++) - rx_pmch(UE, - 0, - subframe%10, - l2); + + if (UE->perfect_ce==1) { + // fill in perfect channel estimates + freq_channel(eNB2UE,UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1); + + for(k=0; k<NUMBER_OF_eNB_MAX; k++) { + for(aa=0; aa<frame_parms->nb_antennas_tx; aa++) { + for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { + for (i=0; i<frame_parms->N_RB_DL*12; i++) { + ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+ + (aa*frame_parms->nb_antennas_rx)][i].x*AMP); + ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+(l*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(eNB2UE->chF[aarx+ + (aa*frame_parms->nb_antennas_rx)][i].y*AMP); + } + } + } + } + } + + if (l==6) + for (l2=2; l2<7; l2++) + rx_pmch(UE, + 0, + subframe%10, + l2); + + if (l==6) + for (l2=2; l2<7; l2++) + rx_pmch(UE, + 0, + subframe%10, + l2); + + if (l==11) + for (l2=7; l2<12; l2++) + rx_pmch(UE, + 0, + subframe%10, + l2); } UE->dlsch_MCH[0]->harq_processes[0]->G = get_G(&UE->frame_parms, - UE->dlsch_MCH[0]->harq_processes[0]->nb_rb, - UE->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, - get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs), - 1,2, - UE->proc.proc_rxtx[0].frame_tx,subframe,0); + UE->dlsch_MCH[0]->harq_processes[0]->nb_rb, + UE->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, + get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs), + 1,2, + UE->proc.proc_rxtx[0].frame_tx,subframe,0); UE->dlsch_MCH[0]->harq_processes[0]->Qm = get_Qm(UE->dlsch_MCH[0]->harq_processes[0]->mcs); - dlsch_unscrambling(&UE->frame_parms,1,UE->dlsch_MCH[0], UE->dlsch_MCH[0]->harq_processes[0]->G, UE->pdsch_vars_MCH[0]->llr[0],0,subframe<<1); - ret = dlsch_decoding(UE, UE->pdsch_vars_MCH[0]->llr[0], &UE->frame_parms, @@ -497,7 +460,7 @@ int main(int argc, char **argv) 0,0,0); if (n_frames==1) - printf("MCH decoding returns %d\n",ret); + printf("MCH decoding returns %u\n",ret); if (ret == (1+UE->dlsch_MCH[0]->max_turbo_iterations)) errs[0]++; @@ -506,15 +469,15 @@ int main(int argc, char **argv) eNB->proc.proc_rxtx[0].frame_tx++; } - printf("errors %d/%d (Pe %e)\n",errs[round],trials,(double)errs[round]/trials); + printf("errors %u/%u (Pe %e)\n",errs[round],trials,(double)errs[round]/trials); if (awgn_flag==0) - fprintf(fd,"SNR_%d_%d = [SNR_%d_%d %f]; errs_mch_%d_%d =[errs_mch_%d_%d %d]; mch_trials_%d_%d =[mch_trials_%d_%d %d];\n", + fprintf(fd,"SNR_%d_%d = [SNR_%d_%d %f]; errs_mch_%d_%d =[errs_mch_%d_%d %u]; mch_trials_%d_%d =[mch_trials_%d_%d %u];\n", mcs,N_RB_DL,mcs,N_RB_DL,SNR, mcs,N_RB_DL,mcs,N_RB_DL,errs[0], mcs,N_RB_DL,mcs,N_RB_DL,trials); else - fprintf(fd,"SNR_awgn_%d = [SNR_awgn_%d %f]; errs_mch_awgn_%d =[errs_mch_awgn_%d %d]; mch_trials_awgn_%d =[mch_trials_awgn_%d %d];\n", + fprintf(fd,"SNR_awgn_%d = [SNR_awgn_%d %f]; errs_mch_awgn_%d =[errs_mch_awgn_%d %u]; mch_trials_awgn_%d =[mch_trials_awgn_%d %u];\n", N_RB_DL,N_RB_DL,SNR, N_RB_DL,N_RB_DL,errs[0], N_RB_DL,N_RB_DL,trials); @@ -525,7 +488,6 @@ int main(int argc, char **argv) break; } - if (n_frames==1) { printf("Dumping PMCH files ( G %d)\n",UE->dlsch_MCH[0]->harq_processes[0]->G); dump_mch(UE,0, @@ -536,9 +498,7 @@ int main(int argc, char **argv) printf("Freeing dlsch structures\n"); free_eNB_dlsch(eNB->dlsch_MCH); free_ue_dlsch(UE->dlsch_MCH[0]); - fclose(fd); - return(0); } diff --git a/openair1/SIMULATION/LTE_PHY/pbchsim.c b/openair1/SIMULATION/LTE_PHY/pbchsim.c index f44ed7b3a21665ec1bd40ba2b3e7fa11d30fbfef..00ad03c52dc8f0ffb038fe2b98328087bd6787e2 100644 --- a/openair1/SIMULATION/LTE_PHY/pbchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pbchsim.c @@ -37,7 +37,7 @@ #include "LAYER2/MAC/vars.h" #ifdef XFORMS -#include "PHY/TOOLS/lte_phy_scope.h" + #include "PHY/TOOLS/lte_phy_scope.h" #endif #include "OCG_vars.h" @@ -58,11 +58,8 @@ int32_t dummy2[2048*14]; int32_t dummy3[2048*14]; -int main(int argc, char **argv) -{ - +int main(int argc, char **argv) { char c; - int i,l,aa; double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1; uint8_t snr1set=0; @@ -81,127 +78,119 @@ int main(int argc, char **argv) int trial, n_trials, ntrials=1, n_errors,n_errors2,n_alamouti; uint8_t transmission_mode = 1,n_tx=1,n_rx=1; uint16_t Nid_cell=0; - int n_frames=1; channel_desc_t *eNB2UE,*eNB2UE1 = NULL,*eNB2UE2 = NULL; uint32_t nsymb,tx_lev,tx_lev1 = 0,tx_lev2 = 0; uint8_t extended_prefix_flag=0; int8_t interf1=-21,interf2=-21; LTE_DL_FRAME_PARMS *frame_parms; - FILE *input_fd=NULL,*pbch_file_fd=NULL; char input_val_str[50],input_val_str2[50]; // double input_val1,input_val2; // uint16_t amask=0; uint8_t frame_mod4,num_pdcch_symbols = 0; uint16_t NB_RB=25; - SCM_t channel_model=AWGN;//Rayleigh1_anticorr; - //DCI_ALLOC_t dci_alloc[8]; uint8_t abstraction_flag=0;//,calibration_flag=0; double pbch_sinr; int pbch_tx_ant; uint8_t N_RB_DL=25,osf=1; - unsigned char frame_type = 0; unsigned char pbch_phase = 0; - #ifdef XFORMS FD_lte_phy_scope_ue *form_ue; char title[255]; #endif - cpuf = get_cpu_freq_GHz(); - logInit(); number_of_cards = 1; while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:N:F:GR:O:dP:")) != -1) { switch (c) { - case 'f': - write_output_file=1; - output_fd = fopen(optarg,"w"); + case 'f': + write_output_file=1; + output_fd = fopen(optarg,"w"); - if (output_fd==NULL) { - printf("Error opening %s\n",optarg); - exit(-1); - } - - break; - - case 'd': - frame_type = 1; - break; + if (output_fd==NULL) { + printf("Error opening %s\n",optarg); + exit(-1); + } - case 'g': - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; break; - case 'B': - channel_model=SCM_B; + case 'd': + frame_type = 1; break; - case 'C': - channel_model=SCM_C; - break; + case 'g': + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; - case 'D': - channel_model=SCM_D; - break; + case 'B': + channel_model=SCM_B; + break; - case 'E': - channel_model=EPA; - break; + case 'C': + channel_model=SCM_C; + break; - case 'F': - channel_model=EVA; - break; + case 'D': + channel_model=SCM_D; + break; - case 'G': - channel_model=ETU; - break; + case 'E': + channel_model=EPA; + break; - default: - msg("Unsupported channel model!\n"); - exit(-1); - } + case 'F': + channel_model=EVA; + break; - break; + case 'G': + channel_model=ETU; + break; - case 'i': - interf1=atoi(optarg); - break; + default: + msg("Unsupported channel model!\n"); + exit(-1); + } - case 'j': - interf2=atoi(optarg); - break; + break; - case 'n': - n_frames = atoi(optarg); - break; + case 'i': + interf1=atoi(optarg); + break; - case 's': - snr0 = atof(optarg); - msg("Setting SNR0 to %f\n",snr0); - break; + case 'j': + interf2=atoi(optarg); + break; - case 'S': - snr1 = atof(optarg); - snr1set=1; - msg("Setting SNR1 to %f\n",snr1); - break; + case 'n': + n_frames = atoi(optarg); + break; + + case 's': + snr0 = atof(optarg); + msg("Setting SNR0 to %f\n",snr0); + break; + + case 'S': + snr1 = atof(optarg); + snr1set=1; + msg("Setting SNR1 to %f\n",snr1); + break; /* case 't': Td= atof(optarg); break; */ - case 'p': - extended_prefix_flag=1; - break; + case 'p': + extended_prefix_flag=1; + break; /* case 'r': @@ -212,111 +201,111 @@ int main(int argc, char **argv) } break; */ - case 'x': - transmission_mode=atoi(optarg); - - if ((transmission_mode!=1) && - (transmission_mode!=2) && - (transmission_mode!=6)) { - msg("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } + case 'x': + transmission_mode=atoi(optarg); + + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=6)) { + msg("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } - break; + break; - case 'y': - n_tx=atoi(optarg); + case 'y': + n_tx=atoi(optarg); - if ((n_tx==0) || (n_tx>2)) { - msg("Unsupported number of tx antennas %d\n",n_tx); - exit(-1); - } + if ((n_tx==0) || (n_tx>2)) { + msg("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); + } - break; + break; - case 'z': - n_rx=atoi(optarg); + case 'z': + n_rx=atoi(optarg); - if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); - exit(-1); - } - - break; + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } - case 'A': - abstraction_flag=1; - ntrials=10000; - msg("Running Abstraction test\n"); - pbch_file_fd=fopen(optarg,"r"); + break; - if (pbch_file_fd==NULL) { - printf("Problem with filename %s\n",optarg); - exit(-1); - } + case 'A': + abstraction_flag=1; + ntrials=10000; + msg("Running Abstraction test\n"); + pbch_file_fd=fopen(optarg,"r"); + + if (pbch_file_fd==NULL) { + printf("Problem with filename %s\n",optarg); + exit(-1); + } - break; + break; // case 'C': // calibration_flag=1; // msg("Running Abstraction calibration for Bias removal\n"); // break; - case 'N': - Nid_cell = atoi(optarg); - break; + case 'N': + Nid_cell = atoi(optarg); + break; - case 'R': - N_RB_DL = atoi(optarg); - break; + case 'R': + N_RB_DL = atoi(optarg); + break; - case 'O': - osf = atoi(optarg); - break; + case 'O': + osf = atoi(optarg); + break; - case 'F': - input_fd = fopen(optarg,"r"); + case 'F': + input_fd = fopen(optarg,"r"); - if (input_fd==NULL) { - printf("Problem with filename %s\n",optarg); - exit(-1); - } + if (input_fd==NULL) { + printf("Problem with filename %s\n",optarg); + exit(-1); + } - break; + break; - case 'P': - pbch_phase = atoi(optarg); + case 'P': + pbch_phase = atoi(optarg); - if (pbch_phase>3) - printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); + if (pbch_phase>3) + printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); - break; + break; - default: - case 'h': - printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", - argv[0]); - printf("-h This message\n"); - printf("-p Use extended prefix mode\n"); - printf("-d Use TDD\n"); - printf("-n Number of frames to simulate\n"); - printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); - printf("-S Ending SNR, runs from SNR0 to SNR1\n"); - printf("-t Delay spread for multipath channel\n"); - printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); - printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); - printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); - printf("-N Nid_cell\n"); - printf("-R N_RB_DL\n"); - printf("-O oversampling factor (1,2,4,8,16)\n"); - printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); - // printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); - printf("-f Output filename (.txt format) for Pe/SNR results\n"); - printf("-F Input filename (.txt format) for RX conformance testing\n"); - exit (-1); - break; + default: + case 'h': + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", + argv[0]); + printf("-h This message\n"); + printf("-p Use extended prefix mode\n"); + printf("-d Use TDD\n"); + printf("-n Number of frames to simulate\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-t Delay spread for multipath channel\n"); + printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-N Nid_cell\n"); + printf("-R N_RB_DL\n"); + printf("-O oversampling factor (1,2,4,8,16)\n"); + printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); + // printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n"); + printf("-f Output filename (.txt format) for Pe/SNR results\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + exit (-1); + break; } } @@ -324,7 +313,6 @@ int main(int argc, char **argv) n_tx=2; lte_param_init(n_tx, n_tx,n_rx,transmission_mode,extended_prefix_flag,frame_type,Nid_cell,3,N_RB_DL,0,osf,0); - eNB1 = malloc(sizeof(PHY_VARS_eNB)); eNB2 = malloc(sizeof(PHY_VARS_eNB)); UE->measurements.n_adj_cells=2; @@ -334,19 +322,16 @@ int main(int argc, char **argv) for (i=0; i<3; i++) lte_gold(&eNB->frame_parms,UE->lte_gold_table[i],Nid_cell+i); - memcpy((void*)&eNB1->frame_parms,(void*)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + memcpy((void *)&eNB1->frame_parms,(void *)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); eNB1->frame_parms.Nid_cell=Nid_cell+1; eNB1->frame_parms.nushift=(Nid_cell+1)%6; eNB1->Mod_id=1; - - memcpy((void*)&eNB2->frame_parms,(void*)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + memcpy((void *)&eNB2->frame_parms,(void *)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); eNB2->frame_parms.Nid_cell=Nid_cell+2; eNB2->frame_parms.nushift=(Nid_cell+2)%6; eNB2->Mod_id=2; - phy_init_lte_eNB(eNB1,0,0); phy_init_lte_eNB(eNB2,0,0); - #ifdef XFORMS fl_initialize (&argc, argv, NULL, 0, 0); form_ue = create_lte_phy_scope_ue(); @@ -362,38 +347,27 @@ int main(int argc, char **argv) } printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - frame_parms = &eNB->frame_parms; - - - txdata = eNB->common_vars.txdata[0]; txdata1 = eNB1->common_vars.txdata[0]; txdata2 = eNB2->common_vars.txdata[0]; - - - s_re = malloc(2*sizeof(double*)); - s_im = malloc(2*sizeof(double*)); - s_re1 = malloc(2*sizeof(double*)); - s_im1 = malloc(2*sizeof(double*)); - s_re2 = malloc(2*sizeof(double*)); - s_im2 = malloc(2*sizeof(double*)); - r_re = malloc(2*sizeof(double*)); - r_im = malloc(2*sizeof(double*)); - r_re1 = malloc(2*sizeof(double*)); - r_im1 = malloc(2*sizeof(double*)); - r_re2 = malloc(2*sizeof(double*)); - r_im2 = malloc(2*sizeof(double*)); - + s_re = malloc(2*sizeof(double *)); + s_im = malloc(2*sizeof(double *)); + s_re1 = malloc(2*sizeof(double *)); + s_im1 = malloc(2*sizeof(double *)); + s_re2 = malloc(2*sizeof(double *)); + s_im2 = malloc(2*sizeof(double *)); + r_re = malloc(2*sizeof(double *)); + r_im = malloc(2*sizeof(double *)); + r_re1 = malloc(2*sizeof(double *)); + r_im1 = malloc(2*sizeof(double *)); + r_re2 = malloc(2*sizeof(double *)); + r_im2 = malloc(2*sizeof(double *)); nsymb = (frame_parms->Ncp == 0) ? 14 : 12; - printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d, interf (%d,%d)\n",NUMBER_OF_OFDM_CARRIERS, frame_parms->Ncp,frame_parms->samples_per_tti,nsymb,interf1,interf2); - printf("eNB1->common_vars.txdataF[0][0] = %p\n", eNB1->common_vars.txdataF[0][0]); - - DLSCH_alloc_pdu2.rah = 0; DLSCH_alloc_pdu2.rballoc = DLSCH_RB_ALLOC; DLSCH_alloc_pdu2.TPC = 0; @@ -405,12 +379,11 @@ int main(int argc, char **argv) DLSCH_alloc_pdu2.rv1 = 0; // Forget second codeword DLSCH_alloc_pdu2.tpmi = (transmission_mode==6 ? 5 : 0) ; // precoding - eNB2UE = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), 0, 0, 0); @@ -419,8 +392,8 @@ int main(int argc, char **argv) eNB2UE1 = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), 0, 4, 0); @@ -429,20 +402,18 @@ int main(int argc, char **argv) eNB2UE2 = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), 0, 8, 0); - if (eNB2UE==NULL) { msg("Problem generating channel model. Exiting.\n"); exit(-1); } for (i=0; i<2; i++) { - s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(s_re[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); @@ -455,7 +426,6 @@ int main(int argc, char **argv) bzero(s_re2[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); s_im2[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(s_im2[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); - r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(r_re[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); @@ -487,7 +457,6 @@ int main(int argc, char **argv) } if (input_fd==NULL) { - // for (i=0;i<6;i++) // pbch_pdu[i] = i; pbch_pdu[0]=100; @@ -515,7 +484,6 @@ int main(int argc, char **argv) &eNB->frame_parms, (eNB->frame_parms.Ncp==0) ? 5 : 4, 10); - } else { generate_sss(eNB->common_vars.txdataF[0], AMP, @@ -537,8 +505,6 @@ int main(int argc, char **argv) &eNB->frame_parms, 2, 12); - - } /* @@ -552,16 +518,12 @@ int main(int argc, char **argv) dci_alloc[1].L = 3; dci_alloc[1].rnti = 0x1234; */ - printf("Generating PBCH for mode1_flag = %d\n", eNB->frame_parms.mode1_flag); - - generate_pilots(eNB, eNB->common_vars.txdataF[0], AMP, LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - /* num_pdcch_symbols = generate_dci_top(1, dci_alloc, @@ -572,7 +534,6 @@ int main(int argc, char **argv) 0); */ - if (num_pdcch_symbols<3) { printf("Less than 3 pdcch symbols\n"); // exit(-1); @@ -584,7 +545,7 @@ int main(int argc, char **argv) dummybuf[2] = dummy2; dummybuf[3] = dummy3; generate_pbch(&eNB->pbch, - (int32_t**)dummybuf, + (int32_t **)dummybuf, AMP, &eNB->frame_parms, pbch_pdu, @@ -618,15 +579,12 @@ int main(int argc, char **argv) eNB1->common_vars.txdataF[0], AMP, LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - - generate_pbch(&eNB1->pbch, eNB1->common_vars.txdataF[0], AMP, &eNB1->frame_parms, pbch_pdu, 0); - } if (interf2>-20) { @@ -638,27 +596,19 @@ int main(int argc, char **argv) 0); */ - - - generate_pilots(eNB2, eNB2->common_vars.txdataF[0], AMP, LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - - generate_pbch(&eNB2->pbch, eNB2->common_vars.txdataF[0], AMP, &eNB2->frame_parms, pbch_pdu, 0); - } - // LOG_M("pilotsF.m","rsF",txdataF[0],frame_parms->ofdm_symbol_size,1,1); - LOG_M("txsigF0.m","txsF0", eNB->common_vars.txdataF[0][0],FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX,1,1); if (eNB->frame_parms.nb_antennas_tx>1) @@ -668,9 +618,6 @@ int main(int argc, char **argv) tx_lev1 = 0; tx_lev2 = 0; - - - for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { if (frame_parms->Ncp == 1) PHY_ofdm_mod(eNB->common_vars.txdataF[0][aa], // input, @@ -743,7 +690,6 @@ int main(int argc, char **argv) } // tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - LOG_M("txsig0.m","txs0", txdata[0],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); if (frame_parms->nb_antennas_tx>1) @@ -762,17 +708,17 @@ int main(int argc, char **argv) i=0; while (!feof(input_fd)) { - if (fscanf(input_fd,"%s %s",input_val_str,input_val_str2) != 2) { //&input_val1,&input_val2); + if (fscanf(input_fd,"%49s %49s",input_val_str,input_val_str2) != 2) { //&input_val1,&input_val2); printf("%s:%d:%s: error with fscanf, exiting\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } if ((i%4)==0) { - ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); - ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); + ((short *)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); + ((short *)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); if ((i/4)<100) - printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); + printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short *)txdata[0])[i/4],((short *)txdata[0])[(i/4)+1]); //1,input_val2,); } i++; @@ -789,7 +735,6 @@ int main(int argc, char **argv) // tx_lev_dB = (unsigned int) dB_fixed(tx_lev); } - // multipath channel for (i=0; i<2*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { @@ -809,10 +754,7 @@ int main(int argc, char **argv) } } - for (SNR=snr0; SNR<snr1; SNR+=.2) { - - n_errors = 0; n_errors2 = 0; n_alamouti = 0; @@ -824,8 +766,6 @@ int main(int argc, char **argv) printf("*********************** trial %d ***************************\n",trial); while (pbch_sinr>-2.0) { - - multipath_channel(eNB2UE,s_re,s_im,r_re,r_im, 2*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES,0); @@ -882,8 +822,8 @@ int main(int argc, char **argv) r_im[aa][i] += (pow(10.0,.05*interf1)*r_im1[aa][i] + pow(10.0,.05*interf2)*r_im2[aa][i]); } - ((short*) UE->common_vars.rxdata[aa])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) UE->common_vars.rxdata[aa])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) UE->common_vars.rxdata[aa])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) UE->common_vars.rxdata[aa])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } @@ -892,7 +832,6 @@ int main(int argc, char **argv) 10*log10(signal_energy(&UE->common_vars.rxdata[0][frame_parms->samples_per_tti/2],4*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES))); } - /* // optional: read rx_frame from file if ((rx_frame_file = fopen("rx_frame.dat","r")) == NULL) @@ -911,19 +850,15 @@ int main(int argc, char **argv) fclose(rx_frame_file); */ - for (l=0; l<eNB->frame_parms.symbols_per_tti; l++) { - // subframe_offset = (l/eNB->frame_parms.symbols_per_tti)*eNB->frame_parms.samples_per_tti; // printf("subframe_offset = %d\n",subframe_offset); - slot_fep(UE, l%(eNB->frame_parms.symbols_per_tti/2), l/(eNB->frame_parms.symbols_per_tti/2), 0, 0, - 0); - + 0); if (l==0) { lte_ue_measurements(UE, @@ -961,16 +896,14 @@ int main(int argc, char **argv) //sprintf(fname,"dl_ch00_%d.m",l); //sprintf(vname,"dl_ch00_%d",l); //LOG_M(fname,vname,&(common_vars->dl_ch_estimates[0][frame_parms->ofdm_symbol_size*(l%6)]),frame_parms->ofdm_symbol_size,1,1); - lte_est_freq_offset(UE->common_vars.common_vars_rx_data_per_thread[/*subframe*/0&0x1].dl_ch_estimates[0], &UE->frame_parms, l, &freq_offset, - 1); + 1); } if (l==((eNB->frame_parms.Ncp==0)?10:9)) { - for (frame_mod4=0; frame_mod4<4; frame_mod4++) { pbch_tx_ant = rx_pbch(&UE->common_vars, UE->pbch_vars[0], @@ -1003,7 +936,6 @@ int main(int argc, char **argv) } } - if ((pbch_tx_ant>0) && (pbch_tx_ant<4)) { if (n_frames==1) msg("pbch decoded sucessfully mode1_flag %d, frame_mod4 %d, tx_ant %d!\n", @@ -1023,7 +955,6 @@ int main(int argc, char **argv) UE, 0,0,1); #endif - } //noise trials if (abstraction_flag==1) { @@ -1049,7 +980,6 @@ int main(int argc, char **argv) } // NSR if (n_frames==1) { - LOG_M("H00.m","h00",&(UE->common_vars.common_vars_rx_data_per_thread[/*subframe*/0&0x1].dl_ch_estimates[0][0][0]),((frame_parms->Ncp==0)?7:6)*(eNB->frame_parms.ofdm_symbol_size),1,1); if (n_tx==2) @@ -1062,7 +992,6 @@ int main(int argc, char **argv) LOG_M("PBCH_rxF_llr.m","pbch_llr",UE->pbch_vars[0]->llr,(frame_parms->Ncp==0) ? 1920 : 1728,1,4); } - for (i=0; i<2; i++) { free(s_re[i]); free(s_im[i]); @@ -1074,15 +1003,15 @@ int main(int argc, char **argv) free(s_im); free(r_re); free(r_im); - - lte_sync_time_free(); if (write_output_file) fclose(output_fd); - return(n_errors); + if (input_fd != NULL) + fclose(input_fd); + return(n_errors); } diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c index 569d2226deb1e7953da67a8d39c7c9690e1bb39e..004eb24243bff7b6ab4272568e2281737f4e3364 100644 --- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c @@ -34,7 +34,7 @@ #include "OCG_vars.h" #ifdef XFORMS -#include "PHY/TOOLS/lte_phy_scope.h" + #include "PHY/TOOLS/lte_phy_scope.h" #endif #include "unitary_defs.h" @@ -51,303 +51,284 @@ double cpuf; DCI_PDU DCI_pdu; -DCI_PDU *get_dci(LTE_DL_FRAME_PARMS *lte_frame_parms,uint8_t log2L, uint8_t log2Lcommon, DCI_format_t format_selector[MAX_NUM_DCI], uint8_t num_dci, uint32_t rnti) -{ +DCI_PDU *get_dci(LTE_DL_FRAME_PARMS *lte_frame_parms,uint8_t log2L, uint8_t log2Lcommon, DCI_format_t format_selector[MAX_NUM_DCI], uint8_t num_dci, uint32_t rnti) { uint32_t BCCH_alloc_pdu[2]; uint32_t DLSCH_alloc_pdu[2]; uint32_t UL_alloc_pdu[2]; - int ind; int dci_length_bytes=0,dci_length=0; int BCCH_pdu_size_bits=0, BCCH_pdu_size_bytes=0; int UL_pdu_size_bits=0, UL_pdu_size_bytes=0; int mcs = 3; - DCI_pdu.Num_dci = 0; if (lte_frame_parms->frame_type == TDD) { switch (lte_frame_parms->N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t); - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->dai = 0; - - ((DCI1A_1_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 0, 4); - ((DCI1A_1_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->ndi = 1; - ((DCI1A_1_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->rv = 0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->mcs = 2; - ((DCI1A_1_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->TPC = 1; - BCCH_pdu_size_bits = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - BCCH_pdu_size_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - - ((DCI0_1_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->type = 0; - ((DCI0_1_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->hopping = 0; - ((DCI0_1_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI0_1_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->mcs = mcs; - ((DCI0_1_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->ndi = 1; - ((DCI0_1_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->TPC = 2; - ((DCI0_1_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->cshift = 3; - ((DCI0_1_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->dai = 1; - ((DCI0_1_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->cqi_req = 1; - UL_pdu_size_bits = sizeof_DCI0_1_5MHz_TDD_1_6_t; - UL_pdu_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t); - break; + case 6: + dci_length = sizeof_DCI1_1_5MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t); + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; + ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->dai = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->type = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->vrb_type = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 0, 4); + ((DCI1A_1_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->ndi = 1; + ((DCI1A_1_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->rv = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->mcs = 2; + ((DCI1A_1_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1A_1_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->TPC = 1; + BCCH_pdu_size_bits = sizeof_DCI1A_1_5MHz_TDD_1_6_t; + BCCH_pdu_size_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); + ((DCI0_1_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->type = 0; + ((DCI0_1_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->hopping = 0; + ((DCI0_1_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI0_1_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->mcs = mcs; + ((DCI0_1_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->ndi = 1; + ((DCI0_1_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->TPC = 2; + ((DCI0_1_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->cshift = 3; + ((DCI0_1_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->dai = 1; + ((DCI0_1_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->cqi_req = 1; + UL_pdu_size_bits = sizeof_DCI0_1_5MHz_TDD_1_6_t; + UL_pdu_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t); + break; - case 25: - dci_length = sizeof_DCI1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_TDD_t); - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->dai = 0; - - ((DCI1A_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 18, 4); - ((DCI1A_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->ndi = 1; - ((DCI1A_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->rv = 0; - ((DCI1A_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->mcs = 2; - ((DCI1A_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->TPC = 1; - BCCH_pdu_size_bits = sizeof_DCI1A_5MHz_TDD_1_6_t; - BCCH_pdu_size_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - - ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->type = 0; - ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->hopping = 0; - ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->mcs = mcs; - ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->ndi = 1; - ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->TPC = 2; - ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->cshift = 3; - ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->dai = 1; - ((DCI0_5MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->cqi_req = 1; - UL_pdu_size_bits = sizeof_DCI0_5MHz_TDD_1_6_t; - UL_pdu_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t); - break; + case 25: + dci_length = sizeof_DCI1_5MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_5MHz_TDD_t); + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; + ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu[0])->dai = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->type = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->vrb_type = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 18, 4); + ((DCI1A_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->ndi = 1; + ((DCI1A_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->rv = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->mcs = 2; + ((DCI1A_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1A_5MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->TPC = 1; + BCCH_pdu_size_bits = sizeof_DCI1A_5MHz_TDD_1_6_t; + BCCH_pdu_size_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); + ((DCI0_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->type = 0; + ((DCI0_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->hopping = 0; + ((DCI0_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI0_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->mcs = mcs; + ((DCI0_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->ndi = 1; + ((DCI0_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->TPC = 2; + ((DCI0_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->cshift = 3; + ((DCI0_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->dai = 1; + ((DCI0_5MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->cqi_req = 1; + UL_pdu_size_bits = sizeof_DCI0_5MHz_TDD_1_6_t; + UL_pdu_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t); + break; - case 50: - dci_length = sizeof_DCI1_10MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_TDD_t); - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->dai = 0; - - ((DCI1A_10MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->vrb_type = 0; - ((DCI1A_10MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 30, 4); - ((DCI1A_10MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->ndi = 1; - ((DCI1A_10MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->rv = 0; - ((DCI1A_10MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->mcs = 2; - ((DCI1A_10MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->TPC = 1; - BCCH_pdu_size_bits = sizeof_DCI1A_10MHz_TDD_1_6_t; - BCCH_pdu_size_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - - ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->type = 0; - ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->hopping = 0; - ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->mcs = mcs; - ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->ndi = 1; - ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->TPC = 2; - ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->cshift = 3; - ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->dai = 1; - ((DCI0_10MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->cqi_req = 1; - UL_pdu_size_bits = sizeof_DCI0_10MHz_TDD_1_6_t; - UL_pdu_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t); - break; + case 50: + dci_length = sizeof_DCI1_10MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_10MHz_TDD_t); + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; + ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu[0])->dai = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->type = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->vrb_type = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 30, 4); + ((DCI1A_10MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->ndi = 1; + ((DCI1A_10MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->rv = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->mcs = 2; + ((DCI1A_10MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1A_10MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->TPC = 1; + BCCH_pdu_size_bits = sizeof_DCI1A_10MHz_TDD_1_6_t; + BCCH_pdu_size_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); + ((DCI0_10MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->type = 0; + ((DCI0_10MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->hopping = 0; + ((DCI0_10MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI0_10MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->mcs = mcs; + ((DCI0_10MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->ndi = 1; + ((DCI0_10MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->TPC = 2; + ((DCI0_10MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->cshift = 3; + ((DCI0_10MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->dai = 1; + ((DCI0_10MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->cqi_req = 1; + UL_pdu_size_bits = sizeof_DCI0_10MHz_TDD_1_6_t; + UL_pdu_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t); + break; - case 100: - dci_length = sizeof_DCI1_20MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_TDD_t); - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->dai = 0; - - ((DCI1A_20MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->vrb_type = 0; - ((DCI1A_20MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 70, 4); - ((DCI1A_20MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->ndi = 1; - ((DCI1A_20MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->rv = 0; - ((DCI1A_20MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->mcs = 2; - ((DCI1A_20MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t*)&BCCH_alloc_pdu[0])->TPC = 1; - BCCH_pdu_size_bits = sizeof_DCI1A_20MHz_TDD_1_6_t; - BCCH_pdu_size_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - - ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->type = 0; - ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->hopping = 0; - ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->mcs = mcs; - ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->ndi = 1; - ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->TPC = 2; - ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->cshift = 3; - ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->dai = 1; - ((DCI0_20MHz_TDD_1_6_t*)&UL_alloc_pdu[0])->cqi_req = 1; - UL_pdu_size_bits = sizeof_DCI0_20MHz_TDD_1_6_t; - UL_pdu_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t); - break; + case 100: + dci_length = sizeof_DCI1_20MHz_TDD_t; + dci_length_bytes = sizeof(DCI1_20MHz_TDD_t); + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; + ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu[0])->dai = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->type = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->vrb_type = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 70, 4); + ((DCI1A_20MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->ndi = 1; + ((DCI1A_20MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->rv = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->mcs = 2; + ((DCI1A_20MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1A_20MHz_TDD_1_6_t *)&BCCH_alloc_pdu[0])->TPC = 1; + BCCH_pdu_size_bits = sizeof_DCI1A_20MHz_TDD_1_6_t; + BCCH_pdu_size_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); + ((DCI0_20MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->type = 0; + ((DCI0_20MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->hopping = 0; + ((DCI0_20MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI0_20MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->mcs = mcs; + ((DCI0_20MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->ndi = 1; + ((DCI0_20MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->TPC = 2; + ((DCI0_20MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->cshift = 3; + ((DCI0_20MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->dai = 1; + ((DCI0_20MHz_TDD_1_6_t *)&UL_alloc_pdu[0])->cqi_req = 1; + UL_pdu_size_bits = sizeof_DCI0_20MHz_TDD_1_6_t; + UL_pdu_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t); + break; } } else { //FDD switch (lte_frame_parms->N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t); - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; - - ((DCI1A_1_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->type = 1; - ((DCI1A_1_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->vrb_type = 0; - ((DCI1A_1_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 0, 4); - ((DCI1A_1_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->ndi = 1; - ((DCI1A_1_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->rv = 0; - ((DCI1A_1_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->mcs = 2; - ((DCI1A_1_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->TPC = 1; - BCCH_pdu_size_bits = sizeof_DCI1A_1_5MHz_FDD_t; - BCCH_pdu_size_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - - ((DCI0_1_5MHz_FDD_t*)&UL_alloc_pdu[0])->type = 0; - ((DCI0_1_5MHz_FDD_t*)&UL_alloc_pdu[0])->hopping = 0; - ((DCI0_1_5MHz_FDD_t*)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI0_1_5MHz_FDD_t*)&UL_alloc_pdu[0])->mcs = mcs; - ((DCI0_1_5MHz_FDD_t*)&UL_alloc_pdu[0])->ndi = 1; - ((DCI0_1_5MHz_FDD_t*)&UL_alloc_pdu[0])->TPC = 2; - ((DCI0_1_5MHz_FDD_t*)&UL_alloc_pdu[0])->cshift = 3; - ((DCI0_1_5MHz_FDD_t*)&UL_alloc_pdu[0])->cqi_req = 1; - UL_pdu_size_bits = sizeof_DCI0_1_5MHz_FDD_t; - UL_pdu_size_bytes = sizeof(DCI0_1_5MHz_FDD_t); - break; + case 6: + dci_length = sizeof_DCI1_1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t); + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; + ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; + ((DCI1A_1_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->type = 1; + ((DCI1A_1_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->vrb_type = 0; + ((DCI1A_1_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 0, 4); + ((DCI1A_1_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->ndi = 1; + ((DCI1A_1_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->rv = 0; + ((DCI1A_1_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->mcs = 2; + ((DCI1A_1_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1A_1_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->TPC = 1; + BCCH_pdu_size_bits = sizeof_DCI1A_1_5MHz_FDD_t; + BCCH_pdu_size_bytes = sizeof(DCI1A_1_5MHz_FDD_t); + ((DCI0_1_5MHz_FDD_t *)&UL_alloc_pdu[0])->type = 0; + ((DCI0_1_5MHz_FDD_t *)&UL_alloc_pdu[0])->hopping = 0; + ((DCI0_1_5MHz_FDD_t *)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI0_1_5MHz_FDD_t *)&UL_alloc_pdu[0])->mcs = mcs; + ((DCI0_1_5MHz_FDD_t *)&UL_alloc_pdu[0])->ndi = 1; + ((DCI0_1_5MHz_FDD_t *)&UL_alloc_pdu[0])->TPC = 2; + ((DCI0_1_5MHz_FDD_t *)&UL_alloc_pdu[0])->cshift = 3; + ((DCI0_1_5MHz_FDD_t *)&UL_alloc_pdu[0])->cqi_req = 1; + UL_pdu_size_bits = sizeof_DCI0_1_5MHz_FDD_t; + UL_pdu_size_bytes = sizeof(DCI0_1_5MHz_FDD_t); + break; - case 25: - dci_length = sizeof_DCI1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_FDD_t); - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; - - ((DCI1A_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->type = 1; - ((DCI1A_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->vrb_type = 0; - ((DCI1A_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 18, 4); - ((DCI1A_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->ndi = 1; - ((DCI1A_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->rv = 0; - ((DCI1A_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->mcs = 2; - ((DCI1A_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t*)&BCCH_alloc_pdu[0])->TPC = 1; - BCCH_pdu_size_bits = sizeof_DCI1A_5MHz_FDD_t; - BCCH_pdu_size_bytes = sizeof(DCI1A_5MHz_FDD_t); - - ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu[0])->type = 0; - ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu[0])->hopping = 0; - ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu[0])->mcs = mcs; - ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu[0])->ndi = 1; - ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu[0])->TPC = 2; - ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu[0])->cshift = 3; - ((DCI0_5MHz_FDD_t*)&UL_alloc_pdu[0])->cqi_req = 1; - UL_pdu_size_bits = sizeof_DCI0_5MHz_FDD_t; - UL_pdu_size_bytes = sizeof(DCI0_5MHz_FDD_t); - break; + case 25: + dci_length = sizeof_DCI1_5MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_5MHz_FDD_t); + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; + ((DCI1A_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->type = 1; + ((DCI1A_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->vrb_type = 0; + ((DCI1A_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 18, 4); + ((DCI1A_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->ndi = 1; + ((DCI1A_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->rv = 0; + ((DCI1A_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->mcs = 2; + ((DCI1A_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1A_5MHz_FDD_t *)&BCCH_alloc_pdu[0])->TPC = 1; + BCCH_pdu_size_bits = sizeof_DCI1A_5MHz_FDD_t; + BCCH_pdu_size_bytes = sizeof(DCI1A_5MHz_FDD_t); + ((DCI0_5MHz_FDD_t *)&UL_alloc_pdu[0])->type = 0; + ((DCI0_5MHz_FDD_t *)&UL_alloc_pdu[0])->hopping = 0; + ((DCI0_5MHz_FDD_t *)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI0_5MHz_FDD_t *)&UL_alloc_pdu[0])->mcs = mcs; + ((DCI0_5MHz_FDD_t *)&UL_alloc_pdu[0])->ndi = 1; + ((DCI0_5MHz_FDD_t *)&UL_alloc_pdu[0])->TPC = 2; + ((DCI0_5MHz_FDD_t *)&UL_alloc_pdu[0])->cshift = 3; + ((DCI0_5MHz_FDD_t *)&UL_alloc_pdu[0])->cqi_req = 1; + UL_pdu_size_bits = sizeof_DCI0_5MHz_FDD_t; + UL_pdu_size_bytes = sizeof(DCI0_5MHz_FDD_t); + break; - case 50: - dci_length = sizeof_DCI1_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_FDD_t); - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; - - ((DCI1A_10MHz_FDD_t*)&BCCH_alloc_pdu[0])->type = 1; - ((DCI1A_10MHz_FDD_t*)&BCCH_alloc_pdu[0])->vrb_type = 0; - ((DCI1A_10MHz_FDD_t*)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 30, 4); - ((DCI1A_10MHz_FDD_t*)&BCCH_alloc_pdu[0])->ndi = 1; - ((DCI1A_10MHz_FDD_t*)&BCCH_alloc_pdu[0])->rv = 0; - ((DCI1A_10MHz_FDD_t*)&BCCH_alloc_pdu[0])->mcs = 2; - ((DCI1A_10MHz_FDD_t*)&BCCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t*)&BCCH_alloc_pdu[0])->TPC = 1; - BCCH_pdu_size_bits = sizeof_DCI1A_10MHz_FDD_t; - BCCH_pdu_size_bytes = sizeof(DCI1A_10MHz_FDD_t); - - ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu[0])->type = 0; - ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu[0])->hopping = 0; - ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu[0])->mcs = mcs; - ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu[0])->ndi = 1; - ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu[0])->TPC = 2; - ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu[0])->cshift = 3; - ((DCI0_10MHz_FDD_t*)&UL_alloc_pdu[0])->cqi_req = 1; - UL_pdu_size_bits = sizeof_DCI0_10MHz_FDD_t; - UL_pdu_size_bytes = sizeof(DCI0_10MHz_FDD_t); - break; + case 50: + dci_length = sizeof_DCI1_10MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_10MHz_FDD_t); + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; + ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; + ((DCI1A_10MHz_FDD_t *)&BCCH_alloc_pdu[0])->type = 1; + ((DCI1A_10MHz_FDD_t *)&BCCH_alloc_pdu[0])->vrb_type = 0; + ((DCI1A_10MHz_FDD_t *)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 30, 4); + ((DCI1A_10MHz_FDD_t *)&BCCH_alloc_pdu[0])->ndi = 1; + ((DCI1A_10MHz_FDD_t *)&BCCH_alloc_pdu[0])->rv = 0; + ((DCI1A_10MHz_FDD_t *)&BCCH_alloc_pdu[0])->mcs = 2; + ((DCI1A_10MHz_FDD_t *)&BCCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1A_10MHz_FDD_t *)&BCCH_alloc_pdu[0])->TPC = 1; + BCCH_pdu_size_bits = sizeof_DCI1A_10MHz_FDD_t; + BCCH_pdu_size_bytes = sizeof(DCI1A_10MHz_FDD_t); + ((DCI0_10MHz_FDD_t *)&UL_alloc_pdu[0])->type = 0; + ((DCI0_10MHz_FDD_t *)&UL_alloc_pdu[0])->hopping = 0; + ((DCI0_10MHz_FDD_t *)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI0_10MHz_FDD_t *)&UL_alloc_pdu[0])->mcs = mcs; + ((DCI0_10MHz_FDD_t *)&UL_alloc_pdu[0])->ndi = 1; + ((DCI0_10MHz_FDD_t *)&UL_alloc_pdu[0])->TPC = 2; + ((DCI0_10MHz_FDD_t *)&UL_alloc_pdu[0])->cshift = 3; + ((DCI0_10MHz_FDD_t *)&UL_alloc_pdu[0])->cqi_req = 1; + UL_pdu_size_bits = sizeof_DCI0_10MHz_FDD_t; + UL_pdu_size_bytes = sizeof(DCI0_10MHz_FDD_t); + break; - case 100: - dci_length = sizeof_DCI1_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_FDD_t); - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; - - ((DCI1A_20MHz_FDD_t*)&BCCH_alloc_pdu[0])->type = 1; - ((DCI1A_20MHz_FDD_t*)&BCCH_alloc_pdu[0])->vrb_type = 0; - ((DCI1A_20MHz_FDD_t*)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 70, 4); - ((DCI1A_20MHz_FDD_t*)&BCCH_alloc_pdu[0])->ndi = 1; - ((DCI1A_20MHz_FDD_t*)&BCCH_alloc_pdu[0])->rv = 0; - ((DCI1A_20MHz_FDD_t*)&BCCH_alloc_pdu[0])->mcs = 2; - ((DCI1A_20MHz_FDD_t*)&BCCH_alloc_pdu[0])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t*)&BCCH_alloc_pdu[0])->TPC = 1; - BCCH_pdu_size_bits = sizeof_DCI1A_20MHz_FDD_t; - BCCH_pdu_size_bytes = sizeof(DCI1A_20MHz_FDD_t); - - ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu[0])->type = 0; - ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu[0])->hopping = 0; - ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; - ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu[0])->mcs = mcs; - ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu[0])->ndi = 1; - ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu[0])->TPC = 2; - ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu[0])->cshift = 3; - ((DCI0_20MHz_FDD_t*)&UL_alloc_pdu[0])->cqi_req = 1; - UL_pdu_size_bits = sizeof_DCI0_20MHz_FDD_t; - UL_pdu_size_bytes = sizeof(DCI0_20MHz_FDD_t); - break; + case 100: + dci_length = sizeof_DCI1_20MHz_FDD_t; + dci_length_bytes = sizeof(DCI1_20MHz_FDD_t); + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rah = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->mcs = mcs; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->ndi = 1; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->rv = 0; + ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu[0])->TPC = 0; + ((DCI1A_20MHz_FDD_t *)&BCCH_alloc_pdu[0])->type = 1; + ((DCI1A_20MHz_FDD_t *)&BCCH_alloc_pdu[0])->vrb_type = 0; + ((DCI1A_20MHz_FDD_t *)&BCCH_alloc_pdu[0])->rballoc = computeRIV(lte_frame_parms->N_RB_DL, 70, 4); + ((DCI1A_20MHz_FDD_t *)&BCCH_alloc_pdu[0])->ndi = 1; + ((DCI1A_20MHz_FDD_t *)&BCCH_alloc_pdu[0])->rv = 0; + ((DCI1A_20MHz_FDD_t *)&BCCH_alloc_pdu[0])->mcs = 2; + ((DCI1A_20MHz_FDD_t *)&BCCH_alloc_pdu[0])->harq_pid = 0; + ((DCI1A_20MHz_FDD_t *)&BCCH_alloc_pdu[0])->TPC = 1; + BCCH_pdu_size_bits = sizeof_DCI1A_20MHz_FDD_t; + BCCH_pdu_size_bytes = sizeof(DCI1A_20MHz_FDD_t); + ((DCI0_20MHz_FDD_t *)&UL_alloc_pdu[0])->type = 0; + ((DCI0_20MHz_FDD_t *)&UL_alloc_pdu[0])->hopping = 0; + ((DCI0_20MHz_FDD_t *)&UL_alloc_pdu[0])->rballoc = DLSCH_RB_ALLOC; + ((DCI0_20MHz_FDD_t *)&UL_alloc_pdu[0])->mcs = mcs; + ((DCI0_20MHz_FDD_t *)&UL_alloc_pdu[0])->ndi = 1; + ((DCI0_20MHz_FDD_t *)&UL_alloc_pdu[0])->TPC = 2; + ((DCI0_20MHz_FDD_t *)&UL_alloc_pdu[0])->cshift = 3; + ((DCI0_20MHz_FDD_t *)&UL_alloc_pdu[0])->cqi_req = 1; + UL_pdu_size_bits = sizeof_DCI0_20MHz_FDD_t; + UL_pdu_size_bytes = sizeof(DCI0_20MHz_FDD_t); + break; } } @@ -360,11 +341,10 @@ DCI_PDU *get_dci(LTE_DL_FRAME_PARMS *lte_frame_parms,uint8_t log2L, uint8_t log2 DCI_pdu.dci_alloc[ind].format = format1A; DCI_pdu.dci_alloc[ind].ra_flag = 0; DCI_pdu.dci_alloc[ind].search_space = DCI_COMMON_SPACE; - memcpy((void*)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &BCCH_alloc_pdu[0], BCCH_pdu_size_bytes); + memcpy((void *)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &BCCH_alloc_pdu[0], BCCH_pdu_size_bytes); DCI_pdu.Num_dci++; printf("Added common dci (%d) for rnti %x\n",ind,SI_RNTI); } - if (format_selector[ind]==format1) { DCI_pdu.dci_alloc[ind].dci_length = dci_length; @@ -373,10 +353,10 @@ DCI_PDU *get_dci(LTE_DL_FRAME_PARMS *lte_frame_parms,uint8_t log2L, uint8_t log2 DCI_pdu.dci_alloc[ind].format = format1; DCI_pdu.dci_alloc[ind].ra_flag = 0; DCI_pdu.dci_alloc[ind].search_space = DCI_UE_SPACE; - memcpy((void*)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &DLSCH_alloc_pdu[0], dci_length_bytes); + memcpy((void *)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &DLSCH_alloc_pdu[0], dci_length_bytes); DCI_pdu.Num_dci++; } - + if (format_selector[ind]==format0) { DCI_pdu.dci_alloc[ind].dci_length = UL_pdu_size_bits; DCI_pdu.dci_alloc[ind].L = log2L; @@ -384,24 +364,20 @@ DCI_PDU *get_dci(LTE_DL_FRAME_PARMS *lte_frame_parms,uint8_t log2L, uint8_t log2 DCI_pdu.dci_alloc[ind].format = format0; DCI_pdu.dci_alloc[ind].ra_flag = 0; DCI_pdu.dci_alloc[ind].search_space = DCI_UE_SPACE; - memcpy((void*)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &UL_alloc_pdu[0], UL_pdu_size_bytes); + memcpy((void *)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &UL_alloc_pdu[0], UL_pdu_size_bytes); DCI_pdu.Num_dci++; } } - + return(&DCI_pdu); } extern int QPSK[4],QPSK2[4]; -int main(int argc, char **argv) -{ - +int main(int argc, char **argv) { char c; - int i,l,aa; double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1; - int **txdata; double s_re[2][30720*2],s_im[2][30720*2],r_re[2][30720*2],r_im[2][30720*2]; double iqim=0.0; @@ -413,7 +389,6 @@ int main(int argc, char **argv) #endif int trial, n_errors_common=0,n_errors_ul=0,n_errors_dl=0,n_errors_cfi=0,n_errors_hi=0; unsigned char eNb_id = 0; - uint8_t awgn_flag=0; int n_frames=1; channel_desc_t *eNB2UE; @@ -427,25 +402,18 @@ int main(int argc, char **argv) DCI_format_t format_selector[MAX_NUM_DCI]; uint8_t num_dci=0; uint8_t numCCE,common_active=0,ul_active=0,dl_active=0; - uint32_t n_trials_common=0,n_trials_ul=0,n_trials_dl=0,false_detection_cnt=0; uint8_t common_rx,ul_rx,dl_rx; uint8_t tdd_config=3; - FILE *input_fd=NULL; char input_val_str[50],input_val_str2[50]; uint16_t n_rnti=0x1234; uint8_t osf=1,N_RB_DL=25; - SCM_t channel_model=Rayleigh1_anticorr; - DCI_ALLOC_t dci_alloc_rx[8]; - int ret; - uint8_t harq_pid; uint8_t phich_ACK; - uint8_t num_phich_interf = 0; lte_frame_type_t frame_type=TDD; // int re_offset; @@ -454,75 +422,71 @@ int main(int argc, char **argv) int k; uint32_t perfect_ce = 0; int CCE_table[800]; - number_of_cards = 1; - cpuf = get_cpu_freq_GHz(); - logInit(); - while ((c = getopt (argc, argv, "hapFg:R:c:n:s:x:y:z:L:M:N:I:f:i:S:P:Y")) != -1) { switch (c) { - case 'a': - printf("Running AWGN simulation\n"); - awgn_flag = 1; - break; - - case 'R': - N_RB_DL = atoi(optarg); - break; + case 'a': + printf("Running AWGN simulation\n"); + awgn_flag = 1; + break; - case 'F': - frame_type = FDD; - break; + case 'R': + N_RB_DL = atoi(optarg); + break; - case 'c': - tdd_config=atoi(optarg); + case 'F': + frame_type = FDD; + break; - if (tdd_config>6) { - printf("Illegal tdd_config %d (should be 0-6)\n",tdd_config); - exit(-1); - } + case 'c': + tdd_config=atoi(optarg); - break; + if (tdd_config>6) { + printf("Illegal tdd_config %d (should be 0-6)\n",tdd_config); + exit(-1); + } - case 'g': - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; break; - case 'B': - channel_model=SCM_B; - break; + case 'g': + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; - case 'C': - channel_model=SCM_C; - break; + case 'B': + channel_model=SCM_B; + break; - case 'D': - channel_model=SCM_D; - break; + case 'C': + channel_model=SCM_C; + break; - case 'E': - channel_model=EPA; - break; + case 'D': + channel_model=SCM_D; + break; - case 'F': - channel_model=EVA; - break; + case 'E': + channel_model=EPA; + break; - case 'G': - channel_model=ETU; - break; + case 'F': + channel_model=EVA; + break; - default: - printf("Unsupported channel model!\n"); - exit(-1); - } + case 'G': + channel_model=ETU; + break; - break; + default: + printf("Unsupported channel model!\n"); + exit(-1); + } + + break; /* case 'i': @@ -532,164 +496,169 @@ int main(int argc, char **argv) interf2=atoi(optarg); break; */ - case 'n': - n_frames = atoi(optarg); - break; + case 'n': + n_frames = atoi(optarg); + break; - case 's': - snr0 = atoi(optarg); - break; + case 's': + snr0 = atoi(optarg); + break; - case 'p': - extended_prefix_flag=1; - break; + case 'p': + extended_prefix_flag=1; + break; - case 'x': - transmission_mode=atoi(optarg); + case 'x': + transmission_mode=atoi(optarg); - if ((transmission_mode!=1) && - (transmission_mode!=2) && - (transmission_mode!=6)) { - printf("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=6)) { + printf("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } - break; + break; - case 'y': - n_tx=atoi(optarg); + case 'y': + n_tx=atoi(optarg); - if ((n_tx==0) || (n_tx>2)) { - printf("Unsupported number of tx antennas %d\n",n_tx); - exit(-1); - } + if ((n_tx==0) || (n_tx>2)) { + printf("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); + } - break; + break; - case 'z': - n_rx=atoi(optarg); + case 'z': + n_rx=atoi(optarg); - if ((n_rx==0) || (n_rx>2)) { - printf("Unsupported number of rx antennas %d\n",n_rx); - exit(-1); - } + if ((n_rx==0) || (n_rx>2)) { + printf("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } - break; + break; - case 'S': - subframe=atoi(optarg); - break; + case 'S': + subframe=atoi(optarg); + break; - case 'L': - log2L=atoi(optarg); + case 'L': + log2L=atoi(optarg); - if ((log2L!=0)&& - (log2L!=1)&& - (log2L!=2)&& - (log2L!=3)) { - printf("Unsupported DCI aggregation level %d (should be 0,1,2,3)\n",log2L); - exit(-1); - } + if ((log2L!=0)&& + (log2L!=1)&& + (log2L!=2)&& + (log2L!=3)) { + printf("Unsupported DCI aggregation level %d (should be 0,1,2,3)\n",log2L); + exit(-1); + } - break; + break; - case 'M': - log2Lcommon=atoi(optarg); + case 'M': + log2Lcommon=atoi(optarg); - if ((log2Lcommon!=2)&& - (log2Lcommon!=3)) { - printf("Unsupported Common DCI aggregation level %d (should be 2 or 3)\n",log2Lcommon); - exit(-1); - } + if ((log2Lcommon!=2)&& + (log2Lcommon!=3)) { + printf("Unsupported Common DCI aggregation level %d (should be 2 or 3)\n",log2Lcommon); + exit(-1); + } - break; + break; - case 'N': - format_selector[num_dci] = (DCI_format_t) atoi(optarg); - if ((format_selector[num_dci]<format0) || (format_selector[num_dci] > format1A)) { - printf("only formats 0, 1, and 1A supported for the moment\n"); - exit(-1); - } - if (format_selector[num_dci]==format0) ul_active=1; - if (format_selector[num_dci]==format1A) common_active=1; - if (format_selector[num_dci]==format1) dl_active=1; - num_dci++; - break; + case 'N': + format_selector[num_dci] = (DCI_format_t) atoi(optarg); - case 'O': - osf = atoi(optarg); - break; + if ((format_selector[num_dci]<format0) || (format_selector[num_dci] > format1A)) { + printf("only formats 0, 1, and 1A supported for the moment\n"); + exit(-1); + } - case 'I': - Nid_cell = atoi(optarg); - break; + if (format_selector[num_dci]==format0) ul_active=1; - case 'f': - input_fd = fopen(optarg,"r"); + if (format_selector[num_dci]==format1A) common_active=1; - if (input_fd==NULL) { - printf("Problem with filename %s\n",optarg); - exit(-1); - } + if (format_selector[num_dci]==format1) dl_active=1; - break; + num_dci++; + break; - case 'i': - n_rnti=atoi(optarg); - break; + case 'O': + osf = atoi(optarg); + break; - case 'P': - num_phich_interf=atoi(optarg); - break; + case 'I': + Nid_cell = atoi(optarg); + break; - case 'Y': - perfect_ce = 1; - break; + case 'f': + input_fd = fopen(optarg,"r"); - case 'h': - printf("%s -h(elp) -a(wgn on) -c tdd_config -n n_frames -r RiceanFactor -s snr0 -t Delayspread -x transmission mode (1,2,6) -y TXant -z RXant -L AggregLevelUEspec -M AggregLevelCommonDCI -N DCIFormat\n\n", - argv[0]); - printf("-h This message\n"); - printf("-a Use AWGN channel and not multipath\n"); - printf("-c TDD config\n"); - printf("-S Subframe number (0..9)\n"); - printf("-R N_RB_DL\n"); - printf("-F use FDD frame\n"); - printf("-p Use extended prefix mode\n"); - printf("-n Number of frames to simulate\n"); - printf("-r Ricean factor (dB, 0 means Rayleigh, 100 is almost AWGN\n"); - printf("-s Starting SNR, runs from SNR to SNR + 5 dB. If n_frames is 1 then just SNR is simulated\n"); - printf("-t Delay spread for multipath channel\n"); - printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-P Number of interfering PHICH\n"); - printf("-L log2 of Aggregation level for UE Specific DCI (0,1,2,3)\n"); - printf("-M log2 Aggregation level for Common DCI (4,8)\n"); - printf("-N Format for UE Spec DCI (0 - format0,\n"); - printf(" 1 - format1,\n"); - printf(" 2 - format1A,\n"); - printf(" 3 - format1B_2A,\n"); - printf(" 4 - format1B_4A,\n"); - printf(" 5 - format1C,\n"); - printf(" 6 - format1D_2A,\n"); - printf(" 7 - format1D_4A,\n"); - printf(" 8 - format2A_2A_L10PRB,\n"); - printf(" 9 - format2A_2A_M10PRB,\n"); - printf(" 10 - format2A_4A_L10PRB,\n"); - printf(" 11 - format2A_4A_M10PRB,\n"); - printf(" 12 - format2_2A_L10PRB,\n"); - printf(" 13 - format2_2A_M10PRB,\n"); - printf(" 14 - format2_4A_L10PRB,\n"); - printf(" 15 - format2_4A_M10PRB\n"); - printf(" 16 - format2_2D_M10PRB\n"); - printf(" 17 - format2_2D_L10PRB\n"); - printf(" can be called multiple times to add more than one DCI\n"); - printf("-O Oversampling factor\n"); - printf("-I Cell Id\n"); - printf("-F Input sample stream\n"); - exit(1); - break; + if (input_fd==NULL) { + printf("Problem with filename %s\n",optarg); + exit(-1); + } + + break; + + case 'i': + n_rnti=atoi(optarg); + break; + + case 'P': + num_phich_interf=atoi(optarg); + break; + + case 'Y': + perfect_ce = 1; + break; + + case 'h': + printf("%s -h(elp) -a(wgn on) -c tdd_config -n n_frames -r RiceanFactor -s snr0 -t Delayspread -x transmission mode (1,2,6) -y TXant -z RXant -L AggregLevelUEspec -M AggregLevelCommonDCI -N DCIFormat\n\n", + argv[0]); + printf("-h This message\n"); + printf("-a Use AWGN channel and not multipath\n"); + printf("-c TDD config\n"); + printf("-S Subframe number (0..9)\n"); + printf("-R N_RB_DL\n"); + printf("-F use FDD frame\n"); + printf("-p Use extended prefix mode\n"); + printf("-n Number of frames to simulate\n"); + printf("-r Ricean factor (dB, 0 means Rayleigh, 100 is almost AWGN\n"); + printf("-s Starting SNR, runs from SNR to SNR + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-t Delay spread for multipath channel\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-P Number of interfering PHICH\n"); + printf("-L log2 of Aggregation level for UE Specific DCI (0,1,2,3)\n"); + printf("-M log2 Aggregation level for Common DCI (4,8)\n"); + printf("-N Format for UE Spec DCI (0 - format0,\n"); + printf(" 1 - format1,\n"); + printf(" 2 - format1A,\n"); + printf(" 3 - format1B_2A,\n"); + printf(" 4 - format1B_4A,\n"); + printf(" 5 - format1C,\n"); + printf(" 6 - format1D_2A,\n"); + printf(" 7 - format1D_4A,\n"); + printf(" 8 - format2A_2A_L10PRB,\n"); + printf(" 9 - format2A_2A_M10PRB,\n"); + printf(" 10 - format2A_4A_L10PRB,\n"); + printf(" 11 - format2A_4A_M10PRB,\n"); + printf(" 12 - format2_2A_L10PRB,\n"); + printf(" 13 - format2_2A_M10PRB,\n"); + printf(" 14 - format2_4A_L10PRB,\n"); + printf(" 15 - format2_4A_M10PRB\n"); + printf(" 16 - format2_2D_M10PRB\n"); + printf(" 17 - format2_2D_L10PRB\n"); + printf(" can be called multiple times to add more than one DCI\n"); + printf("-O Oversampling factor\n"); + printf("-I Cell Id\n"); + printf("-F Input sample stream\n"); + exit(1); + break; } } @@ -701,22 +670,19 @@ int main(int argc, char **argv) n_rx, transmission_mode, extended_prefix_flag, - frame_type, + frame_type, Nid_cell, tdd_config, N_RB_DL, - 0, + 0, osf, perfect_ce); - #ifdef XFORMS fl_initialize (&argc, argv, NULL, 0, 0); form_ue = create_lte_phy_scope_ue(); sprintf (title, "LTE PHY SCOPE UE"); fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); #endif - - mac_xface->computeRIV = computeRIV; mac_xface->frame_parms = &eNB->frame_parms; // init_transport_channels(transmission_mode); @@ -727,35 +693,25 @@ int main(int argc, char **argv) snr1 = snr0+8.0; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - frame_parms = &eNB->frame_parms; printf("Getting %d dcis\n",num_dci); - get_dci(frame_parms, log2L, log2Lcommon, format_selector, num_dci, n_rnti); - txdata = eNB->common_vars.txdata[eNb_id]; - nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12; - printf("Subframe %d, FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d\n", subframe,NUMBER_OF_OFDM_CARRIERS, eNB->frame_parms.Ncp,eNB->frame_parms.samples_per_tti,nsymb); - eNB2UE = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), + N_RB2sampling_rate(eNB->frame_parms.N_RB_DL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL), 0, 0, 0); - L1_rxtx_proc_t *proc_rxtx = (subframe == 0)? &eNB->proc.L1_proc: &eNB->proc.L1_proc_tx; - eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,N_RB_DL,0); UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); - - proc_rxtx->frame_tx = 0; proc_rxtx->subframe_tx = subframe; @@ -765,7 +721,7 @@ int main(int argc, char **argv) i=0; while (!feof(input_fd)) { - ret=fscanf(input_fd,"%s %s",input_val_str,input_val_str2);//&input_val1,&input_val2); + ret=fscanf(input_fd,"%49s %49s",input_val_str,input_val_str2);//&input_val1,&input_val2); if (ret != 2) { printf("%s:%d:%s: fscanf error, exiting\n", __FILE__, __LINE__, __FUNCTION__); @@ -773,11 +729,11 @@ int main(int argc, char **argv) } if ((i%4)==0) { - ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); - ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); + ((short *)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); + ((short *)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); if ((i/4)<100) - printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); + printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short *)txdata[0])[i/4],((short *)txdata[0])[(i/4)+1]); //1,input_val2,); } i++; @@ -794,7 +750,6 @@ int main(int argc, char **argv) tx_lev_dB = (unsigned int) dB_fixed(tx_lev); } - UE->UE_mode[0] = PUSCH; // nCCE_max = get_nCCE(3,&eNB->frame_parms,get_mi(&eNB->frame_parms,0)); @@ -802,8 +757,6 @@ int main(int argc, char **argv) //printf("num_phich interferers %d\n",num_phich_interf); for (SNR=snr0; SNR<snr1; SNR+=0.2) { - - n_errors_common = 0; n_errors_ul = 0; n_errors_dl = 0; @@ -814,14 +767,11 @@ int main(int argc, char **argv) n_trials_dl=0; for (trial=0; trial<n_frames; trial++) { - // printf("DCI (SF %d): txdataF %p (0 %p)\n",subframe,&eNB->common_vars.txdataF[eNb_id][aa][512*14*subframe],&eNB->common_vars.txdataF[eNb_id][aa][0]); for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { memset(&eNB->common_vars.txdataF[eNb_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); - } - generate_pilots_slot(eNB, eNB->common_vars.txdataF[eNb_id], AMP, //1024, @@ -833,24 +783,26 @@ int main(int argc, char **argv) (subframe*2)+1, 0); - if (input_fd == NULL) { numCCE=0; n_trials_common++; common_active = 1; - if (eNB->frame_parms.N_RB_DL >= 50) { - if (ul_active==1) { - n_trials_ul++; - } - } - if (eNB->frame_parms.N_RB_DL >= 25) { - if (dl_active==1) { - n_trials_dl++; - } - } + + if (eNB->frame_parms.N_RB_DL >= 50) { + if (ul_active==1) { + n_trials_ul++; + } + } + + if (eNB->frame_parms.N_RB_DL >= 25) { + if (dl_active==1) { + n_trials_dl++; + } + } + num_pdcch_symbols = get_num_pdcch_symbols(DCI_pdu.Num_dci, DCI_pdu.dci_alloc, frame_parms, subframe); - numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe)); + numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe)); if (n_frames==1) { printf("num_dci %d, num_pddch_symbols %d, nCCE %d\n", @@ -859,35 +811,35 @@ int main(int argc, char **argv) } // apply RNTI-based nCCE allocation - memset(CCE_table,0,800*sizeof(int)); + memset(CCE_table,0,800*sizeof(int)); for (i = 0; i < DCI_pdu.Num_dci; i++) { // SI RNTI if (DCI_pdu.dci_alloc[i].rnti == SI_RNTI) { DCI_pdu.dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table, - 1<<DCI_pdu.dci_alloc[i].L, - numCCE, - 1, - SI_RNTI, - subframe); + 1<<DCI_pdu.dci_alloc[i].L, + numCCE, + 1, + SI_RNTI, + subframe); } // RA RNTI else if (DCI_pdu.dci_alloc[i].ra_flag == 1) { DCI_pdu.dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table, - 1<<DCI_pdu.dci_alloc[i].L, - numCCE, - 1, - DCI_pdu.dci_alloc[i].rnti, - subframe); + 1<<DCI_pdu.dci_alloc[i].L, + numCCE, + 1, + DCI_pdu.dci_alloc[i].rnti, + subframe); } // C RNTI else { DCI_pdu.dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table, - 1<<DCI_pdu.dci_alloc[i].L, - numCCE, - 0, - DCI_pdu.dci_alloc[i].rnti, - subframe); + 1<<DCI_pdu.dci_alloc[i].L, + numCCE, + 0, + DCI_pdu.dci_alloc[i].rnti, + subframe); } if (n_frames==1) @@ -914,19 +866,16 @@ int main(int argc, char **argv) printf("generating PHICH\n"); harq_pid = phich_subframe_to_harq_pid(&eNB->frame_parms, proc_rxtx->frame_tx, subframe); - phich_ACK = taus()&1; eNB->ulsch[0]->harq_processes[harq_pid]->phich_active = 1; eNB->ulsch[0]->harq_processes[harq_pid]->first_rb = 0; eNB->ulsch[0]->harq_processes[harq_pid]->n_DMRS = 0; eNB->ulsch[0]->harq_processes[harq_pid]->phich_ACK = phich_ACK; eNB->ulsch[0]->harq_processes[harq_pid]->dci_alloc = 1; - UE->ulsch[0]->harq_processes[harq_pid]->first_rb = 0; UE->ulsch[0]->harq_processes[harq_pid]->n_DMRS = 0; - generate_phich_top(eNB,proc_rxtx,AMP,0); - + // generate 3 interfering PHICH if (num_phich_interf>0) { eNB->ulsch[0]->harq_processes[harq_pid]->first_rb = 4; @@ -938,15 +887,14 @@ int main(int argc, char **argv) eNB->ulsch[0]->harq_processes[harq_pid]->n_DMRS = 1; generate_phich_top(eNB,proc_rxtx,1024,0); } + if (num_phich_interf>2) { eNB->ulsch[0]->harq_processes[harq_pid]->first_rb = 12; eNB->ulsch[0]->harq_processes[harq_pid]->n_DMRS = 1; generate_phich_top(eNB,proc_rxtx,1024,0); - } eNB->ulsch[0]->harq_processes[harq_pid]->first_rb = 0; - } // LOG_M("pilotsF.m","rsF",txdataF[0],lte_eNB->frame_parms.ofdm_symbol_size,1,1); @@ -960,7 +908,6 @@ int main(int argc, char **argv) tx_lev = 0; - for (aa=0; aa<eNB->frame_parms.nb_antenna_ports_eNB; aa++) { if (eNB->frame_parms.Ncp == 1) PHY_ofdm_mod(&eNB->common_vars.txdataF[eNb_id][aa][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size], // input, @@ -1002,15 +949,12 @@ int main(int argc, char **argv) } } - - if (awgn_flag == 0) { multipath_channel(eNB2UE,s_re,s_im,r_re,r_im, 2*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES,0); } //LOG_M("channel0.m","chan0",ch[0],channel_length,1,8); - // scale by path_loss = NOW - P_noise //sigma2 = pow(10,sigma2_dB/10); //N0W = -95.87; @@ -1025,9 +969,8 @@ int main(int argc, char **argv) // printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB); for (i=0; i<2*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { for (aa=0; aa<UE->frame_parms.nb_antennas_rx; aa++) { - - ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti) + 2*i] = (short) (.667*(r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti) + 2*i+1] = (short) (.667*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble( + ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti) + 2*i] = (short) (.667*(r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti) + 2*i+1] = (short) (.667*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble( 0.0,1.0))); /* ((short*)UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti) + 2*i] = @@ -1040,16 +983,14 @@ int main(int argc, char **argv) // UE receiver for (l=0; l<eNB->frame_parms.symbols_per_tti; l++) { - // subframe_offset = (l/eNB->frame_parms.symbols_per_tti)*eNB->frame_parms.samples_per_tti; // printf("subframe_offset = %d\n",subframe_offset); - slot_fep(UE, l%(eNB->frame_parms.symbols_per_tti/2), (2*subframe)+(l/(eNB->frame_parms.symbols_per_tti/2)), 0, 0, - 0); + 0); if (UE->perfect_ce == 1) { if (awgn_flag==0) { @@ -1083,12 +1024,9 @@ int main(int argc, char **argv) } if (l==((eNB->frame_parms.Ncp==0)?4:3)) { - // LOG_M("H00.m","h00",&(UE->common_vars.dl_ch_estimates[0][0][0]),((frame_parms->Ncp==0)?7:6)*(eNB->frame_parms.ofdm_symbol_size),1,1); - // do PDCCH procedures here UE->pdcch_vars[0][0]->crnti = n_rnti; - // printf("Doing RX : num_pdcch_symbols at TX %d\n",num_pdcch_symbols); rx_pdcch(UE, trial, @@ -1102,7 +1040,7 @@ int main(int argc, char **argv) UE->ulsch[0]->harq_processes[phich_subframe_to_harq_pid(&UE->frame_parms,0,subframe)]->status = ACTIVE; //UE->ulsch[0]->harq_processes[phich_subframe_to_harq_pid(&UE->frame_parms,0,subframe)]->Ndi = 1; rx_phich(UE, - &UE->proc.proc_rxtx[subframe&1], + &UE->proc.proc_rxtx[subframe&1], subframe, 0); } @@ -1112,7 +1050,6 @@ int main(int argc, char **argv) dci_cnt = dci_decoding_procedure(UE, dci_alloc_rx,1, 0,subframe); - common_rx=0; ul_rx=0; dl_rx=0; @@ -1179,7 +1116,6 @@ int main(int argc, char **argv) if (n_errors_cfi > 10) break; } - } // symbol loop if (n_errors_cfi > 100) @@ -1193,17 +1129,17 @@ int main(int argc, char **argv) UE, eNb_id,0,subframe); #endif - } //trials - + if (common_active) printf("SNR %f : n_errors_common = %d/%d (%e)\n", SNR,n_errors_common,n_trials_common,(double)n_errors_common/n_trials_common); + if (ul_active==1) printf("SNR %f : n_errors_ul = %d/%d (%e)\n", SNR,n_errors_ul,n_trials_ul,(double)n_errors_ul/n_trials_ul); + if (dl_active==1) printf("SNR %f : n_errors_dl = %d/%d (%e)\n", SNR,n_errors_dl,n_trials_dl,(double)n_errors_dl/n_trials_dl); + printf("SNR %f : n_errors_cfi = %d/%d (%e)\n", SNR,n_errors_cfi,trial,(double)n_errors_cfi/trial); printf("SNR %f : n_errors_hi = %d/%d (%e)\n", SNR,n_errors_hi,trial,(double)n_errors_hi/trial); - } // SNR - if (n_frames==1) { LOG_M("txsig0.m","txs0", txdata[0],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); @@ -1231,9 +1167,11 @@ int main(int argc, char **argv) lte_sync_time_free(); - return(n_errors_ul); + if ( input_fd != NULL) + fclose(input_fd); - } + return(n_errors_ul); +} diff --git a/openair1/SIMULATION/LTE_PHY/prachsim.c b/openair1/SIMULATION/LTE_PHY/prachsim.c index 7475017d85becb53cb083ee93165c49795302d17..0771917bfba865ac0daacad3e7f0d75303ff4a69 100644 --- a/openair1/SIMULATION/LTE_PHY/prachsim.c +++ b/openair1/SIMULATION/LTE_PHY/prachsim.c @@ -48,11 +48,8 @@ extern uint16_t prach_root_sequence_map0_3[838]; void dump_prach_config(LTE_DL_FRAME_PARMS *frame_parms,uint8_t subframe); -int main(int argc, char **argv) -{ - +int main(int argc, char **argv) { char c; - int i,aa,aarx; double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1=0.0,ue_speed0=0.0,ue_speed1=0.0; uint8_t snr1set=0; @@ -64,7 +61,6 @@ int main(int argc, char **argv) int trial; //, ntrials=1; uint8_t transmission_mode = 1,n_tx=1,n_rx=1; uint16_t Nid_cell=0; - uint8_t awgn_flag=0; uint8_t hs_flag=0; int n_frames=1; @@ -73,9 +69,7 @@ int main(int argc, char **argv) uint8_t extended_prefix_flag=0; // int8_t interf1=-19,interf2=-19; LTE_DL_FRAME_PARMS *frame_parms; - SCM_t channel_model=Rayleigh1; - // uint8_t abstraction_flag=0,calibration_flag=0; // double prach_sinr; uint8_t osf=1,N_RB_DL=25; @@ -91,211 +85,212 @@ int main(int argc, char **argv) double ue_speed = 0; int NCS_config = 1,rootSequenceIndex=0; int threequarter_fs = 0; - cpuf = get_cpu_freq_GHz(); - logInit(); - number_of_cards = 1; - - while ((c = getopt (argc, argv, "hHaA:Cr:p:g:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) { switch (c) { - case 'a': - printf("Running AWGN simulation\n"); - awgn_flag = 1; - /* ntrials not used later, no need to set */ - //ntrials=1; - break; - - case 'd': - delay = atoi(optarg); - break; - - case 'g': - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; + case 'a': + printf("Running AWGN simulation\n"); + awgn_flag = 1; + /* ntrials not used later, no need to set */ + //ntrials=1; break; - case 'B': - channel_model=SCM_B; + case 'd': + delay = atoi(optarg); break; - case 'C': - channel_model=SCM_C; - break; + case 'g': + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; - case 'D': - channel_model=SCM_D; - break; + case 'B': + channel_model=SCM_B; + break; - case 'E': - channel_model=EPA; - break; + case 'C': + channel_model=SCM_C; + break; - case 'F': - channel_model=EVA; - break; + case 'D': + channel_model=SCM_D; + break; - case 'G': - channel_model=ETU; - break; + case 'E': + channel_model=EPA; + break; - case 'H': - channel_model=Rayleigh8; + case 'F': + channel_model=EVA; + break; - case 'I': - channel_model=Rayleigh1; + case 'G': + channel_model=ETU; + break; - case 'J': - channel_model=Rayleigh1_corr; + case 'H': + channel_model=Rayleigh8; + break; - case 'K': - channel_model=Rayleigh1_anticorr; + case 'I': + channel_model=Rayleigh1; + break; - case 'L': - channel_model=Rice8; + case 'J': + channel_model=Rayleigh1_corr; + break; - case 'M': - channel_model=Rice1; + case 'K': + channel_model=Rayleigh1_anticorr; + break; + + case 'L': + channel_model=Rice8; + break; + + case 'M': + channel_model=Rice1; + break; + + case 'N': + channel_model=Rayleigh1_800; + break; + + default: + msg("Unsupported channel model!\n"); + exit(-1); + } - case 'N': - channel_model=Rayleigh1_800; break; - default: - msg("Unsupported channel model!\n"); - exit(-1); - } + case 'E': + threequarter_fs=1; + break; - break; + case 'n': + n_frames = atoi(optarg); + break; - case 'E': - threequarter_fs=1; - break; + case 's': + snr0 = atof(optarg); + msg("Setting SNR0 to %f\n",snr0); + break; - case 'n': - n_frames = atoi(optarg); - break; + case 'S': + snr1 = atof(optarg); + snr1set=1; + msg("Setting SNR1 to %f\n",snr1); + break; - case 's': - snr0 = atof(optarg); - msg("Setting SNR0 to %f\n",snr0); - break; + case 'p': + preamble_tx=atoi(optarg); + break; - case 'S': - snr1 = atof(optarg); - snr1set=1; - msg("Setting SNR1 to %f\n",snr1); - break; + case 'v': + ue_speed0 = atoi(optarg); + break; - case 'p': - preamble_tx=atoi(optarg); - break; + case 'V': + ue_speed1 = atoi(optarg); + ue_speed1set = 1; + break; - case 'v': - ue_speed0 = atoi(optarg); - break; + case 'Z': + NCS_config = atoi(optarg); - case 'V': - ue_speed1 = atoi(optarg); - ue_speed1set = 1; - break; + if ((NCS_config > 15) || (NCS_config < 0)) + printf("Illegal NCS_config %d, (should be 0-15)\n",NCS_config); - case 'Z': - NCS_config = atoi(optarg); + break; - if ((NCS_config > 15) || (NCS_config < 0)) - printf("Illegal NCS_config %d, (should be 0-15)\n",NCS_config); + case 'H': + printf("High-Speed Flag enabled\n"); + hs_flag = 1; + break; - break; + case 'L': + rootSequenceIndex = atoi(optarg); - case 'H': - printf("High-Speed Flag enabled\n"); - hs_flag = 1; - break; + if ((rootSequenceIndex < 0) || (rootSequenceIndex > 837)) + printf("Illegal rootSequenceNumber %d, (should be 0-837)\n",rootSequenceIndex); - case 'L': - rootSequenceIndex = atoi(optarg); + break; - if ((rootSequenceIndex < 0) || (rootSequenceIndex > 837)) - printf("Illegal rootSequenceNumber %d, (should be 0-837)\n",rootSequenceIndex); + case 'x': + transmission_mode=atoi(optarg); - break; + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=6)) { + msg("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } - case 'x': - transmission_mode=atoi(optarg); + break; - if ((transmission_mode!=1) && - (transmission_mode!=2) && - (transmission_mode!=6)) { - msg("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } + case 'y': + n_tx=atoi(optarg); - break; + if ((n_tx==0) || (n_tx>2)) { + msg("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); + } - case 'y': - n_tx=atoi(optarg); + break; - if ((n_tx==0) || (n_tx>2)) { - msg("Unsupported number of tx antennas %d\n",n_tx); - exit(-1); - } + case 'z': + n_rx=atoi(optarg); - break; + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } - case 'z': - n_rx=atoi(optarg); + break; - if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); - exit(-1); - } + case 'N': + Nid_cell = atoi(optarg); + break; + + case 'R': + N_RB_DL = atoi(optarg); + break; - break; - - case 'N': - Nid_cell = atoi(optarg); - break; - - case 'R': - N_RB_DL = atoi(optarg); - break; - - case 'O': - osf = atoi(optarg); - break; - - case 'F': - break; - - default: - case 'h': - printf("%s -h(elp) -a(wgn on) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", - argv[0]); - printf("-h This message\n"); - printf("-a Use AWGN channel and not multipath\n"); - printf("-n Number of frames to simulate\n"); - printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); - printf("-S Ending SNR, runs from SNR0 to SNR1\n"); - printf("-g [A,B,C,D,E,F,G,I,N] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) or Rayleigh1 (I) or Rayleigh1_800 (N) models (ignores delay spread and Ricean factor)\n"); - printf("-z Number of RX antennas used in eNB\n"); - printf("-N Nid_cell\n"); - printf("-O oversampling factor (1,2,4,8,16)\n"); - // printf("-f PRACH format (0=1,1=2,2=3,3=4)\n"); - printf("-d Channel delay \n"); - printf("-v Starting UE velocity in km/h, runs from 'v' to 'v+50km/h'. If n_frames is 1 just 'v' is simulated \n"); - printf("-V Ending UE velocity in km/h, runs from 'v' to 'V'"); - printf("-L rootSequenceIndex (0-837)\n"); - printf("-Z NCS_config (ZeroCorrelationZone) (0-15)\n"); - printf("-H Run with High-Speed Flag enabled \n"); - printf("-R Number of PRB (6,15,25,50,75,100)\n"); - printf("-F Input filename (.txt format) for RX conformance testing\n"); - exit (-1); - break; + case 'O': + osf = atoi(optarg); + break; + + case 'F': + break; + + default: + case 'h': + printf("%s -h(elp) -a(wgn on) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", + argv[0]); + printf("-h This message\n"); + printf("-a Use AWGN channel and not multipath\n"); + printf("-n Number of frames to simulate\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-g [A,B,C,D,E,F,G,I,N] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) or Rayleigh1 (I) or Rayleigh1_800 (N) models (ignores delay spread and Ricean factor)\n"); + printf("-z Number of RX antennas used in eNB\n"); + printf("-N Nid_cell\n"); + printf("-O oversampling factor (1,2,4,8,16)\n"); + // printf("-f PRACH format (0=1,1=2,2=3,3=4)\n"); + printf("-d Channel delay \n"); + printf("-v Starting UE velocity in km/h, runs from 'v' to 'v+50km/h'. If n_frames is 1 just 'v' is simulated \n"); + printf("-V Ending UE velocity in km/h, runs from 'v' to 'V'"); + printf("-L rootSequenceIndex (0-837)\n"); + printf("-Z NCS_config (ZeroCorrelationZone) (0-15)\n"); + printf("-H Run with High-Speed Flag enabled \n"); + printf("-R Number of PRB (6,15,25,50,75,100)\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + exit (-1); + break; } } @@ -304,17 +299,16 @@ int main(int argc, char **argv) lte_param_init(n_tx, n_tx, - n_rx, - transmission_mode, - extended_prefix_flag, - FDD, - Nid_cell, - 3, - N_RB_DL, - threequarter_fs, - osf, - 0); - + n_rx, + transmission_mode, + extended_prefix_flag, + FDD, + Nid_cell, + 3, + N_RB_DL, + threequarter_fs, + osf, + 0); if (snr1set==0) { if (n_frames==1) @@ -331,30 +325,22 @@ int main(int argc, char **argv) } printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - frame_parms = &eNB->frame_parms; - - txdata = UE->common_vars.txdata; printf("txdata %p\n",&txdata[0][subframe*frame_parms->samples_per_tti]); - - s_re = malloc(2*sizeof(double*)); - s_im = malloc(2*sizeof(double*)); - r_re = malloc(2*sizeof(double*)); - r_im = malloc(2*sizeof(double*)); + s_re = malloc(2*sizeof(double *)); + s_im = malloc(2*sizeof(double *)); + r_re = malloc(2*sizeof(double *)); + r_im = malloc(2*sizeof(double *)); nsymb = (frame_parms->Ncp == 0) ? 14 : 12; - printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d\n",NUMBER_OF_OFDM_CARRIERS, frame_parms->Ncp,frame_parms->samples_per_tti,nsymb); - - - msg("[SIM] Using SCM/101\n"); UE2eNB = new_channel_desc_scm(UE->frame_parms.nb_antennas_tx, eNB->frame_parms.nb_antennas_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), + N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), 0.0, delay, 0); @@ -365,12 +351,10 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(s_re[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(s_im[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); - r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(r_re[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); @@ -382,30 +366,22 @@ int main(int argc, char **argv) UE->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=NCS_config; UE->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag=hs_flag; UE->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset=0; - - eNB->frame_parms.prach_config_common.rootSequenceIndex=rootSequenceIndex; eNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; eNB->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=NCS_config; eNB->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag=hs_flag; eNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset=0; - eNB->node_function = eNodeB_3GPP; eNB->proc.subframe_rx = subframe; eNB->proc.subframe_prach = subframe; - /* N_ZC not used later, so prach_fmt is also useless, don't set */ //prach_fmt = get_prach_fmt(eNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, // eNB->frame_parms.frame_type); /* N_ZC not used later, no need to set */ //N_ZC = (prach_fmt <4)?839:139; - compute_prach_seq(&eNB->frame_parms.prach_config_common,eNB->frame_parms.frame_type,eNB->X_u); - compute_prach_seq(&UE->frame_parms.prach_config_common,UE->frame_parms.frame_type,UE->X_u); - UE->prach_vars[0]->amp = AMP; - UE->prach_resources[0] = &prach_resources; if (preamble_tx == 99) @@ -416,18 +392,14 @@ int main(int argc, char **argv) UE->prach_resources[0]->ra_PreambleIndex = preamble_tx; UE->prach_resources[0]->ra_TDD_map_index = 0; - tx_lev = generate_prach(UE, 0, //eNB_id, subframe, 0); //Nf - /* tx_lev_dB not used later, no need to set */ //tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - LOG_M("txsig0_new.m","txs0", &txdata[0][subframe*frame_parms->samples_per_tti],frame_parms->samples_per_tti,1,1); //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); - // multipath channel dump_prach_config(&eNB->frame_parms,subframe); @@ -450,8 +422,6 @@ int main(int argc, char **argv) } } - - for (SNR=snr0; SNR<snr1; SNR+=.2) { for (ue_speed=ue_speed0; ue_speed<ue_speed1; ue_speed+=10) { delay_avg = 0.0; @@ -461,7 +431,6 @@ int main(int argc, char **argv) prach_errors=0; for (trial=0; trial<n_frames; trial++) { - sigma2_dB = 10*log10((double)tx_lev) - SNR; if (n_frames==1) @@ -471,7 +440,6 @@ int main(int argc, char **argv) sigma2 = pow(10,sigma2_dB/10); // printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB); - if (awgn_flag == 0) { multipath_tv_channel(UE2eNB,s_re,s_im,r_re,r_im, 2*frame_parms->samples_per_tti,0); @@ -485,9 +453,8 @@ int main(int argc, char **argv) for (i=0; i<frame_parms->samples_per_tti; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { - - ((short*) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } @@ -496,7 +463,6 @@ int main(int argc, char **argv) preamble_delay_list, 0, //Nf 0); //tdd_mapindex - preamble_energy_max = preamble_energy_list[0]; preamble_max = 0; @@ -524,8 +490,8 @@ int main(int argc, char **argv) LOG_M("prach0.m","prach0", &txdata[0][subframe*frame_parms->samples_per_tti],frame_parms->samples_per_tti,1,1); LOG_M("prachF0.m","prachF0", &eNB->prach_vars.prachF[0],24576,1,1); LOG_M("rxsig0.m","rxs0", - &eNB->common_vars.rxdata[0][0][subframe*frame_parms->samples_per_tti], - frame_parms->samples_per_tti,1,1); + &eNB->common_vars.rxdata[0][0][subframe*frame_parms->samples_per_tti], + frame_parms->samples_per_tti,1,1); LOG_M("rxsigF0.m","rxsF0", eNB->prach_vars.rxsigF[0],6144,1,1); LOG_M("prach_preamble.m","prachp",&eNB->X_u[0],839,1,1); } @@ -539,7 +505,6 @@ int main(int argc, char **argv) // printf("(%f,%f)\n",SNR,(double)prach_errors/(double)n_frames); } //SNR loop - for (i=0; i<2; i++) { free(s_re[i]); free(s_im[i]); @@ -551,11 +516,8 @@ int main(int argc, char **argv) free(s_im); free(r_re); free(r_im); - lte_sync_time_free(); - return(0); - } diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c index ad236a6f7568bb9a7d6aeb4a81195bf48a60039e..a58f844945706b37c30457494964734f55540502 100644 --- a/openair1/SIMULATION/LTE_PHY/pucchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c @@ -45,37 +45,29 @@ PHY_VARS_UE *UE; double cpuf; -int main(int argc, char **argv) -{ - +int main(int argc, char **argv) { char c; - int i,l,aa; double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1=0.0; uint8_t snr1set=0; //mod_sym_t **txdataF; int **txdata; double s_re0[30720],s_re1[30720],s_im0[30720],s_im1[30720],r_re0[30720],r_im0[30720],r_re1[30720],r_im1[30720]; - double *s_re[2]={s_re0,s_re1}; - double *s_im[2]={s_im0,s_im1}; - double *r_re[2]={r_re0,r_re1}; - double *r_im[2]={r_im0,r_im1}; + double *s_re[2]= {s_re0,s_re1}; + double *s_im[2]= {s_im0,s_im1}; + double *r_re[2]= {r_re0,r_re1}; + double *r_im[2]= {r_im0,r_im1}; double ricean_factor=0.0000005,iqim=0.0; - int trial, n_trials, ntrials=1, n_errors; uint8_t transmission_mode = 1,n_tx=1,n_rx=1; unsigned char eNB_id = 0; uint16_t Nid_cell=0; - int n_frames=1; channel_desc_t *UE2eNB; uint32_t nsymb,tx_lev; uint8_t extended_prefix_flag=0; - LTE_DL_FRAME_PARMS *frame_parms; - SCM_t channel_model=Rayleigh1_corr; - // double pucch_sinr; uint8_t osf=1,N_RB_DL=25; uint32_t pucch_tx=0,pucch1_missed=0,pucch1_false=0,pucch3_false=0,sig; @@ -90,202 +82,203 @@ int main(int argc, char **argv) double stat_no_sig,stat_sig; uint8_t N0=40; uint8_t pucch1_thres=10; - uint16_t n1_pucch = 0; uint16_t n2_pucch = 0; uint16_t n3_pucch = 20; - uint16_t n_rnti=0x1234; - number_of_cards = 1; - cpuf = get_cpu_freq_GHz(); while ((c = getopt (argc, argv, "har:pf:g:n:s:S:x:y:z:N:F:T:R:")) != -1) { switch (c) { - case 'a': - printf("Running AWGN simulation\n"); - channel_model = AWGN; - ntrials=1; - break; - - case 'f': - if (atoi(optarg)==0) - pucch_format = pucch_format1; - else if (atoi(optarg)==1) - pucch_format = pucch_format1a; - else if (atoi(optarg)==2) - pucch_format = pucch_format1b; - else if (atoi(optarg)==6) // 3,4,5 is reserved for format2,2a,2b - pucch_format = pucch_format3; - else { - printf("Unsupported pucch_format %d\n",atoi(optarg)); - exit(-1); - } + case 'a': + printf("Running AWGN simulation\n"); + channel_model = AWGN; + ntrials=1; + break; - break; + case 'f': + if (atoi(optarg)==0) + pucch_format = pucch_format1; + else if (atoi(optarg)==1) + pucch_format = pucch_format1a; + else if (atoi(optarg)==2) + pucch_format = pucch_format1b; + else if (atoi(optarg)==6) // 3,4,5 is reserved for format2,2a,2b + pucch_format = pucch_format3; + else { + printf("Unsupported pucch_format %d\n",atoi(optarg)); + exit(-1); + } - case 'g': - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; break; - case 'B': - channel_model=SCM_B; - break; + case 'g': + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; - case 'C': - channel_model=SCM_C; - break; + case 'B': + channel_model=SCM_B; + break; - case 'D': - channel_model=SCM_D; - break; + case 'C': + channel_model=SCM_C; + break; - case 'E': - channel_model=EPA; - break; + case 'D': + channel_model=SCM_D; + break; - case 'F': - channel_model=EVA; - break; + case 'E': + channel_model=EPA; + break; - case 'G': - channel_model=ETU; - break; + case 'F': + channel_model=EVA; + break; + + case 'G': + channel_model=ETU; + break; + + case 'H': + channel_model=Rayleigh8; + break; - case 'H': - channel_model=Rayleigh8; + case 'I': + channel_model=Rayleigh1; + break; - case 'I': - channel_model=Rayleigh1; + case 'J': + channel_model=Rayleigh1_corr; + break; - case 'J': - channel_model=Rayleigh1_corr; + case 'K': + channel_model=Rayleigh1_anticorr; + break; - case 'K': - channel_model=Rayleigh1_anticorr; + case 'L': + channel_model=Rice8; + break; - case 'L': - channel_model=Rice8; + case 'M': + channel_model=Rice1; + break; + + default: + printf("Unsupported channel model!\n"); + exit(-1); + } - case 'M': - channel_model=Rice1; break; - default: - printf("Unsupported channel model!\n"); - exit(-1); - } + case 'n': + n_frames = atoi(optarg); + break; - break; + case 's': + snr0 = atof(optarg); + printf("Setting SNR0 to %f\n",snr0); + break; - case 'n': - n_frames = atoi(optarg); - break; + case 'S': + snr1 = atof(optarg); + snr1set=1; + printf("Setting SNR1 to %f\n",snr1); + break; - case 's': - snr0 = atof(optarg); - printf("Setting SNR0 to %f\n",snr0); - break; + case 'p': + extended_prefix_flag=1; + break; - case 'S': - snr1 = atof(optarg); - snr1set=1; - printf("Setting SNR1 to %f\n",snr1); - break; + case 'r': + ricean_factor = pow(10,-.1*atof(optarg)); - case 'p': - extended_prefix_flag=1; - break; + if (ricean_factor>1) { + printf("Ricean factor must be between 0 and 1\n"); + exit(-1); + } - case 'r': - ricean_factor = pow(10,-.1*atof(optarg)); + break; - if (ricean_factor>1) { - printf("Ricean factor must be between 0 and 1\n"); - exit(-1); - } + case 'x': + transmission_mode=atoi(optarg); - break; + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=6)) { + printf("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } - case 'x': - transmission_mode=atoi(optarg); + break; - if ((transmission_mode!=1) && - (transmission_mode!=2) && - (transmission_mode!=6)) { - printf("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } + case 'y': + n_tx=atoi(optarg); - break; + if ((n_tx==0) || (n_tx>2)) { + printf("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); + } - case 'y': - n_tx=atoi(optarg); + break; - if ((n_tx==0) || (n_tx>2)) { - printf("Unsupported number of tx antennas %d\n",n_tx); - exit(-1); - } + case 'z': + n_rx=atoi(optarg); - break; + if ((n_rx==0) || (n_rx>2)) { + printf("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } - case 'z': - n_rx=atoi(optarg); + break; - if ((n_rx==0) || (n_rx>2)) { - printf("Unsupported number of rx antennas %d\n",n_rx); - exit(-1); - } + case 'N': + N0 = atoi(optarg); + break; + + case 'T': + pucch1_thres = atoi(optarg); + break; + + case 'R': + N_RB_DL = atoi(optarg); + break; - break; - - case 'N': - N0 = atoi(optarg); - break; - - case 'T': - pucch1_thres = atoi(optarg); - break; - - case 'R': - N_RB_DL = atoi(optarg); - break; - - case 'O': - osf = atoi(optarg); - break; - - case 'F': - break; - - default: - case 'h': - printf("%s -h(elp) -a(wgn on) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -r Ricean_FactordB -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -N CellId\n", - argv[0]); - printf("-h This message\n"); - printf("-a Use AWGN channel and not multipath\n"); - printf("-p Use extended prefix mode\n"); - printf("-n Number of frames to simulate\n"); - printf("-r Ricean factor (dB, 0 means Rayleigh, 100 is almost AWGN\n"); - printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); - printf("-S Ending SNR, runs from SNR0 to SNR1\n"); - printf("-t Delay spread for multipath channel\n"); - printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); - printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); - printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); - printf("-N Noise variance in dB\n"); - printf("-R N_RB_DL\n"); - printf("-O oversampling factor (1,2,4,8,16)\n"); - printf("-f PUCCH format (0=1,1=1a,2=1b,6=3), formats 2/2a/2b not supported\n"); - printf("-F Input filename (.txt format) for RX conformance testing\n"); - exit (-1); - break; + case 'O': + osf = atoi(optarg); + break; + + case 'F': + break; + + default: + case 'h': + printf("%s -h(elp) -a(wgn on) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -r Ricean_FactordB -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -N CellId\n", + argv[0]); + printf("-h This message\n"); + printf("-a Use AWGN channel and not multipath\n"); + printf("-p Use extended prefix mode\n"); + printf("-n Number of frames to simulate\n"); + printf("-r Ricean factor (dB, 0 means Rayleigh, 100 is almost AWGN\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-t Delay spread for multipath channel\n"); + printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-N Noise variance in dB\n"); + printf("-R N_RB_DL\n"); + printf("-O oversampling factor (1,2,4,8,16)\n"); + printf("-f PUCCH format (0=1,1=1a,2=1b,6=3), formats 2/2a/2b not supported\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + exit (-1); + break; } } @@ -299,17 +292,16 @@ int main(int argc, char **argv) lte_param_init(n_tx, n_tx, - n_rx, - transmission_mode, - extended_prefix_flag, - FDD, - Nid_cell, - 3, - N_RB_DL, - 0, - osf, - 0); - + n_rx, + transmission_mode, + extended_prefix_flag, + FDD, + Nid_cell, + 3, + N_RB_DL, + 0, + osf, + 0); if (snr1set==0) { if (n_frames==1) @@ -319,42 +311,30 @@ int main(int argc, char **argv) } printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - frame_parms = &eNB->frame_parms; - - txdata = eNB->common_vars.txdata[eNB_id]; - nsymb = (frame_parms->Ncp == 0) ? 14 : 12; - printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d\n",NUMBER_OF_OFDM_CARRIERS, frame_parms->Ncp,frame_parms->samples_per_tti,nsymb); - - - printf("[SIM] Using SCM/101\n"); UE2eNB = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, - N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), - N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), + N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), + N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), 0.0, 0, 0); - if (UE2eNB==NULL) { printf("Problem generating channel model. Exiting.\n"); exit(-1); } init_ncs_cell(&eNB->frame_parms,eNB->ncs_cell); - init_ncs_cell(&UE->frame_parms,UE->ncs_cell); - init_ul_hopping(&eNB->frame_parms); init_ul_hopping(&UE->frame_parms); - eNB->frame_parms.pucch_config_common.deltaPUCCH_Shift = 2; eNB->frame_parms.pucch_config_common.nRB_CQI = 4; eNB->frame_parms.pucch_config_common.nCS_AN = 6; @@ -362,40 +342,38 @@ int main(int argc, char **argv) UE->frame_parms.pucch_config_common.nRB_CQI = 4; UE->frame_parms.pucch_config_common.nCS_AN = 6; - - if( (pucch_format == pucch_format1) || (pucch_format == pucch_format1a) || (pucch_format == pucch_format1b) ){ + if( (pucch_format == pucch_format1) || (pucch_format == pucch_format1a) || (pucch_format == pucch_format1b) ) { pucch_payload = 0; generate_pucch1x(UE->common_vars.txdataF, - frame_parms, - UE->ncs_cell, - pucch_format, - &pucch_config_dedicated, - n1_pucch, - 0, //shortened_format, - &pucch_payload, - AMP, //amp, - subframe); //subframe - }else if( pucch_format == pucch_format3){ - for(i=0;i<pucch3_payload_size;i++) + frame_parms, + UE->ncs_cell, + pucch_format, + &pucch_config_dedicated, + n1_pucch, + 0, //shortened_format, + &pucch_payload, + AMP, //amp, + subframe); //subframe + } else if( pucch_format == pucch_format3) { + for(i=0; i<pucch3_payload_size; i++) pucch3_payload[i]=(uint8_t)(taus()&0x1); + generate_pucch3x(UE->common_vars.txdataF, - frame_parms, - UE->ncs_cell, - pucch_format, - &pucch_config_dedicated, - n3_pucch, - 0, //shortened_format, - pucch3_payload, - AMP, //amp, - subframe, //subframe - n_rnti); //rnti + frame_parms, + UE->ncs_cell, + pucch_format, + &pucch_config_dedicated, + n3_pucch, + 0, //shortened_format, + pucch3_payload, + AMP, //amp, + subframe, //subframe + n_rnti); //rnti } - LOG_M("txsigF0.m","txsF0", &UE->common_vars.txdataF[0][2*subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX*nsymb,1,1); + LOG_M("txsigF0.m","txsF0", &UE->common_vars.txdataF[0][2*subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX*nsymb,1,1); tx_lev = 0; - - for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { if (frame_parms->Ncp == 1) PHY_ofdm_mod(&UE->common_vars.txdataF[aa][2*subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX], // input, @@ -413,16 +391,12 @@ int main(int argc, char **argv) //apply_7_5_kHz(UE,UE->common_vars.txdata[aa],1+(subframe<<1)); apply_7_5_kHz(UE,&txdata[aa][eNB->frame_parms.samples_per_tti*subframe],0); apply_7_5_kHz(UE,&txdata[aa][eNB->frame_parms.samples_per_tti*subframe],1); - - } tx_lev += signal_energy(&txdata[aa][subframe*eNB->frame_parms.samples_per_tti], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); } - - LOG_M("txsig0.m","txs0", txdata[0], FRAME_LENGTH_COMPLEX_SAMPLES,1,1); //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); @@ -435,28 +409,19 @@ int main(int argc, char **argv) } } - - for (SNR=snr0; SNR<snr1; SNR+=.2) { - printf("n_frames %d SNR %f\n",n_frames,SNR); - n_errors = 0; pucch_tx = 0; pucch1_missed=0; pucch1_false=0; pucch3_false=0; - stat_no_sig = 0; stat_sig = 0; for (trial=0; trial<n_frames; trial++) { - - - multipath_channel(UE2eNB,s_re,s_im,r_re,r_im, eNB->frame_parms.samples_per_tti,0); - sigma2_dB = N0;//10*log10((double)tx_lev) - SNR; tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/(double)tx_lev); @@ -478,11 +443,11 @@ int main(int argc, char **argv) sig=1; } else { if (trial<(n_frames>>1)) { - //printf("no sig =>"); + //printf("no sig =>"); sig= 0; } else { sig=1; - //printf("sig =>"); + //printf("sig =>"); pucch_tx++; } } @@ -493,14 +458,11 @@ int main(int argc, char **argv) // fill measurement symbol (19) with noise for (i=0; i<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { - - ((short*) &eNB->common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &eNB->common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &eNB->common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &eNB->common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } - - for (i=0; i<2*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { if (n_trials==0) { @@ -508,14 +470,12 @@ int main(int argc, char **argv) // r_im[aa][i] += (pow(10.0,.05*interf1)*r_im1[aa][i] + pow(10.0,.05*interf2)*r_im2[aa][i]); } - if (sig==1) { - ((short*) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i] = (short) (((tx_gain*r_re[aa][i]) +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i+1] = (short) (((tx_gain*r_im[aa][i]) + (iqim*r_re[aa][i]*tx_gain) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i] = (short) (((tx_gain*r_re[aa][i]) +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i+1] = (short) (((tx_gain*r_im[aa][i]) + (iqim*r_re[aa][i]*tx_gain) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } else { - ((short*) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - + ((short *) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) &eNB->common_vars.rxdata[0][aa][subframe*frame_parms->samples_per_tti])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } } @@ -524,7 +484,6 @@ int main(int argc, char **argv) remove_7_5_kHz(eNB,1+(subframe<<1)); for (l=0; l<eNB->frame_parms.symbols_per_tti/2; l++) { - slot_fep_ul(&eNB->frame_parms, &eNB->common_vars, l, @@ -539,16 +498,13 @@ int main(int argc, char **argv) 0, 0 ); - - } - // if (sig == 1) // printf("*"); lte_eNB_I0_measurements(eNB, subframe, - 0, + 0, 1); eNB->measurements[0].n0_power_tot_dB = N0;//(int8_t)(sigma2_dB-10*log10(eNB->frame_parms.ofdm_symbol_size/(12*NB_RB))); stat = rx_pucch(eNB, @@ -580,9 +536,9 @@ int main(int argc, char **argv) }*/ } else if( (pucch_format==pucch_format1a) || (pucch_format==pucch_format1b) ) { pucch1_false = (pucch_payload_rx != pucch_payload) ? (pucch1_false+1) : pucch1_false; - } else if (pucch_format==pucch_format3){ - for(i=0;i<pucch3_payload_size;i++){ - if(pucch3_payload[i]!=pucch3_payload_rx[i]){ + } else if (pucch_format==pucch_format3) { + for(i=0; i<pucch3_payload_size; i++) { + if(pucch3_payload[i]!=pucch3_payload_rx[i]) { pucch3_false = (pucch3_false+1); break; } @@ -611,11 +567,8 @@ int main(int argc, char **argv) LOG_M("rxsigF0.m","rxsF0", &eNB->common_vars.rxdataF[0][0][0],512*nsymb*2,2,1); } - lte_sync_time_free(); - return(n_errors); - } diff --git a/openair1/SIMULATION/LTE_PHY/scansim.c b/openair1/SIMULATION/LTE_PHY/scansim.c index cb419f57c248a5f7011a126639d831b118104a0b..5ceeee7f2f5d5d16575183e05cb2d5185186ed1e 100644 --- a/openair1/SIMULATION/LTE_PHY/scansim.c +++ b/openair1/SIMULATION/LTE_PHY/scansim.c @@ -38,7 +38,7 @@ #include "LAYER2/MAC/vars.h" #ifdef XFORMS -#include "PHY/TOOLS/lte_phy_scope.h" + #include "PHY/TOOLS/lte_phy_scope.h" #endif #include "OCG_vars.h" @@ -58,11 +58,8 @@ mod_sym_t dummy2[2048*14]; mod_sym_t dummy3[2048*14]; -int main(int argc, char **argv) -{ - +int main(int argc, char **argv) { char c; - int i,l,aa; double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1; uint8_t snr1set=0; @@ -82,226 +79,192 @@ int main(int argc, char **argv) int trial, n_trials, ntrials=1, n_errors,n_errors2,n_alamouti; uint8_t transmission_mode = 1,n_tx=1,n_rx=1; uint16_t Nid_cell=0; - int n_frames=1; channel_desc_t *eNB2UE,*eNB2UE1,*eNB2UE2; uint32_t nsymb,tx_lev,tx_lev1,tx_lev2; uint8_t extended_prefix_flag=0; LTE_DL_FRAME_PARMS *frame_parms; - FILE *input_fd=NULL,*pbch_file_fd=NULL; char input_val_str[50],input_val_str2[50]; // double input_val1,input_val2; // uint16_t amask=0; uint8_t frame_mod4,num_pdcch_symbols; uint16_t NB_RB=25; - SCM_t channel_model=AWGN;//Rayleigh1_anticorr; - DCI_ALLOC_t dci_alloc[8]; uint8_t abstraction_flag=0;//,calibration_flag=0; int pbch_tx_ant; uint8_t N_RB_DL=100,osf=1; - unsigned char frame_type = FDD; unsigned char pbch_phase = 0; - #ifdef XFORMS FD_lte_phy_scope_ue *form_ue; char title[255]; #endif - logInit(); number_of_cards = 1; openair_daq_vars.rx_rf_mode = 1; - /* - rxdataF = (int **)malloc16(2*sizeof(int*)); - rxdataF[0] = (int *)malloc16(FRAME_LENGTH_BYTES); - rxdataF[1] = (int *)malloc16(FRAME_LENGTH_BYTES); - - rxdata = (int **)malloc16(2*sizeof(int*)); - rxdata[0] = (int *)malloc16(FRAME_LENGTH_BYTES); - rxdata[1] = (int *)malloc16(FRAME_LENGTH_BYTES); - */ while ((c = getopt (argc, argv, "f:hpf:g:n:s:S:t:x:y:z:N:F:GdP:")) != -1) { switch (c) { - case 'f': - write_output_file=1; - output_fd = fopen(optarg,"w"); - - if (output_fd==NULL) { - printf("Error opening %s\n",optarg); - exit(-1); - } + case 'f': + write_output_file=1; + output_fd = fopen(optarg,"w"); - break; - - case 'd': - frame_type = TDD; - break; + if (output_fd==NULL) { + printf("Error opening %s\n",optarg); + exit(-1); + } - case 'g': - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; break; - case 'B': - channel_model=SCM_B; + case 'd': + frame_type = TDD; break; - case 'C': - channel_model=SCM_C; - break; + case 'g': + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; - case 'D': - channel_model=SCM_D; - break; + case 'B': + channel_model=SCM_B; + break; - case 'E': - channel_model=EPA; - break; + case 'C': + channel_model=SCM_C; + break; + + case 'D': + channel_model=SCM_D; + break; + + case 'E': + channel_model=EPA; + break; + + case 'F': + channel_model=EVA; + break; + + case 'G': + channel_model=ETU; + break; + + default: + msg("Unsupported channel model!\n"); + exit(-1); + } - case 'F': - channel_model=EVA; break; - case 'G': - channel_model=ETU; + case 'n': + n_frames = atoi(optarg); break; - default: - msg("Unsupported channel model!\n"); - exit(-1); - } + case 's': + snr0 = atof(optarg); + msg("Setting SNR0 to %f\n",snr0); + break; - break; + case 'S': + snr1 = atof(optarg); + snr1set=1; + msg("Setting SNR1 to %f\n",snr1); + break; - case 'n': - n_frames = atoi(optarg); - break; + case 'p': + extended_prefix_flag=1; + break; - case 's': - snr0 = atof(optarg); - msg("Setting SNR0 to %f\n",snr0); - break; + case 'x': + transmission_mode=atoi(optarg); - case 'S': - snr1 = atof(optarg); - snr1set=1; - msg("Setting SNR1 to %f\n",snr1); - break; + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=6)) { + msg("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } - /* - case 't': - Td= atof(optarg); break; - */ - case 'p': - extended_prefix_flag=1; - 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); + case 'y': + n_tx=atoi(optarg); + + if ((n_tx==0) || (n_tx>2)) { + msg("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); } - break; - */ - case 'x': - transmission_mode=atoi(optarg); - - if ((transmission_mode!=1) && - (transmission_mode!=2) && - (transmission_mode!=6)) { - msg("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } - break; + break; - case 'y': - n_tx=atoi(optarg); + case 'z': + n_rx=atoi(optarg); - if ((n_tx==0) || (n_tx>2)) { - msg("Unsupported number of tx antennas %d\n",n_tx); - exit(-1); - } + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } - break; + break; - case 'z': - n_rx=atoi(optarg); + case 'A': + abstraction_flag=1; + ntrials=10000; + msg("Running Abstraction test\n"); + pbch_file_fd=fopen(optarg,"r"); + + if (pbch_file_fd==NULL) { + printf("Problem with filename %s\n",optarg); + exit(-1); + } - if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); - exit(-1); - } + break; - break; + case 'N': + Nid_cell = atoi(optarg); + break; - case 'A': - abstraction_flag=1; - ntrials=10000; - msg("Running Abstraction test\n"); - pbch_file_fd=fopen(optarg,"r"); + case 'F': + input_fd = fopen(optarg,"r"); - if (pbch_file_fd==NULL) { - printf("Problem with filename %s\n",optarg); - exit(-1); - } + if (input_fd==NULL) { + printf("Problem with filename %s\n",optarg); + exit(-1); + } - break; + break; - // case 'C': - // calibration_flag=1; - // msg("Running Abstraction calibration for Bias removal\n"); - // break; - case 'N': - Nid_cell = atoi(optarg); - break; + case 'P': + pbch_phase = atoi(optarg); - case 'F': - input_fd = fopen(optarg,"r"); + if (pbch_phase>3) + printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); - if (input_fd==NULL) { - printf("Problem with filename %s\n",optarg); - exit(-1); - } + break; - break; - - case 'P': - pbch_phase = atoi(optarg); - - if (pbch_phase>3) - printf("Illegal PBCH phase (0-3) got %d\n",pbch_phase); - - break; - - default: - case 'h': - printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -N CellId\n", - argv[0]); - printf("-h This message\n"); - printf("-p Use extended prefix mode\n"); - printf("-d Use TDD\n"); - printf("-n Number of frames to simulate\n"); - printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); - printf("-S Ending SNR, runs from SNR0 to SNR1\n"); - printf("-t Delay spread for multipath channel\n"); - printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); - printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-N Nid_cell\n"); - printf("-f Output filename (.txt format) for Pe/SNR results\n"); - printf("-F Input filename (.txt format) for RX conformance testing\n"); - exit (-1); - break; + default: + case 'h': + printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -N CellId\n", + argv[0]); + printf("-h This message\n"); + printf("-p Use extended prefix mode\n"); + printf("-d Use TDD\n"); + printf("-n Number of frames to simulate\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-t Delay spread for multipath channel\n"); + printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-N Nid_cell\n"); + printf("-f Output filename (.txt format) for Pe/SNR results\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + exit (-1); + break; } } @@ -309,16 +272,15 @@ int main(int argc, char **argv) n_tx=2; lte_param_init(n_tx, - n_rx, - transmission_mode, - extended_prefix_flag, - frame_type, - Nid_cell, - 3, - N_RB_DL, - osf, - 0); - + n_rx, + transmission_mode, + extended_prefix_flag, + frame_type, + Nid_cell, + 3, + N_RB_DL, + osf, + 0); #ifdef XFORMS fl_initialize (&argc, argv, NULL, 0, 0); form_ue = create_lte_phy_scope_ue(); @@ -334,38 +296,27 @@ int main(int argc, char **argv) } printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - frame_parms = &PHY_vars_eNB->lte_frame_parms; - - - txdata = PHY_vars_eNB->lte_eNB_common_vars.txdata[0]; txdata1 = PHY_vars_eNB1->lte_eNB_common_vars.txdata[0]; txdata2 = PHY_vars_eNB2->lte_eNB_common_vars.txdata[0]; - - - s_re = malloc(2*sizeof(double*)); - s_im = malloc(2*sizeof(double*)); - s_re1 = malloc(2*sizeof(double*)); - s_im1 = malloc(2*sizeof(double*)); - s_re2 = malloc(2*sizeof(double*)); - s_im2 = malloc(2*sizeof(double*)); - r_re = malloc(2*sizeof(double*)); - r_im = malloc(2*sizeof(double*)); - r_re1 = malloc(2*sizeof(double*)); - r_im1 = malloc(2*sizeof(double*)); - r_re2 = malloc(2*sizeof(double*)); - r_im2 = malloc(2*sizeof(double*)); - + s_re = malloc(2*sizeof(double *)); + s_im = malloc(2*sizeof(double *)); + s_re1 = malloc(2*sizeof(double *)); + s_im1 = malloc(2*sizeof(double *)); + s_re2 = malloc(2*sizeof(double *)); + s_im2 = malloc(2*sizeof(double *)); + r_re = malloc(2*sizeof(double *)); + r_im = malloc(2*sizeof(double *)); + r_re1 = malloc(2*sizeof(double *)); + r_im1 = malloc(2*sizeof(double *)); + r_re2 = malloc(2*sizeof(double *)); + r_im2 = malloc(2*sizeof(double *)); nsymb = (frame_parms->Ncp == 0) ? 14 : 12; - printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d\n",NUMBER_OF_OFDM_CARRIERS, frame_parms->Ncp,frame_parms->samples_per_tti,nsymb); - printf("PHY_vars_eNB1->lte_eNB_common_vars.txdataF[0][0] = %p\n", PHY_vars_eNB1->lte_eNB_common_vars.txdataF[0][0]); - - DLSCH_alloc_pdu2.rah = 0; DLSCH_alloc_pdu2.rballoc = DLSCH_RB_ALLOC; DLSCH_alloc_pdu2.TPC = 0; @@ -377,16 +328,14 @@ int main(int argc, char **argv) DLSCH_alloc_pdu2.rv1 = 0; // Forget second codeword DLSCH_alloc_pdu2.tpmi = (transmission_mode==6 ? 5 : 0) ; // precoding - eNB2UE = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, - PHY_vars_UE->lte_frame_parms.nb_antennas_rx, - channel_model, - N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), - N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), - 0, - 0, - 0); - + PHY_vars_UE->lte_frame_parms.nb_antennas_rx, + channel_model, + N_RB2sampling_rate(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL), + 0, + 0, + 0); if (eNB2UE==NULL) { msg("Problem generating channel model. Exiting.\n"); @@ -394,7 +343,6 @@ int main(int argc, char **argv) } for (i=0; i<2; i++) { - s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(s_re[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); @@ -407,7 +355,6 @@ int main(int argc, char **argv) bzero(s_re2[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); s_im2[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(s_im2[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); - r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(r_re[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); @@ -450,9 +397,7 @@ int main(int argc, char **argv) (PHY_vars_eNB->lte_frame_parms.Ncp==0) ? 5 : 4, 10); */ - } else { - generate_sss(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, &PHY_vars_eNB->lte_frame_parms, @@ -473,11 +418,8 @@ int main(int argc, char **argv) &PHY_vars_eNB->lte_frame_parms, 2, 12); - - } - /* generate_pilots(PHY_vars_eNB, PHY_vars_eNB->lte_eNB_common_vars.txdataF[0], @@ -494,7 +436,6 @@ int main(int argc, char **argv) PHY_vars_eNB->lte_eNB_common_vars.txdataF[0], 0); */ - /* if (num_pdcch_symbols<3) { printf("Less than 3 pdcch symbols\n"); @@ -530,9 +471,6 @@ int main(int argc, char **argv) tx_lev1 = 0; tx_lev2 = 0; - - - for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) { if (frame_parms->Ncp == 1) PHY_ofdm_mod(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0][aa], // input, @@ -552,7 +490,6 @@ int main(int argc, char **argv) OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); } - LOG_M("txsig0.m","txs0", txdata[0],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); if (frame_parms->nb_antennas_tx>1) @@ -567,19 +504,14 @@ int main(int argc, char **argv) } } - for (SNR=snr0; SNR<snr1; SNR+=.2) { - - n_errors = 0; n_errors2 = 0; n_alamouti = 0; for (trial=0; trial<n_frames; trial++) { - multipath_channel(eNB2UE,s_re,s_im,r_re,r_im, 2*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES,0); - sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(double)(12*NB_RB)) - SNR; if (n_frames==1) @@ -603,8 +535,8 @@ int main(int argc, char **argv) //printf("n_trial %d\n",n_trials); for (i=0; i<2*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_rx; aa++) { - ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[2*i] = (short) ((r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) PHY_vars_UE->lte_ue_common_vars.rxdata[aa])[2*i+1] = (short) ((r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } @@ -614,8 +546,6 @@ int main(int argc, char **argv) printf("rx_level data symbol %f\n", 10*log10(signal_energy(&PHY_vars_UE->lte_ue_common_vars.rxdata[0][frame_parms->samples_per_tti/2],4*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES))); } - - } //noise trials } // trials @@ -629,30 +559,65 @@ int main(int argc, char **argv) } // NSR if (n_frames==1) { - } - for (i=0; i<2; i++) { free(s_re[i]); free(s_im[i]); + + if (s_im1) + free(s_im1[i]); + + if (s_im2) + free(s_im2[i]); + free(r_re[i]); + + if (r_re1) + free(r_re1[i]); + + if (r_re2) + free(r_re2[i]); + free(r_im[i]); + + if (s_re1) + free(s_re1[i]); + + if (s_re2) + free(s_re2[i]); + + if (r_im1) + free(r_im1[i]); + + if (r_im2) + free(r_im2[i]); } free(s_re); + free(s_re1); + free(s_re2); free(s_im); + free(s_im1); + free(s_im2); free(r_re); + free(r_re1); + free(r_re2); free(r_im); - - + free(r_im1); + free(r_im2); lte_sync_time_free(); if (write_output_file) fclose(output_fd); - return(n_errors); + if (input_fd) + fclose(input_fd); + + if (pbch_file_fd) + fclose(pbch_file_fd); + return(n_errors); } diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index 59116bc5e176ebf4565fd1bde7f2ff27148ba56b..2c0385efbfdcaa3c6de6ceceaef45e36d8b3728e 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -37,7 +37,7 @@ #include "PHY/vars.h" #include "MAC_INTERFACE/vars.h" #ifdef IFFT_FPGA -#include "PHY/LTE_REFSIG/mod_table.h" + #include "PHY/LTE_REFSIG/mod_table.h" #endif #include "SCHED/defs.h" #include "SCHED/vars.h" @@ -47,8 +47,8 @@ #include "LAYER2/MAC/vars.h" #ifdef XFORMS -#include <forms.h> -#include "../../USERSPACE_TOOLS/SCOPE/lte_scope.h" + #include <forms.h> + #include "../../USERSPACE_TOOLS/SCOPE/lte_scope.h" #endif //XFORMS @@ -77,11 +77,8 @@ void do_forms2(FD_lte_scope *form, int16_t *dlsch_llr, int16_t *pbch_comp, int8_t *pbch_llr, - int coded_bits_per_codeword) -{ - + int coded_bits_per_codeword) { int i,j,k,s; - float Re,Im; float mag_sig[NB_ANTENNAS_RX*4*NUMBER_OF_OFDM_CARRIERS*NUMBER_OF_OFDM_SYMBOLS_PER_SLOT], sig_time[NB_ANTENNAS_RX*4*NUMBER_OF_OFDM_CARRIERS*NUMBER_OF_OFDM_SYMBOLS_PER_SLOT], @@ -91,15 +88,11 @@ void do_forms2(FD_lte_scope *form, *llr,*llr_time; int ind; float avg, cum_avg; - - extern int* sync_corr_ue0; - + extern int *sync_corr_ue0; // uint16_t nsymb = (frame_parms->Ncp == 0) ? 14 : 12; - llr = malloc(max(coded_bits_per_codeword,1920)*sizeof(float)); llr_time = malloc(max(coded_bits_per_codeword,1920)*sizeof(float)); - // Channel frequency response if (channel_f[0] != NULL) { cum_avg = 0; @@ -122,7 +115,6 @@ void do_forms2(FD_lte_scope *form, } avg = cum_avg/NUMBER_OF_USEFUL_CARRIERS; - //fl_set_xyplot_ybounds(form->channel_f,30,70); fl_set_xyplot_data(form->channel_f,sig_time,mag_sig,ind,"","",""); } @@ -196,7 +188,6 @@ void do_forms2(FD_lte_scope *form, //fl_set_xyplot_ybounds(form->scatter_plot,-100,100); } - // PDCCH I/Q j=0; @@ -210,7 +201,6 @@ void do_forms2(FD_lte_scope *form, //fl_set_xyplot_xbounds(form->scatter_plot,-100,100); //fl_set_xyplot_ybounds(form->scatter_plot,-100,100); - // DLSCH LLR if (dlsch_llr != NULL) { for(i=0; i<coded_bits_per_codeword; i++) { @@ -246,35 +236,25 @@ void do_forms2(FD_lte_scope *form, //fl_set_xyplot_ybounds(form->scatter_plot,-2000,2000); } - free(llr); free(llr_time); - } #endif -void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmission_mode,unsigned char extended_prefix_flag,uint8_t frame_type,uint16_t Nid_cell,uint8_t N_RB_DL,uint8_t osf) -{ - +void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmission_mode,unsigned char extended_prefix_flag,uint8_t frame_type,uint16_t Nid_cell,uint8_t N_RB_DL,uint8_t osf) { LTE_DL_FRAME_PARMS *lte_frame_parms; int i; - printf("Start lte_param_init, frame_type %d, extended_prefix %d\n",frame_type,extended_prefix_flag); PHY_vars_eNB = malloc(sizeof(PHY_VARS_eNB)); PHY_vars_eNB1 = malloc(sizeof(PHY_VARS_eNB)); PHY_vars_eNB2 = malloc(sizeof(PHY_VARS_eNB)); - PHY_vars_UE[0] = malloc(sizeof(PHY_VARS_UE)); PHY_vars_UE[1] = malloc(sizeof(PHY_VARS_UE)); //PHY_config = malloc(sizeof(PHY_CONFIG)); mac_xface = malloc(sizeof(MAC_xface)); - randominit(0); 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 lte_frame_parms->N_RB_UL = N_RB_DL; lte_frame_parms->Ncp = extended_prefix_flag; @@ -292,63 +272,42 @@ void lte_param_init(unsigned char N_tx, unsigned char N_rx,unsigned char transmi lte_frame_parms->frame_type = frame_type; lte_frame_parms->node_id = 2; init_frame_parms(lte_frame_parms,osf); - - - - phy_init_top(lte_frame_parms); //allocation - lte_frame_parms->twiddle_fft = twiddle_fft; lte_frame_parms->twiddle_ifft = twiddle_ifft; lte_frame_parms->rev = rev; - phy_init_lte_top(lte_frame_parms); - - memcpy((void*)&PHY_vars_UE[0]->lte_frame_parms,(void*)&PHY_vars_eNB->lte_frame_parms,sizeof(LTE_DL_FRAME_PARMS)); - memcpy((void*)&PHY_vars_UE[1]->lte_frame_parms,(void*)&PHY_vars_eNB->lte_frame_parms,sizeof(LTE_DL_FRAME_PARMS)); - + memcpy((void *)&PHY_vars_UE[0]->lte_frame_parms,(void *)&PHY_vars_eNB->lte_frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + memcpy((void *)&PHY_vars_UE[1]->lte_frame_parms,(void *)&PHY_vars_eNB->lte_frame_parms,sizeof(LTE_DL_FRAME_PARMS)); phy_init_lte_ue(PHY_vars_UE[0],1,0); for (i=0; i<3; i++) lte_gold(lte_frame_parms,PHY_vars_UE[0]->lte_gold_table[i],i); PHY_vars_UE[0]->Mod_id = 0; - phy_init_lte_ue(PHY_vars_UE[1],1,0); for (i=0; i<3; i++) lte_gold(lte_frame_parms,PHY_vars_UE[1]->lte_gold_table[i],i); PHY_vars_UE[1]->Mod_id = 1; - phy_init_lte_eNB(PHY_vars_eNB,0,0,0); - - memcpy((void*)&PHY_vars_eNB1->lte_frame_parms,(void*)&PHY_vars_eNB->lte_frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + memcpy((void *)&PHY_vars_eNB1->lte_frame_parms,(void *)&PHY_vars_eNB->lte_frame_parms,sizeof(LTE_DL_FRAME_PARMS)); PHY_vars_eNB1->lte_frame_parms.nushift=1; PHY_vars_eNB1->lte_frame_parms.Nid_cell=2; - - memcpy((void*)&PHY_vars_eNB2->lte_frame_parms,(void*)&PHY_vars_eNB->lte_frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + memcpy((void *)&PHY_vars_eNB2->lte_frame_parms,(void *)&PHY_vars_eNB->lte_frame_parms,sizeof(LTE_DL_FRAME_PARMS)); PHY_vars_eNB2->lte_frame_parms.nushift=2; PHY_vars_eNB2->lte_frame_parms.Nid_cell=3; - phy_init_lte_eNB(PHY_vars_eNB1,0,0,0); - phy_init_lte_eNB(PHY_vars_eNB2,0,0,0); - phy_init_lte_top(lte_frame_parms); - printf("Done lte_param_init\n"); - - } -int main(int argc, char **argv) -{ - +int main(int argc, char **argv) { char c; - int i,iout,l,aa,aarx; double sigma2, sigma2_dB=0,SNR,snr0=10.0,snr1=11.0; uint8_t snr1set=0; @@ -373,26 +332,19 @@ int main(int argc, char **argv) uint8_t extended_prefix_flag=0,frame_type=1; int8_t interf1=-21,interf2=-21; LTE_DL_FRAME_PARMS *frame_parms; - FILE *input_fd=NULL,*pbch_file_fd=NULL; char input_val_str[50],input_val_str2[50]; uint8_t num_pdcch_symbols=1; uint16_t NB_RB=25; - SCM_t channel_model=Rayleigh8; - uint8_t abstraction_flag=0; double pbch_sinr; uint8_t N_RB_DL=25,osf=1; - int openair_fd=(int)0; int tcxo=74,fc=0; unsigned char temp[4]; - int oai_hw_input=0; int oai_hw_output=0; - - DCI_ALLOC_t dci_alloc[8],dci_alloc_rx[8]; uint16_t n_rnti=1234,dci_cnt; unsigned int coded_bits_per_codeword; @@ -406,21 +358,16 @@ int main(int argc, char **argv) uint32_t rxgain[4]= {30,30,30,30}; uint32_t do_forms=0; int ret; - #ifdef XFORMS FD_lte_scope *form_dl=NULL; FD_lte_scope *form_dl1=NULL; char title[255]; #endif - int UE_idx,N_carriers=1,subframe=2; int dual_stream_flag=0; unsigned char i_mod = 2; - int rx_offset_mod; - logInit(); - number_of_cards = 1; openair_daq_vars.rx_rf_mode = 1; @@ -435,141 +382,141 @@ int main(int argc, char **argv) */ while ((c = getopt (argc, argv, "aehc:f:g:i:j:n:r:s:t:x:y:z:A:F:N:O:R:S:ZYDT:C:G:dB:U:u")) != -1) { switch (c) { - case 'a': - printf("Running AWGN simulation\n"); - awgn_flag = 1; - break; - - case 'f': - output_fd = fopen(optarg,"w"); - write_output_file=1; - break; - - case 'g': - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; + case 'a': + printf("Running AWGN simulation\n"); + awgn_flag = 1; break; - case 'B': - channel_model=SCM_B; + case 'f': + output_fd = fopen(optarg,"w"); + write_output_file=1; break; - case 'C': - channel_model=SCM_C; - break; + case 'g': + switch((char)*optarg) { + case 'A': + channel_model=SCM_A; + break; - case 'D': - channel_model=SCM_D; - break; + case 'B': + channel_model=SCM_B; + break; - case 'E': - channel_model=EPA; - break; + case 'C': + channel_model=SCM_C; + break; - case 'F': - channel_model=EVA; - break; + case 'D': + channel_model=SCM_D; + break; - case 'G': - channel_model=ETU; - break; + case 'E': + channel_model=EPA; + break; - default: - msg("Unsupported channel model!\n"); - exit(-1); - } + case 'F': + channel_model=EVA; + break; - break; + case 'G': + channel_model=ETU; + break; - case 'C': - sscanf(optarg,"%d,%d,%d,%d",&carrier_freq[0],&carrier_freq[1],&carrier_freq[2],&carrier_freq[3]); - printf("Configuring for frequencies %d,%d,%d,%d\n",carrier_freq[0],carrier_freq[1],carrier_freq[2],carrier_freq[3]); - //carrier_freq = atoi(optarg); - break; + default: + msg("Unsupported channel model!\n"); + exit(-1); + } - case 'G': - sscanf(optarg,"%d,%d,%d,%d",&rxgain[0],&rxgain[1],&rxgain[2],&rxgain[3]); - printf("Configuring for gains %d,%d,%d,%d\n",rxgain[0],rxgain[1],rxgain[2],rxgain[3]); - //rxgain = atoi(optarg); - break; + break; - case 'i': - interf1=atoi(optarg); - break; + case 'C': + sscanf(optarg,"%d,%d,%d,%d",&carrier_freq[0],&carrier_freq[1],&carrier_freq[2],&carrier_freq[3]); + printf("Configuring for frequencies %d,%d,%d,%d\n",carrier_freq[0],carrier_freq[1],carrier_freq[2],carrier_freq[3]); + //carrier_freq = atoi(optarg); + break; - case 'c': - deltaF=atof(optarg); - break; + case 'G': + sscanf(optarg,"%d,%d,%d,%d",&rxgain[0],&rxgain[1],&rxgain[2],&rxgain[3]); + printf("Configuring for gains %d,%d,%d,%d\n",rxgain[0],rxgain[1],rxgain[2],rxgain[3]); + //rxgain = atoi(optarg); + break; - case 'j': - interf2=atoi(optarg); - break; + case 'i': + interf1=atoi(optarg); + break; - case 'n': - n_frames = atoi(optarg); - break; + case 'c': + deltaF=atof(optarg); + break; - case 's': - snr0 = atof(optarg); - msg("Setting SNR0 to %f\n",snr0); - break; + case 'j': + interf2=atoi(optarg); + break; - case 'S': - snr1 = atof(optarg); - snr1set=1; - msg("Setting SNR1 to %f\n",snr1); - break; + case 'n': + n_frames = atoi(optarg); + break; + + case 's': + snr0 = atof(optarg); + msg("Setting SNR0 to %f\n",snr0); + break; + + case 'S': + snr1 = atof(optarg); + snr1set=1; + msg("Setting SNR1 to %f\n",snr1); + break; /* case 't': Td= atof(optarg); break; */ - case 'e': - extended_prefix_flag=1; - break; + case 'e': + extended_prefix_flag=1; + break; - case 'd': - do_forms=1; - break; + case 'd': + do_forms=1; + break; - case 'r': - n_rnti=atoi(optarg); - break; + case 'r': + n_rnti=atoi(optarg); + break; - case 'x': - transmission_mode=atoi(optarg); + case 'x': + transmission_mode=atoi(optarg); - if ((transmission_mode!=1) && - (transmission_mode!=2) && - (transmission_mode!=5) && - (transmission_mode!=6)) { - msg("Unsupported transmission mode %d\n",transmission_mode); - exit(-1); - } + if ((transmission_mode!=1) && + (transmission_mode!=2) && + (transmission_mode!=5) && + (transmission_mode!=6)) { + msg("Unsupported transmission mode %d\n",transmission_mode); + exit(-1); + } - break; + break; - case 'y': - n_tx=atoi(optarg); + case 'y': + n_tx=atoi(optarg); - if ((n_tx==0) || (n_tx>2)) { - msg("Unsupported number of tx antennas %d\n",n_tx); - exit(-1); - } + if ((n_tx==0) || (n_tx>2)) { + msg("Unsupported number of tx antennas %d\n",n_tx); + exit(-1); + } - break; + break; - case 'z': - n_rx=atoi(optarg); + case 'z': + n_rx=atoi(optarg); - if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); - exit(-1); - } + if ((n_rx==0) || (n_rx>2)) { + msg("Unsupported number of rx antennas %d\n",n_rx); + exit(-1); + } - break; + break; /* case 'A': @@ -583,96 +530,96 @@ int main(int argc, char **argv) } break; */ - case 'D': - frame_type=0; - msg("Running in FDD\n"); - break; + case 'D': + frame_type=0; + msg("Running in FDD\n"); + break; - case 'N': - Nid_cell = atoi(optarg); - break; + case 'N': + Nid_cell = atoi(optarg); + break; - case 'R': - N_RB_DL = atoi(optarg); - break; + case 'R': + N_RB_DL = atoi(optarg); + break; - case 'O': - osf = atoi(optarg); - break; + case 'O': + osf = atoi(optarg); + break; - case 'Z': - oai_hw_input = 1; - break; + case 'Z': + oai_hw_input = 1; + break; - case 'Y': - oai_hw_output = 1; - break; + case 'Y': + oai_hw_output = 1; + break; - case 'F': - input_fd = fopen(optarg,"r"); + case 'F': + input_fd = fopen(optarg,"r"); - if (input_fd==NULL) { - printf("Problem with filename %s\n",optarg); - exit(-1); - } + if (input_fd==NULL) { + printf("Problem with filename %s\n",optarg); + exit(-1); + } - break; + break; - case 'T': - tcxo = atoi(optarg); - break; + case 'T': + tcxo = atoi(optarg); + break; - case 'B': - N_carriers = atoi(optarg); + case 'B': + N_carriers = atoi(optarg); - if ((N_carriers!=1) && (N_carriers!=2)) { - printf("N_carriers must be 1 or 2!\n"); - exit(-1); - } + if ((N_carriers!=1) && (N_carriers!=2)) { + printf("N_carriers must be 1 or 2!\n"); + exit(-1); + } - break; + break; - case 'U': - subframe = atoi(optarg); - break; + case 'U': + subframe = atoi(optarg); + break; - case 'u': - dual_stream_flag=1; - break; + case 'u': + dual_stream_flag=1; + break; - default: - case 'h': - printf("-h This message\n"); - printf("-a Use AWGN channel and not multipath\n"); - printf("-e Use extended prefix mode\n"); - printf("-d Display signal output on XFORMS scope\n"); - printf("-D Use FDD frame\n"); - printf("-n Number of frames to simulate\n"); - printf("-r RNTI for DCI detection in SF 0/5\n"); - printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); - printf("-S Ending SNR, runs from SNR0 to SNR1\n"); - printf("-t Delay spread for multipath channel\n"); - printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); - printf("-c Frequency offset\n"); - printf("-x Transmission mode (1,2,6 for the moment)\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); - printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); - printf("-N Nid_cell\n"); - printf("-R N_RB_DL\n"); - printf("-O oversampling factor (1,2,4,8,16)\n"); - //printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); - printf("-f Output filename (.txt format) for Pe/SNR results\n"); - printf("-F Input filename (.txt format) for RX conformance testing\n"); - printf("-Y just generate tx frame and send it to hardware\n"); - printf("-Z grab frame from hardware and do rx processing\n"); - printf("-T set TCXO parameter on CBMIMO1 hardware\n"); - printf("-C set frequency for ExpressMIMO hardware. Can take up to four parameters in format f1,f2,f3,f4\n"); - printf("-G set RX gain for ExpressMIMO hardware. Can take up to four parameters in format g1,g2,g3,g4\n"); - printf("-d enables the graphical display"); - exit (-1); - break; + default: + case 'h': + printf("-h This message\n"); + printf("-a Use AWGN channel and not multipath\n"); + printf("-e Use extended prefix mode\n"); + printf("-d Display signal output on XFORMS scope\n"); + printf("-D Use FDD frame\n"); + printf("-n Number of frames to simulate\n"); + printf("-r RNTI for DCI detection in SF 0/5\n"); + printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); + printf("-S Ending SNR, runs from SNR0 to SNR1\n"); + printf("-t Delay spread for multipath channel\n"); + printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-c Frequency offset\n"); + printf("-x Transmission mode (1,2,6 for the moment)\n"); + printf("-y Number of TX antennas used in eNB\n"); + printf("-z Number of RX antennas used in UE\n"); + printf("-i Relative strength of first intefering eNB (in dB) - cell_id mod 3 = 1\n"); + printf("-j Relative strength of second intefering eNB (in dB) - cell_id mod 3 = 2\n"); + printf("-N Nid_cell\n"); + printf("-R N_RB_DL\n"); + printf("-O oversampling factor (1,2,4,8,16)\n"); + //printf("-A Interpolation_filname Run with Abstraction to generate Scatter plot using interpolation polynomial in file\n"); + printf("-f Output filename (.txt format) for Pe/SNR results\n"); + printf("-F Input filename (.txt format) for RX conformance testing\n"); + printf("-Y just generate tx frame and send it to hardware\n"); + printf("-Z grab frame from hardware and do rx processing\n"); + printf("-T set TCXO parameter on CBMIMO1 hardware\n"); + printf("-C set frequency for ExpressMIMO hardware. Can take up to four parameters in format f1,f2,f3,f4\n"); + printf("-G set RX gain for ExpressMIMO hardware. Can take up to four parameters in format g1,g2,g3,g4\n"); + printf("-d enables the graphical display"); + exit (-1); + break; } } @@ -707,7 +654,6 @@ int main(int argc, char **argv) } printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - frame_parms = &PHY_vars_eNB->lte_frame_parms; frame_parms->dual_tx = 0; frame_parms->freq_idx = 0; @@ -738,22 +684,18 @@ int main(int argc, char **argv) if ((oai_hw_input==1) || (oai_hw_output==1)) { msg("setting TCXO to %d\n",tcxo); - ioctl(openair_fd,openair_SET_TCXO_DAC,(void *)&tcxo); } #ifdef IFFT_FPGA - txdata = (int **)malloc16(2*sizeof(int*)); + txdata = (int **)malloc16(2*sizeof(int *)); txdata[0] = (int *)malloc16(FRAME_LENGTH_BYTES); txdata[1] = (int *)malloc16(FRAME_LENGTH_BYTES); - bzero(txdata[0],FRAME_LENGTH_BYTES); bzero(txdata[1],FRAME_LENGTH_BYTES); - - txdataF2 = (int **)malloc16(2*sizeof(int*)); + txdataF2 = (int **)malloc16(2*sizeof(int *)); txdataF2[0] = (int *)malloc16(FRAME_LENGTH_BYTES_NO_PREFIX); txdataF2[1] = (int *)malloc16(FRAME_LENGTH_BYTES_NO_PREFIX); - bzero(txdataF2[0],FRAME_LENGTH_BYTES_NO_PREFIX); bzero(txdataF2[1],FRAME_LENGTH_BYTES_NO_PREFIX); #else @@ -761,26 +703,21 @@ int main(int argc, char **argv) txdata1 = PHY_vars_eNB1->lte_eNB_common_vars.txdata[eNb_id]; txdata2 = PHY_vars_eNB2->lte_eNB_common_vars.txdata[eNb_id]; #endif - - s_re = malloc(2*sizeof(double*)); - s_im = malloc(2*sizeof(double*)); - s_re1 = malloc(2*sizeof(double*)); - s_im1 = malloc(2*sizeof(double*)); - s_re2 = malloc(2*sizeof(double*)); - s_im2 = malloc(2*sizeof(double*)); - r_re = malloc(2*sizeof(double*)); - r_im = malloc(2*sizeof(double*)); - r_re1 = malloc(2*sizeof(double*)); - r_im1 = malloc(2*sizeof(double*)); - r_re2 = malloc(2*sizeof(double*)); - r_im2 = malloc(2*sizeof(double*)); - + s_re = malloc(2*sizeof(double *)); + s_im = malloc(2*sizeof(double *)); + s_re1 = malloc(2*sizeof(double *)); + s_im1 = malloc(2*sizeof(double *)); + s_re2 = malloc(2*sizeof(double *)); + s_im2 = malloc(2*sizeof(double *)); + r_re = malloc(2*sizeof(double *)); + r_im = malloc(2*sizeof(double *)); + r_re1 = malloc(2*sizeof(double *)); + r_im1 = malloc(2*sizeof(double *)); + r_re2 = malloc(2*sizeof(double *)); + r_im2 = malloc(2*sizeof(double *)); nsymb = (frame_parms->Ncp == 0) ? 14 : 12; - printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Symbols per subframe %d\n",NUMBER_OF_OFDM_CARRIERS, frame_parms->Ncp,frame_parms->samples_per_tti,nsymb); - - eNB2UE = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx, PHY_vars_UE[0]->lte_frame_parms.nb_antennas_rx, channel_model, @@ -807,14 +744,12 @@ int main(int argc, char **argv) 0, 0); - if (eNB2UE==NULL) { msg("Problem generating channel model. Exiting.\n"); exit(-1); } for (i=0; i<2; i++) { - s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(s_re[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); @@ -827,7 +762,6 @@ int main(int argc, char **argv) bzero(s_re2[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); s_im2[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(s_im2[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); - r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); bzero(r_re[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); @@ -867,69 +801,67 @@ int main(int argc, char **argv) // load_pbch_desc(pbch_file_fd); // } - if ((input_fd==NULL)&&(oai_hw_input==0)) { - // for (i=0;i<6;i++) // pbch_pdu[i] = i; //pbch_pdu[0]=100; //pbch_pdu[1]=1; //pbch_pdu[2]=0; - ((uint8_t*) pbch_pdu)[0] = 0; + ((uint8_t *) pbch_pdu)[0] = 0; switch (PHY_vars_eNB->lte_frame_parms.N_RB_DL) { - case 6: - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0x1f) | (0<<5); - break; + case 6: + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0x1f) | (0<<5); + break; - case 15: - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0x1f) | (1<<5); - break; + case 15: + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0x1f) | (1<<5); + break; - case 25: - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0x1f) | (2<<5); - break; + case 25: + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0x1f) | (2<<5); + break; - case 50: - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0x1f) | (3<<5); - break; + case 50: + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0x1f) | (3<<5); + break; - case 100: - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0x1f) | (4<<5); - break; + case 100: + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0x1f) | (4<<5); + break; - default: - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0x1f) | (2<<5); - break; + default: + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0x1f) | (2<<5); + break; } - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0xef) | - ((PHY_vars_eNB->lte_frame_parms.phich_config_common.phich_duration << 4)&0x10); + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0xef) | + ((PHY_vars_eNB->lte_frame_parms.phich_config_common.phich_duration << 4)&0x10); switch (PHY_vars_eNB->lte_frame_parms.phich_config_common.phich_resource) { - case oneSixth: - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0xf3) | (0<<3); - break; + case oneSixth: + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0xf3) | (0<<3); + break; - case half: - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0xf3) | (1<<3); - break; + case half: + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0xf3) | (1<<3); + break; - case one: - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0xf3) | (2<<3); - break; + case one: + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0xf3) | (2<<3); + break; - case two: - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0xf3) | (3<<3); - break; + case two: + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0xf3) | (3<<3); + break; - default: - break; + default: + break; } - ((uint8_t*) pbch_pdu)[0] = (((uint8_t*) pbch_pdu)[0]&0xfc) | ((PHY_vars_eNB->frame>>8)&0x3); - ((uint8_t*) pbch_pdu)[1] = PHY_vars_eNB->frame&0xfc; - ((uint8_t*) pbch_pdu)[2] = 0; + ((uint8_t *) pbch_pdu)[0] = (((uint8_t *) pbch_pdu)[0]&0xfc) | ((PHY_vars_eNB->frame>>8)&0x3); + ((uint8_t *) pbch_pdu)[1] = PHY_vars_eNB->frame&0xfc; + ((uint8_t *) pbch_pdu)[2] = 0; if (PHY_vars_eNB->lte_frame_parms.frame_type == 1) { generate_pss(PHY_vars_eNB->lte_eNB_common_vars.txdataF[0], @@ -975,21 +907,11 @@ int main(int argc, char **argv) 10); } - - printf("Generating PBCH for mode1_flag = %d, frame_type %d\n", PHY_vars_eNB->lte_frame_parms.mode1_flag,PHY_vars_eNB->lte_frame_parms.frame_type); - - generate_pilots(PHY_vars_eNB, PHY_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - - - - - - generate_pbch(&PHY_vars_eNB->lte_eNB_pbch, PHY_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, @@ -1010,24 +932,16 @@ int main(int argc, char **argv) &PHY_vars_eNB1->lte_frame_parms, (PHY_vars_eNB1->lte_frame_parms.Ncp==0)?6:5, 0); - - - - - generate_pilots(PHY_vars_eNB1, PHY_vars_eNB1->lte_eNB_common_vars.txdataF[0], AMP, LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - - generate_pbch(&PHY_vars_eNB1->lte_eNB_pbch, PHY_vars_eNB1->lte_eNB_common_vars.txdataF[0], AMP, &PHY_vars_eNB1->lte_frame_parms, pbch_pdu, 0); - } if (interf2>-20) { @@ -1036,36 +950,28 @@ int main(int argc, char **argv) &PHY_vars_eNB2->lte_frame_parms, (PHY_vars_eNB2->lte_frame_parms.Ncp==0)?6:5, 0); - - - - - generate_pilots(PHY_vars_eNB2, PHY_vars_eNB2->lte_eNB_common_vars.txdataF[0], AMP, LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - - generate_pbch(&PHY_vars_eNB2->lte_eNB_pbch, PHY_vars_eNB2->lte_eNB_common_vars.txdataF[0], AMP, &PHY_vars_eNB2->lte_frame_parms, pbch_pdu, 0); - } // Generate two PDCCH if (frame_type == 0) { - ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->rah = 0; - ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->TPC = 0; - ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->harq_pid = 0; - ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->mcs = 0; - ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->ndi = 1; - ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->rv = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu)->rah = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu)->rballoc = DLSCH_RB_ALLOC; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu)->TPC = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu)->harq_pid = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu)->mcs = 0; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu)->ndi = 1; + ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu)->rv = 0; dci_alloc[0].dci_length = sizeof_DCI1_5MHz_FDD_t; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_FDD_t)); dci_alloc[0].L = 2; @@ -1073,16 +979,16 @@ int main(int argc, char **argv) dci_alloc[0].format = format1; dci_alloc[0].search_space = DCI_UE_SPACE; } else { - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->rah = 0; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->rballoc = DLSCH_RB_ALLOC; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->TPC = 0; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->dai = 0; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->harq_pid = 0; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->mcs = 0; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->ndi = 1; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->rv = 0; - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->tpmi = (transmission_mode>=5 ? 5 : 0); // precoding - ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->dl_power_off = (transmission_mode==5 ? 0 : 1); + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&DLSCH_alloc_pdu)->rah = 0; + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&DLSCH_alloc_pdu)->rballoc = DLSCH_RB_ALLOC; + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&DLSCH_alloc_pdu)->TPC = 0; + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&DLSCH_alloc_pdu)->dai = 0; + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&DLSCH_alloc_pdu)->harq_pid = 0; + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&DLSCH_alloc_pdu)->mcs = 0; + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&DLSCH_alloc_pdu)->ndi = 1; + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&DLSCH_alloc_pdu)->rv = 0; + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&DLSCH_alloc_pdu)->tpmi = (transmission_mode>=5 ? 5 : 0); // precoding + ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&DLSCH_alloc_pdu)->dl_power_off = (transmission_mode==5 ? 0 : 1); dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); dci_alloc[0].L = 2; @@ -1107,7 +1013,6 @@ int main(int argc, char **argv) PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNb_id], 5); */ - // LOG_M("pilotsF.m","rsF",txdataF[0],lte_frame_parms->ofdm_symbol_size,1,1); #ifdef IFFT_FPGA LOG_M("txsigF0.m","txsF0", PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNb_id][0],300*120,1,4); @@ -1116,8 +1021,7 @@ int main(int argc, char **argv) LOG_M("txsigF1.m","txsF1", PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNb_id][1],300*120,1,4); for (i=0; i<10; i++) - debug_msg("%08x\n",((unsigned int*)&PHY_vars_eNB->lte_eNB_common_vars.txdataF[0][0][1*(PHY_vars_eNB->lte_frame_parms.N_RB_DL*12)*(PHY_vars_eNB->lte_frame_parms.symbols_per_tti>>1)])[i]); - + debug_msg("%08x\n",((unsigned int *)&PHY_vars_eNB->lte_eNB_common_vars.txdataF[0][0][1*(PHY_vars_eNB->lte_frame_parms.N_RB_DL*12)*(PHY_vars_eNB->lte_frame_parms.symbols_per_tti>>1)])[i]); // do talbe lookup and write results to txdataF2 for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) { @@ -1125,9 +1029,9 @@ int main(int argc, char **argv) for (i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX; i++) if ((i%512>=1) && (i%512<=150)) - txdataF2[aa][i] = ((int*)mod_table)[PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNb_id][aa][l++]]; + txdataF2[aa][i] = ((int *)mod_table)[PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNb_id][aa][l++]]; else if (i%512>=362) - txdataF2[aa][i] = ((int*)mod_table)[PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNb_id][aa][l++]]; + txdataF2[aa][i] = ((int *)mod_table)[PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNb_id][aa][l++]]; else txdataF2[aa][i] = 0; @@ -1139,11 +1043,9 @@ int main(int argc, char **argv) if (PHY_vars_eNB->lte_frame_parms.nb_antennas_tx>1) LOG_M("txsigF21.m","txsF21", txdataF2[1],FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX,1,1); - tx_lev=0; for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) { - if (frame_parms->Ncp == 1) PHY_ofdm_mod(txdataF2[aa], // input txdata[aa], // output @@ -1169,9 +1071,6 @@ int main(int argc, char **argv) tx_lev = 0; - - - for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) { if (frame_parms->Ncp == 1) PHY_ofdm_mod(PHY_vars_eNB->lte_eNB_common_vars.txdataF[eNb_id][aa], // input, @@ -1234,9 +1133,6 @@ int main(int argc, char **argv) } #endif - - - LOG_M("txsig0.m","txs0", txdata[0],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); if (frame_parms->nb_antennas_tx>1) @@ -1245,7 +1141,7 @@ int main(int argc, char **argv) i=0; while (!feof(input_fd)) { - ret=fscanf(input_fd,"%s %s",input_val_str,input_val_str2);//&input_val1,&input_val2); + ret=fscanf(input_fd,"%49s %49s",input_val_str,input_val_str2);//&input_val1,&input_val2); /* if ((i%4)==0) { ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); @@ -1254,9 +1150,8 @@ int main(int argc, char **argv) printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); } */ - ((short*)txdata[0])[i<<1] = 16*(short)(strtod(input_val_str,NULL)); - ((short*)txdata[0])[(i<<1)+1] = 16*(short)(strtod(input_val_str2,NULL)); - + ((short *)txdata[0])[i<<1] = 16*(short)(strtod(input_val_str,NULL)); + ((short *)txdata[0])[(i<<1)+1] = 16*(short)(strtod(input_val_str2,NULL)); i++; if (i==(FRAME_LENGTH_COMPLEX_SAMPLES)) @@ -1270,8 +1165,6 @@ int main(int argc, char **argv) OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); } else { // get from OAI HW // set check if we have to set up a signal generator here - - printf("Doing Acquisition from OAI HW\n"); snr0=snr1-.1; } @@ -1283,13 +1176,10 @@ int main(int argc, char **argv) sn = sin(2*M_PI*foff*i); for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) { - - tmp_re = (double)((short*)txdata[aa])[(i<<1)]*cs - (double)((short*)txdata[aa])[1+(i<<1)]*sn; - - tmp_im = (double)((short*)txdata[aa])[1+(i<<1)]*cs + (double)((short*)txdata[aa])[(i<<1)]*sn; + tmp_re = (double)((short *)txdata[aa])[(i<<1)]*cs - (double)((short *)txdata[aa])[1+(i<<1)]*sn; + tmp_im = (double)((short *)txdata[aa])[1+(i<<1)]*cs + (double)((short *)txdata[aa])[(i<<1)]*sn; if (awgn_flag == 0) { - s_re[aa][i] = tmp_re; s_im[aa][i] = tmp_im; @@ -1302,7 +1192,6 @@ int main(int argc, char **argv) s_re2[aa][i] = ((double)(((short *)txdata2[aa]))[(i<<1)]); s_im2[aa][i] = ((double)(((short *)txdata2[aa]))[(i<<1)+1]); } - } else { for (aarx=0; aarx<PHY_vars_UE[0]->lte_frame_parms.nb_antennas_rx; aarx++) { if (aa==0) { @@ -1330,19 +1219,14 @@ int main(int argc, char **argv) } if (oai_hw_output==0) { - for (SNR=snr0; SNR<snr1; SNR+=.2) { - n_errors = 0; n_errors2 = 0; n_alamouti = 0; for (trial=0; trial<n_frames; trial++) { - if (oai_hw_input == 0) { - if (awgn_flag == 0) { - multipath_channel(eNB2UE,s_re,s_im,r_re,r_im, FRAME_LENGTH_COMPLEX_SAMPLES,0);//LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES,0); @@ -1353,7 +1237,6 @@ int main(int argc, char **argv) if (interf2>-20) multipath_channel(eNB2UE2,s_re2,s_im2,r_re2,r_im2, LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES,0); - } // awgn_flag sigma2_dB = 10*log10((double)tx_lev) +10*log10(PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size/(12*NB_RB)) - SNR; @@ -1363,7 +1246,6 @@ int main(int argc, char **argv) //AWGN sigma2 = pow(10,sigma2_dB/10); - /* if (n_frames==1) { printf("rx_level data symbol %f, tx_lev %f\n", @@ -1371,16 +1253,14 @@ int main(int argc, char **argv) 10*log10(tx_lev)); } */ - iout = 0;//taus()%(FRAME_LENGTH_COMPLEX_SAMPLES>>2); for (i=0; i<FRAME_LENGTH_COMPLEX_SAMPLES; i++) { //nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { for (aa=0; aa<PHY_vars_eNB->lte_frame_parms.nb_antennas_rx; aa++) { r_re[aa][i] += (pow(10.0,.05*interf1)*r_re1[aa][i] + pow(10.0,.05*interf2)*r_re2[aa][i]); r_im[aa][i] += (pow(10.0,.05*interf1)*r_im1[aa][i] + pow(10.0,.05*interf2)*r_im2[aa][i]); - - ((short*) PHY_vars_UE[0]->lte_ue_common_vars.rxdata[aa])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) PHY_vars_UE[0]->lte_ue_common_vars.rxdata[aa])[(2*i)+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) PHY_vars_UE[0]->lte_ue_common_vars.rxdata[aa])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short *) PHY_vars_UE[0]->lte_ue_common_vars.rxdata[aa])[(2*i)+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } iout++; @@ -1440,11 +1320,9 @@ int main(int argc, char **argv) 0); } - PHY_vars_UE[UE_idx]->lte_ue_pdcch_vars[0]->crnti = n_rnti; PHY_vars_UE[UE_idx]->transmission_mode[0] = transmission_mode; PHY_vars_UE[UE_idx]->UE_mode[0] = PUSCH; - printf("Fine Frequency offset %d\n",PHY_vars_UE[UE_idx]->lte_ue_common_vars.freq_offset); printf("Doing PDCCH RX : num_pdcch_symbols at TX %d\n",num_pdcch_symbols); rx_pdcch(&PHY_vars_UE[UE_idx]->lte_ue_common_vars, @@ -1456,7 +1334,6 @@ int main(int argc, char **argv) (PHY_vars_UE[UE_idx]->lte_frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI, PHY_vars_UE[UE_idx]->is_secondary_ue); printf("Got PCFICH for %d pdcch symbols\n",PHY_vars_UE[UE_idx]->lte_ue_pdcch_vars[0]->num_pdcch_symbols); - dci_cnt = dci_decoding_procedure(PHY_vars_UE[UE_idx], dci_alloc_rx, 0, @@ -1475,9 +1352,7 @@ int main(int argc, char **argv) SI_RNTI, 0, P_RNTI); - i_mod = get_Qm(PHY_vars_UE[UE_idx]->dlsch_ue[0][0]->harq_processes[0]->mcs); - /* // overwrite some values until source is sure PHY_vars_UE[UE_idx]->dlsch_ue[0][0]->nb_rb = 25; @@ -1485,7 +1360,6 @@ int main(int argc, char **argv) PHY_vars_UE[UE_idx]->dlsch_ue[0][0]->harq_processes[0]->Ndi = 1; PHY_vars_UE[UE_idx]->dlsch_ue[0][0]->harq_processes[0]->mcs = 0; */ - dump_dci(&PHY_vars_UE[UE_idx]->lte_frame_parms, &dci_alloc_rx[0]); for (l=PHY_vars_UE[UE_idx]->lte_ue_pdcch_vars[0]->num_pdcch_symbols; @@ -1590,20 +1464,16 @@ int main(int argc, char **argv) i_mod); } - - coded_bits_per_codeword = get_G(&PHY_vars_UE[UE_idx]->lte_frame_parms, PHY_vars_UE[UE_idx]->dlsch_ue[0][0]->nb_rb, PHY_vars_UE[UE_idx]->dlsch_ue[0][0]->rb_alloc, get_Qm(PHY_vars_UE[UE_idx]->dlsch_ue[0][0]->harq_processes[PHY_vars_UE[UE_idx]->dlsch_ue[0][0]->current_harq_pid]->mcs), PHY_vars_UE[UE_idx]->lte_ue_pdcch_vars[0]->num_pdcch_symbols, subframe); - - printf("G %d, TBS %d, pdcch_sym %d\n", + printf("G %u, TBS %d, pdcch_sym %d\n", coded_bits_per_codeword, dlsch_tbs25[get_I_TBS(PHY_vars_UE[UE_idx]->dlsch_ue[0][0]->harq_processes[0]->mcs)][PHY_vars_UE[UE_idx]->dlsch_ue[0][0]->nb_rb-1], num_pdcch_symbols); - dlsch_unscrambling(&PHY_vars_UE[UE_idx]->lte_frame_parms, PHY_vars_UE[UE_idx]->lte_ue_pdcch_vars[0]->num_pdcch_symbols, PHY_vars_UE[UE_idx]->dlsch_ue[0][0], @@ -1611,7 +1481,6 @@ int main(int argc, char **argv) PHY_vars_UE[UE_idx]->lte_ue_pdsch_vars[0]->llr[0], 0, subframe<<1); - ret = dlsch_decoding(PHY_vars_UE[UE_idx], PHY_vars_UE[UE_idx]->lte_ue_pdsch_vars[0]->llr[0], &PHY_vars_UE[UE_idx]->lte_frame_parms, @@ -1635,53 +1504,52 @@ int main(int argc, char **argv) n_errors++; } - #ifdef XFORMS if (do_forms==1) { do_forms2(form_dl, frame_parms, PHY_vars_UE[0]->lte_ue_pdcch_vars[0]->num_pdcch_symbols, - (int16_t**)PHY_vars_UE[0]->lte_ue_common_vars.dl_ch_estimates_time, - (int16_t**)PHY_vars_UE[0]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0], - (int16_t**)PHY_vars_UE[0]->lte_ue_common_vars.rxdata, - (int16_t**)PHY_vars_UE[0]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF, - (int16_t*)PHY_vars_UE[0]->lte_ue_pdcch_vars[0]->rxdataF_comp[0], - (int16_t*)PHY_vars_UE[0]->lte_ue_pdsch_vars[0]->rxdataF_comp[0], - (int16_t*)PHY_vars_UE[0]->lte_ue_pdsch_vars[1]->rxdataF_comp[0], - (int16_t*)PHY_vars_UE[0]->lte_ue_pdsch_vars[0]->llr[0], - (int16_t*)PHY_vars_UE[0]->lte_ue_pbch_vars[0]->rxdataF_comp[0], - (int8_t*)PHY_vars_UE[0]->lte_ue_pbch_vars[0]->llr, + (int16_t **)PHY_vars_UE[0]->lte_ue_common_vars.dl_ch_estimates_time, + (int16_t **)PHY_vars_UE[0]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0], + (int16_t **)PHY_vars_UE[0]->lte_ue_common_vars.rxdata, + (int16_t **)PHY_vars_UE[0]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF, + (int16_t *)PHY_vars_UE[0]->lte_ue_pdcch_vars[0]->rxdataF_comp[0], + (int16_t *)PHY_vars_UE[0]->lte_ue_pdsch_vars[0]->rxdataF_comp[0], + (int16_t *)PHY_vars_UE[0]->lte_ue_pdsch_vars[1]->rxdataF_comp[0], + (int16_t *)PHY_vars_UE[0]->lte_ue_pdsch_vars[0]->llr[0], + (int16_t *)PHY_vars_UE[0]->lte_ue_pbch_vars[0]->rxdataF_comp[0], + (int8_t *)PHY_vars_UE[0]->lte_ue_pbch_vars[0]->llr, coded_bits_per_codeword); if (N_carriers==2) do_forms2(form_dl1, frame_parms, PHY_vars_UE[1]->lte_ue_pdcch_vars[0]->num_pdcch_symbols, - (int16_t**)PHY_vars_UE[1]->lte_ue_common_vars.dl_ch_estimates_time, - (int16_t**)PHY_vars_UE[1]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0], - (int16_t**)PHY_vars_UE[1]->lte_ue_common_vars.rxdata, - (int16_t**)PHY_vars_UE[1]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF, - (int16_t*)PHY_vars_UE[1]->lte_ue_pdcch_vars[0]->rxdataF_comp[0], - (int16_t*)PHY_vars_UE[1]->lte_ue_pdsch_vars[0]->rxdataF_comp[0], - (int16_t*)PHY_vars_UE[1]->lte_ue_pdsch_vars[3]->rxdataF_comp[0], - (int16_t*)PHY_vars_UE[1]->lte_ue_pdsch_vars[0]->llr[0], - (int16_t*)PHY_vars_UE[1]->lte_ue_pbch_vars[0]->rxdataF_comp[0], - (int8_t*)PHY_vars_UE[1]->lte_ue_pbch_vars[0]->llr, + (int16_t **)PHY_vars_UE[1]->lte_ue_common_vars.dl_ch_estimates_time, + (int16_t **)PHY_vars_UE[1]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0], + (int16_t **)PHY_vars_UE[1]->lte_ue_common_vars.rxdata, + (int16_t **)PHY_vars_UE[1]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF, + (int16_t *)PHY_vars_UE[1]->lte_ue_pdcch_vars[0]->rxdataF_comp[0], + (int16_t *)PHY_vars_UE[1]->lte_ue_pdsch_vars[0]->rxdataF_comp[0], + (int16_t *)PHY_vars_UE[1]->lte_ue_pdsch_vars[3]->rxdataF_comp[0], + (int16_t *)PHY_vars_UE[1]->lte_ue_pdsch_vars[0]->llr[0], + (int16_t *)PHY_vars_UE[1]->lte_ue_pbch_vars[0]->rxdataF_comp[0], + (int8_t *)PHY_vars_UE[1]->lte_ue_pbch_vars[0]->llr, 1920); } #endif - } // trials } // SNR if (n_frames==1) { - - LOG_M("H00.m","h00",&(PHY_vars_UE[0]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][0][0]),((frame_parms->Ncp==0)?7:6)*(PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size),1,1); + LOG_M("H00.m","h00",&(PHY_vars_UE[0]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][0][0]), + ((frame_parms->Ncp==0)?7:6)*(PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size),1,1); if (n_tx==2) - LOG_M("H10.m","h10",&(PHY_vars_UE[0]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][2][0]),((frame_parms->Ncp==0)?7:6)*(PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size),1,1); + LOG_M("H10.m","h10",&(PHY_vars_UE[0]->lte_ue_common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][2][0]), + ((frame_parms->Ncp==0)?7:6)*(PHY_vars_eNB->lte_frame_parms.ofdm_symbol_size),1,1); LOG_M("rxsig0.m","rxs0", PHY_vars_UE[0]->lte_ue_common_vars.rxdata[0],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); LOG_M("rxsigF0.m","rxsF0", PHY_vars_UE[0]->lte_ue_common_vars.rxdataF[0],NUMBER_OF_OFDM_CARRIERS*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*nsymb,2,1); @@ -1691,16 +1559,13 @@ int main(int argc, char **argv) LOG_M("pdcch_rxF_ext0.m","pdcch_rxF_ext0",PHY_vars_UE[0]->lte_ue_pdcch_vars[eNb_id]->rxdataF_ext[0],3*300,1,1); LOG_M("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",PHY_vars_UE[0]->lte_ue_pdcch_vars[eNb_id]->rxdataF_comp[0],4*300,1,1); LOG_M("pdcch_rxF_llr.m","pdcch_llr",PHY_vars_UE[0]->lte_ue_pdcch_vars[eNb_id]->llr,2400,1,4); - coded_bits_per_codeword = get_G(&PHY_vars_UE[0]->lte_frame_parms, PHY_vars_UE[0]->dlsch_ue[0][0]->nb_rb, PHY_vars_UE[0]->dlsch_ue[0][0]->rb_alloc, get_Qm(PHY_vars_UE[0]->dlsch_ue[0][0]->harq_processes[0]->mcs), PHY_vars_UE[0]->lte_ue_pdcch_vars[0]->num_pdcch_symbols, 0); - dump_dlsch2(PHY_vars_UE[0],0,0,&coded_bits_per_codeword); - } } else { printf("Sending frame to OAI HW\n"); @@ -1720,8 +1585,6 @@ int main(int argc, char **argv) } #endif - - #ifdef IFFT_FPGA free(txdataF2[0]); free(txdataF2[1]); @@ -1750,20 +1613,20 @@ int main(int argc, char **argv) free(r_re); printf("Freeing r_im\n"); free(r_im); - - lte_sync_time_free(); if (write_output_file) fclose(output_fd); + if (input_fd) + fclose(input_fd); + if ((oai_hw_input==1)|| (oai_hw_output==1)) { close(openair_fd); } return(n_errors); - } diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 09d0bb9150ebda157ea30b2009352345e1cb0434..588a96ca6d4a16f44b3c1f2c6dbbb61dcb69f26d 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -55,7 +55,7 @@ #include "PHY/TOOLS/lte_phy_scope.h" #include "dummy_functions.c" - +#include "nfapi/oai_integration/vendor_ext.h" #include "common/config/config_load_configmodule.h" double cpuf; #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) @@ -81,7 +81,7 @@ double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */ double t_rx_min = 1000000000; /*!< \brief initial min process time for tx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ -int nfapi_mode = 0; + extern void fep_full(RU_t *ru); extern void ru_fep_full_2thread(RU_t *ru); @@ -349,19 +349,6 @@ int main(int argc, char **argv) { char input_val_str[50],input_val_str2[50]; // FILE *rx_frame_file; FILE *csv_fdUL=NULL; - /* - FILE *fperen=NULL; - char fperen_name[512]; - - FILE *fmageren=NULL; - char fmageren_name[512]; - - FILE *flogeren=NULL; - char flogeren_name[512]; - */ - /* FILE *ftxlev; - char ftxlev_name[512]; - */ char csv_fname[512]; static int n_frames=5000; static int n_ch_rlz = 1; @@ -405,7 +392,6 @@ int main(int argc, char **argv) { cpu_freq_GHz = (double)get_cpu_freq_GHz(); cpuf = cpu_freq_GHz; set_parallel_conf("PARALLEL_SINGLE_THREAD"); - printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); AssertFatal(load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) != NULL, "cannot load configuration module, exiting\n"); @@ -456,10 +442,8 @@ int main(int argc, char **argv) { { "help", "display help and exit", PARAMFLAG_BOOL, iptr:&help, defintval:0, TYPE_INT, 0 }, { "", "",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, }; - struct option * long_options = parse_oai_options(options); - + struct option *long_options = parse_oai_options(options); int option_index; - int res; while ((res=getopt_long_only(argc, argv, "", long_options, &option_index)) == 0) { @@ -467,125 +451,125 @@ int main(int argc, char **argv) { if (long_options[option_index].has_arg==no_argument) *(bool *)options[option_index].iptr=1; else switch (options[option_index].type) { - case TYPE_INT: - *(int *)options[option_index].iptr=atoi(optarg); - break; - - case TYPE_DOUBLE: - *(double *)options[option_index].dblptr=atof(optarg); - break; - - case TYPE_UINT8: - *(uint8_t *)options[option_index].dblptr=atoi(optarg); - break; - - case TYPE_UINT16: - *(uint16_t *)options[option_index].dblptr=atoi(optarg); - break; - - default: - printf("not decoded type.\n"); - exit(1); + case TYPE_INT: + *(int *)options[option_index].iptr=atoi(optarg); + break; + + case TYPE_DOUBLE: + *(double *)options[option_index].dblptr=atof(optarg); + break; + + case TYPE_UINT8: + *(uint8_t *)options[option_index].dblptr=atoi(optarg); + break; + + case TYPE_UINT16: + *(uint16_t *)options[option_index].dblptr=atoi(optarg); + break; + + default: + printf("not decoded type.\n"); + exit(1); } continue; } switch (long_options[option_index].name[0]) { - case 'T': - tdd_config=atoi(optarg); - frame_type=TDD; - break; + case 'T': + tdd_config=atoi(optarg); + frame_type=TDD; + break; - case 'a': - channel_model = AWGN; - chMod = 1; - break; + case 'a': + channel_model = AWGN; + chMod = 1; + break; - case 'g': - strncpy(channel_model_input,optarg,9); - struct tmp { - char opt; - int m; - int M; - } - tmp[]= { - {'A',SCM_A,2}, - {'B',SCM_B,3}, - {'C',SCM_C,4}, - {'D',SCM_D,5}, - {'E',EPA,6}, - {'G',ETU,8}, - {'H',Rayleigh8,9}, - {'I',Rayleigh1,10}, - {'J',Rayleigh1_corr,11}, - {'K',Rayleigh1_anticorr,12}, - {'L',Rice8,13}, - {'M',Rice1,14}, - {'N',AWGN,1}, - {0,0,0} - }; - struct tmp *ptr; - - for (ptr=tmp; ptr->opt!=0; ptr++) - if ( ptr->opt == optarg[0] ) { - channel_model=ptr->m; - chMod=ptr->M; - break; - } - - AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); - break; + case 'g': + strncpy(channel_model_input,optarg,9); + struct tmp { + char opt; + int m; + int M; + } + tmp[]= { + {'A',SCM_A,2}, + {'B',SCM_B,3}, + {'C',SCM_C,4}, + {'D',SCM_D,5}, + {'E',EPA,6}, + {'G',ETU,8}, + {'H',Rayleigh8,9}, + {'I',Rayleigh1,10}, + {'J',Rayleigh1_corr,11}, + {'K',Rayleigh1_anticorr,12}, + {'L',Rice8,13}, + {'M',Rice1,14}, + {'N',AWGN,1}, + {0,0,0} + }; + struct tmp *ptr; + + for (ptr=tmp; ptr->opt!=0; ptr++) + if ( ptr->opt == optarg[0] ) { + channel_model=ptr->m; + chMod=ptr->M; + break; + } - case 'x': - transmission_m=atoi(optarg); - AssertFatal(transmission_m==1 || transmission_m==2, - "Unsupported transmission mode %d\n",transmission_m); - break; + AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); + break; - case 'r': - nb_rb = atoi(optarg); - nb_rb_set = 1; - break; + case 'x': + transmission_m=atoi(optarg); + AssertFatal(transmission_m==1 || transmission_m==2, + "Unsupported transmission mode %d\n",transmission_m); + break; + + case 'r': + nb_rb = atoi(optarg); + nb_rb_set = 1; + break; //case 'c': // cyclic_shift = atoi(optarg); // break; - case 'i': - input_fdUL = fopen(optarg,"r"); - printf("Reading in %s (%p)\n",optarg,input_fdUL); - AssertFatal(input_fdUL != (FILE *)NULL,"Unknown file %s\n",optarg); - break; + case 'i': + input_fdUL = fopen(optarg,"r"); + printf("Reading in %s (%p)\n",optarg,input_fdUL); + AssertFatal(input_fdUL != (FILE *)NULL,"Unknown file %s\n",optarg); + break; - case 'A': - beta_ACK = atoi(optarg); - AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n"); - break; + case 'A': + beta_ACK = atoi(optarg); + AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n"); + break; - case 'C': - beta_CQI = atoi(optarg); - AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n"); - break; + case 'C': + beta_CQI = atoi(optarg); + AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n"); + break; - case 'R': - beta_RI = atoi(optarg); - AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n"); - break; + case 'R': + beta_RI = atoi(optarg); + AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n"); + break; - case 'P': - dump_perf=1; - opp_enabled=1; - break; + case 'P': + dump_perf=1; + opp_enabled=1; + break; - case 'L': - set_parallel_conf(optarg); - break; - - default: - printf("Wrong option: %s\n",long_options[option_index].name); - exit(1); - break; + case 'L': + set_parallel_conf(optarg); + break; + + default: + printf("Wrong option: %s\n",long_options[option_index].name); + exit(1); + break; } } @@ -594,14 +578,15 @@ int main(int argc, char **argv) { exit(1); } - if (help || verbose ) - display_options_values(options, true); + display_options_values(options, true); + if (help) exit(0); - + if (thread_struct.parallel_conf != PARALLEL_SINGLE_THREAD) set_worker_conf("WORKER_ENABLE"); + RC.nb_L1_inst = 1; RC.nb_RU = 1; lte_param_init(&eNB,&UE,&ru, @@ -619,7 +604,7 @@ int main(int argc, char **argv) { threequarter_fs, osf, 0); - RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); + RC.eNB = (PHY_VARS_eNB ** *)malloc(sizeof(PHY_VARS_eNB **)); RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); RC.ru = (RU_t **)malloc(sizeof(RC.ru)); RC.eNB[0][0] = eNB; @@ -637,7 +622,7 @@ int main(int argc, char **argv) { eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; printf("lte_param_init done\n"); // for a call to phy_reset_ue later we need PHY_vars_UE_g allocated and pointing to UE - PHY_vars_UE_g = (PHY_VARS_UE ***)malloc(sizeof(PHY_VARS_UE **)); + PHY_vars_UE_g = (PHY_VARS_UE ** *)malloc(sizeof(PHY_VARS_UE **)); PHY_vars_UE_g[0] = (PHY_VARS_UE **) malloc(sizeof(PHY_VARS_UE *)); PHY_vars_UE_g[0][0] = UE; @@ -822,7 +807,7 @@ int main(int argc, char **argv) { if (cqi_flag == 1) coded_bits_per_codeword-=UE->ulsch[0]->O; rate = (double)dlsch_tbs25[get_I_TBS(mcs)][nb_rb-1]/(coded_bits_per_codeword); - printf("Rate = %f (mod %d), coded bits %d\n",rate,get_Qm_ul(mcs),coded_bits_per_codeword); + printf("Rate = %f (mod %d), coded bits %u\n",rate,get_Qm_ul(mcs),coded_bits_per_codeword); for (ch_realization=0; ch_realization<n_ch_rlz; ch_realization++) { /* @@ -884,7 +869,7 @@ int main(int argc, char **argv) { i=0; while (!feof(input_fdUL)) { - ret=fscanf(input_fdUL,"%s %s",input_val_str,input_val_str2);//&input_val1,&input_val2); + ret=fscanf(input_fdUL,"%49s %49s",input_val_str,input_val_str2);//&input_val1,&input_val2); if (ret != 2) printf("ERROR: error reading file\n"); @@ -971,7 +956,7 @@ int main(int argc, char **argv) { eNB->ulsch[0]->harq_processes[harq_pid]->round=round; UE->ulsch[0]->harq_processes[harq_pid]->round=round; - if (n_frames==1) printf("filling ulsch: Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx); + if (n_frames==1) printf("filling ulsch: Trial %u : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx); round_trials[round]++; UL_req.sfn_sf = (1<<4)+subframe; @@ -1062,10 +1047,10 @@ int main(int argc, char **argv) { sigma2_dB = N0;//-10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12));//10*log10((double)tx_lev) +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); // compute tx_gain to achieve target SNR (per resource element!) - tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/(double)tx_lev);//*(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev); + tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/(double)tx_lev);// *(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev); if (n_frames==1) - printf("tx_lev = %d (%d.%d dB,%f), gain %f\n",tx_lev,tx_lev_dB/10,tx_lev_dB,10*log10((double)tx_lev),10*log10(tx_gain)); + printf("tx_lev = %u (%u.%u dB,%f), gain %f\n",tx_lev,tx_lev_dB/10,tx_lev_dB,10*log10((double)tx_lev),10*log10(tx_gain)); // fill measurement symbol (19) with noise for (i=0; i<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { @@ -1100,7 +1085,7 @@ int main(int argc, char **argv) { // calculate freq domain representation to compute SINR freq_channel(UE2eNB, N_RB_DL,12*N_RB_DL + 1); // snr=pow(10.0,.1*SNR); - fprintf(csv_fdUL,"%f,%d,%d,%f,%f,%f,",SNR,tx_lev,tx_lev_dB,sigma2_dB,tx_gain,SNR2); + fprintf(csv_fdUL,"%f,%u,%u,%f,%f,%f,",SNR,tx_lev,tx_lev_dB,sigma2_dB,tx_gain,SNR2); //fprintf(csv_fdUL,"%f,",SNR); for (u=0; u<12*nb_rb; u++) { @@ -1156,12 +1141,12 @@ int main(int argc, char **argv) { if (eNB->frame_parms.nb_antennas_rx>1) LOG_M("rxsig1UL.m","rxs1", &ru->common.rxdata[1][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); } - start_meas(&eNB->phy_proc_rx); + start_meas(&eNB->phy_proc_rx); ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? ru_fep_full_2thread : fep_full; ru->feprx(ru); phy_procedures_eNB_uespec_RX(eNB,proc_rxtx); - stop_meas(&eNB->phy_proc_rx); - + stop_meas(&eNB->phy_proc_rx); + if (cqi_flag > 0) { cqi_error = 0; @@ -1226,11 +1211,10 @@ int main(int argc, char **argv) { } dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); - - if (round == 4) exit(-1); + round=5; } - if (n_frames==1) printf("round %d errors %d/%d\n",round,errs[round],trials); + if (n_frames==1) printf("round %d errors %u/%u\n",round,errs[round],trials); round++; @@ -1288,7 +1272,7 @@ int main(int argc, char **argv) { LOG_UDUMPMSG(SIM,dataArray(table_rx),table_rx->size,LOG_DUMP_DOUBLE,"The receiver raw data: \n"); } - printf("\n**********rb: %d ***mcs : %d *********SNR = %f dB (%f): TX %d dB (gain %f dB), N0W %f dB, I0 %d dB, delta_IF %d [ (%d,%d) dB / (%d,%d) dB ]**************************\n", + printf("\n**********rb: %d ***mcs : %d *********SNR = %f dB (%f): TX %u dB (gain %f dB), N0W %f dB, I0 %d dB, delta_IF %d [ (%d,%d) dB / (%d,%d) dB ]**************************\n", nb_rb,mcs,SNR,SNR2, tx_lev_dB, 20*log10(tx_gain), @@ -1300,7 +1284,7 @@ int main(int argc, char **argv) { eNB->measurements.n0_power_dB[0], eNB->measurements.n0_power_dB[1]); effective_rate = ((double)(round_trials[0])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); - printf("Errors (%d/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e) => effective rate %f (%3.1f%%,%f,%f), normalized delay %f (%f)\n", + printf("Errors (%u/%u %u/%u %u/%u %u/%u), Pe = (%e,%e,%e,%e) => effective rate %f (%3.1f%%,%f,%f), normalized delay %f (%f)\n", errs[0], round_trials[0], errs[1], @@ -1322,16 +1306,16 @@ int main(int argc, char **argv) { (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); if (cqi_flag >0) { - printf("CQI errors %d/%d,false positives %d/%d, CQI false negatives %d/%d\n", + printf("CQI errors %d/%u,false positives %d/%u, CQI false negatives %d/%u\n", cqi_errors,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3], cqi_crc_falsepositives,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3], cqi_crc_falsenegatives,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]); } if (eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0] > 0) - printf("ACK/NAK errors %d/%d\n",ack_errors,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]); + printf("ACK/NAK errors %d/%u\n",ack_errors,round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]); - fprintf(bler_fd,"%f;%d;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d\n", + fprintf(bler_fd,"%f;%d;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u\n", SNR, mcs, nb_rb, @@ -1358,15 +1342,15 @@ int main(int argc, char **argv) { printStatIndent(&UE->ulsch_rate_matching_stats,"ULSCH rate-matching time"); printStatIndent(&UE->ulsch_interleaving_stats,"ULSCH sub-block interleaving"); printStatIndent(&UE->ulsch_multiplexing_stats,"ULSCH multiplexing time"); - printf("\n"); + printf("\n"); printDistribution(&eNB->phy_proc_rx,table_rx,"Total PHY proc rx subframe"); printDistribution(&ru->ofdm_demod_stats,table_rx_fft,"|__ OFDM_demod time"); printDistribution(&eNB->ulsch_demodulation_stats,table_rx_demod,"|__ ULSCH demodulation time"); - printDistribution(&eNB->ulsch_decoding_stats,table_rx_dec,"|__ ULSCH Decoding time"); + printDistribution(&eNB->ulsch_decoding_stats,table_rx_dec,"|__ ULSCH Decoding time"); printf(" (%.2f Mbit/s, avg iter %.2f, max %.2f)\n", UE->ulsch[0]->harq_processes[harq_pid]->TBS/1000.0, - (double)iter_trials, - (double)eNB->ulsch_decoding_stats.max*timeBase); + (double)iter_trials, + (double)eNB->ulsch_decoding_stats.max*timeBase); printStatIndent2(&eNB->ulsch_deinterleaving_stats,"sub-block interleaving" ); printStatIndent2(&eNB->ulsch_demultiplexing_stats,"sub-block demultiplexing" ); printStatIndent2(&eNB->ulsch_rate_unmatching_stats,"sub-block rate-matching" ); @@ -1404,7 +1388,7 @@ int main(int argc, char **argv) { if ( (test_perf != 0) && (100 * effective_rate > test_perf )) { //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3\n"); - fprintf(time_meas_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;", + fprintf(time_meas_fd,"%f;%d;%d;%f;%u;%u;%u;%u;%u;%u;%u;%u;", SNR, mcs, eNB->ulsch[0]->harq_processes[harq_pid]->TBS, @@ -1418,7 +1402,7 @@ int main(int argc, char **argv) { errs[3], round_trials[3]); //fprintf(time_meas_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3;ND;\n"); - fprintf(time_meas_fd,"%f;%d;%d;%f;%2.1f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%e;%e;%e;%e;%f;%f;", + fprintf(time_meas_fd,"%f;%d;%d;%f;%2.1f;%f;%u;%u;%u;%u;%u;%u;%u;%u;%e;%e;%e;%e;%f;%f;", SNR, mcs, eNB->ulsch[0]->harq_processes[harq_pid]->TBS, @@ -1463,34 +1447,34 @@ int main(int argc, char **argv) { ); //fprintf(time_meas_fd,"UE_PROC_TX_STD;UE_PROC_TX_MAX;UE_PROC_TX_MIN;UE_PROC_TX_MED;UE_PROC_TX_Q1;UE_PROC_TX_Q3;UE_PROC_TX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", - squareRoot(&UE->phy_proc_tx), t_tx_max, t_tx_min, median(table_tx), q1(table_tx), q3(table_tx), n_tx_dropped); + squareRoot(&UE->phy_proc_tx), t_tx_max, t_tx_min, median(table_tx), q1(table_tx), q3(table_tx), n_tx_dropped); //fprintf(time_meas_fd,"IFFT;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", - squareRoot(&UE->ofdm_mod_stats), + squareRoot(&UE->ofdm_mod_stats), median(table_tx_ifft),q1(table_tx_ifft),q3(table_tx_ifft)); //fprintf(time_meas_fd,"MOD;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", - squareRoot(&UE->ulsch_modulation_stats), + squareRoot(&UE->ulsch_modulation_stats), median(table_tx_mod), q1(table_tx_mod), q3(table_tx_mod)); //fprintf(time_meas_fd,"ENC;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", - squareRoot(&UE->ulsch_encoding_stats), + squareRoot(&UE->ulsch_encoding_stats), median(table_tx_enc),q1(table_tx_enc),q3(table_tx_enc)); //fprintf(time_meas_fd,"eNB_PROC_RX_STD;eNB_PROC_RX_MAX;eNB_PROC_RX_MIN;eNB_PROC_RX_MED;eNB_PROC_RX_Q1;eNB_PROC_RX_Q3;eNB_PROC_RX_DROPPED;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", - squareRoot(&eNB->phy_proc_rx), t_rx_max, t_rx_min, + squareRoot(&eNB->phy_proc_rx), t_rx_max, t_rx_min, median(table_rx), q1(table_rx), q3(table_rx), n_rx_dropped); //fprintf(time_meas_fd,"FFT;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", - squareRoot(&ru->ofdm_demod_stats), + squareRoot(&ru->ofdm_demod_stats), median(table_rx_fft), q1(table_rx_fft), q3(table_rx_fft)); //fprintf(time_meas_fd,"DEMOD;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f;", - squareRoot(&eNB->ulsch_demodulation_stats), + squareRoot(&eNB->ulsch_demodulation_stats), median(table_rx_demod), q1(table_rx_demod), q3(table_rx_demod)); //fprintf(time_meas_fd,"DEC;\n"); fprintf(time_meas_fd,"%f;%f;%f;%f\n", - squareRoot(&eNB->ulsch_decoding_stats), + squareRoot(&eNB->ulsch_decoding_stats), median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec)); printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); break; @@ -1523,5 +1507,7 @@ int main(int argc, char **argv) { return(0); } - - +/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */ +uint64_t get_softmodem_optmask(void) { + return 0; +} diff --git a/openair1/SIMULATION/LTE_PHY/unitary_defs.h b/openair1/SIMULATION/LTE_PHY/unitary_defs.h index 1f91df1306e0f71e0165bec462c482b9130703c3..10a5366082fbf61fe9b47430cc4c91cc1a811c75 100644 --- a/openair1/SIMULATION/LTE_PHY/unitary_defs.h +++ b/openair1/SIMULATION/LTE_PHY/unitary_defs.h @@ -22,10 +22,10 @@ openair0_device openair0; volatile int oai_exit=0; -void exit_function(const char* file, const char* function, const int line,const char *s) { +void exit_function(const char* file, const char* function, const int line,const char *s) { const char * msg= s==NULL ? "no comment": s; - printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); - exit(-1); + printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); + exit(-1); } extern unsigned int dlsch_tbs25[27][25],TBStable[27][110]; diff --git a/openair1/SIMULATION/TOOLS/abstraction.c b/openair1/SIMULATION/TOOLS/abstraction.c index 6b846bb2d5db9e584d54cfd027792506d6363ae8..7ac19804176115087bb1db54b803543bd20a7bf9 100644 --- a/openair1/SIMULATION/TOOLS/abstraction.c +++ b/openair1/SIMULATION/TOOLS/abstraction.c @@ -32,17 +32,14 @@ // NEW code with lookup table for sin/cos based on delay profile (TO BE TESTED) -double **cos_lut=NULL,**sin_lut=NULL; +double **cos_lut=NULL,* *sin_lut=NULL; //#if 1 -int init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) -{ - - +int init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) { double delta_f,freq; // 90 kHz spacing double delay; int16_t f; @@ -50,21 +47,18 @@ int init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) if ((n_samples&1)==0) { fprintf(stderr, "freq_channel_init: n_samples has to be odd\n"); - return(-1); + return(-1); } - cos_lut = (double **)malloc(n_samples*sizeof(double*)); - sin_lut = (double **)malloc(n_samples*sizeof(double*)); - + cos_lut = (double **)malloc(n_samples*sizeof(double *)); + sin_lut = (double **)malloc(n_samples*sizeof(double *)); delta_f = nb_rb*180000/(n_samples-1); for (f=-(n_samples>>1); f<=(n_samples>>1); f++) { freq=delta_f*(double)f*1e-6;// due to the fact that delays is in mus - cos_lut[f+(n_samples>>1)] = (double *)malloc((int)desc->nb_taps*sizeof(double)); sin_lut[f+(n_samples>>1)] = (double *)malloc((int)desc->nb_taps*sizeof(double)); - for (l=0; l<(int)desc->nb_taps; l++) { if (desc->nb_taps==1) delay = desc->delays[l]; @@ -74,17 +68,13 @@ int init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) cos_lut[f+(n_samples>>1)][l] = cos(2*M_PI*freq*delay); sin_lut[f+(n_samples>>1)][l] = sin(2*M_PI*freq*delay); //printf("values cos:%d, sin:%d\n", cos_lut[f][l], sin_lut[f][l]); - } } return(0); } -int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) -{ - - +int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) { int16_t f,f2,d; uint8_t aarx,aatx,l; double *clut,*slut; @@ -95,7 +85,7 @@ int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) // n_samples has to be a odd number because we assume the spectrum is symmetric around the DC and includes the DC if ((n_samples&1)==0) { fprintf(stderr, "freq_channel: n_samples has to be odd\n"); - return(-1); + return(-1); } // printf("no of taps:%d,",(int)desc->nb_taps); @@ -104,6 +94,7 @@ int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) // we are initializing the lut for the largets possible n_samples=12*nb_rb+1 // if called with n_samples<12*nb_rb+1, we decimate the lut n_samples_max=12*nb_rb+1; + if (init_freq_channel(desc,nb_rb,n_samples_max)==0) freq_channel_init=1; else @@ -111,9 +102,7 @@ int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) } d=(n_samples_max-1)/(n_samples-1); - //printf("no_samples=%d, n_samples_max=%d, d=%d\n",n_samples,n_samples_max,d); - start_meas(&desc->interp_freq); for (f=-n_samples_max/2,f2=-n_samples/2; f<n_samples_max/2; f+=d,f2++) { @@ -126,7 +115,6 @@ int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].y=0.0; for (l=0; l<(int)desc->nb_taps; l++) { - desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].x+=(desc->a[l][aarx+(aatx*desc->nb_rx)].x*clut[l]+ desc->a[l][aarx+(aatx*desc->nb_rx)].y*slut[l]); desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].y+=(-desc->a[l][aarx+(aatx*desc->nb_rx)].x*slut[l]+ @@ -137,7 +125,6 @@ int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) } stop_meas(&desc->interp_freq); - return(0); } @@ -146,16 +133,13 @@ double compute_pbch_sinr(channel_desc_t *desc, channel_desc_t *desc_i2, double snr_dB,double snr_i1_dB, double snr_i2_dB, - uint16_t nb_rb) -{ - + uint16_t nb_rb) { double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB); uint16_t f; uint8_t aarx,aatx; double S; struct complex S_i1; struct complex S_i2; - avg_sinr=0.0; // printf("nb_rb %d\n",nb_rb); @@ -202,18 +186,14 @@ double compute_sinr(channel_desc_t *desc, channel_desc_t *desc_i2, double snr_dB,double snr_i1_dB, double snr_i2_dB, - uint16_t nb_rb) -{ - + uint16_t nb_rb) { double avg_sinr,snr=pow(10.0,.1*snr_dB),snr_i1=pow(10.0,.1*snr_i1_dB),snr_i2=pow(10.0,.1*snr_i2_dB); uint16_t f; uint8_t aarx,aatx; double S; struct complex S_i1; struct complex S_i2; - DevAssert( nb_rb > 0 ); - avg_sinr=0.0; // printf("nb_rb %d\n",nb_rb); @@ -256,12 +236,9 @@ double compute_sinr(channel_desc_t *desc, int pbch_polynomial_degree=6; double pbch_awgn_polynomial[7]= {-7.2926e-05, -2.8749e-03, -4.5064e-02, -3.5301e-01, -1.4655e+00, -3.6282e+00, -6.6907e+00}; -void load_pbch_desc(FILE *pbch_file_fd) -{ - +void load_pbch_desc(FILE *pbch_file_fd) { int i, ret; char dummy[25]; - ret = fscanf(pbch_file_fd,"%d",&pbch_polynomial_degree); if (ret < 0) { @@ -277,7 +254,7 @@ void load_pbch_desc(FILE *pbch_file_fd) printf("PBCH polynomial : "); for (i=0; i<=pbch_polynomial_degree; i++) { - ret = fscanf(pbch_file_fd,"%s",dummy); + ret = fscanf(pbch_file_fd,"%24s",dummy); if (ret < 0) { printf("fscanf failed: %s\n", strerror(errno)); @@ -291,9 +268,7 @@ void load_pbch_desc(FILE *pbch_file_fd) printf("\n"); } -double pbch_bler(double sinr) -{ - +double pbch_bler(double sinr) { int i; double log10_bler=pbch_awgn_polynomial[pbch_polynomial_degree]; double sinrpow=sinr; @@ -317,6 +292,5 @@ double pbch_bler(double sinr) //printf ("sinr %f bler %f\n",sinr,bler); return(bler); - } diff --git a/openair1/SIMULATION/TOOLS/ch_desc_proto.c b/openair1/SIMULATION/TOOLS/ch_desc_proto.c index 8b07a596a925774c1c6cdc4a9296bcec2e8673be..b1e71fcfb4a0c99bd2066e9d58dedf342860de9d 100644 --- a/openair1/SIMULATION/TOOLS/ch_desc_proto.c +++ b/openair1/SIMULATION/TOOLS/ch_desc_proto.c @@ -31,17 +31,14 @@ enum sector {SEC1, SEC2, SEC3}; scenario_desc_t scenario; -void get_chan_desc(node_desc_t* node_tx, node_desc_t* node_rx, channel_desc_t *ch_desc, scenario_desc_t* scenario) -{ +void get_chan_desc(node_desc_t *node_tx, node_desc_t *node_rx, channel_desc_t *ch_desc, scenario_desc_t *scenario) { double dist; dist = sqrt(pow((node_tx->x - node_rx->x), 2) + pow((node_tx->y - node_rx->y), 2)); - /* conversion of distance into KM 3gpp (36-942)*/ ch_desc->path_loss_dB = (128.1 + 37.6 * log10(dist/1000)); } -int main() -{ +int main() { int enb_count = 16; int ue_count = 50; double sect_angle[3]= {0,2*PI/3,4*PI/3}; @@ -75,19 +72,16 @@ int main() "bler_9.csv", "bler_10.csv", "bler_11.csv", "bler_12.csv", "bler_13.csv", "bler_14.csv", "bler_15.csv", "bler_16.csv", "bler_17.csv", "bler_18.csv", "bler_19.csv", "bler_20.csv", "bler_21.csv", "bler_22.csv" }; - double beta[MCS_COUNT] = {0, 0, 0, 0, 0.9459960937499999, 1.2912109374999994, 1.0133789062499998, 1.000390625, 1.02392578125, 1.8595703124999998, 2.424389648437498, 2.3946533203124982, 2.5790039062499988, 2.4084960937499984, 2.782617187499999, 2.7868652343749996, 3.92099609375, 4.0392578125, 4.56109619140625, 5.03338623046875, 5.810888671875, 6.449108886718749 }; - double enb_position[][2] = {{1100,1100},{1100,2100},{1100,3100},{1100,4100}, {2100,1100},{2100,2100},{2100,3100},{2100,4100}, {3100,1100},{3100,2100},{3100,3100},{3100,4100}, {4100,1100},{4100,2100},{4100,3100},{4100,4100} }; - double ue_position[][2] = {{3340,4740},{1500,620},{1780,4220},{1300,3540},{780,3100}, {1140,540},{1340,3660},{860,1220},{2700,2140},{3860,3060}, {3740,1060},{1700,3060},{2180,1620},{4420,1060},{1300,3340}, @@ -99,15 +93,12 @@ int main() {3420,2820},{1580,3940},{660,2100},{2740,1180},{2500,2500}, {3580,3580},{3740,3140},{3020,3020},{4340,4140},{980,4300} }; - randominit(0); - ///////////////////////////////////////////////////////////////////////////////////////////////// int tabl_len=0; double local_table[MCS_COUNT][9][9]; for (mcs = 5; mcs <= MCS_COUNT; mcs++) { - fp = fopen(file_name[mcs - 1],"r"); if (fp == NULL) { @@ -117,7 +108,6 @@ int main() tabl_len=0; while (!feof(fp)) { - sinr_bler = strtok(buffer, ";"); local_table[mcs-1][0][tabl_len] = atof(sinr_bler); sinr_bler = strtok(NULL,";"); @@ -133,12 +123,8 @@ int main() for (tabl_len=0; tabl_len<9; tabl_len++) printf("%lf %lf \n ",local_table[mcs-1][0][tabl_len],local_table[mcs-1][1][tabl_len]); - - } - - //////////////////////////////////////////////////////////////////////////////////////////////////// for (enb_index = 0; enb_index < enb_count; enb_index++) @@ -172,7 +158,6 @@ int main() ul_channel[ue_index][enb_index] = new_channel_desc_scm(1, 1, SCM_C, 7.68, 0, 0, 0); dl_channel[ue_index][enb_index] = new_channel_desc_scm(1, 1, SCM_C, 7.68, 0, 0, 0); //printf("ue %d enb %d\n", ue_index, enb_index); - /* Calculating the angle in the range -pi to pi from the slope */ //(ue_data[ue_index])->alpha_rad[enb_index] = (double)(atan2((ue_data[ue_index]->x - enb_data[enb_index]->x), (ue_data[ue_index]->y - enb_data[enb_index]->y))); ue_data[ue_index]->alpha_rad[enb_index] = atan2((ue_data[ue_index]->x - enb_data[enb_index]->x), (ue_data[ue_index]->y - enb_data[enb_index]->y)); @@ -190,8 +175,7 @@ int main() /* gain = -min(Am , 12 * (theta/theta_3dB)^2) */ gain_max = (gain_sec[SEC1] > gain_sec[SEC2]) ? ((gain_sec[SEC1] > gain_sec[SEC3]) ? gain_sec[SEC1]:gain_sec[SEC3]) : - ((gain_sec[SEC2] > gain_sec[SEC3]) ? gain_sec[SEC2]:gain_sec[SEC3]); - + ((gain_sec[SEC2] > gain_sec[SEC3]) ? gain_sec[SEC2]:gain_sec[SEC3]); get_chan_desc(enb_data[enb_index], ue_data[ue_index], ul_channel[ue_index][enb_index], &scenario); get_chan_desc(enb_data[enb_index], ue_data[ue_index], dl_channel[ue_index][enb_index], &scenario); @@ -204,7 +188,6 @@ int main() //return_value = random_channel(ul_channel[ue_index][enb_index]); return_value = random_channel(dl_channel[ue_index][enb_index]); - /* Thermal noise is calculated using 10log10(K*T*B) K = Boltzmann´s constant T = room temperature B = bandwidth */ /* Taken as constant for the time being since the BW is not changing */ thermal_noise = -105; //value in dBm @@ -222,7 +205,6 @@ int main() - (thermal_noise + ue_data[ue_index]->rx_noise_level) + 10 * log10 (pow(dl_channel[ue_index][enb_index]->chF[0][count].r, 2) + pow(dl_channel[ue_index][enb_index]->chF[0][count].i, 2)); - //printf("Dl_link SNR for res. block %d is %lf\n", count, sinr[enb_index][count]); } } @@ -252,7 +234,6 @@ int main() //printf("mcs value %d \n",mcs); //printf("beta value %lf \n",-beta[mcs-1]); //printf("snr_eff value %lf \n",log(sinr_eff[ue_index][mcs-1])); - sinr_eff[ue_index][mcs-1] = -beta[mcs-1] *log((sinr_eff[ue_index][mcs-1])/(2*nb_rb));// //printf("snr_eff value %lf \n",sinr_eff[ue_index][mcs-1]); sinr_eff[ue_index][mcs-1] = 10 * log10(sinr_eff[ue_index][mcs-1]); @@ -264,9 +245,7 @@ int main() } sinr_eff[ue_index][mcs-1] /= 10; - //printf("Effective snr %lf \n",sinr_eff[ue_index][mcs-1]); - bler[ue_index][mcs-1] = 0; /*line_num = 0; @@ -295,37 +274,31 @@ int main() } fclose(fp);*/ for (tabl_len=0; tabl_len<9; tabl_len++) { - if(tabl_len==0) if (sinr_eff[ue_index][mcs-1] < local_table[mcs-1][0][tabl_len]) { bler[ue_index][mcs-1] = 1; break; } - if (sinr_eff[ue_index][mcs-1] == local_table[mcs-1][0][tabl_len]) { bler[ue_index][mcs-1] = local_table[mcs-1][1][tabl_len]; } - } //printf("\n###Dl_link UE %d attached to eNB %d \n MCS %d effective SNR %lf BLER %lf", ue_index, att_enb_index, mcs,sinr_eff[ue_index][mcs-1],bler[ue_index][mcs-1]); } //printf("\n\n"); - printf("\n Ue_ix enb_ix mcs5 mcs6 mcs7 mcs8 mcs9 mcs10 mcs11 mcs12 mcs13\ mcs14 mcs15 mcs16 mcs17 mcs18 mcs19 mcs20 mcs21 mcs22\n"); - printf("SINR %4d %4d %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\ - %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\n", + %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\n", ue_index, att_enb_index, sinr_eff[ue_index][4], sinr_eff[ue_index][5], sinr_eff[ue_index][6], sinr_eff[ue_index][7], sinr_eff[ue_index][8], sinr_eff[ue_index][9], sinr_eff[ue_index][10], sinr_eff[ue_index][11], sinr_eff[ue_index][12], sinr_eff[ue_index][13], sinr_eff[ue_index][14], sinr_eff[ue_index][15], sinr_eff[ue_index][16], sinr_eff[ue_index][17], sinr_eff[ue_index][18], sinr_eff[ue_index][19], sinr_eff[ue_index][20], sinr_eff[ue_index][21], sinr_eff[ue_index][22]); - printf("BLER %4d %4d %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\ - %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\n", + %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f %+4.2f\n", ue_index, att_enb_index, bler[ue_index][4], bler[ue_index][5], bler[ue_index][6], bler[ue_index][7], bler[ue_index][8], bler[ue_index][9], bler[ue_index][10], bler[ue_index][11], bler[ue_index][12], bler[ue_index][13], bler[ue_index][14], bler[ue_index][15], bler[ue_index][16], bler[ue_index][17], diff --git a/openair1/SIMULATION/TOOLS/gauss.c b/openair1/SIMULATION/TOOLS/gauss.c index f69748270b0cc8a4baf23e54ae8fc0259159913e..cc4b1fb793e1115bc2c8de5bc7abb5b603f7369d 100644 --- a/openair1/SIMULATION/TOOLS/gauss.c +++ b/openair1/SIMULATION/TOOLS/gauss.c @@ -27,20 +27,15 @@ unsigned int *generate_gauss_LUT(unsigned char Nbits, unsigned char L - ) -{ - + ) { unsigned int *LUT_ptr,i; - LUT_ptr = (unsigned int *)malloc((1<<(Nbits-1))*sizeof(int)); assert(LUT_ptr); - for (i=0; i<(1<<(Nbits-1)); i++) { LUT_ptr[i] = (unsigned int)((double)((unsigned int)(1<<31))*erf(i*L/(double)(1<<(Nbits-1)))); - #ifdef LUTDEBUG - printf("pos %d : LUT_ptr[%d]=%x (%f)\n",i,i,LUT_ptr[i],(double)(erf(i*L/(double)(1<<(Nbits-1))))); + printf("pos %u : LUT_ptr[%u]=%x (%f)\n",i,i,LUT_ptr[i],(double)(erf(i*L/(double)(1<<(Nbits-1))))); #endif //LUTDEBUG } @@ -51,40 +46,29 @@ unsigned int *generate_gauss_LUT(unsigned char Nbits, int gauss(unsigned int *gauss_LUT, unsigned char Nbits - ) -{ - + ) { unsigned int search_pos,step_size,u,tmp,tmpm1,tmpp1,s; - // Get a 32-bit uniform random-variable u = taus(); - #ifdef DEBUG printf("u = %u\n",u); #endif //DEBUG - // if it is larger than 2^31 (here negative), save the sign and rescale down to 31-bits. - s = u & 0x80000000; u &= 0x7fffffff; - - #ifdef DEBUG - printf("u = %x,s=%d\n",u,s); + printf("u = %x,s=%u\n",u,s); #endif //DEBUG - search_pos = (1<<(Nbits-2)); // starting position of the binary search step_size = search_pos; do { - step_size >>= 1; - tmp = gauss_LUT[search_pos]; tmpm1 = gauss_LUT[search_pos-1]; tmpp1 = gauss_LUT[search_pos+1]; #ifdef DEBUG - printf("search_pos %d, step_size %d: t %x tm %x,tp %x\n",search_pos,step_size,tmp,tmpm1,tmpp1); + printf("search_pos %u, step_size %u: t %x tm %x,tp %x\n",search_pos,step_size,tmp,tmpm1,tmpp1); #endif //DEBUG if (u <= tmp) @@ -96,12 +80,10 @@ int gauss(unsigned int *gauss_LUT, return s==0 ? search_pos : - search_pos; else search_pos += step_size; - } while (step_size > 0); // If it gets here we're beyond the positive edge so return max return s==0 ? (1<<(Nbits-1))-1 : 1-((1<<(Nbits-1))); - } @@ -109,9 +91,7 @@ int gauss(unsigned int *gauss_LUT, #define Nhistbits 8 -void main(int argc,char **argv) -{ - +void main(int argc,char **argv) { unsigned int *gauss_LUT_ptr,i; unsigned int hist[(1<<Nhistbits)]; int gvar,maxg=0,ming=9999999,maxnum=0,L,Ntrials,Nbits; @@ -125,7 +105,6 @@ void main(int argc,char **argv) Nbits = atoi(argv[1]); L = atoi(argv[2]); Ntrials = atoi(argv[3]); - set_taus_seed(); // Generate Gaussian LUT 12-bit quantization over 5 standard deviations gauss_LUT_ptr = generate_gauss_LUT(Nbits,L); @@ -134,7 +113,6 @@ void main(int argc,char **argv) hist[i] = 0; for (i=0; i<Ntrials; i++) { - gvar = gauss(gauss_LUT_ptr,Nbits); if (gvar == ((1<<(Nbits-1))-1)) @@ -151,10 +129,8 @@ void main(int argc,char **argv) printf("Tail probability = %e(%x)\n",2*erfc((double)L*gauss_LUT_ptr[(1<<(Nbits-1))-1]/(unsigned int)(1<<31)),gauss_LUT_ptr[(1<<(Nbits-1))-1]); printf("max %d, min %d, mean %f, stddev %f, Pr(maxnum)=%e(%d)\n",maxg,ming,meang,sqrt(varg),(double)maxnum/Ntrials,maxnum); - // for (i=0;i<(1<<Nhistbits);i++) // printf("%d : %u\n",i,hist[i]); - free(gauss_LUT_ptr); } diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c index daa3462b1c85c1f4cf6ec22fcb29cea1e740c6e3..f4835570bf386eef8435720825d8e620c3b49c37 100644 --- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c +++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c @@ -37,24 +37,18 @@ void multipath_tv_channel(channel_desc_t *desc, double **rx_sig_re, double **rx_sig_im, uint16_t length, - uint8_t keep_channel) -{ - - double complex **tx,**rx,***H_t,*rx_temp;//, *tv_H_t; + uint8_t keep_channel) { + double complex **tx,**rx,* **H_t,*rx_temp; //, *tv_H_t; double path_loss = pow(10,desc->path_loss_dB/20); int i,j,k,dd; - dd = abs(desc->channel_offset); - #ifdef DEBUG_CH - printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %d\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length, + printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %g\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length, desc->max_Doppler); #endif - tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex)); rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex)); - - H_t= (double complex ***) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **)); + H_t= (double complex ** *) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **)); // tv_H_t = (double complex *) malloc(length*sizeof(double complex)); rx_temp= (double complex *) calloc(length,sizeof(double complex)); @@ -128,17 +122,13 @@ void multipath_tv_channel(channel_desc_t *desc, } free(H_t); - free(rx_temp); } //TODO: make phi_rad a parameter of this function -void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length) -{ - +void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length) { int i,j,p,l,k; double *alpha,*phi_rad,pi=acos(-1),*w_Hz; - alpha = (double *)calloc(desc->nb_paths,sizeof(double)); phi_rad = (double *)calloc(desc->nb_paths,sizeof(double)); w_Hz = (double *)calloc(desc->nb_paths,sizeof(double)); @@ -203,21 +193,17 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length) } // time varying convolution -void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int dd) -{ - +void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int dd) { int i,j; for(i=0; i<((int)nb_samples-dd); i++) { for(j=0; j<nb_taps; j++) { if(i>j) y[i+dd] += creal(h[i][j])*creal(x[i-j])-cimag(h[i][j])*cimag(x[i-j]) + I*(creal(h[i][j])*cimag(x[i-j])+cimag(h[i][j])*creal(x[i-j])); - } } } -double frand_a_b(double a, double b) -{ +double frand_a_b(double a, double b) { return (rand()/(double)RAND_MAX)*(b-a)+a; } diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h new file mode 100644 index 0000000000000000000000000000000000000000..9e341f9bcbc87c2a19f1e28ba7d994b31153f96a --- /dev/null +++ b/openair2/COMMON/f1ap_messages_def.h @@ -0,0 +1,48 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* F1AP -> SCTP */ +MESSAGE_DEF(F1AP_CU_SCTP_REQ , MESSAGE_PRIORITY_MED, f1ap_cu_setup_req_t , f1ap_cu_setup_req) + +/* eNB_DU application layer -> F1AP messages or CU F1AP -> RRC*/ +MESSAGE_DEF(F1AP_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_setup_req_t , f1ap_setup_req) + +/* F1AP -> eNB_DU or eNB_CU_RRC -> F1AP application layer messages */ +MESSAGE_DEF(F1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, f1ap_setup_resp_t , f1ap_setup_resp) +MESSAGE_DEF(F1AP_SETUP_FAILURE , MESSAGE_PRIORITY_MED, f1ap_setup_failure_t , f1ap_setup_failure) + +/* MAC -> F1AP messages */ +MESSAGE_DEF(F1AP_INITIAL_UL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_initial_ul_rrc_message_t , f1ap_initial_ul_rrc_message) +MESSAGE_DEF(F1AP_UL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_ul_rrc_message_t , f1ap_ul_rrc_message) +//MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_resp_t, f1ap_initial_context_setup_resp) +//MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_FAILURE, MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_failure_t, f1ap_initial_context_setup_failure) +MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_req_t, f1ap_ue_context_release_req) +MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cmd) + + +/* RRC -> F1AP messages */ +MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t , f1ap_dl_rrc_message ) +//MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req ) +MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_req_t, f1ap_ue_context_setup_req) + + + + diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h new file mode 100644 index 0000000000000000000000000000000000000000..d83f9cb71d74c9f00ba6ef2a6d7ee32e1665103a --- /dev/null +++ b/openair2/COMMON/f1ap_messages_types.h @@ -0,0 +1,308 @@ +/* + * 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 F1AP_MESSAGES_TYPES_H_ +#define F1AP_MESSAGES_TYPES_H_ + +#include "rlc.h" + +//-------------------------------------------------------------------------------------------// +// Defines to access message fields. + +#define F1AP_CU_SCTP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_cu_sctp_req + +#define F1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_req +#define F1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_resp +#define F1AP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_failure + +#define F1AP_INITIAL_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_initial_ul_rrc_message +#define F1AP_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ul_rrc_message +#define F1AP_UE_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_req +#define F1AP_UE_CONTEXT_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_resp +#define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp +#define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail + +#define F1AP_DL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_dl_rrc_message +#define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req +#define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req +#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req + +/* Length of the transport layer address string + * 160 bits / 8 bits by char. + */ +#define F1AP_TRANSPORT_LAYER_ADDRESS_SIZE (160 / 8) + +#define F1AP_MAX_NB_CU_IP_ADDRESS 10 + +// Note this should be 512 from maxval in 38.473 +#define F1AP_MAX_NB_CELLS 2 + +typedef struct f1ap_net_ip_address_s { + unsigned ipv4:1; + unsigned ipv6:1; + char ipv4_address[16]; + char ipv6_address[46]; +} f1ap_net_ip_address_t; + +typedef struct f1ap_cu_setup_req_s { + // +} f1ap_cu_setup_req_t; + +typedef struct f1ap_setup_req_s { + + // Midhaul networking parameters + + /* Connexion id used between SCTP/F1AP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* The eNB IP address to bind */ + f1ap_net_ip_address_t CU_f1_ip_address; + f1ap_net_ip_address_t DU_f1_ip_address; + + /* Number of SCTP streams used for a mme association */ + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + + uint16_t default_sctp_stream_id; + + // F1_Setup_Req payload + uint64_t gNB_DU_id; + char *gNB_DU_name; + + /* The type of the cell */ + enum cell_type_e cell_type; + + /// number of DU cells available + uint16_t num_cells_available; //0< num_cells_available <= 512; + + // Served Cell Information + /* Tracking area code */ + uint16_t tac[F1AP_MAX_NB_CELLS]; + + /* Mobile Country Codes + * Mobile Network Codes + */ + uint16_t mcc[F1AP_MAX_NB_CELLS];//[6]; + uint16_t mnc[F1AP_MAX_NB_CELLS];//[6]; + uint8_t mnc_digit_length[F1AP_MAX_NB_CELLS];//[6]; + + // NR Global Cell Id + uint64_t nr_cellid[F1AP_MAX_NB_CELLS]; + // NR Physical Cell Ids + uint16_t nr_pci[F1AP_MAX_NB_CELLS]; + // Number of slide support items (max 16, could be increased to as much as 1024) + uint16_t num_ssi[F1AP_MAX_NB_CELLS];//[6]; + uint8_t sst[F1AP_MAX_NB_CELLS];//[16][6]; + uint8_t sd[F1AP_MAX_NB_CELLS];//[16][6]; + // fdd_flag = 1 means FDD, 0 means TDD + int fdd_flag; + + union { + struct { + uint32_t ul_nr_arfcn; + uint8_t ul_scs; + uint8_t ul_nrb; + + uint32_t dl_nr_arfcn; + uint8_t dl_scs; + uint8_t dl_nrb; + + uint32_t sul_active; + uint32_t sul_nr_arfcn; + uint8_t sul_scs; + uint8_t sul_nrb; + + uint8_t ul_num_frequency_bands; + uint16_t ul_nr_band[32]; + uint8_t ul_num_sul_frequency_bands; + uint16_t ul_nr_sul_band[32]; + + uint8_t dl_num_frequency_bands; + uint16_t dl_nr_band[32]; + uint8_t dl_num_sul_frequency_bands; + uint16_t dl_nr_sul_band[32]; + } fdd; + struct { + + uint32_t nr_arfcn; + uint8_t scs; + uint8_t nrb; + + uint32_t sul_active; + uint32_t sul_nr_arfcn; + uint8_t sul_scs; + uint8_t sul_nrb; + + uint8_t num_frequency_bands; + uint16_t nr_band[32]; + uint8_t num_sul_frequency_bands; + uint16_t nr_sul_band[32]; + + } tdd; + } nr_mode_info[F1AP_MAX_NB_CELLS]; + + char *measurement_timing_information[F1AP_MAX_NB_CELLS]; + uint8_t ranac[F1AP_MAX_NB_CELLS]; + + // System Information + uint8_t *mib[F1AP_MAX_NB_CELLS]; + int mib_length[F1AP_MAX_NB_CELLS]; + uint8_t *sib1[F1AP_MAX_NB_CELLS]; + int sib1_length[F1AP_MAX_NB_CELLS]; + + +} f1ap_setup_req_t; + +typedef struct f1ap_setup_resp_s { + /* Connexion id used between SCTP/F1AP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* Number of SCTP streams used for a mme association */ + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + + /// string holding gNB_CU_name + char *gNB_CU_name; + /// number of DU cells to activate + uint16_t num_cells_to_activate; //0< num_cells_to_activate <= 512; + /// mcc of DU cells + uint16_t mcc[F1AP_MAX_NB_CELLS]; + /// mnc of DU cells + uint16_t mnc[F1AP_MAX_NB_CELLS]; + /// mnc digit length of DU cells + uint8_t mnc_digit_length[F1AP_MAX_NB_CELLS]; + // NR Global Cell Id + uint64_t nr_cellid[F1AP_MAX_NB_CELLS]; + /// NRPCI + uint16_t nrpci[F1AP_MAX_NB_CELLS]; + /// num SI messages per DU cell + uint8_t num_SI[F1AP_MAX_NB_CELLS]; + /// SI message containers (up to 21 messages per cell) + uint8_t *SI_container[F1AP_MAX_NB_CELLS][21]; + int SI_container_length[F1AP_MAX_NB_CELLS][21]; +} f1ap_setup_resp_t; + +typedef struct f1ap_setup_failure_s { + uint16_t cause; + uint16_t time_to_wait; + uint16_t criticality_diagnostics; +} f1ap_setup_failure_t; + +typedef struct f1ap_dl_rrc_message_s { + + uint32_t gNB_CU_ue_id; + uint32_t gNB_DU_ue_id; + uint32_t old_gNB_DU_ue_id; + uint16_t rnti; + uint8_t srb_id; + uint8_t execute_duplication; + uint8_t *rrc_container; + int rrc_container_length; + union { + // both map 0..255 => 1..256 + uint8_t en_dc; + uint8_t ngran; + } RAT_frequency_priority_information; +} f1ap_dl_rrc_message_t; + +typedef struct f1ap_initial_ul_rrc_message_s { + uint32_t gNB_DU_ue_id; + /// mcc of DU cell + uint16_t mcc; + /// mnc of DU cell + uint16_t mnc; + /// mnc digit length of DU cells + uint8_t mnc_digit_length; + /// nr cell id + uint64_t nr_cellid; + /// crnti + uint16_t crnti; + uint8_t *rrc_container; + int rrc_container_length; + uint8_t *du2cu_rrc_container; + int du2cu_rrc_container_length; +} f1ap_initial_ul_rrc_message_t; + +typedef struct f1ap_ul_rrc_message_s { + uint16_t rnti; + uint8_t srb_id; + uint8_t *rrc_container; + int rrc_container_length; +} f1ap_ul_rrc_message_t; + +typedef struct f1ap_up_tnl_s { + in_addr_t tl_address; // currently only IPv4 supported + uint32_t gtp_teid; +} f1ap_up_tnl_t; + +typedef struct f1ap_drb_to_be_setup_s { + uint8_t drb_id; + f1ap_up_tnl_t up_ul_tnl[2]; + uint8_t up_ul_tnl_length; + rlc_mode_t rlc_mode; +} f1ap_drb_to_be_setup_t; + +typedef struct f1ap_ue_context_setup_req_s { + uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti + uint32_t *gNB_DU_ue_id; + uint16_t rnti; + // SpCell Info + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + uint64_t nr_cellid; + uint8_t servCellIndex; + uint8_t *cellULConfigured; + uint32_t servCellId; + uint8_t *cu_to_du_rrc_information; + uint8_t cu_to_du_rrc_information_length; + f1ap_drb_to_be_setup_t *drbs_to_be_setup; // BK: need to replace by s1ap_initial_context_setup_req + uint8_t drbs_to_be_setup_length; // BK: need to replace by s1ap_initial_context_setup_req + s1ap_initial_context_setup_req_t *s1ap_initial_context_setup_req; + // coniatner for the rrc_eNB_generate_SecurityModeCommand message + uint8_t *rrc_container; + int rrc_container_length; +} f1ap_ue_context_setup_req_t; + +typedef enum F1ap_Cause_e { + F1AP_CAUSE_NOTHING, /* No components present */ + F1AP_CAUSE_RADIO_NETWORK, + F1AP_CAUSE_TRANSPORT, + F1AP_CAUSE_PROTOCOL, + F1AP_CAUSE_MISC, +} f1ap_Cause_t; + +typedef struct f1ap_ue_context_release_s { + uint16_t rnti; + f1ap_Cause_t cause; + long cause_value; + uint8_t *rrc_container; + int rrc_container_length; +} f1ap_ue_context_release_req_t, f1ap_ue_context_release_cmd_t, + f1ap_ue_context_release_cplt_t; + +#endif /* F1AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h index 014122023530eabb6eca70c9c1f2f3b405fc83b8..ab05f394a1c9d04d2490ba5a9527f448dd834034 100644 --- a/openair2/COMMON/mac_rrc_primitives.h +++ b/openair2/COMMON/mac_rrc_primitives.h @@ -390,7 +390,7 @@ typedef struct { -#define IDLE 0 +//#define IDLE 0 #define NEED_RADIO_CONFIG 3 #define RADIO_CONFIG_TX 2 #define RADIO_CONFIG_OK 1 diff --git a/openair2/COMMON/messages_def.h b/openair2/COMMON/messages_def.h index f6e2dd0f4b0159defbbdc18c065957045972a3ec..b0219db50a284739c41f86c49b40523baddc62af 100644 --- a/openair2/COMMON/messages_def.h +++ b/openair2/COMMON/messages_def.h @@ -34,6 +34,7 @@ #include "ral_messages_def.h" #endif #include "s1ap_messages_def.h" +#include "f1ap_messages_def.h" #include "x2ap_messages_def.h" #include "sctp_messages_def.h" #include "udp_messages_def.h" diff --git a/openair2/COMMON/nas_messages_def.h b/openair2/COMMON/nas_messages_def.h index 34d6d64a1fbd736c63851658a7dfa7135c7d3976..ee3b97e7a98dd0a085a9f958c212a77cdd55d5fb 100644 --- a/openair2/COMMON/nas_messages_def.h +++ b/openair2/COMMON/nas_messages_def.h @@ -26,7 +26,6 @@ * Author: winckel */ -#if defined(ENABLE_USE_MME) && defined(ENABLE_NAS_UE_LOGGING) //-------------------------------------------------------------------------------------------// // Messages for NAS logging MESSAGE_DEF(NAS_DL_EMM_RAW_MSG, MESSAGE_PRIORITY_MED, nas_raw_msg_t, nas_dl_emm_raw_msg) @@ -46,4 +45,4 @@ MESSAGE_DEF(NAS_DL_ESM_PROTECTED_MSG, MESSAGE_PRIORITY_MED, nas_esm_ MESSAGE_DEF(NAS_UL_ESM_PROTECTED_MSG, MESSAGE_PRIORITY_MED, nas_esm_protected_msg_t, nas_ul_esm_protected_msg) //-------------------------------------------------------------------------------------------// -#endif /* ENABLE_USE_MME */ + diff --git a/openair2/COMMON/nas_messages_types.h b/openair2/COMMON/nas_messages_types.h index 5cb1927aca782c5dc1a1f5eff27e7b86d6171c27..8f0e54f85c5c4e4d132ef9eb4e354cfb31393f25 100644 --- a/openair2/COMMON/nas_messages_types.h +++ b/openair2/COMMON/nas_messages_types.h @@ -29,7 +29,7 @@ #ifndef NAS_MESSAGES_TYPES_H_ #define NAS_MESSAGES_TYPES_H_ -# if defined(ENABLE_USE_MME) && defined(ENABLE_NAS_UE_LOGGING) + #include "nas_message.h" @@ -142,5 +142,4 @@ typedef struct nas_esm_protected_msg_s { ESM_msg choice; } nas_esm_protected_msg_t; -# endif /* ENABLE_USE_MME */ #endif /* NAS_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index ee8d6abcc9cb2e4b97ec53e0346e28ec59c44598..ef9f591958819c6d4d4f5aef784b6bddd204bece 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -236,9 +236,7 @@ typedef struct protocol_ctxt_s { sub_frame_t subframe; /*!< \brief LTE sub frame number.*/ eNB_index_t eNB_index; /*!< \brief valid for UE indicating the index of connected eNB(s) */ boolean_t configured; /*!< \brief flag indicating whether the instance is configured or not */ -#ifdef Rel14 boolean_t brOption; -#endif } protocol_ctxt_t; // warning time hardcoded #define PROTOCOL_CTXT_TIME_MILLI_SECONDS(CtXt_h) ((CtXt_h)->frame*10+(CtXt_h)->subframe) diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index 08ea93f427add5aa6dbd032e54180848cb3e85da..40005459666864367edcbc5eee52917950d48d27 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -72,3 +72,6 @@ MESSAGE_DEF(NAS_CONN_ESTABLI_CNF, MESSAGE_PRIORITY_MED, NasConnEstab MESSAGE_DEF(NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NasConnReleaseInd, nas_conn_release_ind) MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, NasUlDataCnf, nas_ul_data_cnf) MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd, nas_dl_data_ind) + +// eNB: realtime -> RRC messages +MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 15eb33358eaab40858fb9f19a042824ed31e2ea7..635e284c627610ac93023a449e601abfc5472dd1 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -32,9 +32,11 @@ #include "as_message.h" #include "rrc_types.h" #include "s1ap_messages_types.h" - #include "LTE_SystemInformationBlockType2.h" +#include "f1ap_messages_types.h" +#include "LTE_SystemInformationBlockType2.h" #include "LTE_SL-OffsetIndicator-r12.h" #include "LTE_SubframeBitmapSL-r12.h" +#include "LTE_DRX-Config.h" #include "LTE_SL-CP-Len-r12.h" #include "LTE_SL-PeriodComm-r12.h" #include "LTE_SL-DiscResourcePool-r12.h" @@ -81,6 +83,8 @@ #define NAS_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_cnf #define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind +#define RRC_SUBFRAME_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.rrc_subframe_process + //-------------------------------------------------------------------------------------------// typedef struct RrcStateInd_s { Rrc_State_t state; @@ -138,6 +142,14 @@ typedef struct RadioResourceConfig_s { long bcch_modificationPeriodCoeff; long pcch_defaultPagingCycle; long pcch_nB; + LTE_DRX_Config_PR drx_Config_present; + long drx_onDurationTimer; + long drx_InactivityTimer; + long drx_RetransmissionTimer; + LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR drx_longDrx_CycleStartOffset_present; + long drx_longDrx_CycleStartOffset; + long drx_shortDrx_Cycle; + long drx_shortDrx_ShortCycleTimer; long ue_TimersAndConstants_t300; long ue_TimersAndConstants_t301; long ue_TimersAndConstants_t310; @@ -146,7 +158,7 @@ typedef struct RadioResourceConfig_s { long ue_TimersAndConstants_n311; long ue_TransmissionMode; long ue_multiple_max; -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //SIB2 BR Options long* preambleTransMax_CE_r13; BOOLEAN_t prach_ConfigCommon_v1310; @@ -190,7 +202,7 @@ typedef struct RrcConfigurationReq_s { RadioResourceConfig radioresourceconfig[MAX_NUM_CCs]; RadioResourceConfig radioresourceconfig_BR[MAX_NUM_CCs]; - + #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) //MIB long schedulingInfoSIB1_BR_r13[MAX_NUM_CCs]; @@ -253,11 +265,11 @@ typedef struct RrcConfigurationReq_s { bool sib2_freq_hoppingParameters_r13_exists [MAX_NUM_CCs]; long *sib2_mpdcch_pdsch_hoppingNB_r13 [MAX_NUM_CCs]; long *sib2_interval_DLHoppingConfigCommonModeA_r13 [MAX_NUM_CCs]; - long sib2_interval_DLHoppingConfigCommonModeA_r13_val [MAX_NUM_CCs]; - long *sib2_interval_DLHoppingConfigCommonModeB_r13 [MAX_NUM_CCs]; - long sib2_interval_DLHoppingConfigCommonModeB_r13_val [MAX_NUM_CCs]; + long sib2_interval_DLHoppingConfigCommonModeA_r13_val [MAX_NUM_CCs]; + long *sib2_interval_DLHoppingConfigCommonModeB_r13 [MAX_NUM_CCs]; + long sib2_interval_DLHoppingConfigCommonModeB_r13_val [MAX_NUM_CCs]; long *sib2_interval_ULHoppingConfigCommonModeA_r13 [MAX_NUM_CCs]; - long sib2_interval_ULHoppingConfigCommonModeA_r13_val [MAX_NUM_CCs]; + long sib2_interval_ULHoppingConfigCommonModeA_r13_val [MAX_NUM_CCs]; long *sib2_interval_ULHoppingConfigCommonModeB_r13 [MAX_NUM_CCs]; long sib2_interval_ULHoppingConfigCommonModeB_r13_val [MAX_NUM_CCs]; long *sib2_mpdcch_pdsch_hoppingOffset_r13 [MAX_NUM_CCs]; @@ -400,4 +412,10 @@ typedef nas_release_ind_t NasConnReleaseInd; typedef ul_info_transfer_cnf_t NasUlDataCnf; typedef dl_info_transfer_ind_t NasDlDataInd; +// eNB: realtime -> RRC messages +typedef struct rrc_subframe_process_s { + protocol_ctxt_t ctxt; + int CC_id; +} RrcSubframeProcess; + #endif /* RRC_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/s1ap_messages_def.h b/openair2/COMMON/s1ap_messages_def.h index f98782f19ec238bb32de3fd0ce770372fa032f37..57201721ced6b4019577343a897bae1bdb3db2cd 100644 --- a/openair2/COMMON/s1ap_messages_def.h +++ b/openair2/COMMON/s1ap_messages_def.h @@ -39,6 +39,8 @@ MESSAGE_DEF(S1AP_PAGING_LOG , MESSAGE_PRIORITY_MED, IttiMsgText MESSAGE_DEF(S1AP_E_RAB_RELEASE_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_release_request_log) MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_e_rab_release_response_log) MESSAGE_DEF(S1AP_ERROR_INDICATION_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_error_indication_log) +MESSAGE_DEF(S1AP_PATH_SWITCH_REQ_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_path_switch_req_log) +MESSAGE_DEF(S1AP_PATH_SWITCH_REQ_ACK_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_path_switch_req_ack_log) /* eNB application layer -> S1AP messages */ MESSAGE_DEF(S1AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, s1ap_register_enb_req_t , s1ap_register_enb_req) @@ -62,6 +64,8 @@ MESSAGE_DEF(S1AP_E_RAB_SETUP_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_se MESSAGE_DEF(S1AP_E_RAB_SETUP_REQUEST_FAIL , MESSAGE_PRIORITY_MED, s1ap_e_rab_setup_req_fail_t , s1ap_e_rab_setup_request_fail) MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_modify_resp_t , s1ap_e_rab_modify_resp) MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_resp_t , s1ap_e_rab_release_resp) +MESSAGE_DEF(S1AP_PATH_SWITCH_REQ , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_t , s1ap_path_switch_req) +MESSAGE_DEF(S1AP_PATH_SWITCH_REQ_ACK , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_ack_t , s1ap_path_switch_req_ack) /* S1AP -> RRC messages */ MESSAGE_DEF(S1AP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t , s1ap_downlink_nas ) diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index f56a340cb24d7df4c9db45b4c6f6b156568c2817..2ea8237184fa96462c3fffe17f7877b3f2200db5 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -42,6 +42,8 @@ #define S1AP_E_RAB_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_setup_resp #define S1AP_E_RAB_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_setup_req_fail #define S1AP_E_RAB_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modify_resp +#define S1AP_PATH_SWITCH_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req +#define S1AP_PATH_SWITCH_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req_ack #define S1AP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_downlink_nas #define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req @@ -269,6 +271,17 @@ typedef struct e_rab_setup_s { uint32_t gtp_teid; } e_rab_setup_t; +typedef struct e_rab_tobeswitched_s { + /* Unique e_rab_id for the UE. */ + uint8_t e_rab_id; + + /* The transport layer address for the IP packets */ + transport_layer_addr_t sgw_addr; + + /* S-GW Tunnel endpoint identifier */ + uint32_t gtp_teid; +} e_rab_tobeswitched_t; + typedef struct e_rab_modify_s { /* Unique e_rab_id for the UE. */ uint8_t e_rab_id; @@ -480,6 +493,8 @@ typedef struct s1ap_initial_context_setup_req_s { /* eNB ue s1ap id as initialized by S1AP layer */ unsigned eNB_ue_s1ap_id:24; + uint32_t mme_ue_s1ap_id; + /* UE aggregate maximum bitrate */ ambr_t ue_ambr; @@ -533,7 +548,7 @@ typedef struct s1ap_e_rab_setup_req_s { uint16_t ue_initial_id; /* MME UE id */ - uint16_t mme_ue_s1ap_id; + uint32_t mme_ue_s1ap_id; /* eNB ue s1ap id as initialized by S1AP layer */ unsigned eNB_ue_s1ap_id:24; @@ -560,6 +575,58 @@ typedef struct s1ap_e_rab_setup_resp_s { e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB]; } s1ap_e_rab_setup_resp_t; +typedef struct s1ap_path_switch_req_s { + + unsigned eNB_ue_s1ap_id:24; + + /* Number of e_rab setup-ed in the list */ + uint8_t nb_of_e_rabs; + + /* list of e_rab setup-ed by RRC layers */ + e_rab_setup_t e_rabs_tobeswitched[S1AP_MAX_E_RAB]; + + /* MME UE id */ + uint32_t mme_ue_s1ap_id; + + s1ap_gummei_t ue_gummei; + + uint16_t ue_initial_id; + + /* Security algorithms */ + security_capabilities_t security_capabilities; + +} s1ap_path_switch_req_t; + +typedef struct s1ap_path_switch_req_ack_s { + + /* UE id for initial connection to S1AP */ + uint16_t ue_initial_id; + + unsigned eNB_ue_s1ap_id:24; + + /* MME UE id */ + uint32_t mme_ue_s1ap_id; + + /* UE aggregate maximum bitrate */ + ambr_t ue_ambr; + + /* Number of e_rab setup-ed in the list */ + uint8_t nb_e_rabs_tobeswitched; + + /* list of e_rab to be switched by RRC layers */ + e_rab_tobeswitched_t e_rabs_tobeswitched[S1AP_MAX_E_RAB]; + + /* Number of e_rabs to be released by RRC */ + uint8_t nb_e_rabs_tobereleased; + + /* list of e_rabs to be released */ + e_rab_failed_t e_rabs_tobereleased[S1AP_MAX_E_RAB]; + + /* Security key */ + int next_hop_chain_count; + uint8_t next_security_key[SECURITY_KEY_LENGTH]; + +} s1ap_path_switch_req_ack_t; // S1AP --> RRC messages typedef struct s1ap_ue_release_command_s { @@ -582,7 +649,7 @@ typedef struct s1ap_e_rab_modify_req_s { uint16_t ue_initial_id; /* MME UE id */ - uint16_t mme_ue_s1ap_id; + uint32_t mme_ue_s1ap_id; /* eNB ue s1ap id as initialized by S1AP layer */ unsigned eNB_ue_s1ap_id:24; @@ -615,7 +682,7 @@ typedef struct e_rab_release_s { typedef struct s1ap_e_rab_release_command_s { /* MME UE id */ - uint16_t mme_ue_s1ap_id; + uint32_t mme_ue_s1ap_id; /* eNB ue s1ap id as initialized by S1AP layer */ unsigned eNB_ue_s1ap_id:24; @@ -633,7 +700,7 @@ typedef struct s1ap_e_rab_release_command_s { typedef struct s1ap_e_rab_release_resp_s { /* MME UE id */ - uint16_t mme_ue_s1ap_id; + uint32_t mme_ue_s1ap_id; /* eNB ue s1ap id as initialized by S1AP layer */ unsigned eNB_ue_s1ap_id:24; diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h index 318c4649e411fe51dc40ff7b3e6b27be252a97a3..2ccb7b1c29059395641813059ba1c39100f85641 100644 --- a/openair2/COMMON/tasks_def.h +++ b/openair2/COMMON/tasks_def.h @@ -46,6 +46,8 @@ TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000) // GTP_V1U task TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000) TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200) +TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200) +TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200) /// X2ap task, acts as both source and target TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200) /// Sctp task (Used by both S1AP and X2AP) @@ -54,7 +56,7 @@ TASK_DEF(TASK_SCTP, TASK_PRIORITY_MED, 200) TASK_DEF(TASK_ENB_APP, TASK_PRIORITY_MED, 200) /// eNB Agent task TASK_DEF(TASK_FLEXRAN_AGENT, TASK_PRIORITY_MED, 200) - +TASK_DEF(TASK_PROTO_AGENT, TASK_PRIORITY_MED, 200) // UE tasks and sub-tasks: /// Radio Resource Control task diff --git a/openair2/COMMON/x2ap_messages_def.h b/openair2/COMMON/x2ap_messages_def.h index d5555c183989b4573501e005620fba7b57302787..2a040c8000e9d001d8d0bc586fc30d6168fe39f4 100644 --- a/openair2/COMMON/x2ap_messages_def.h +++ b/openair2/COMMON/x2ap_messages_def.h @@ -32,6 +32,7 @@ MESSAGE_DEF(X2AP_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgT /* eNB application layer -> X2AP messages */ MESSAGE_DEF(X2AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, x2ap_register_enb_req_t , x2ap_register_enb_req) +MESSAGE_DEF(X2AP_SUBFRAME_PROCESS , MESSAGE_PRIORITY_MED, x2ap_subframe_process_t , x2ap_subframe_process) /* X2AP -> eNB application layer messages */ MESSAGE_DEF(X2AP_REGISTER_ENB_CNF , MESSAGE_PRIORITY_MED, x2ap_register_enb_cnf_t , x2ap_register_enb_cnf) @@ -40,3 +41,7 @@ MESSAGE_DEF(X2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, x2ap_der /* handover messages X2AP <-> RRC */ MESSAGE_DEF(X2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, x2ap_handover_req_t , x2ap_handover_req) MESSAGE_DEF(X2AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_handover_req_ack_t , x2ap_handover_req_ack) +MESSAGE_DEF(X2AP_HANDOVER_CANCEL , MESSAGE_PRIORITY_MED, x2ap_handover_cancel_t , x2ap_handover_cancel) + +/* handover messages X2AP <-> S1AP */ +MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, x2ap_ue_context_release_t , x2ap_ue_context_release) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 9b744ded6b5641b13ca03ccd52e27c9a9d30584a..708430b8b2a740c7f9d848d361333e12831dc789 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -22,6 +22,7 @@ #ifndef X2AP_MESSAGES_TYPES_H_ #define X2AP_MESSAGES_TYPES_H_ +#include "s1ap_messages_types.h" #include "LTE_PhysCellId.h" //-------------------------------------------------------------------------------------------// @@ -32,11 +33,32 @@ #define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack #define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf #define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind +#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release +#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel #define X2AP_MAX_NB_ENB_IP_ADDRESS 2 // eNB application layer -> X2AP messages + +/* X2AP UE CONTEXT RELEASE */ +typedef struct x2ap_ue_context_release_s { + /* used for X2AP->RRC in source and RRC->X2AP in target */ + int rnti; + + int source_assoc_id; +} x2ap_ue_context_release_t; + +typedef enum { + X2AP_T_RELOC_PREP_TIMEOUT, + X2AP_TX2_RELOC_OVERALL_TIMEOUT +} x2ap_handover_cancel_cause_t; + +typedef struct x2ap_handover_cancel_s { + int rnti; + x2ap_handover_cancel_cause_t cause; +} x2ap_handover_cancel_t; + typedef struct x2ap_register_enb_req_s { /* Unique eNB_id to identify the eNB within EPC. * For macro eNB ids this field should be 20 bits long. @@ -94,8 +116,16 @@ typedef struct x2ap_register_enb_req_s { /* eNB port for X2C*/ uint32_t enb_port_for_X2C; + + /* timers (unit: millisecond) */ + int t_reloc_prep; + int tx2_reloc_overall; } x2ap_register_enb_req_t; +typedef struct x2ap_subframe_process_s { + /* nothing, we simply use the module ID in the header */ +} x2ap_subframe_process_t; + //-------------------------------------------------------------------------------------------// // X2AP -> eNB application layer messages typedef struct x2ap_register_enb_cnf_s { @@ -127,12 +157,12 @@ typedef struct x2ap_lastvisitedcell_info_s { uint64_t time_UE_StayedInCell; }x2ap_lastvisitedcell_info_t; -//used for src typedef struct x2ap_handover_req_s { - int source_rnti; /* TODO: to be fixed/remove */ - int source_x2id; /* TODO: to be fixed/remove */ + /* used for RRC->X2AP in source eNB */ + int rnti; - unsigned old_eNB_ue_s1ap_id:24; + /* used for X2AP->RRC in target eNB */ + int x2_id; LTE_PhysCellId_t target_physCellId; @@ -158,19 +188,34 @@ typedef struct x2ap_handover_req_s { /* list of e_rab setup-ed by RRC layers */ e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB]; - /* ue_context_pP->ue_context.e_rab[i].param.sgw_addr; */ + /* list of e_rab to be setup by RRC layers */ + e_rab_t e_rab_param[S1AP_MAX_E_RAB]; x2ap_lastvisitedcell_info_t lastvisitedcell_info; - /* TODO: this parameter has to be removed */ - int target_mod_id; + uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; + int rrc_buffer_size; + + int target_assoc_id; } x2ap_handover_req_t; typedef struct x2ap_handover_req_ack_s { - int source_rnti; /* TODO: to be fixed/remove */ - int source_x2id; /* TODO: to be fixed/remove */ - /* TODO: this parameter has to be removed */ - int target_mod_id; + /* used for RRC->X2AP in target and X2AP->RRC in source */ + int rnti; + + /* used for RRC->X2AP in target */ + int x2_id_target; + + int source_assoc_id; + + uint8_t nb_e_rabs_tobesetup; + + /* list of e_rab setup-ed by RRC layers */ + e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB]; + + /* list of e_rab to be setup by RRC layers */ + e_rab_t e_rab_param[S1AP_MAX_E_RAB]; + uint8_t rrc_buffer[1024 /* arbitrary, big enough */]; int rrc_buffer_size; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 6cc3caced61a7f8324d0bf1fe2d7ccec01c6a25e..7110f681d78efa51f03c25a809c467100c59a515 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -40,9 +40,6 @@ #include "common/utils/LOG/log.h" -/*Flags showing if a mac agent has already been registered*/ -unsigned int mac_agent_registered[NUM_MAX_ENB]; - /*Array containing the Agent-MAC interfaces*/ AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; @@ -83,7 +80,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, for (i = 0; i < report_config->nr_ue; i++) { - UE_id = flexran_get_ue_id(mod_id, i); + UE_id = flexran_get_mac_ue_id(mod_id, i); ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; ue_report[i]->has_rnti = 1; @@ -102,12 +99,14 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } ue_report[i]->bsr = elem; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR; } /* Check flag for creation of PHR report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { ue_report[i]->phr = flexran_get_ue_phr (enb_id, UE_id); // eNB_UE_list->UE_template[UE_PCCID(enb_id,UE_id)][UE_id].phr_info; ue_report[i]->has_phr = 1; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR; } @@ -148,7 +147,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // Add RLC buffer status reports to the full report if (ue_report[i]->n_rlc_report > 0) ue_report[i]->rlc_report = rlc_reports; - + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RLC_BS; } @@ -161,7 +160,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // found in stats_common.pb-c.h. See // flex_ce_type in FlexRAN specification ue_report[i]->has_pending_mac_ces = 1; - + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS; } /* Check flag for creation of DL CQI report */ @@ -386,7 +385,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, dl_report->csi_report = csi_reports; //Add the DL CQI report to the stats report ue_report[i]->dl_cqi_report = dl_report; - + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_DL_CQI; } /* Check flag for creation of paging buffer status report */ @@ -431,6 +430,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, paging_report->paging_info = p_info; //Add the paging report to the UE report ue_report[i]->pbr = paging_report; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PBS; } /* Check flag for creation of UL CQI report */ @@ -502,7 +502,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } // Add full UL CQI report to the UE report ue_report[i]->ul_cqi_report = full_ul_report; - + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_UL_CQI; } if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) { @@ -598,7 +598,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, ue_report[i]->mac_stats = macstats; - + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS; } @@ -640,6 +640,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0); ni_report->has_p0_nominal_pucch = 1; cell_report[i]->noise_inter_report = ni_report; + cell_report[i]->flags |= PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE; } } @@ -660,14 +661,9 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, return -1; } -int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg) { - //TODO: Need to deallocate memory for the stats reply message - if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG) - goto error; - free(msg->stats_reply_msg->header); +int flexran_agent_mac_destroy_stats_reply(Protocol__FlexStatsReply *reply) { int i, j, k; - Protocol__FlexStatsReply *reply = msg->stats_reply_msg; Protocol__FlexDlCqiReport *dl_report; Protocol__FlexUlCqiReport *ul_report; Protocol__FlexPagingBufferReport *paging_report; @@ -758,25 +754,24 @@ int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg) { free(ul_report->pucch_dbm[j]); } free(ul_report->pucch_dbm); + free(ul_report); + } + if (reply->ue_report[i]->flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) { + for (j = 0; j < reply->ue_report[i]->mac_stats->n_mac_sdus_dl; j++) + free(reply->ue_report[i]->mac_stats->mac_sdus_dl[j]); + free(reply->ue_report[i]->mac_stats->mac_sdus_dl); + free(reply->ue_report[i]->mac_stats); } - free(reply->ue_report[i]); } - free(reply->ue_report); // Free memory for all Cell reports for (i = 0; i < reply->n_cell_report; i++) { - free(reply->cell_report[i]->noise_inter_report); - free(reply->cell_report[i]); + if (reply->cell_report[i]->flags & PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE) { + free(reply->cell_report[i]->noise_inter_report); + } } - free(reply->cell_report); - free(reply); - free(msg); return 0; - - error: - //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); - return -1; } int flexran_agent_mac_sr_info(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { @@ -905,7 +900,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle // LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10); - sf_trigger_msg->n_dl_info = flexran_get_num_ues(mod_id); + sf_trigger_msg->n_dl_info = flexran_get_mac_num_ues(mod_id); Protocol__FlexDlInfo **dl_info = NULL; @@ -921,9 +916,9 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle dl_info[i] = malloc(sizeof(Protocol__FlexDlInfo)); if(dl_info[i] == NULL) goto error; - UE_id = flexran_get_ue_id(mod_id, i); + UE_id = flexran_get_mac_ue_id(mod_id, i); protocol__flex_dl_info__init(dl_info[i]); - dl_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); + dl_info[i]->rnti = flexran_get_mac_ue_crnti(mod_id, UE_id); dl_info[i]->has_rnti = 1; /*Fill in the right id of this round's HARQ process for this UE*/ // uint8_t harq_id; @@ -957,7 +952,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle /* Fill in the number of UL reception status related info, based on the number of currently * transmitting UEs */ - sf_trigger_msg->n_ul_info = flexran_get_num_ues(mod_id); + sf_trigger_msg->n_ul_info = flexran_get_mac_num_ues(mod_id); Protocol__FlexUlInfo **ul_info = NULL; @@ -972,9 +967,9 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle goto error; protocol__flex_ul_info__init(ul_info[i]); - UE_id = flexran_get_ue_id(mod_id, i); + UE_id = flexran_get_mac_ue_id(mod_id, i); - ul_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); + ul_info[i]->rnti = flexran_get_mac_ue_crnti(mod_id, UE_id); ul_info[i]->has_rnti = 1; /* Fill in the Tx power control command for this UE (if available), * primary carrier */ @@ -1357,11 +1352,17 @@ void flexran_agent_send_sf_trigger(mid_t mod_id) { -int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { - if (mac_agent_registered[mod_id]) { +int flexran_agent_register_mac_xface(mid_t mod_id) +{ + if (agent_mac_xface[mod_id]) { LOG_E(MAC, "MAC agent for eNB %d is already registered\n", mod_id); return -1; } + AGENT_MAC_xface *xface = malloc(sizeof(AGENT_MAC_xface)); + if (!xface) { + LOG_E(FLEXRAN_AGENT, "could not allocate memory for MAC agent xface %d\n", mod_id); + return -1; + } //xface->agent_ctxt = &shared_ctxt[mod_id]; xface->flexran_agent_send_sr_info = flexran_agent_send_sr_info; @@ -1371,14 +1372,125 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->dl_scheduler_loaded_lib = NULL; xface->ul_scheduler_loaded_lib = NULL; - mac_agent_registered[mod_id] = 1; agent_mac_xface[mod_id] = xface; return 0; } -int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { +void flexran_agent_fill_mac_cell_config(mid_t mod_id, uint8_t cc_id, + Protocol__FlexCellConfig *conf) { + if (!conf->si_config) { + conf->si_config = malloc(sizeof(Protocol__FlexSiConfig)); + if (conf->si_config) + protocol__flex_si_config__init(conf->si_config); + } + + if (conf->si_config) { + conf->si_config->sfn = flexran_get_current_system_frame_num(mod_id); + conf->si_config->has_sfn = 1; + } + + /* get a pointer to the config which is maintained in the agent throughout + * its lifetime */ + conf->slice_config = flexran_agent_get_slice_config(mod_id); +} +void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id, + Protocol__FlexUeConfig *ue_conf) +{ + if (ue_conf->has_rnti && ue_conf->rnti != flexran_get_mac_ue_crnti(mod_id, ue_id)) { + LOG_E(FLEXRAN_AGENT, "ue_config existing RNTI %x does not match MAC RNTI %x\n", + ue_conf->rnti, flexran_get_mac_ue_crnti(mod_id, ue_id)); + return; + } + ue_conf->rnti = flexran_get_mac_ue_crnti(mod_id, ue_id); + ue_conf->has_rnti = 1; + + ue_conf->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, ue_id); + ue_conf->has_dl_slice_id = 1; + ue_conf->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, ue_id); + ue_conf->has_ul_slice_id = 1; + + ue_conf->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id, ue_id); + ue_conf->has_ue_aggregated_max_bitrate_ul = 1; + + ue_conf->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id, ue_id); + ue_conf->has_ue_aggregated_max_bitrate_dl = 1; + + /* TODO update through RAN API */ + //config->has_pcell_carrier_index = 1; + //config->pcell_carrier_index = UE_PCCID(mod_id, i); + + //TODO: Set carrier aggregation support (boolean) +} + +void flexran_agent_fill_mac_lc_ue_config(mid_t mod_id, mid_t ue_id, + Protocol__FlexLcUeConfig *lc_ue_conf) +{ + lc_ue_conf->rnti = flexran_get_mac_ue_crnti(mod_id, ue_id); + lc_ue_conf->has_rnti = 1; + + lc_ue_conf->n_lc_config = flexran_get_num_ue_lcs(mod_id, ue_id); + if (lc_ue_conf->n_lc_config == 0) + return; + + Protocol__FlexLcConfig **lc_config = + calloc(lc_ue_conf->n_lc_config, sizeof(Protocol__FlexLcConfig *)); + if (!lc_config) { + LOG_E(FLEXRAN_AGENT, "could not allocate memory for lc_config of UE %x\n", lc_ue_conf->rnti); + lc_ue_conf->n_lc_config = 0; + return; // can not allocate memory, skip rest + } + for (int j = 0; j < lc_ue_conf->n_lc_config; j++) { + lc_config[j] = malloc(sizeof(Protocol__FlexLcConfig)); + if (!lc_config[j]) continue; // go over this error, try entry + protocol__flex_lc_config__init(lc_config[j]); + + lc_config[j]->has_lcid = 1; + lc_config[j]->lcid = j+1; + + const int lcg = flexran_get_lcg(mod_id, ue_id, j+1); + if (lcg >= 0 && lcg <= 3) { + lc_config[j]->has_lcg = 1; + lc_config[j]->lcg = flexran_get_lcg(mod_id, ue_id, j+1); + } + + lc_config[j]->has_direction = 1; + lc_config[j]->direction = flexran_get_direction(ue_id, j+1); + //TODO: Bearer type. One of FLQBT_* values. Currently only default bearer supported + lc_config[j]->has_qos_bearer_type = 1; + lc_config[j]->qos_bearer_type = PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_NON_GBR; + + //TODO: Set the QCI defined in TS 23.203, coded as defined in TS 36.413 + // One less than the actual QCI value. Needs to be generalized + lc_config[j]->has_qci = 1; + lc_config[j]->qci = 1; + if (lc_config[j]->direction == PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_GBR) { + /* TODO all of the need to be taken from API */ + //TODO: Set the max bitrate (UL) + lc_config[j]->has_e_rab_max_bitrate_ul = 0; + lc_config[j]->e_rab_max_bitrate_ul = 0; + //TODO: Set the max bitrate (DL) + lc_config[j]->has_e_rab_max_bitrate_dl = 0; + lc_config[j]->e_rab_max_bitrate_dl = 0; + //TODO: Set the guaranteed bitrate (UL) + lc_config[j]->has_e_rab_guaranteed_bitrate_ul = 0; + lc_config[j]->e_rab_guaranteed_bitrate_ul = 0; + //TODO: Set the guaranteed bitrate (DL) + lc_config[j]->has_e_rab_guaranteed_bitrate_dl = 0; + lc_config[j]->e_rab_guaranteed_bitrate_dl = 0; + } + } + lc_ue_conf->lc_config = lc_config; +} + +int flexran_agent_unregister_mac_xface(mid_t mod_id) +{ + if (!agent_mac_xface[mod_id]) { + LOG_E(FLEXRAN_AGENT, "MAC agent CM for eNB %d is not registered\n", mod_id); + return -1; + } + AGENT_MAC_xface *xface = agent_mac_xface[mod_id]; //xface->agent_ctxt = NULL; xface->flexran_agent_send_sr_info = NULL; xface->flexran_agent_send_sf_trigger = NULL; @@ -1387,12 +1499,17 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->dl_scheduler_loaded_lib = NULL; xface->ul_scheduler_loaded_lib = NULL; - mac_agent_registered[mod_id] = 0; + free(xface); agent_mac_xface[mod_id] = NULL; return 0; } +AGENT_MAC_xface *flexran_agent_get_mac_xface(mid_t mod_id) +{ + return agent_mac_xface[mod_id]; +} + void flexran_create_config_structures(mid_t mod_id) { int i; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h index 0d686a53eed6fa5c13fc39129e0aff4508b86056..8ca855a6b34de6903f3a5251e7e794fdc6544947 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -36,6 +36,8 @@ #include "flexran_agent_common.h" #include "flexran_agent_extern.h" +// for flexran_agent_get_mac_xface() +#include "flexran_agent_extern.h" /* Initialization function for the agent structures etc */ @@ -51,7 +53,7 @@ int flexran_agent_mac_destroy_sf_trigger(Protocol__FlexranMessage *msg); /* Statistics reply protocol message constructor and destructor */ int flexran_agent_mac_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); -int flexran_agent_mac_destroy_stats_reply(Protocol__FlexranMessage *msg); +int flexran_agent_mac_destroy_stats_reply(Protocol__FlexStatsReply *reply); /* DL MAC scheduling decision protocol message constructor (empty command) and destructor */ int flexran_agent_mac_create_empty_dl_config(mid_t mod_id, Protocol__FlexranMessage **msg); @@ -81,11 +83,23 @@ void flexran_agent_send_update_mac_stats(mid_t mod_id); /// Provide to the scheduler a pending dl_mac_config message void flexran_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__FlexranMessage **msg); +/* Fill the MAC part of an cell_config message */ +void flexran_agent_fill_mac_cell_config(mid_t mod_id, uint8_t cc_id, + Protocol__FlexCellConfig *conf); + +/* Fill the MAC part of a ue_config message */ +void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id, + Protocol__FlexUeConfig *ue_conf); + +/* Fill the lc_ue_config->lc_config message */ +void flexran_agent_fill_mac_lc_ue_config(mid_t mod_id, mid_t ue_id, + Protocol__FlexLcUeConfig *lc_ue_conf); + /*Register technology specific interface callbacks*/ -int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface); +int flexran_agent_register_mac_xface(mid_t mod_id); /*Unregister technology specific callbacks*/ -int flexran_agent_unregister_mac_xface(mid_t mod_id, AGENT_MAC_xface*xface); +int flexran_agent_unregister_mac_xface(mid_t mod_id); /*************************************** * FlexRAN agent - slice configuration * diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 8e0dc5726979861f68ae8fc707447774059a86d9..6ce9038923f21f5ede29e012cd8468c9f8e1726e 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -790,9 +790,9 @@ int parse_dl_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) { goto error; } // Check what key needs to be set - if (mac_agent_registered[mod_id]) { + if (flexran_agent_get_mac_xface(mod_id)) { LOG_D(ENB_APP, "Setting parameter %s\n", event.data.scalar.value); - param = dlsym(agent_mac_xface[mod_id]->dl_scheduler_loaded_lib, + param = dlsym(flexran_agent_get_mac_xface(mod_id)->dl_scheduler_loaded_lib, (char *) event.data.scalar.value); if (param == NULL) { goto error; @@ -845,9 +845,9 @@ int parse_ul_scheduler_parameters(mid_t mod_id, yaml_parser_t *parser) { goto error; } // Check what key needs to be set - if (mac_agent_registered[mod_id]) { + if (flexran_agent_get_mac_xface(mod_id)) { LOG_D(ENB_APP, "Setting parameter %s\n", event.data.scalar.value); - param = dlsym(agent_mac_xface[mod_id]->ul_scheduler_loaded_lib, + param = dlsym(flexran_agent_get_mac_xface(mod_id)->ul_scheduler_loaded_lib, (char *) event.data.scalar.value); if (param == NULL) { goto error; @@ -891,11 +891,11 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { LOG_I(FLEXRAN_AGENT, "Loading function: %s\n", function_name); void *loaded_scheduler = dlsym(lib, function_name); if (loaded_scheduler) { - if (mac_agent_registered[mod_id]) { - if (agent_mac_xface[mod_id]->dl_scheduler_loaded_lib != NULL) { - dlclose(agent_mac_xface[mod_id]->dl_scheduler_loaded_lib); + if (flexran_agent_get_mac_xface(mod_id)) { + if (flexran_agent_get_mac_xface(mod_id)->dl_scheduler_loaded_lib != NULL) { + dlclose(flexran_agent_get_mac_xface(mod_id)->dl_scheduler_loaded_lib); } - agent_mac_xface[mod_id]->dl_scheduler_loaded_lib = lib; + flexran_agent_get_mac_xface(mod_id)->dl_scheduler_loaded_lib = lib; LOG_I(FLEXRAN_AGENT, "New DL UE scheduler: %s\n", function_name); } } else { diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c index 7cb39fb7239a17af935fa026ab0d20c12b866dbb..293ebab7a8c376f07f20432144fd4662c1ee4166 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -28,42 +28,36 @@ #include "flexran_agent_pdcp.h" - -/*Trigger boolean for PDCP measurement*/ -bool triggered_pdcp = false; -/*Flags showing if a pdcp agent has already been registered*/ -unsigned int pdcp_agent_registered[NUM_MAX_ENB]; - /*Array containing the Agent-PDCP interfaces*/ AGENT_PDCP_xface *agent_pdcp_xface[NUM_MAX_ENB]; // MAX_MOBILES_PER_ENB void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id, - const mid_t ue_id, + uint16_t uid, Protocol__FlexPdcpStats *pdcp_aggr_stats){ int lcid=0; /* only calculate the DRBs */ - //LOG_I(FLEXRAN_AGENT, "enb %d ue %d \n", mod_id, ue_id); + //LOG_I(FLEXRAN_AGENT, "enb %d ue %d \n", mod_id, uid); for (lcid=NUM_MAX_SRB ; lcid < NUM_MAX_SRB + NUM_MAX_DRB; lcid++){ - pdcp_aggr_stats->pkt_tx += flexran_get_pdcp_tx(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_tx_bytes += flexran_get_pdcp_tx_bytes(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_tx_w += flexran_get_pdcp_tx_w(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_tx_bytes_w += flexran_get_pdcp_tx_bytes_w(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_tx_aiat += flexran_get_pdcp_tx_aiat(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_tx_aiat_w += flexran_get_pdcp_tx_aiat_w(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_tx += flexran_get_pdcp_tx(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_tx_bytes += flexran_get_pdcp_tx_bytes(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_tx_w += flexran_get_pdcp_tx_w(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_tx_bytes_w += flexran_get_pdcp_tx_bytes_w(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_tx_aiat += flexran_get_pdcp_tx_aiat(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_tx_aiat_w += flexran_get_pdcp_tx_aiat_w(mod_id, uid, lcid); - pdcp_aggr_stats->pkt_rx += flexran_get_pdcp_rx(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_rx_bytes += flexran_get_pdcp_rx_bytes(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_rx_w += flexran_get_pdcp_rx_w(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_rx_bytes_w += flexran_get_pdcp_rx_bytes_w(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_rx_aiat += flexran_get_pdcp_rx_aiat(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_rx_aiat_w += flexran_get_pdcp_rx_aiat_w(mod_id,ue_id,lcid); - pdcp_aggr_stats->pkt_rx_oo += flexran_get_pdcp_rx_oo(mod_id,ue_id,lcid); + pdcp_aggr_stats->pkt_rx += flexran_get_pdcp_rx(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_rx_bytes += flexran_get_pdcp_rx_bytes(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_rx_w += flexran_get_pdcp_rx_w(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_rx_bytes_w += flexran_get_pdcp_rx_bytes_w(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_rx_aiat += flexran_get_pdcp_rx_aiat(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_rx_aiat_w += flexran_get_pdcp_rx_aiat_w(mod_id, uid, lcid); + pdcp_aggr_stats->pkt_rx_oo += flexran_get_pdcp_rx_oo(mod_id, uid, lcid); } @@ -78,7 +72,6 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; int i; - int UE_id; // int cc_id = 0; @@ -86,7 +79,8 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, if (report_config->nr_ue > 0) { for (i = 0; i < report_config->nr_ue; i++) { - UE_id = flexran_get_ue_id(mod_id, i); + const rnti_t rnti = report_config->ue_report_type[i].ue_rnti; + const uint16_t uid = flexran_get_pdcp_uid_from_rnti(mod_id, rnti); /* Check flag for creation of buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS) { @@ -97,7 +91,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, goto error; protocol__flex_pdcp_stats__init(pdcp_aggr_stats); - flexran_agent_pdcp_aggregate_stats(mod_id, UE_id, pdcp_aggr_stats); + flexran_agent_pdcp_aggregate_stats(mod_id, uid, pdcp_aggr_stats); pdcp_aggr_stats->has_pkt_tx=1; pdcp_aggr_stats->has_pkt_tx_bytes =1; @@ -106,7 +100,7 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, pdcp_aggr_stats->has_pkt_tx_aiat =1; pdcp_aggr_stats->has_pkt_tx_aiat_w =1; - pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, UE_id, DEFAULT_DRB); + pdcp_aggr_stats->pkt_tx_sn = flexran_get_pdcp_tx_sn(mod_id, uid, DEFAULT_DRB); pdcp_aggr_stats->has_pkt_tx_sn =1; pdcp_aggr_stats->has_pkt_rx =1; @@ -117,14 +111,14 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, pdcp_aggr_stats->has_pkt_rx_aiat_w =1; pdcp_aggr_stats->has_pkt_rx_oo =1; - pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, UE_id, DEFAULT_DRB); + pdcp_aggr_stats->pkt_rx_sn = flexran_get_pdcp_rx_sn(mod_id, uid, DEFAULT_DRB); pdcp_aggr_stats->has_pkt_rx_sn =1; pdcp_aggr_stats->sfn = flexran_get_pdcp_sfn(mod_id); pdcp_aggr_stats->has_sfn =1; ue_report[i]->pdcp_stats = pdcp_aggr_stats; - + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PDCP_STATS; } } } else { @@ -144,30 +138,51 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, return -1; } +int flexran_agent_pdcp_destroy_stats_reply(Protocol__FlexStatsReply *reply) +{ + for (int i = 0; i < reply->n_ue_report; ++i) { + if (reply->ue_report[i]->pdcp_stats) + free(reply->ue_report[i]->pdcp_stats); + } + return 0; +} -int flexran_agent_register_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface) { - if (pdcp_agent_registered[mod_id]) { - LOG_E(PDCP, "PDCP agent for eNB %d is already registered\n", mod_id); +int flexran_agent_register_pdcp_xface(mid_t mod_id) +{ + if (agent_pdcp_xface[mod_id]) { + LOG_E(FLEXRAN_AGENT, "PDCP agent CM for eNB %d is already registered\n", mod_id); + return -1; + } + AGENT_PDCP_xface *xface = malloc(sizeof(AGENT_PDCP_xface)); + if (!xface) { + LOG_E(FLEXRAN_AGENT, "could not allocate memory for PDCP agent xface %d\n", mod_id); return -1; } //xface->flexran_pdcp_stats_measurement = NULL; - pdcp_agent_registered[mod_id] = 1; agent_pdcp_xface[mod_id] = xface; return 0; } -int flexran_agent_unregister_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface) { - +int flexran_agent_unregister_pdcp_xface(mid_t mod_id) +{ + if (!agent_pdcp_xface[mod_id]) { + LOG_E(FLEXRAN_AGENT, "PDCP agent CM for eNB %d is not registered\n", mod_id); + return -1; + } //xface->agent_ctxt = NULL; //xface->flexran_pdcp_stats_measurement = NULL; - - pdcp_agent_registered[mod_id] = 0; + free(agent_pdcp_xface[mod_id]); agent_pdcp_xface[mod_id] = NULL; return 0; } + +AGENT_PDCP_xface *flexran_agent_get_pdcp_xface(mid_t mod_id) +{ + return agent_pdcp_xface[mod_id]; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h index 83aac45406e17b5f5526898e45a5212475cd2e9b..246f9709b512e5e90ad4058a85a0a9377ff15de9 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h @@ -39,6 +39,8 @@ #include "flexran_agent_defs.h" #include "flexran_agent_pdcp_defs.h" #include "flexran_agent_ran_api.h" +// for flexran_agent_get_pdcp_xface() +#include "flexran_agent_extern.h" /********************************** * FlexRAN agent - technology PDCP API @@ -49,16 +51,17 @@ int flexran_agent_pdcp_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); +int flexran_agent_pdcp_destroy_stats_reply(Protocol__FlexStatsReply *reply); /* Get the stats from RAN API and aggregate them per USER*/ void flexran_agent_pdcp_aggregate_stats(const mid_t mod_id, - const mid_t ue_id, + uint16_t uid, Protocol__FlexPdcpStats *pdcp_aggr_stats); /*Register technology specific interface callbacks*/ -int flexran_agent_register_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface *xface); +int flexran_agent_register_pdcp_xface(mid_t mod_id); /*Unregister technology specific callbacks*/ -int flexran_agent_unregister_pdcp_xface(mid_t mod_id, AGENT_PDCP_xface*xface); +int flexran_agent_unregister_pdcp_xface(mid_t mod_id); #endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.c b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.c new file mode 100644 index 0000000000000000000000000000000000000000..2f8726293813d900635ed893584c2ecb16049c1e --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.c @@ -0,0 +1,179 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_phy.c + * \brief FlexRAN agent Control Module PHY + * \author Robert Schmidt + * \date Oct 2018 + */ + +#include "flexran_agent_phy.h" +#include "flexran_agent_ran_api.h" + +/* Array containing the Agent-PHY interfaces */ +AGENT_PHY_xface *agent_phy_xface[NUM_MAX_ENB]; + +void flexran_agent_fill_phy_cell_config(mid_t mod_id, uint8_t cc_id, + Protocol__FlexCellConfig *conf) { + conf->phy_cell_id = flexran_get_cell_id(mod_id, cc_id); + conf->has_phy_cell_id = 1; + + conf->pusch_hopping_offset = flexran_get_hopping_offset(mod_id, cc_id); + conf->has_pusch_hopping_offset = 1; + + conf->hopping_mode = flexran_get_hopping_mode(mod_id, cc_id); + conf->has_hopping_mode = 1; + + conf->n_sb = flexran_get_n_SB(mod_id, cc_id); + conf->has_n_sb = 1; + + conf->phich_resource = flexran_get_phich_resource(mod_id, cc_id); + conf->has_phich_resource = 1; + + conf->phich_duration = flexran_get_phich_duration(mod_id, cc_id); + conf->has_phich_duration = 1; + + conf->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(mod_id, cc_id); + conf->has_init_nr_pdcch_ofdm_sym = 1; + + conf->dl_bandwidth = flexran_get_N_RB_DL(mod_id, cc_id); + conf->has_dl_bandwidth = 1; + + conf->ul_bandwidth = flexran_get_N_RB_UL(mod_id, cc_id); + conf->has_ul_bandwidth = 1; + + conf->ul_cyclic_prefix_length = flexran_get_ul_cyclic_prefix_length(mod_id, cc_id); + conf->has_ul_cyclic_prefix_length = 1; + + conf->dl_cyclic_prefix_length = flexran_get_dl_cyclic_prefix_length(mod_id, cc_id); + conf->has_dl_cyclic_prefix_length = 1; + + conf->antenna_ports_count = flexran_get_antenna_ports(mod_id, cc_id); + conf->has_antenna_ports_count = 1; + + conf->duplex_mode = flexran_get_duplex_mode(mod_id, cc_id); + conf->has_duplex_mode = 1; + + conf->subframe_assignment = flexran_get_subframe_assignment(mod_id, cc_id); + conf->has_subframe_assignment = 1; + + conf->special_subframe_patterns = flexran_get_special_subframe_assignment(mod_id, cc_id); + conf->has_special_subframe_patterns = 1; + + //TODO: Fill in with actual value, The MBSFN radio frame period + conf->n_mbsfn_subframe_config_rfperiod = 0; + uint32_t *elem_rfperiod = malloc(sizeof(uint32_t) * conf->n_mbsfn_subframe_config_rfperiod); + if (elem_rfperiod) + for(int j = 0; j < conf->n_mbsfn_subframe_config_rfperiod; j++) + elem_rfperiod[j] = 1; + conf->mbsfn_subframe_config_rfperiod = elem_rfperiod; + + //TODO: Fill in with actual value, The MBSFN radio frame offset + conf->n_mbsfn_subframe_config_rfoffset = 0; + uint32_t *elem_rfoffset = malloc(sizeof(uint32_t) * conf->n_mbsfn_subframe_config_rfoffset); + if (elem_rfoffset) + for(int j = 0; j < conf->n_mbsfn_subframe_config_rfoffset; j++) + elem_rfoffset[j] = 1; + conf->mbsfn_subframe_config_rfoffset = elem_rfoffset; + + //TODO: Fill in with actual value, Bitmap indicating the MBSFN subframes + conf->n_mbsfn_subframe_config_sfalloc = 0; + uint32_t *elem_sfalloc = malloc(sizeof(uint32_t) * conf->n_mbsfn_subframe_config_sfalloc); + if (elem_sfalloc) + for(int j = 0; j < conf->n_mbsfn_subframe_config_sfalloc; j++) + elem_sfalloc[j] = 1; + conf->mbsfn_subframe_config_sfalloc = elem_sfalloc; + + conf->prach_config_index = flexran_get_prach_ConfigIndex(mod_id, cc_id); + conf->has_prach_config_index = 1; + + conf->prach_freq_offset = flexran_get_prach_FreqOffset(mod_id, cc_id); + conf->has_prach_freq_offset = 1; + + conf->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(mod_id, cc_id); + conf->has_max_harq_msg3tx = 1; + + conf->n1pucch_an = flexran_get_n1pucch_an(mod_id, cc_id); + conf->has_n1pucch_an = 1; + + conf->deltapucch_shift = flexran_get_deltaPUCCH_Shift(mod_id, cc_id); + conf->has_deltapucch_shift = 1; + + conf->nrb_cqi = flexran_get_nRB_CQI(mod_id, cc_id); + conf->has_nrb_cqi = 1; + + conf->srs_subframe_config = flexran_get_srs_SubframeConfig(mod_id, cc_id); + conf->has_srs_subframe_config = 1; + + conf->srs_bw_config = flexran_get_srs_BandwidthConfig(mod_id, cc_id); + conf->has_srs_bw_config = 1; + + conf->srs_mac_up_pts = flexran_get_srs_MaxUpPts(mod_id, cc_id); + conf->has_srs_mac_up_pts = 1; + + conf->dl_freq = flexran_agent_get_operating_dl_freq (mod_id, cc_id); + conf->has_dl_freq = 1; + + conf->ul_freq = flexran_agent_get_operating_ul_freq (mod_id, cc_id); + conf->has_ul_freq = 1; + + conf->eutra_band = flexran_agent_get_operating_eutra_band (mod_id, cc_id); + conf->has_eutra_band = 1; + + conf->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(mod_id, cc_id); + conf->has_dl_pdsch_power = 1; + + conf->enable_64qam = flexran_get_enable64QAM(mod_id, cc_id); + conf->has_enable_64qam = 1; +} + +int flexran_agent_register_phy_xface(mid_t mod_id) { + if (agent_phy_xface[mod_id]) { + LOG_E(PHY, "PHY agent for eNB %d is already registered\n", mod_id); + return -1; + } + + AGENT_PHY_xface *xface = malloc(sizeof(AGENT_PHY_xface)); + + if (!xface) { + LOG_E(FLEXRAN_AGENT, "could not allocate memory for PHY agent xface %d\n", mod_id); + return -1; + } + + agent_phy_xface[mod_id] = xface; + return 0; +} + +int flexran_agent_unregister_phy_xface(mid_t mod_id) +{ + if (!agent_phy_xface[mod_id]) { + LOG_E(FLEXRAN_AGENT, "PHY agent for eNB %d is not registered\n", mod_id); + return -1; + } + free(agent_phy_xface[mod_id]); + agent_phy_xface[mod_id] = NULL; + return 0; +} + +AGENT_PHY_xface *flexran_agent_get_phy_xface(mid_t mod_id) +{ + return agent_phy_xface[mod_id]; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.h b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.h new file mode 100644 index 0000000000000000000000000000000000000000..25b3deac35fbb9b27f3f143c700bb7f4a8148e10 --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy.h @@ -0,0 +1,58 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file flexran_agent_phy.h + * \brief FlexRAN agent Control Module PHY header + * \author Robert Schmidt + * \date Oct 2018 + */ + +#ifndef FLEXRAN_AGENT_PHY_H_ +#define FLEXRAN_AGENT_PHY_H_ + +#include "header.pb-c.h" +#include "flexran.pb-c.h" +#include "stats_messages.pb-c.h" +#include "stats_common.pb-c.h" + + +#include "flexran_agent_common.h" +#include "flexran_agent_defs.h" +#include "flexran_agent_phy_defs.h" +#include "flexran_agent_ran_api.h" +// for flexran_agent_get_phy_xface() +#include "flexran_agent_extern.h" + +/********************************** + * FlexRAN agent - technology PHY API + **********************************/ + +/* Fill the PHY part of an cell_config message */ +void flexran_agent_fill_phy_cell_config(mid_t mod_id, uint8_t cc_id, + Protocol__FlexCellConfig *conf); + +/* Register technology specific interface callbacks */ +int flexran_agent_register_phy_xface(mid_t mod_id); + +/* Unregister technology specific callbacks */ +int flexran_agent_unregister_phy_xface(mid_t mod_id); + +#endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy_defs.h b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..06c262ef7fafc8c912177b27e0fdb2648a51742f --- /dev/null +++ b/openair2/ENB_APP/CONTROL_MODULES/PHY/flexran_agent_phy_defs.h @@ -0,0 +1,35 @@ +/* + * 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 __FLEXRAN_AGENT_PHY_PRIMITIVES_H__ +#define __FLEXRAN_AGENT_PHY_PRIMITIVES_H__ + +#include "flexran_agent_defs.h" +#include "flexran.pb-c.h" +#include "header.pb-c.h" + +/* FLEXRAN AGENT-PHY Interface */ +typedef struct { + + /* currently empty, will be used to control RU */ + +} AGENT_PHY_xface; + +#endif /* __FLEXRAN_AGENT_PHY_PRIMITIVES_H__ */ diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index 7d7f48a61008608100d074492b9bf738c7ee4f5e..a785c681635f2db9d0c6cb83b8a80a5f531dd5ae 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -27,7 +27,7 @@ */ #include "flexran_agent_rrc.h" - +#include "flexran_agent_ran_api.h" #include "liblfds700.h" @@ -36,9 +36,6 @@ /*Trigger boolean for RRC measurement*/ bool triggered_rrc = false; -/*Flags showing if an rrc agent has already been registered*/ -unsigned int rrc_agent_registered[NUM_MAX_ENB]; - /*Array containing the Agent-RRC interfaces*/ AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; @@ -71,154 +68,21 @@ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_ch goto error; } protocol__flex_ue_config__init(config); - if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED) { - // Simply set the rnti of the UE - config->has_rnti = 1; - config->rnti = rnti; - } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED - || state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED) { - int i = find_UE_id(mod_id, rnti); + switch (state_change) { + case PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED: config->has_rnti = 1; config->rnti = rnti; - config->imsi = flexran_get_ue_imsi(mod_id, i); - config->has_imsi = 1; - config->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, i); - config->has_dl_slice_id = 1; - config->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, i); - config->has_ul_slice_id = 1; - if(flexran_get_time_alignment_timer(mod_id,i) != -1) { - config->time_alignment_timer = flexran_get_time_alignment_timer(mod_id,i); - config->has_time_alignment_timer = 1; - } - if(flexran_get_meas_gap_config(mod_id,i) != -1){ - config->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id,i); - config->has_meas_gap_config_pattern = 1; - } - if(config->has_meas_gap_config_pattern == 1 && - config->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { - config->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id,i); - config->has_meas_gap_config_sf_offset = 1; - } - //TODO: Set the SPS configuration (Optional) - //Not supported for now, so we do not set it - - //TODO: Set the SR configuration (Optional) - //We do not set it for now - - //TODO: Set the CQI configuration (Optional) - //We do not set it for now - - if(flexran_get_ue_transmission_mode(mod_id,i) != -1) { - config->transmission_mode = flexran_get_ue_transmission_mode(mod_id,i); - config->has_transmission_mode = 1; - } - - config->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id,i); - config->has_ue_aggregated_max_bitrate_ul = 1; - - config->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id,i); - config->has_ue_aggregated_max_bitrate_dl = 1; - - Protocol__FlexUeCapabilities *c_capabilities; - c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); - protocol__flex_ue_capabilities__init(c_capabilities); - c_capabilities->has_half_duplex = 1; - c_capabilities->half_duplex = flexran_get_half_duplex(mod_id, i); - c_capabilities->has_intra_sf_hopping = 1; - c_capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, i); - c_capabilities->has_type2_sb_1 = 1; - c_capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, i); - c_capabilities->has_ue_category = 1; - c_capabilities->ue_category = flexran_get_ue_category(mod_id, i); - c_capabilities->has_res_alloc_type1 = 1; - c_capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, i); - //Set the capabilites to the message - config->capabilities = c_capabilities; - - if(flexran_get_ue_transmission_antenna(mod_id,i) != -1) { - config->has_ue_transmission_antenna = 1; - config->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id,i); - } - - if(flexran_get_tti_bundling(mod_id,i) != -1) { - config->has_tti_bundling = 1; - config->tti_bundling = flexran_get_tti_bundling(mod_id,i); - } - - if(flexran_get_maxHARQ_TX(mod_id,i) != -1){ - config->has_max_harq_tx = 1; - config->max_harq_tx = flexran_get_maxHARQ_TX(mod_id,i); - } - - if(flexran_get_beta_offset_ack_index(mod_id,i) != -1) { - config->has_beta_offset_ack_index = 1; - config->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id,i); - } - - if(flexran_get_beta_offset_ri_index(mod_id,i) != -1) { - config->has_beta_offset_ri_index = 1; - config->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id,i); - } - - if(flexran_get_beta_offset_cqi_index(mod_id,i) != -1) { - config->has_beta_offset_cqi_index = 1; - config->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id,i); - } - - /* assume primary carrier */ - if(flexran_get_ack_nack_simultaneous_trans(mod_id,i,0) != -1) { - config->has_ack_nack_simultaneous_trans = 1; - config->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,i,0); - } - - if(flexran_get_simultaneous_ack_nack_cqi(mod_id,i) != -1) { - config->has_simultaneous_ack_nack_cqi = 1; - config->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id,i); - } - - if(flexran_get_aperiodic_cqi_rep_mode(mod_id,i) != -1) { - config->has_aperiodic_cqi_rep_mode = 1; - int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id,i); - if (mode > 4) { - config->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; - } else { - config->aperiodic_cqi_rep_mode = mode; - } - } - - if(flexran_get_tdd_ack_nack_feedback_mode(mod_id, i) != -1) { - config->has_tdd_ack_nack_feedback = 1; - config->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id,i); - } - - if(flexran_get_ack_nack_repetition_factor(mod_id, i) != -1) { - config->has_ack_nack_repetition_factor = 1; - config->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id,i); - } - - if(flexran_get_extended_bsr_size(mod_id, i) != -1) { - config->has_extended_bsr_size = 1; - config->extended_bsr_size = flexran_get_extended_bsr_size(mod_id,i); - } - - config->has_pcell_carrier_index = 1; - config->pcell_carrier_index = UE_PCCID(mod_id, i); - //TODO: Set carrier aggregation support (boolean) - config->has_ca_support = 0; - config->ca_support = 0; - if(config->has_ca_support){ - //TODO: Set cross carrier scheduling support (boolean) - config->has_cross_carrier_sched_support = 1; - config->cross_carrier_sched_support = 0; - //TODO: Set secondary cells configuration - // We do not set it for now. No carrier aggregation support - - //TODO: Set deactivation timer for secondary cell - config->has_scell_deactivation_timer = 0; - config->scell_deactivation_timer = 0; - } - } else if (state_change == PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_MOVED) { - // TODO: Not supported for now. Leave blank + break; + case PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED: + case PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED: + flexran_agent_fill_rrc_ue_config(mod_id, rnti, config); + /* we don't call into the MAC CM here; it will be called later through an + * ue_config_request */ + break; + case PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_MOVED: + default: + LOG_E(FLEXRAN_AGENT, "state change FLUESC_MOVED or unknown state occured for RNTI %x\n", + rnti); } ue_state_change_msg->config = config; @@ -242,16 +106,18 @@ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_ch return; error: if (err_code != 0) - LOG_E(FLEXRAN_AGENT, "Could not send UE state message becasue of %d \n",err_code); + LOG_E(FLEXRAN_AGENT, "Could not send UE state message becasue of %d for RNTI %x\n", + err_code, rnti); } - int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_STATE_CHANGE_MSG) goto error; free(msg->ue_state_change_msg->header); - //TODO: Free the contents of the UE config structure + if (msg->ue_state_change_msg->config->capabilities) + free(msg->ue_state_change_msg->config->capabilities); + free(msg->ue_state_change_msg->config); free(msg->ue_state_change_msg); free(msg); return 0; @@ -264,30 +130,27 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { /* this is called by RRC as a part of rrc xface . The controller previously requested this*/ void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t* measResults) { - //int i; // int priority = 0; // Warning Preventing // void *data; // int size; // err_code_t err_code = -100; triggered_rrc = true; - //int num; /* TODO do we need this at the current state? meas_stats is never put into a * protobuf message?! - num = flexran_get_num_ues (mod_id); + int num = flexran_get_rrc_num_ues (mod_id); + rnti_t rntis[num]; + flexran_get_rrc_rnti_list(mod_id, rntis, num); meas_stats = malloc(sizeof(rrc_meas_stats) * num); - for (i = 0; i < num; i++){ - UE_id = flexran_get_ue_id(mod_id, i); - meas_stats[i].rnti = flexran_get_ue_crnti(mod_id, UE_id); - meas_stats[i].meas_id = flexran_get_rrc_pcell_measid(mod_id, UE_id); - meas_stats[i].rsrp = flexran_get_rrc_pcell_rsrp(mod_id, UE_id) - 140; + for (int i = 0; i < num; i++){ + const rnti_t rnti = rntis[i]; + meas_stats[i].rnti = rnti; + meas_stats[i].meas_id = flexran_get_rrc_pcell_measid(mod_id, rnti); + meas_stats[i].rsrp = flexran_get_rrc_pcell_rsrp(mod_id, rnti) - 140; // measResults->measResultPCell.rsrpResult - 140; - meas_stats[i].rsrq = flexran_get_rrc_pcell_rsrq(mod_id, UE_id)/2 - 20; - // (measResults->measResultPCell.rsrqResult)/2 - 20; - - } + meas_stats[i].rsrq = flexran_get_rrc_pcell_rsrq(mod_id, rnti)/2 - 20; */ // repl->neigh_meas = NULL; @@ -496,17 +359,11 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report) { - - // Protocol__FlexHeader *header; - int i,j; - int UE_id; - - /* Allocate memory for list of UE reports */ if (report_config->nr_ue > 0) { - - for (i = 0; i < report_config->nr_ue; i++) { - - UE_id = flexran_get_ue_id(mod_id, i); + rnti_t rntis[report_config->nr_ue]; + flexran_get_rrc_rnti_list(mod_id, rntis, report_config->nr_ue); + for (int i = 0; i < report_config->nr_ue; i++) { + const rnti_t rnti = rntis[i]; /* Check flag for creation of buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS) { @@ -518,15 +375,14 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, goto error; protocol__flex_rrc_measurements__init(rrc_measurements); - rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id, UE_id); - rrc_measurements->has_measid = 1; - - rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id, UE_id); - rrc_measurements->has_pcell_rsrp = 1; - - rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id, UE_id); - rrc_measurements->has_pcell_rsrq = 1 ; - + rrc_measurements->measid = flexran_get_rrc_pcell_measid(mod_id, rnti); + rrc_measurements->has_measid = 1; + + rrc_measurements->pcell_rsrp = flexran_get_rrc_pcell_rsrp(mod_id, rnti); + rrc_measurements->has_pcell_rsrp = 1; + + rrc_measurements->pcell_rsrq = flexran_get_rrc_pcell_rsrq(mod_id, rnti); + rrc_measurements->has_pcell_rsrq = 1 ; /* Target Cell, Neghibouring*/ Protocol__FlexNeighCellsMeasurements *neigh_meas; @@ -536,7 +392,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, protocol__flex_neigh_cells_measurements__init(neigh_meas); - neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, UE_id); + neigh_meas->n_eutra_meas = flexran_get_rrc_num_ncell(mod_id, rnti); Protocol__FlexEutraMeasurements **eutra_meas = NULL; @@ -546,7 +402,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, if (eutra_meas == NULL) goto error; - for (j = 0; j < neigh_meas->n_eutra_meas; j++ ){ + for (int j = 0; j < neigh_meas->n_eutra_meas; j++ ){ eutra_meas[j] = malloc(sizeof(Protocol__FlexEutraMeasurements)); if (eutra_meas[j] == NULL) @@ -554,7 +410,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, protocol__flex_eutra_measurements__init(eutra_meas[j]); - eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, UE_id, j); + eutra_meas[j]->phys_cell_id = flexran_get_rrc_neigh_phy_cell_id(mod_id, rnti, j); eutra_meas[j]->has_phys_cell_id = 1; @@ -565,10 +421,10 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, protocol__flex_eutra_ref_signal_meas__init(meas_result); - meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, UE_id, eutra_meas[j]->phys_cell_id); + meas_result->rsrp = flexran_get_rrc_neigh_rsrp(mod_id, rnti, eutra_meas[j]->phys_cell_id); meas_result->has_rsrp = 1; - meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, UE_id, eutra_meas[j]->phys_cell_id); + meas_result->rsrq = flexran_get_rrc_neigh_rsrq(mod_id, rnti, eutra_meas[j]->phys_cell_id); meas_result->has_rsrq = 1; eutra_meas[j]->meas_result = meas_result; @@ -582,6 +438,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, } ue_report[i]->rrc_measurements = rrc_measurements; + ue_report[i]->flags |= PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_RRC_MEASUREMENTS; } @@ -618,6 +475,7 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, // ni_report->p0_nominal_pucch = flexran_get_p0_nominal_pucch(enb_id, 0); // ni_report->has_p0_nominal_pucch = 1; // cell_report[i]->noise_inter_report = ni_report; + // cell_report[i]->flags |= PROTOCOL__FLEX_CELL_STATS_TYPE__FLCST_NOISE_INTERFERENCE; // } // } @@ -630,12 +488,10 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, error: - for (i = 0; i < report_config->nr_ue; i++){ + for (int i = 0; i < report_config->nr_ue; i++){ - UE_id = flexran_get_ue_id(mod_id, i); - - if (ue_report[i]->rrc_measurements->neigh_meas != NULL){ - for (j = 0; j < flexran_get_rrc_num_ncell(mod_id, UE_id); j++){ + if (ue_report[i]->rrc_measurements && ue_report[i]->rrc_measurements->neigh_meas != NULL){ + for (int j = 0; j < ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++){ free(ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]); } @@ -651,10 +507,131 @@ int flexran_agent_rrc_stats_reply(mid_t mod_id, return -1; } +int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply) +{ + for (int i = 0; i < reply->n_ue_report; i++){ + if (reply->ue_report[i]->rrc_measurements && reply->ue_report[i]->rrc_measurements->neigh_meas){ + for (int j = 0; j < reply->ue_report[i]->rrc_measurements->neigh_meas->n_eutra_meas; j++){ + free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]->meas_result); + free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas[j]); + } + free(reply->ue_report[i]->rrc_measurements->neigh_meas->eutra_meas); + free(reply->ue_report[i]->rrc_measurements->neigh_meas); + free(reply->ue_report[i]->rrc_measurements); + } + } + return 0; +} + +void flexran_agent_fill_rrc_ue_config(mid_t mod_id, rnti_t rnti, + Protocol__FlexUeConfig *ue_conf) +{ + if (ue_conf->has_rnti && ue_conf->rnti != rnti) { + LOG_E(FLEXRAN_AGENT, "ue_config existing RNTI %x does not match RRC RNTI %x\n", + ue_conf->rnti, rnti); + return; + } + ue_conf->has_rnti = 1; + ue_conf->rnti = rnti; + ue_conf->imsi = flexran_get_ue_imsi(mod_id, rnti); + ue_conf->has_imsi = 1; + + //TODO: Set the DRX configuration (optional) + //Not supported for now, so we do not set it + + ue_conf->time_alignment_timer = flexran_get_time_alignment_timer(mod_id, rnti); + ue_conf->has_time_alignment_timer = 1; + + ue_conf->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id, rnti); + ue_conf->has_meas_gap_config_pattern = 1; + + if(ue_conf->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { + ue_conf->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id, rnti); + ue_conf->has_meas_gap_config_sf_offset = 1; + } + + //TODO: Set the SPS configuration (Optional) + //Not supported for now, so we do not set it + + //TODO: Set the SR configuration (Optional) + //We do not set it for now + + //TODO: Set the CQI configuration (Optional) + //We do not set it for now + + ue_conf->transmission_mode = flexran_get_ue_transmission_mode(mod_id, rnti); + ue_conf->has_transmission_mode = 1; + + Protocol__FlexUeCapabilities *c_capabilities; + c_capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); + if (c_capabilities) { + protocol__flex_ue_capabilities__init(c_capabilities); + + c_capabilities->has_half_duplex = 1; + c_capabilities->half_duplex = flexran_get_half_duplex(mod_id, rnti); + + c_capabilities->has_intra_sf_hopping = 1; + c_capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, rnti); + + c_capabilities->has_type2_sb_1 = 1; + c_capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, rnti); + + c_capabilities->has_ue_category = 1; + c_capabilities->ue_category = flexran_get_ue_category(mod_id, rnti); + + c_capabilities->has_res_alloc_type1 = 1; + c_capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, rnti); + + ue_conf->capabilities = c_capabilities; + } + + ue_conf->has_ue_transmission_antenna = 1; + ue_conf->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id, rnti); + + ue_conf->has_tti_bundling = 1; + ue_conf->tti_bundling = flexran_get_tti_bundling(mod_id, rnti); + + ue_conf->has_max_harq_tx = 1; + ue_conf->max_harq_tx = flexran_get_maxHARQ_TX(mod_id, rnti); + + ue_conf->has_beta_offset_ack_index = 1; + ue_conf->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id, rnti); + + ue_conf->has_beta_offset_ri_index = 1; + ue_conf->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id, rnti); + + ue_conf->has_beta_offset_cqi_index = 1; + ue_conf->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id, rnti); + + /* assume primary carrier */ + ue_conf->has_ack_nack_simultaneous_trans = 1; + ue_conf->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id,0); + + ue_conf->has_simultaneous_ack_nack_cqi = 1; + ue_conf->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id, rnti); + + ue_conf->has_aperiodic_cqi_rep_mode = 1; + ue_conf->aperiodic_cqi_rep_mode = flexran_get_aperiodic_cqi_rep_mode(mod_id, rnti); + + ue_conf->has_tdd_ack_nack_feedback = 1; + ue_conf->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id, rnti); + + ue_conf->has_ack_nack_repetition_factor = 1; + ue_conf->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id, rnti); + + ue_conf->has_extended_bsr_size = 1; + ue_conf->extended_bsr_size = flexran_get_extended_bsr_size(mod_id, rnti); +} -int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) { - if (rrc_agent_registered[mod_id]) { - LOG_E(RRC, "RRC agent for eNB %d is already registered\n", mod_id); +int flexran_agent_register_rrc_xface(mid_t mod_id) +{ + if (agent_rrc_xface[mod_id]) { + LOG_E(FLEXRAN_AGENT, "RRC agent for eNB %d is already registered\n", mod_id); + return -1; + } + AGENT_RRC_xface *xface = malloc(sizeof(AGENT_RRC_xface)); + if (!xface) { + LOG_E(FLEXRAN_AGENT, "could not allocate memory for RRC agent xface %d\n", mod_id); return -1; } @@ -663,21 +640,98 @@ int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) { xface->flexran_agent_notify_ue_state_change = flexran_agent_ue_state_change; xface->flexran_trigger_rrc_measurements = flexran_trigger_rrc_measurements; - rrc_agent_registered[mod_id] = 1; agent_rrc_xface[mod_id] = xface; return 0; } -int flexran_agent_unregister_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface) { +void flexran_agent_fill_rrc_cell_config(mid_t mod_id, uint8_t cc_id, + Protocol__FlexCellConfig *conf) { + + if (!conf->si_config) { + conf->si_config = malloc(sizeof(Protocol__FlexSiConfig)); + if (conf->si_config) + protocol__flex_si_config__init(conf->si_config); + } + + if (conf->si_config) { + // TODO THIS IS DU RRC + conf->si_config->sib1_length = flexran_get_sib1_length(mod_id, cc_id); + conf->si_config->has_sib1_length = 1; + + conf->si_config->si_window_length = (uint32_t) flexran_get_si_window_length(mod_id, cc_id); + conf->si_config->has_si_window_length = 1; + + conf->si_config->n_si_message = 0; + + /* Protocol__FlexSiMessage **si_message; */ + /* si_message = malloc(sizeof(Protocol__FlexSiMessage *) * si_config->n_si_message); */ + /* if(si_message == NULL) */ + /* goto error; */ + /* for(j = 0; j < si_config->n_si_message; j++){ */ + /* si_message[j] = malloc(sizeof(Protocol__FlexSiMessage)); */ + /* if(si_message[j] == NULL) */ + /* goto error; */ + /* protocol__flex_si_message__init(si_message[j]); */ + /* //TODO: Fill in with actual value, Periodicity of SI msg in radio frames */ + /* si_message[j]->periodicity = 1; //SIPeriod */ + /* si_message[j]->has_periodicity = 1; */ + /* //TODO: Fill in with actual value, rhe length of the SI message in bytes */ + /* si_message[j]->length = 10; */ + /* si_message[j]->has_length = 1; */ + /* } */ + /* if(si_config->n_si_message > 0){ */ + /* si_config->si_message = si_message; */ + /* } */ + } + + conf->ra_response_window_size = flexran_get_ra_ResponseWindowSize(mod_id, cc_id); + conf->has_ra_response_window_size = 1; + + // belongs to MAC but is read in RRC + conf->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(mod_id, cc_id); + conf->has_mac_contention_resolution_timer = 1; + + conf->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (mod_id, cc_id); + conf->has_ul_pusch_power = 1; + + conf->n_plmn_id = flexran_get_rrc_num_plmn_ids(mod_id); + conf->plmn_id = calloc(conf->n_plmn_id, sizeof(Protocol__FlexPlmn *)); + if (conf->plmn_id) { + for (int i = 0; i < conf->n_plmn_id; i++) { + conf->plmn_id[i] = malloc(sizeof(Protocol__FlexPlmn)); + if (!conf->plmn_id[i]) continue; + protocol__flex_plmn__init(conf->plmn_id[i]); + conf->plmn_id[i]->mcc = flexran_get_rrc_mcc(mod_id, i); + conf->plmn_id[i]->has_mcc = 1; + conf->plmn_id[i]->mnc = flexran_get_rrc_mnc(mod_id, i); + conf->plmn_id[i]->has_mnc = 1; + conf->plmn_id[i]->mnc_length = flexran_get_rrc_mnc_digit_length(mod_id, i); + conf->plmn_id[i]->has_mnc_length = 1; + } + } else { + conf->n_plmn_id = 0; + } +} +int flexran_agent_unregister_rrc_xface(mid_t mod_id) +{ + if (!agent_rrc_xface[mod_id]) { + LOG_E(FLEXRAN_AGENT, "RRC agent for eNB %d is not registered\n", mod_id); + return -1; + } //xface->agent_ctxt = NULL; // xface->flexran_agent_send_update_rrc_stats = NULL; - xface->flexran_agent_notify_ue_state_change = NULL; - xface->flexran_trigger_rrc_measurements = NULL; - rrc_agent_registered[mod_id] = 0; + agent_rrc_xface[mod_id]->flexran_agent_notify_ue_state_change = NULL; + agent_rrc_xface[mod_id]->flexran_trigger_rrc_measurements = NULL; + free(agent_rrc_xface[mod_id]); agent_rrc_xface[mod_id] = NULL; return 0; } + +AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id) +{ + return agent_rrc_xface[mod_id]; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h index b6cb674ce985085efb617a178548eac1c1a23d9d..4b9cec861427871ec0c4973f03062564c78e081a 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h @@ -37,11 +37,10 @@ #include "flexran_agent_common.h" #include "flexran_agent_rrc_defs.h" +// for flexran_agent_get_rrc_xface() +#include "flexran_agent_extern.h" -/* Initialization function for the agent structures etc */ -void flexran_agent_init_rrc_agent(mid_t mod_id); - /* UE state change message constructor and destructor */ void flexran_agent_ue_state_change(mid_t mod_id, uint32_t rnti, uint8_t state_change); int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg); @@ -59,12 +58,20 @@ void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t *); /* Statistics reply protocol message constructor and destructor */ int flexran_agent_rrc_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); -int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexranMessage *msg); +int flexran_agent_rrc_destroy_stats_reply(Protocol__FlexStatsReply *reply); + +/* Fill the RRC part of a ue_config message */ +void flexran_agent_fill_rrc_ue_config(mid_t mod_id, rnti_t rnti, + Protocol__FlexUeConfig *ue_conf); + +/* Fill the RRC part of an cell_config message */ +void flexran_agent_fill_rrc_cell_config(mid_t mod_id, uint8_t cc_id, + Protocol__FlexCellConfig *conf); /*Register technology specific interface callbacks*/ -int flexran_agent_register_rrc_xface(mid_t mod_id, AGENT_RRC_xface *xface); +int flexran_agent_register_rrc_xface(mid_t mod_id); /*Unregister technology specific callbacks*/ -int flexran_agent_unregister_rrc_xface(mid_t mod_id, AGENT_RRC_xface*xface); +int flexran_agent_unregister_rrc_xface(mid_t mod_id); #endif diff --git a/openair2/ENB_APP/L1_paramdef.h b/openair2/ENB_APP/L1_paramdef.h index b062235ff69b6aaefb5cc40bff392419df524df3..210b753afbb19e84ba04693393651f1d73442373 100644 --- a/openair2/ENB_APP/L1_paramdef.h +++ b/openair2/ENB_APP/L1_paramdef.h @@ -44,7 +44,21 @@ #define CONFIG_STRING_L1_LOCAL_N_PORTD "local_n_portd" #define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd" #define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference" - +#define CONFIG_STRING_L1_PRACH_DTX_THRESHOLD "prach_dtx_threshold" +#define CONFIG_STRING_L1_PUCCH1_DTX_THRESHOLD "pucch1_dtx_threshold" +#define CONFIG_STRING_L1_PUCCH1AB_DTX_THRESHOLD "pucch1ab_dtx_threshold" +#define CONFIG_STRING_L1_PRACH_DTX_EMTC0_THRESHOLD "prach_dtx_emtc0_threshold" +#define CONFIG_STRING_L1_PUCCH1_DTX_EMTC0_THRESHOLD "pucch1_dtx_emtc0_threshold" +#define CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC0_THRESHOLD "pucch1ab_dtx_emtc0_threshold" +#define CONFIG_STRING_L1_PRACH_DTX_EMTC1_THRESHOLD "prach_dtx_emtc1_threshold" +#define CONFIG_STRING_L1_PUCCH1_DTX_EMTC1_THRESHOLD "pucch1_dtx_emtc1_threshold" +#define CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC1_THRESHOLD "pucch1ab_dtx_emtc1_threshold" +#define CONFIG_STRING_L1_PRACH_DTX_EMTC2_THRESHOLD "prach_dtx_emtc2_threshold" +#define CONFIG_STRING_L1_PUCCH1_DTX_EMTC2_THRESHOLD "pucch1_dtx_emtc2_threshold" +#define CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC2_THRESHOLD "pucch1ab_dtx_emtc2_threshold" +#define CONFIG_STRING_L1_PRACH_DTX_EMTC3_THRESHOLD "prach_dtx_emtc3_threshold" +#define CONFIG_STRING_L1_PUCCH1_DTX_EMTC3_THRESHOLD "pucch1_dtx_emtc3_threshold" +#define CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC3_THRESHOLD "pucch1ab_dtx_emtc3_threshold" /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* L1 configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -59,7 +73,22 @@ {CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ -} +{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, iptr:NULL, defintval:100, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PUCCH1_DTX_THRESHOLD, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PUCCH1AB_DTX_THRESHOLD, NULL, 0, iptr:NULL, defintval:4, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PRACH_DTX_EMTC0_THRESHOLD, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PUCCH1_DTX_EMTC0_THRESHOLD, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC0_THRESHOLD, NULL, 0, iptr:NULL, defintval:4, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PRACH_DTX_EMTC1_THRESHOLD, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PUCCH1_DTX_EMTC1_THRESHOLD, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC1_THRESHOLD, NULL, 0, iptr:NULL, defintval:4, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PRACH_DTX_EMTC2_THRESHOLD, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PUCCH1_DTX_EMTC2_THRESHOLD, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC2_THRESHOLD, NULL, 0, iptr:NULL, defintval:4, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PRACH_DTX_EMTC3_THRESHOLD, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PUCCH1_DTX_EMTC3_THRESHOLD, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ + {CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC3_THRESHOLD, NULL, 0, iptr:NULL, defintval:4, TYPE_INT, 0} \ + } #define L1_CC_IDX 0 #define L1_TRANSPORT_N_PREFERENCE_IDX 1 #define L1_LOCAL_N_IF_NAME_IDX 2 @@ -69,5 +98,19 @@ #define L1_REMOTE_N_PORTC_IDX 6 #define L1_LOCAL_N_PORTD_IDX 7 #define L1_REMOTE_N_PORTD_IDX 8 - +#define L1_PRACH_DTX_THRESHOLD_IDX 9 +#define L1_PUCCH1_DTX_THRESHOLD_IDX 10 +#define L1_PUCCH1AB_DTX_THRESHOLD_IDX 11 +#define L1_PRACH_DTX_EMTC0_THRESHOLD_IDX 12 +#define L1_PUCCH1_DTX_EMTC0_THRESHOLD_IDX 13 +#define L1_PUCCH1AB_DTX_EMTC0_THRESHOLD_IDX 14 +#define L1_PRACH_DTX_EMTC1_THRESHOLD_IDX 15 +#define L1_PUCCH1_DTX_EMTC1_THRESHOLD_IDX 16 +#define L1_PUCCH1AB_DTX_EMTC1_THRESHOLD_IDX 17 +#define L1_PRACH_DTX_EMTC2_THRESHOLD_IDX 18 +#define L1_PUCCH1_DTX_EMTC2_THRESHOLD_IDX 19 +#define L1_PUCCH1AB_DTX_EMTC2_THRESHOLD_IDX 20 +#define L1_PRACH_DTX_EMTC3_THRESHOLD_IDX 21 +#define L1_PUCCH1_DTX_EMTC3_THRESHOLD_IDX 22 +#define L1_PUCCH1AB_DTX_EMTC3_THRESHOLD_IDX 23 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto index 3af59c1537691b5ac40104cfab714106a770a257..695d7bcdb1f07378779a674b3d29a3001dfc2544 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto @@ -218,6 +218,9 @@ enum flex_aperiodic_cqi_report_mode { FLACRM_RM30 = 3; FLACRM_RM31 = 4; FLACRM_NONE = 5; + FLACRM_RM32_v1250 = 6; + FLACRM_RM10_v1310 = 7; + FLACRM_RM11_v1310 = 8; } enum flex_tdd_ack_nack_feedback_mode { @@ -259,3 +262,9 @@ enum flex_ue_state_change_type { FLUESC_DEACTIVATED = 2; FLUESC_MOVED = 3; } + +message flex_plmn { + optional uint32 mcc = 1; + optional uint32 mnc = 2; + optional uint32 mnc_length = 3; +} diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 1d5da8dd2abc0e756615096aee666e54125053dc..dd983aa09c700f82931834b70a003ee091280d77 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -5,7 +5,6 @@ import "config_common.proto"; message flex_cell_config { optional uint32 phy_cell_id = 1; // The PCI of this cell - optional uint32 cell_id = 2; // The PLMN cell id of this cell optional uint32 pusch_hopping_offset = 3; // PUSCH resources in RBs for hopping optional uint32 hopping_mode = 4; // One of the FLHM_* enum values optional uint32 n_sb = 5; // The number of subbands @@ -43,6 +42,7 @@ message flex_cell_config { optional uint32 eutra_band= 37; // operating band optional int32 dl_pdsch_power = 38; // operating downlink power optional int32 ul_pusch_power = 39; // operating uplink power + repeated flex_plmn plmn_id = 40; // The PLMN cell id of this cell optional flex_slice_config slice_config = 42; } diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 9255372340283d8ce89bb0c1c4cfc6c19a2710a9..b1702f949e4af2204a546975387da8913ca71de0 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -31,6 +31,7 @@ message flexran_message { flex_agent_reconfiguration agent_reconfiguration_msg = 17; flex_rrc_triggering rrc_triggering = 18; flex_ul_mac_config ul_mac_config_msg = 19; + flex_disconnect disconnect_msg = 20; } } @@ -64,9 +65,21 @@ enum flexran_err { // // Maintenance and discovery messages // +enum flex_bs_capability { + LOPHY = 0; + HIPHY = 1; + LOMAC = 2; + HIMAC = 3; + RLC = 4; + PDCP = 5; + SDAP = 6; + RRC = 7; +} message flex_hello { - optional flex_header header = 1; + optional flex_header header = 1; + optional uint64 bs_id = 2; // Unique id to distinguish the eNB + repeated flex_bs_capability capabilities = 3; } message flex_echo_request { @@ -131,7 +144,6 @@ message flex_enb_config_request { message flex_enb_config_reply { optional flex_header header = 1; - optional uint64 eNB_id = 2; // Unique id to distinguish the eNB repeated flex_cell_config cell_config = 3; optional uint32 device_spec = 4; } @@ -223,4 +235,6 @@ message flex_echo_reply_latency { } } - +message flex_disconnect { + optional flex_header header = 1; +} diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto index 8900b934920eca605cce1746c2aa014ef8564bce..c91d2e2c09929f83545fb057e22d570ebdc22e0e 100644 --- a/openair2/ENB_APP/MESSAGES/V2/header.proto +++ b/openair2/ENB_APP/MESSAGES/V2/header.proto @@ -12,6 +12,7 @@ enum flex_type { FLPT_HELLO = 0; FLPT_ECHO_REQUEST = 1; FLPT_ECHO_REPLY = 2; + FLPT_DISCONNECT = 20; // Statistics and measurement messages FLPT_STATS_REQUEST = 3; diff --git a/openair2/ENB_APP/NB_IoT_config.c b/openair2/ENB_APP/NB_IoT_config.c index 08c3d30fa366cc0012c9550ea202d9b396567112..26ba8989e17ae258a29d8490c6ad0e956e5cb03b 100644 --- a/openair2/ENB_APP/NB_IoT_config.c +++ b/openair2/ENB_APP/NB_IoT_config.c @@ -33,13 +33,9 @@ #include "log.h" #include "log_extern.h" #include "assertions.h" -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -# include "sctp_eNB_task.h" -# endif -#endif +#include "intertask_interface.h" +#include "s1ap_eNB.h" +#include "sctp_eNB_task.h" #include "SystemInformationBlockType2.h" #include "PHY/phy_extern.h" @@ -56,11 +52,10 @@ void RCconfig_NbIoTL1(void) { paramdef_t NbIoT_L1_Params[] = L1PARAMS_DESC; paramlist_def_t NbIoT_L1_ParamList = {NBIOT_L1LIST_CONFIG_STRING,NULL,0}; + /* No component carrier for NbIoT, ignore number of CC */ + // NbIoT_L1_Params[L1_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD; + config_getlist( &NbIoT_L1_ParamList,NbIoT_L1_Params,sizeof(NbIoT_L1_Params)/sizeof(paramdef_t), NULL); -/* No component carrier for NbIoT, ignore number of CC */ -// NbIoT_L1_Params[L1_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD; - - config_getlist( &NbIoT_L1_ParamList,NbIoT_L1_Params,sizeof(NbIoT_L1_Params)/sizeof(paramdef_t), NULL); if (NbIoT_L1_ParamList.numelt > 0) { if (RC.L1_NB_IoT == NULL) { RC.L1_NB_IoT = (PHY_VARS_eNB_NB_IoT **)malloc(RC.nb_nb_iot_L1_inst*sizeof(PHY_VARS_eNB_NB_IoT *)); @@ -68,219 +63,190 @@ void RCconfig_NbIoTL1(void) { memset(RC.L1_NB_IoT,0,RC.nb_nb_iot_L1_inst*sizeof(PHY_VARS_eNB_NB_IoT *)); } - - for(int j = 0; j <NbIoT_L1_ParamList.numelt ; j++) { + for(int j = 0; j <NbIoT_L1_ParamList.numelt ; j++) { if (RC.L1_NB_IoT[j] == NULL) { - RC.L1_NB_IoT[j] = (PHY_VARS_eNB_NB_IoT *)malloc(sizeof(PHY_VARS_eNB_NB_IoT)); - LOG_I(PHY,"RC.L1_NB_IoT[%d] = %p\n",j,RC.L1_NB_IoT[j]); - memset(RC.L1_NB_IoT[j],0,sizeof(PHY_VARS_eNB_NB_IoT)); + RC.L1_NB_IoT[j] = (PHY_VARS_eNB_NB_IoT *)malloc(sizeof(PHY_VARS_eNB_NB_IoT)); + LOG_I(PHY,"RC.L1_NB_IoT[%d] = %p\n",j,RC.L1_NB_IoT[j]); + memset(RC.L1_NB_IoT[j],0,sizeof(PHY_VARS_eNB_NB_IoT)); } - if (strcmp(*(NbIoT_L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { + if (strcmp(*(NbIoT_L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { + } else if (strcmp(*(NbIoT_L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { + RC.L1_NB_IoT[j]->eth_params_n.local_if_name = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.my_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.remote_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.my_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.remote_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.my_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.remote_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.transp_preference = ETH_UDP_MODE; + } else { // other midhaul } - else if (strcmp(*(NbIoT_L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { - RC.L1_NB_IoT[j]->eth_params_n.local_if_name = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); - RC.L1_NB_IoT[j]->eth_params_n.my_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); - RC.L1_NB_IoT[j]->eth_params_n.remote_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); - RC.L1_NB_IoT[j]->eth_params_n.my_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); - RC.L1_NB_IoT[j]->eth_params_n.remote_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr); - RC.L1_NB_IoT[j]->eth_params_n.my_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); - RC.L1_NB_IoT[j]->eth_params_n.remote_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); - RC.L1_NB_IoT[j]->eth_params_n.transp_preference = ETH_UDP_MODE; - } - - else { // other midhaul - } }// j=0..num_inst + printf("Initializing northbound interface for NB-IoT L1\n"); l1_north_init_NB_IoT(); } else { - LOG_I(PHY,"No " NBIOT_L1LIST_CONFIG_STRING " configuration found"); + LOG_I(PHY,"No " NBIOT_L1LIST_CONFIG_STRING " configuration found"); } } void RCconfig_NbIoTmacrlc(void) { - - - paramdef_t NbIoT_MacRLC_Params[] = MACRLCPARAMS_DESC; paramlist_def_t NbIoT_MacRLC_ParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0}; - - -/* No component carrier for NbIoT, ignore number of CC */ -// NbIoT_MacRLC_Params[MACRLC_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD; - - config_getlist( &NbIoT_MacRLC_ParamList,NbIoT_MacRLC_Params,sizeof(NbIoT_MacRLC_Params)/sizeof(paramdef_t), NULL); - + /* No component carrier for NbIoT, ignore number of CC */ + // NbIoT_MacRLC_Params[MACRLC_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD; + config_getlist( &NbIoT_MacRLC_ParamList,NbIoT_MacRLC_Params,sizeof(NbIoT_MacRLC_Params)/sizeof(paramdef_t), NULL); if ( NbIoT_MacRLC_ParamList.numelt > 0) { mac_top_init_eNB_NB_IoT(); - for (int j=0;j<RC.nb_nb_iot_macrlc_inst;j++) { + for (int j=0; j<RC.nb_nb_iot_macrlc_inst; j++) { if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) { - // check number of instances is same as RRC/PDCP - + // check number of instances is same as RRC/PDCP } else if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) { - RC.nb_iot_mac[j]->eth_params_n.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr)); - RC.nb_iot_mac[j]->eth_params_n.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr)); - RC.nb_iot_mac[j]->eth_params_n.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr)); - RC.nb_iot_mac[j]->eth_params_n.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr); - RC.nb_iot_mac[j]->eth_params_n.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr); - RC.nb_iot_mac[j]->eth_params_n.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr); - RC.nb_iot_mac[j]->eth_params_n.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);; - RC.nb_iot_mac[j]->eth_params_n.transp_preference = ETH_UDP_MODE; + RC.nb_iot_mac[j]->eth_params_n.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);; + RC.nb_iot_mac[j]->eth_params_n.transp_preference = ETH_UDP_MODE; } else { // other midhaul - AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr)); - } + AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr)); + } if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_L1") == 0) { - - } else if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "nfapi") == 0) { - RC.nb_iot_mac[j]->eth_params_s.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_IF_NAME_IDX].strptr)); - RC.nb_iot_mac[j]->eth_params_s.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_ADDRESS_IDX].strptr)); - RC.nb_iot_mac[j]->eth_params_s.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_ADDRESS_IDX].strptr)); - RC.nb_iot_mac[j]->eth_params_s.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTC_IDX].iptr); - RC.nb_iot_mac[j]->eth_params_s.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTC_IDX].iptr); - RC.nb_iot_mac[j]->eth_params_s.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr); - RC.nb_iot_mac[j]->eth_params_s.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); - RC.nb_iot_mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; + RC.nb_iot_mac[j]->eth_params_s.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_IF_NAME_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; } else { // other midhaul - AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); - } + AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); + } }// j=0..num_inst */ } else {// MacRLC_ParamList.numelt > 0 - AssertFatal (0, - "No " NBIOT_MACRLCLIST_CONFIG_STRING " configuration found"); + AssertFatal (0, + "No " NBIOT_MACRLCLIST_CONFIG_STRING " configuration found"); } } - -int RCconfig_NbIoTRRC(MessageDef *msg_p, int nbiotrrc_id,eNB_RRC_INST_NB_IoT *nbiotrrc) { - +int RCconfig_NbIoTRRC(MessageDef *msg_p, int nbiotrrc_id,eNB_RRC_INST_NB_IoT *nbiotrrc) { char instprefix[MAX_OPTNAME_SIZE*3 + 32]; - - - checkedparam_t NBIoTCheckParams[] = NBIOT_RRCPARAMS_CHECK_DESC; + checkedparam_t NBIoTCheckParams[] = NBIOT_RRCPARAMS_CHECK_DESC_0_14; + checkedparam_t NBIoTCheckParamsB[] = NBIOT_RRCPARAMS_CHECK_DESC_15_end; paramdef_t NBIoTParams[] = NBIOTRRCPARAMS_DESC; - paramdef_t NBIoTPrachParams[] = NBIOTRRC_NPRACH_PARAMS_DESC; checkedparam_t NBIoTPrachCheckParams[] = NBIOT_RRCLIST_NPRACHPARAMSCHECK_DESC; - paramdef_t NBIoTRRCRefParams[] = NBIOTRRCPARAMS_RRCREF_DESC; - paramdef_t NBIoTLteCCParams[] = NBIOT_LTECCPARAMS_DESC; checkedparam_t NBIoTLteCCCheckParams[] = NBIOT_LTECCPARAMS_CHECK_DESC; -/* map parameter checking array instances to parameter definition array instances */ + + /* map parameter checking array instances to parameter definition array instances */ for (int i=0; (i<sizeof(NBIoTParams)/sizeof(paramdef_t)) && (i<sizeof(NBIoTCheckParams)/sizeof(checkedparam_t)); i++ ) { - NBIoTParams[i].chkPptr = &(NBIoTCheckParams[i]); - } + NBIoTParams[i].chkPptr = &(NBIoTCheckParams[i]); + } + + for (int i=0; (i<sizeof(NBIoTParams)/sizeof(paramdef_t)) && (i<sizeof(NBIoTCheckParamsB)/sizeof(checkedparam_t)); i++ ) { + NBIoTParams[i+15].chkPptr = &(NBIoTCheckParamsB[i]); + } + for (int i=0; (i<sizeof(NBIoTPrachParams)/sizeof(paramdef_t)) && (i<sizeof(NBIoTPrachCheckParams)/sizeof(checkedparam_t)); i++ ) { - NBIoTPrachParams[i].chkPptr = &(NBIoTPrachCheckParams[i]); + NBIoTPrachParams[i].chkPptr = &(NBIoTPrachCheckParams[i]); } -/* brut force itti message fields assignment, to be redesigned with itti replacement */ + /* brut force itti message fields assignment, to be redesigned with itti replacement */ NBIoTParams[NBIOT_RACH_RARESPONSEWINDOWSIZE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_raResponseWindowSize_NB); NBIoTParams[NBIOT_RACH_MACCONTENTIONRESOLUTIONTIMER_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_macContentionResolutionTimer_NB); - NBIoTParams[NBIOT_RACH_POWERRAMPINGSTEP_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep_NB); + NBIoTParams[NBIOT_RACH_POWERRAMPINGSTEP_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep_NB); NBIoTParams[NBIOT_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_preambleInitialReceivedTargetPower_NB); - NBIoTParams[NBIOT_RACH_PREAMBLETRANSMAX_CE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax_CE_NB); - NBIoTParams[NBIOT_BCCH_MODIFICATIONPERIODCOEFF_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff_NB); - NBIoTParams[NBIOT_PCCH_DEFAULTPAGINGCYCLE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle_NB); - NBIoTParams[NBIOT_NPRACH_CP_LENGTH_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_CP_Length); - NBIoTParams[NBIOT_NPRACH_RSRP_RANGE_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_rsrp_range); - - - + NBIoTParams[NBIOT_RACH_PREAMBLETRANSMAX_CE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax_CE_NB); + NBIoTParams[NBIOT_BCCH_MODIFICATIONPERIODCOEFF_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff_NB); + NBIoTParams[NBIOT_PCCH_DEFAULTPAGINGCYCLE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle_NB); + NBIoTParams[NBIOT_NPRACH_CP_LENGTH_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_CP_Length); + NBIoTParams[NBIOT_NPRACH_RSRP_RANGE_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_rsrp_range); NBIoTParams[NBIOT_MAXNUMPREAMBLEATTEMPTCE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).maxNumPreambleAttemptCE_NB); - - NBIoTParams[NBIOT_NPDSCH_NRS_POWER_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdsch_nrs_Power); - NBIoTParams[NBIOT_NPUSCH_ACK_NACK_NUMREPETITIONS_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p). npusch_ack_nack_numRepetitions_NB); - NBIoTParams[NBIOT_NPUSCH_SRS_SUBFRAMECONFIG_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p). npusch_srs_SubframeConfig_NB); - NBIoTParams[NBIOT_NPUSCH_THREETONE_CYCLICSHIFT_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_threeTone_CyclicShift_r13); + NBIoTParams[NBIOT_NPDSCH_NRS_POWER_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdsch_nrs_Power); + NBIoTParams[NBIOT_NPUSCH_ACK_NACK_NUMREPETITIONS_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p). npusch_ack_nack_numRepetitions_NB); + NBIoTParams[NBIOT_NPUSCH_SRS_SUBFRAMECONFIG_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p). npusch_srs_SubframeConfig_NB); + NBIoTParams[NBIOT_NPUSCH_THREETONE_CYCLICSHIFT_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_threeTone_CyclicShift_r13); NBIoTParams[NBIOT_NPUSCH_SIXTONE_CYCLICSHIFT_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_sixTone_CyclicShift_r13); - NBIoTParams[NBIOT_NPUSCH_GROUPASSIGNMENTNPUSCH_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_groupAssignmentNPUSCH_r13); - NBIoTParams[NBIOT_DL_GAPTHRESHOLD_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapThreshold_NB); - NBIoTParams[NBIOT_DL_GAPPERIODICITY_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapPeriodicity_NB); - - NBIoTParams[NBIOT_NPUSCH_P0_NOMINALNPUSCH_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_p0_NominalNPUSCH); - - NBIoTParams[NBIOT_DELTAPREAMBLEMSG3_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).deltaPreambleMsg3); - NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T300_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300_NB); + NBIoTParams[NBIOT_DL_GAPTHRESHOLD_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapThreshold_NB); + NBIoTParams[NBIOT_DL_GAPPERIODICITY_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapPeriodicity_NB); + NBIoTParams[NBIOT_NPUSCH_P0_NOMINALNPUSCH_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_p0_NominalNPUSCH); + NBIoTParams[NBIOT_DELTAPREAMBLEMSG3_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).deltaPreambleMsg3); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T300_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300_NB); NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T301_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301_NB); - NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T310_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310_NB); - NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T311_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311_NB); - NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_N310_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T310_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T311_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_N310_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310_NB); NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_N311_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311_NB); - sprintf(instprefix, NBIOT_RRCLIST_CONFIG_STRING ".[%i]",nbiotrrc_id); - config_get( NBIoTParams,sizeof(NBIoTParams)/sizeof(paramdef_t),instprefix); - + config_get( NBIoTParams,sizeof(NBIoTParams)/sizeof(paramdef_t),instprefix); NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_SubcarrierMSG3_RangeStart = config_get_processedint( &(NBIoTParams[NBIOT_NPRACH_SUBCARRIERMSG3_RANGESTART_IDX]) ); - NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_groupHoppingEnabled = config_get_processedint( &(NBIoTParams[NBIOT_NPUSCH_GROUPHOPPINGENABLED_IDX] ) ); - NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapDurationCoeff_NB = config_get_processedint( &(NBIoTParams[NBIOT_DL_GAPDURATIONCOEFF_NB_IDX] ) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_groupHoppingEnabled = config_get_processedint( &(NBIoTParams[NBIOT_NPUSCH_GROUPHOPPINGENABLED_IDX] ) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapDurationCoeff_NB = config_get_processedint( &(NBIoTParams[NBIOT_DL_GAPDURATIONCOEFF_NB_IDX] ) ); NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_alpha = config_get_processedint( &(NBIoTParams[NBIOT_NPUSCH_ALPHA_IDX] ) ); + for (int i=0; i<MAX_NUM_NBIOT_CELEVELS; i++) { - char *tmpptr=NULL; - NBIoTPrachParams[NBIOT_NPRACH_PERIODICITY_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_Periodicity[i]); - NBIoTPrachParams[NBIOT_NPRACH_STARTTIME_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_StartTime[i]); - NBIoTPrachParams[NBIOT_NPRACH_SUBCARRIEROFFSET_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_SubcarrierOffset[i]); - NBIoTPrachParams[NBIOT_NPRACH_NUMSUBCARRIERS_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_NumSubcarriers[i]); - NBIoTPrachParams[NBIOT_NUMREPETITIONSPERPREAMBLEATTEMPT_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).numRepetitionsPerPreambleAttempt_NB[i]); - NBIoTParams[NBIOT_NPDCCH_NUMREPETITIONS_RA_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_NumRepetitions_RA[i]); - NBIoTParams[NBIOT_NPDCCH_STARTSF_CSS_RA_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_StartSF_CSS_RA[i]); - NBIoTParams[NBIOT_NPDCCH_OFFSET_RA_IDX].strptr = &tmpptr; - sprintf(instprefix, "%s.[%i].%s.[%i]",NBIOT_RRCLIST_CONFIG_STRING, nbiotrrc_id,NBIOT_RRCLIST_NPRACHPARAMS_CONFIG_STRING,i); - config_get( NBIoTPrachParams,sizeof(NBIoTPrachParams)/sizeof(paramdef_t),instprefix); - NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_Offset_RA[i] = config_get_processedint( &(NBIoTPrachParams[NBIOT_NPDCCH_OFFSET_RA_IDX]) ); + char *tmpptr=NULL; + NBIoTPrachParams[NBIOT_NPRACH_PERIODICITY_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_Periodicity[i]); + NBIoTPrachParams[NBIOT_NPRACH_STARTTIME_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_StartTime[i]); + NBIoTPrachParams[NBIOT_NPRACH_SUBCARRIEROFFSET_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_SubcarrierOffset[i]); + NBIoTPrachParams[NBIOT_NPRACH_NUMSUBCARRIERS_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_NumSubcarriers[i]); + NBIoTPrachParams[NBIOT_NUMREPETITIONSPERPREAMBLEATTEMPT_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).numRepetitionsPerPreambleAttempt_NB[i]); + NBIoTParams[NBIOT_NPDCCH_NUMREPETITIONS_RA_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_NumRepetitions_RA[i]); + NBIoTParams[NBIOT_NPDCCH_STARTSF_CSS_RA_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_StartSF_CSS_RA[i]); + NBIoTParams[NBIOT_NPDCCH_OFFSET_RA_IDX].strptr = &tmpptr; + sprintf(instprefix, "%s.[%i].%s.[%i]",NBIOT_RRCLIST_CONFIG_STRING, nbiotrrc_id,NBIOT_RRCLIST_NPRACHPARAMS_CONFIG_STRING,i); + config_get( NBIoTPrachParams,sizeof(NBIoTPrachParams)/sizeof(paramdef_t),instprefix); + NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_Offset_RA[i] = config_get_processedint( &(NBIoTPrachParams[NBIOT_NPDCCH_OFFSET_RA_IDX]) ); } -/* get the LTE RRC and CC this NB-IoT RRC instance is attached to */ - sprintf(instprefix, NBIOT_RRCLIST_CONFIG_STRING ".[%i]." NBIOT_LTERRCREF_CONFIG_STRING, nbiotrrc_id ); - config_get( NBIoTRRCRefParams,sizeof(NBIoTRRCRefParams)/sizeof(paramdef_t),instprefix); -/* read SIB1 parameters in the LTE RRC and CC sections */ + /* get the LTE RRC and CC this NB-IoT RRC instance is attached to */ + sprintf(instprefix, NBIOT_RRCLIST_CONFIG_STRING ".[%i]." NBIOT_LTERRCREF_CONFIG_STRING, nbiotrrc_id ); + config_get( NBIoTRRCRefParams,sizeof(NBIoTRRCRefParams)/sizeof(paramdef_t),instprefix); + /* read SIB1 parameters in the LTE RRC and CC sections */ sprintf(instprefix, ENB_CONFIG_STRING_ENB_LIST ".[%i]." ENB_CONFIG_STRING_COMPONENT_CARRIERS ".[%i]", - *(NBIoTRRCRefParams[NBIOT_RRCINST_IDX].uptr), *(NBIoTRRCRefParams[NBIOT_CCINST_IDX].uptr)); - - NBIoTLteCCParams[LTECCPARAMS_TDD_CONFIG_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).tdd_config); - NBIoTLteCCParams[LTECCPARAMS_TDD_CONFIG_S_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).tdd_config_s); - NBIoTLteCCParams[LTECCPARAMS_EUTRA_BAND_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).eutra_band); - NBIoTLteCCParams[LTECCPARAMS_DOWNLINK_FREQUENCY_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).downlink_frequency); + *(NBIoTRRCRefParams[NBIOT_RRCINST_IDX].uptr), *(NBIoTRRCRefParams[NBIOT_CCINST_IDX].uptr)); + NBIoTLteCCParams[LTECCPARAMS_TDD_CONFIG_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).tdd_config); + NBIoTLteCCParams[LTECCPARAMS_TDD_CONFIG_S_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).tdd_config_s); + NBIoTLteCCParams[LTECCPARAMS_EUTRA_BAND_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).eutra_band); + NBIoTLteCCParams[LTECCPARAMS_DOWNLINK_FREQUENCY_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).downlink_frequency); NBIoTLteCCParams[LTECCPARAMS_UPLINK_FREQUENCY_OFFSET_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset); - NBIoTLteCCParams[LTECCPARAMS_NID_CELL_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).Nid_cell); - NBIoTLteCCParams[LTECCPARAMS_N_RB_DL_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).N_RB_DL); + NBIoTLteCCParams[LTECCPARAMS_NID_CELL_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).Nid_cell); + NBIoTLteCCParams[LTECCPARAMS_N_RB_DL_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).N_RB_DL); for (int i=0; (i<sizeof(NBIoTLteCCParams)/sizeof(paramdef_t)) && (i<sizeof(NBIoTLteCCCheckParams)/sizeof(checkedparam_t)); i++ ) { - NBIoTLteCCParams[i].chkPptr = &(NBIoTLteCCCheckParams[i]); + NBIoTLteCCParams[i].chkPptr = &(NBIoTLteCCCheckParams[i]); } - config_get( NBIoTLteCCParams,sizeof(NBIoTLteCCParams)/sizeof(paramdef_t),instprefix); - NBIOTRRC_CONFIGURATION_REQ (msg_p).frame_type = config_get_processedint( &(NBIoTLteCCParams[LTECCPARAMS_FRAME_TYPE_IDX]) ); + + config_get( NBIoTLteCCParams,sizeof(NBIoTLteCCParams)/sizeof(paramdef_t),instprefix); + NBIOTRRC_CONFIGURATION_REQ (msg_p).frame_type = config_get_processedint( &(NBIoTLteCCParams[LTECCPARAMS_FRAME_TYPE_IDX]) ); NBIOTRRC_CONFIGURATION_REQ (msg_p).prefix_type = config_get_processedint( &(NBIoTLteCCParams[LTECCPARAMS_PREFIX_TYPE_IDX]) ); NBIOTRRC_CONFIGURATION_REQ (msg_p).prefix_type = config_get_processedint( &(NBIoTLteCCParams[LTECCPARAMS_PREFIX_TYPE_UL_IDX]) ); -return 0; + return 0; } void RCConfig_NbIoT(RAN_CONTEXT_t *RC) { - paramlist_def_t NbIoT_MACRLCParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0}; paramlist_def_t NbIoT_L1ParamList = {NBIOT_L1LIST_CONFIG_STRING,NULL,0}; paramlist_def_t NbIoT_ParamList = {NBIOT_RRCLIST_CONFIG_STRING,NULL,0}; - - config_getlist( &NbIoT_ParamList,NULL,0,NULL); RC->nb_nb_iot_rrc_inst = NbIoT_ParamList.numelt; - - - - - config_getlist( &NbIoT_MACRLCParamList,NULL,0, NULL); - RC->nb_nb_iot_macrlc_inst = NbIoT_MACRLCParamList.numelt; - // Get num L1 instances - config_getlist( &NbIoT_L1ParamList,NULL,0, NULL); - RC->nb_nb_iot_L1_inst = NbIoT_L1ParamList.numelt; - + config_getlist( &NbIoT_MACRLCParamList,NULL,0, NULL); + RC->nb_nb_iot_macrlc_inst = NbIoT_MACRLCParamList.numelt; + // Get num L1 instances + config_getlist( &NbIoT_L1ParamList,NULL,0, NULL); + RC->nb_nb_iot_L1_inst = NbIoT_L1ParamList.numelt; } diff --git a/openair2/ENB_APP/RRC_config_tools.c b/openair2/ENB_APP/RRC_config_tools.c index e778439d3d2420c887bd6605891bb62c06ff78aa..c0cd1b5a6f9e7984adf09c3d9b7a13145e265af2 100644 --- a/openair2/ENB_APP/RRC_config_tools.c +++ b/openair2/ENB_APP/RRC_config_tools.c @@ -24,7 +24,7 @@ ------------------- AUTHOR : Francois TABURET COMPANY : NOKIA BellLabs France - EMAIL : francois.taburet@nokia-bell-labs.com + EMAIL : francois.taburet@nokia-bell-labs.com */ @@ -33,13 +33,9 @@ #include "common/utils/LOG/log.h" #include "assertions.h" -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -# include "sctp_eNB_task.h" -# endif -#endif +#include "intertask_interface.h" +#include "s1ap_eNB.h" +#include "sctp_eNB_task.h" #include "LTE_SystemInformationBlockType2.h" #include "common/config/config_userapi.h" #include "RRC_config_tools.h" @@ -84,8 +80,7 @@ int config_check_band_frequencies( int ind, int16_t band, uint32_t downlink_frequency, int32_t uplink_frequency_offset, - uint32_t frame_type) -{ + uint32_t frame_type) { int errors = 0; if (band > 0) { @@ -94,21 +89,18 @@ int config_check_band_frequencies( int ind, for (band_index = 0; band_index < sizeof (eutra_bands) / sizeof (eutra_bands[0]); band_index++) { if (band == eutra_bands[band_index].band) { uint32_t uplink_frequency = downlink_frequency + uplink_frequency_offset; - AssertError (eutra_bands[band_index].dl_min < downlink_frequency, errors ++, "enb %d downlink frequency %u too low (%u) for band %d!", ind, downlink_frequency, eutra_bands[band_index].dl_min, band); AssertError (downlink_frequency < eutra_bands[band_index].dl_max, errors ++, "enb %d downlink frequency %u too high (%u) for band %d!", ind, downlink_frequency, eutra_bands[band_index].dl_max, band); - AssertError (eutra_bands[band_index].ul_min < uplink_frequency, errors ++, "enb %d uplink frequency %u too low (%u) for band %d!", ind, uplink_frequency, eutra_bands[band_index].ul_min, band); AssertError (uplink_frequency < eutra_bands[band_index].ul_max, errors ++, "enb %d uplink frequency %u too high (%u) for band %d!", ind, uplink_frequency, eutra_bands[band_index].ul_max, band); - AssertError (eutra_bands[band_index].frame_type == frame_type, errors ++, "enb %d invalid frame type (%d/%d) for band %d!", ind, eutra_bands[band_index].frame_type, frame_type, band); @@ -116,7 +108,6 @@ int config_check_band_frequencies( int ind, } } - return errors; } diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 35871b15d266e061ecc819ec1d62dac0bbd69321..0580f0eb52cffe0fffd2cecab1234059b76cfdae 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -34,108 +34,63 @@ #include "enb_config.h" #include "assertions.h" #include "common/ran_context.h" +#include "targets/RT/USER/lte-softmodem.h" #include "common/utils/LOG/log.h" -#if defined(ENABLE_ITTI) # include "intertask_interface.h" -# if defined(ENABLE_USE_MME) # include "s1ap_eNB.h" # include "sctp_eNB_task.h" # include "gtpv1u_eNB_task.h" -/* temporary warning removale while implementing noS1 */ -/* as config option */ -# else -# ifdef EPC_MODE_ENABLED -# undef EPC_MODE_ENABLED -# endif -# define EPC_MODE_ENABLED 0 -# endif +# include "flexran_agent.h" + # include "x2ap_eNB.h" # include "x2ap_messages_types.h" # define X2AP_ENB_REGISTER_RETRY_DELAY 10 #include "openair1/PHY/INIT/phy_init.h" extern unsigned char NB_eNB_INST; -#endif extern RAN_CONTEXT_t RC; -#if defined(ENABLE_ITTI) - -/*------------------------------------------------------------------------------*/ -# if defined(ENABLE_USE_MME) # define ENB_REGISTER_RETRY_DELAY 10 -# endif #include "targets/RT/USER/lte-softmodem.h" -/*------------------------------------------------------------------------------*/ -/* -static void configure_phy(module_id_t enb_id, const Enb_properties_array_t* enb_properties) -{ - MessageDef *msg_p; - int CC_id; - - msg_p = itti_alloc_new_message (TASK_ENB_APP, PHY_CONFIGURATION_REQ); - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_CONFIGURATION_REQ (msg_p).frame_type[CC_id] = enb_properties->properties[enb_id]->frame_type[CC_id]; - PHY_CONFIGURATION_REQ (msg_p).prefix_type[CC_id] = enb_properties->properties[enb_id]->prefix_type[CC_id]; - PHY_CONFIGURATION_REQ (msg_p).downlink_frequency[CC_id] = enb_properties->properties[enb_id]->downlink_frequency[CC_id]; - PHY_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[CC_id] = enb_properties->properties[enb_id]->uplink_frequency_offset[CC_id]; - PHY_CONFIGURATION_REQ (msg_p).nb_antennas_tx[CC_id] = enb_properties->properties[enb_id]->nb_antennas_tx[CC_id]; - PHY_CONFIGURATION_REQ (msg_p).nb_antennas_rx[CC_id] = enb_properties->properties[enb_id]->nb_antennas_rx[CC_id]; - PHY_CONFIGURATION_REQ (msg_p).tx_gain[CC_id] = enb_properties->properties[enb_id]->tx_gain[CC_id]; - PHY_CONFIGURATION_REQ (msg_p).rx_gain[CC_id] = enb_properties->properties[enb_id]->rx_gain[CC_id]; - } - itti_send_msg_to_task (TASK_PHY_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); -} -*/ /*------------------------------------------------------------------------------*/ -static void configure_rrc(uint32_t enb_id) -{ - MessageDef *msg_p = NULL; - // int CC_id; - - msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ); - if (RC.rrc[enb_id]) { - RCconfig_RRC(msg_p,enb_id, RC.rrc[enb_id]); - - - LOG_I(ENB_APP,"Sending configuration message to RRC task\n"); - itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - - } - else AssertFatal(0,"RRC context for eNB %d not allocated\n",enb_id); -} - -/*------------------------------------------------------------------------------*/ -# if defined(ENABLE_USE_MME) -static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end)//, const Enb_properties_array_t *enb_properties) -{ +static uint32_t eNB_app_register(ngran_node_t node_type,uint32_t enb_id_start, uint32_t enb_id_end) { uint32_t enb_id; MessageDef *msg_p; uint32_t register_enb_pending = 0; for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { { - /* note: there is an implicit relationship between the data structure and the message name */ - msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); - - RCconfig_S1(msg_p, enb_id); - - if (enb_id == 0) RCconfig_gtpu(); + if (NODE_IS_DU(node_type)) { // F1AP registration + // configure F1AP here for F1C + LOG_I(ENB_APP,"ngran_eNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n"); + msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ); + RCconfig_DU_F1(msg_p, enb_id); + + LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); + itti_send_msg_to_task (TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + // configure GTPu here for F1U + } + else { // S1AP registration + /* note: there is an implicit relationship between the data structure and the message name */ + msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); + RCconfig_S1(msg_p, enb_id); - LOG_I(ENB_APP,"default drx %d\n",((S1AP_REGISTER_ENB_REQ(msg_p)).default_drx)); + if (enb_id == 0) RCconfig_gtpu(); - LOG_I(ENB_APP,"[eNB %d] eNB_app_register for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); + LOG_I(ENB_APP,"default drx %d\n",((S1AP_REGISTER_ENB_REQ(msg_p)).default_drx)); - itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + LOG_I(ENB_APP,"[eNB %d] eNB_app_register via S1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); + itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + } register_enb_pending++; } @@ -143,26 +98,19 @@ static uint32_t eNB_app_register(uint32_t enb_id_start, uint32_t enb_id_end)//, return register_enb_pending; } -# endif -#endif + /*------------------------------------------------------------------------------*/ -static uint32_t eNB_app_register_x2(uint32_t enb_id_start, uint32_t enb_id_end) -{ +static uint32_t eNB_app_register_x2(uint32_t enb_id_start, uint32_t enb_id_end) { uint32_t enb_id; MessageDef *msg_p; uint32_t register_enb_x2_pending = 0; for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { - { - msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ); - RCconfig_X2(msg_p, enb_id); - itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - register_enb_x2_pending++; } } @@ -171,73 +119,37 @@ static uint32_t eNB_app_register_x2(uint32_t enb_id_start, uint32_t enb_id_end) } /*------------------------------------------------------------------------------*/ -void *eNB_app_task(void *args_p) -{ -#if defined(ENABLE_ITTI) +void *eNB_app_task(void *args_p) { uint32_t enb_nb = RC.nb_inst; uint32_t enb_id_start = 0; uint32_t enb_id_end = enb_id_start + enb_nb; -# if defined(ENABLE_USE_MME) uint32_t register_enb_pending=0; - uint32_t registered_enb; + uint32_t registered_enb=0; long enb_register_retry_timer_id; -# endif - uint32_t x2_register_enb_pending; - uint32_t x2_registered_enb; + uint32_t x2_register_enb_pending = 0; + uint32_t x2_registered_enb = 0; long x2_enb_register_retry_timer_id; - uint32_t enb_id; MessageDef *msg_p = NULL; instance_t instance; int result; /* for no gcc warnings */ (void)instance; - itti_mark_task_ready (TASK_ENB_APP); - LOG_I(PHY, "%s() Task ready initialise structures\n", __FUNCTION__); - - RCconfig_L1(); - - RCconfig_macrlc(); - - LOG_I(PHY, "%s() RC.nb_L1_inst:%d\n", __FUNCTION__, RC.nb_L1_inst); - - if (RC.nb_L1_inst>0) AssertFatal(l1_north_init_eNB()==0,"could not initialize L1 north interface\n"); - - AssertFatal (enb_nb <= RC.nb_inst, - "Number of eNB is greater than eNB defined in configuration file (%d/%d)!", - enb_nb, RC.nb_inst); - - LOG_I(ENB_APP,"Allocating eNB_RRC_INST for %d instances\n",RC.nb_inst); - - RC.rrc = (eNB_RRC_INST **)malloc(RC.nb_inst*sizeof(eNB_RRC_INST *)); - LOG_I(PHY, "%s() RC.nb_inst:%d RC.rrc:%p\n", __FUNCTION__, RC.nb_inst, RC.rrc); - - for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { - RC.rrc[enb_id] = (eNB_RRC_INST*)malloc(sizeof(eNB_RRC_INST)); - LOG_I(PHY, "%s() Creating RRC instance RC.rrc[%d]:%p (%d of %d)\n", __FUNCTION__, enb_id, RC.rrc[enb_id], enb_id+1, enb_id_end); - memset((void *)RC.rrc[enb_id],0,sizeof(eNB_RRC_INST)); - configure_rrc(enb_id); + /* Try to register each eNB */ + // This assumes that node_type of all RRC instances is the same + if (EPC_MODE_ENABLED) { + register_enb_pending = eNB_app_register(RC.rrc[0]->node_type, enb_id_start, enb_id_end); } -# if defined(ENABLE_USE_MME) - /* Try to register each eNB */ - registered_enb = 0; - register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p); -#else - /* Start L2L1 task */ - msg_p = itti_alloc_new_message(TASK_ENB_APP, INITIALIZE_MESSAGE); - itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p); -#endif - - /* Try to register each eNB with each other */ - x2_registered_enb = 0; - x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end); + /* Try to register each eNB with each other */ + if (is_x2ap_enabled() && !NODE_IS_DU(RC.rrc[0]->node_type)) { + x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end); + } do { // Wait for a message itti_receive_msg (TASK_ENB_APP, &msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); switch (ITTI_MSG_ID(msg_p)) { @@ -255,63 +167,105 @@ void *eNB_app_task(void *args_p) break; case S1AP_REGISTER_ENB_CNF: -# if defined(ENABLE_USE_MME) - LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), - S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); - - DevAssert(register_enb_pending > 0); - register_enb_pending--; - - /* Check if at least eNB is registered with one MME */ - if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) { - registered_enb++; - } - - /* Check if all register eNB requests have been processed */ - if (register_enb_pending == 0) { - if (registered_enb == enb_nb) { - /* If all eNB are registered, start L2L1 task */ - MessageDef *msg_init_p; - - msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); - - } else { - LOG_W(ENB_APP, " %d eNB not associated with a MME, retrying registration in %d seconds ...\n", - enb_nb - registered_enb, ENB_REGISTER_RETRY_DELAY); - - /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */ - if (timer_setup (ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, - NULL, &enb_register_retry_timer_id) < 0) { - LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n"); - - sleep(ENB_REGISTER_RETRY_DELAY); - /* Restart the registration process */ - registered_enb = 0; - register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p); - } - } - } -#endif + AssertFatal(!NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received S1AP_REGISTER_ENB_CNF\n"); + if (EPC_MODE_ENABLED) { + LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); + DevAssert(register_enb_pending > 0); + register_enb_pending--; + + /* Check if at least eNB is registered with one MME */ + if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) { + registered_enb++; + } + + /* Check if all register eNB requests have been processed */ + if (register_enb_pending == 0) { + if (registered_enb == enb_nb) { + /* If all eNB are registered, start L2L1 task */ + MessageDef *msg_init_p; + msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); + itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); + } else { + LOG_W(ENB_APP, " %d eNB not associated with a MME, retrying registration in %d seconds ...\n", + enb_nb - registered_enb, ENB_REGISTER_RETRY_DELAY); + + /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */ + if (timer_setup (ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + NULL, &enb_register_retry_timer_id) < 0) { + LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n"); + sleep(ENB_REGISTER_RETRY_DELAY); + /* Restart the registration process */ + registered_enb = 0; + register_enb_pending = eNB_app_register (RC.rrc[0]->node_type,enb_id_start, enb_id_end); + } + } + } + } /* if (EPC_MODE_ENABLED) */ + + break; + + case F1AP_SETUP_RESP: + AssertFatal(NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received F1AP_REGISTER_ENB_CNF in CU/eNB\n"); + + LOG_I(ENB_APP, "Received %s: associated ngran_eNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p), + F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate); + + handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p)); + + DevAssert(register_enb_pending > 0); + register_enb_pending--; + + /* Check if at least eNB is registered with one MME */ + if (F1AP_SETUP_RESP(msg_p).num_cells_to_activate > 0) { + registered_enb++; + } + + /* Check if all register eNB requests have been processed */ + if (register_enb_pending == 0) { + if (registered_enb == enb_nb) { + /* If all eNB cells are registered, start L2L1 task */ + MessageDef *msg_init_p; + + msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); + itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); + + } else { + LOG_W(ENB_APP, " %d eNB not associated with a MME, retrying registration in %d seconds ...\n", + enb_nb - registered_enb, ENB_REGISTER_RETRY_DELAY); + + /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */ + if (timer_setup (ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, + NULL, &enb_register_retry_timer_id) < 0) { + LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n"); + + sleep(ENB_REGISTER_RETRY_DELAY); + /* Restart the registration process */ + registered_enb = 0; + register_enb_pending = eNB_app_register (RC.rrc[0]->node_type,enb_id_start, enb_id_end);//, enb_properties_p); + } + } + } + break; case S1AP_DEREGISTERED_ENB_IND: if (EPC_MODE_ENABLED) { LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme); - /* TODO handle recovering of registration */ } + break; case TIMER_HAS_EXPIRED: -# if defined(ENABLE_USE_MME) + if (EPC_MODE_ENABLED) { LOG_I(ENB_APP, " Received %s: timer_id %ld\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id); if (TIMER_HAS_EXPIRED (msg_p).timer_id == enb_register_retry_timer_id) { /* Restart the registration process */ registered_enb = 0; - register_enb_pending = eNB_app_register (enb_id_start, enb_id_end);//, enb_properties_p); + register_enb_pending = eNB_app_register (RC.rrc[0]->node_type, enb_id_start, enb_id_end); } if (TIMER_HAS_EXPIRED (msg_p).timer_id == x2_enb_register_retry_timer_id) { @@ -319,20 +273,19 @@ void *eNB_app_task(void *args_p) x2_registered_enb = 0; x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end); } -# endif + } /* if (EPC_MODE_ENABLED) */ + break; case X2AP_DEREGISTERED_ENB_IND: LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2); - /* TODO handle recovering of registration */ break; case X2AP_REGISTER_ENB_CNF: LOG_I(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), X2AP_REGISTER_ENB_CNF(msg_p).nb_x2); - DevAssert(x2_register_enb_pending > 0); x2_register_enb_pending--; @@ -345,19 +298,17 @@ void *eNB_app_task(void *args_p) if (x2_register_enb_pending == 0) { if (x2_registered_enb == enb_nb) { /* If all eNB are registered, start RRC HO task */ - - }else { + } else { uint32_t x2_not_associated = enb_nb - x2_registered_enb; - LOG_W(ENB_APP, " %d eNB %s not associated with the target\n", x2_not_associated, x2_not_associated > 1 ? "are" : "is"); + // timer to retry /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */ if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL, &x2_enb_register_retry_timer_id) < 0) { LOG_E(ENB_APP, " Can not start eNB X2AP register: retry timer, use \"sleep\" instead!\n"); - sleep(X2AP_ENB_REGISTER_RETRY_DELAY); /* Restart the registration process */ x2_registered_enb = 0; @@ -377,18 +328,13 @@ void *eNB_app_task(void *args_p) AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } while (1); -#endif - - return NULL; } -void handle_reconfiguration(module_id_t mod_id) -{ +void handle_reconfiguration(module_id_t mod_id) { struct timespec start, end; clock_gettime(CLOCK_MONOTONIC, &start); flexran_agent_info_t *flexran = RC.flexran[mod_id]; - LOG_I(ENB_APP, "lte-softmodem soft-restart requested\n"); if (ENB_WAIT == flexran->node_ctrl_state) { @@ -411,8 +357,10 @@ void handle_reconfiguration(module_id_t mod_id) LOG_I(ENB_APP, " * eNB %d: Waiting for FlexRAN RTController command *\n", mod_id); pthread_mutex_lock(&flexran->mutex_node_ctrl); flexran->node_ctrl_state = ENB_WAIT; + while (ENB_NORMAL_OPERATION != flexran->node_ctrl_state) pthread_cond_wait(&flexran->cond_node_ctrl, &flexran->mutex_node_ctrl); + pthread_mutex_unlock(&flexran->mutex_node_ctrl); } @@ -424,11 +372,13 @@ void handle_reconfiguration(module_id_t mod_id) clock_gettime(CLOCK_MONOTONIC, &end); end.tv_sec -= start.tv_sec; + if (end.tv_nsec >= start.tv_nsec) { end.tv_nsec -= start.tv_nsec; } else { end.tv_sec -= 1; end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000; } + LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000); } diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 94bb1fff568e529d9ffbb955a31dfbdf7f5ba58e..8e428e60b1613b28526f32690f928140954d2e6e 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -35,15 +35,10 @@ #include "enb_config.h" #include "UTIL/OTG/otg.h" #include "UTIL/OTG/otg_externs.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" - #if defined(ENABLE_USE_MME) - #include "s1ap_eNB.h" - #include "sctp_eNB_task.h" - #else - #define EPC_MODE_ENABLED 0 - #endif -#endif +#include "intertask_interface.h" +#include "s1ap_eNB.h" +#include "sctp_eNB_task.h" +#include "common/ran_context.h" #include "sctp_default_values.h" #include "LTE_SystemInformationBlockType2.h" #include "LAYER2/MAC/mac_extern.h" @@ -59,7 +54,7 @@ #include "common/config/config_userapi.h" #include "RRC_config_tools.h" #include "enb_paramdef.h" - +#include "proto_agent.h" #define RRC_INACTIVITY_THRESH 0 extern uint16_t sf_ahead; @@ -73,63 +68,10 @@ extern char *parallel_config; extern char *worker_config; void RCconfig_flexran() { - uint16_t i; - uint16_t num_enbs; - char aprefix[MAX_OPTNAME_SIZE*2 + 8]; - /* this will possibly truncate the cell id (RRC assumes int32_t). - Both Nid_cell and enb_id are signed in RRC case, but we use unsigned for - the bitshifting to work properly */ - int32_t Nid_cell = 0; - uint16_t Nid_cell_tr = 0; - uint32_t enb_id = 0; - - /* - int32_t srb1_timer_poll_retransmit = 0; - int32_t srb1_timer_reordering = 0; - int32_t srb1_timer_status_prohibit = 0; - int32_t srb1_poll_pdu = 0; - int32_t srb1_poll_byte = 0; - int32_t srb1_max_retx_threshold = 0; - */ - - /* get number of eNBs */ paramdef_t ENBSParams[] = ENBSPARAMS_DESC; config_get(ENBSParams, sizeof(ENBSParams)/sizeof(paramdef_t), NULL); - num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; - /* for eNB ID */ - paramdef_t ENBParams[] = ENBPARAMS_DESC; - paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST, NULL, 0}; - /* for Nid_cell */ - checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; - ccparams_lte_t ccparams_lte; - memset((void*)&ccparams_lte,0,sizeof(ccparams_lte_t)); - paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte); - paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0}; - - // Note: these should be turned on for EMTC support inside of FlexRAN - // ccparams_emtc_t ccparams_emtc; - //paramdef_t brParams[] = BRPARAMS_DESC(ccparams_emtc); - //paramdef_t schedulingInfoBrParams[] = SI_INFO_BR_DESC(ccparams_emtc); - //paramlist_def_t schedulingInfoBrParamList = {ENB_CONFIG_STRING_SCHEDULING_INFO_BR, NULL, 0}; - //paramdef_t rachcelevelParams[] = RACH_CE_LEVELINFOLIST_R13_DESC(ccparams_emtc); - //paramlist_def_t rachcelevellist = {ENB_CONFIG_STRING_RACH_CE_LEVELINFOLIST_R13, NULL, 0}; - //paramdef_t rsrprangeParams[] = RSRP_RANGE_LIST_DESC(ccparams_emtc); - //paramlist_def_t rsrprangelist = {ENB_CONFIG_STRING_RSRP_RANGE_LIST, NULL, 0}; - //paramdef_t prachParams[] = PRACH_PARAMS_CE_R13_DESC(ccparams_emtc); - //paramlist_def_t prachParamslist = {ENB_CONFIG_STRING_PRACH_PARAMETERS_CE_R13, NULL, 0}; - //paramdef_t n1PUCCH_ANR13Params[] = N1PUCCH_AN_INFOLIST_R13_DESC(ccparams_emtc); - //paramlist_def_t n1PUCCHInfoList = {ENB_CONFIG_STRING_N1PUCCH_AN_INFOLIST_R13, NULL, 0}; - //paramdef_t pcchv1310Params[] = PCCH_CONFIG_V1310_DESC(ccparams_emtc); - //paramdef_t sib2freqhoppingParams[] = SIB2_FREQ_HOPPING_R13_DESC(ccparams_emtc); - - // paramdef_t SRB1Params[] = SRB1PARAMS_DESC; - - /* map parameter checking array instances to parameter definition array instances */ - for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) { - CCsParams[I].chkPptr = &(config_check_CCparams[I]); - } - + uint16_t num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; paramdef_t flexranParams[] = FLEXRANPARAMS_DESC; config_get(flexranParams, sizeof(flexranParams)/sizeof(paramdef_t), CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); @@ -141,7 +83,7 @@ void RCconfig_flexran() { num_enbs, sizeof(flexran_agent_info_t *)); } - for (i = 0; i < num_enbs; i++) { + for (uint16_t i = 0; i < num_enbs; i++) { RC.flexran[i] = calloc(1, sizeof(flexran_agent_info_t)); AssertFatal(RC.flexran[i], "can't ALLOCATE %zu Bytes for flexran agent info (iteration %d/%d)\n", @@ -159,37 +101,7 @@ void RCconfig_flexran() { RC.flexran[i]->remote_port = *(flexranParams[FLEXRAN_PORT_IDX].uptr); RC.flexran[i]->cache_name = strdup(*(flexranParams[FLEXRAN_CACHE_IDX].strptr)); RC.flexran[i]->node_ctrl_state = strcasecmp(*(flexranParams[FLEXRAN_AWAIT_RECONF_IDX].strptr), "yes") == 0 ? ENB_WAIT : ENB_NORMAL_OPERATION; - config_getlist(&ENBParamList, ENBParams, sizeof(ENBParams)/sizeof(paramdef_t),NULL); - - /* eNB ID from configuration, as read in by RCconfig_RRC() */ - if (!ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr) { - // Calculate a default eNB ID - if (EPC_MODE_ENABLED) - enb_id = i + (s1ap_generate_eNB_id () & 0xFFFF8); - else - enb_id = i; - } else { - enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr); - } - - /* cell ID */ - sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i); - config_getlist(&CCsParamList, NULL, 0, aprefix); - - if (CCsParamList.numelt > 0) { - sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, i, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0); - config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); - Nid_cell_tr = (uint16_t) Nid_cell; - } - - RC.flexran[i]->mod_id = i; - RC.flexran[i]->agent_id = (((uint64_t)i) << 48) | (((uint64_t)enb_id) << 16) | ((uint64_t)Nid_cell_tr); - /* assume for the moment the monolithic case, i.e. agent can provide - information for all layers */ - RC.flexran[i]->capability_mask = FLEXRAN_CAP_LOPHY | FLEXRAN_CAP_HIPHY - | FLEXRAN_CAP_LOMAC | FLEXRAN_CAP_HIMAC - | FLEXRAN_CAP_RLC | FLEXRAN_CAP_PDCP - | FLEXRAN_CAP_SDAP | FLEXRAN_CAP_RRC; + RC.flexran[i]->mod_id = i; } } @@ -253,6 +165,17 @@ void RCconfig_L1(void) { RC.eNB[j][0]->eth_params_n .remote_portd); } else { // other midhaul } + + // PRACH/PUCCH parameters + RC.eNB[j][0]->prach_DTX_threshold = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_THRESHOLD_IDX].iptr); + RC.eNB[j][0]->pucch1_DTX_threshold = *(L1_ParamList.paramarray[j][L1_PUCCH1_DTX_THRESHOLD_IDX].iptr); + RC.eNB[j][0]->pucch1ab_DTX_threshold = *(L1_ParamList.paramarray[j][L1_PUCCH1AB_DTX_THRESHOLD_IDX].iptr); + + for (int ce_level=0; ce_level<4; ce_level++) { + RC.eNB[j][0]->prach_DTX_threshold_emtc[ce_level] = *(L1_ParamList.paramarray[j][L1_PRACH_DTX_EMTC0_THRESHOLD_IDX+ce_level].iptr); + RC.eNB[j][0]->pucch1_DTX_threshold_emtc[ce_level] = *(L1_ParamList.paramarray[j][L1_PUCCH1_DTX_EMTC0_THRESHOLD_IDX+ce_level].iptr); + RC.eNB[j][0]->pucch1ab_DTX_threshold_emtc[ce_level] = *(L1_ParamList.paramarray[j][L1_PUCCH1AB_DTX_EMTC0_THRESHOLD_IDX+ce_level].iptr); + } }// j=0..num_inst LOG_I(ENB_APP,"Initializing northbound interface for L1\n"); @@ -282,19 +205,19 @@ void RCconfig_L1(void) { } } -void RCconfig_macrlc() { +void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]) { int j; paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC; paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0}; config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL); + config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL); if ( MacRLC_ParamList.numelt > 0) { RC.nb_macrlc_inst=MacRLC_ParamList.numelt; mac_top_init_eNB(); RC.nb_mac_CC = (int *)malloc(RC.nb_macrlc_inst*sizeof(int)); - - for (j=0; j<RC.nb_macrlc_inst; j++) { + for (j = 0; j < RC.nb_macrlc_inst; j++) { RC.mac[j]->puSch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCH10xSNR_IDX ].iptr); RC.mac[j]->puCch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCH10xSNR_IDX ].iptr); RC.nb_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr); @@ -303,7 +226,9 @@ void RCconfig_macrlc() { if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) { // check number of instances is same as RRC/PDCP - } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) { + printf("Configuring local RRC for MACRLC\n"); + } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) { + printf("Configuring F1 interfaces for MACRLC\n"); RC.mac[j]->eth_params_n.local_if_name = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr)); RC.mac[j]->eth_params_n.my_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr)); RC.mac[j]->eth_params_n.remote_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr)); @@ -312,6 +237,7 @@ void RCconfig_macrlc() { RC.mac[j]->eth_params_n.my_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr); RC.mac[j]->eth_params_n.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);; RC.mac[j]->eth_params_n.transp_preference = ETH_UDP_MODE; + macrlc_has_f1[j] = 1; } else { // other midhaul AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr)); } @@ -345,51 +271,45 @@ void RCconfig_macrlc() { printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); } }// j=0..num_inst - } else {// MacRLC_ParamList.numelt > 0 + } /*else {// MacRLC_ParamList.numelt > 0 // ignore it + AssertFatal (0, "No " CONFIG_STRING_MACRLC_LIST " configuration found"); - } + }*/ } -int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { - +int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { int num_enbs = 0; int j,k = 0; int32_t enb_id = 0; int nb_cc = 0; + int32_t offsetMaxLimit = 0; + int32_t cycleNb = 0; + MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_CONFIGURATION_REQ); ccparams_lte_t ccparams_lte; ccparams_sidelink_t SLconfig; ccparams_eMTC_t eMTCconfig; - - memset((void*)&ccparams_lte,0,sizeof(ccparams_lte_t)); - memset((void*)&SLconfig,0,sizeof(ccparams_sidelink_t)); - memset((void*)&eMTCconfig,0,sizeof(ccparams_eMTC_t)); - - + memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t)); + memset((void *)&SLconfig,0,sizeof(ccparams_sidelink_t)); + memset((void *)&eMTCconfig,0,sizeof(ccparams_eMTC_t)); paramdef_t ENBSParams[] = ENBSPARAMS_DESC; paramdef_t ENBParams[] = ENBPARAMS_DESC; paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0}; checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte); paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0}; - paramdef_t eMTCParams[] = EMTCPARAMS_DESC((&eMTCconfig)); checkedparam_t config_check_eMTCparams[] = EMTCPARAMS_CHECK; - srb1_params_t srb1_params; - memset((void*)&srb1_params,0,sizeof(srb1_params_t)); + memset((void *)&srb1_params,0,sizeof(srb1_params_t)); paramdef_t SRB1Params[] = SRB1PARAMS_DESC(srb1_params); - - paramdef_t SLParams[] = CCPARAMS_SIDELINK_DESC(SLconfig); - /* map parameter checking array instances to parameter definition array instances */ for (int I=0; I< ( sizeof(CCsParams)/ sizeof(paramdef_t) ) ; I++) { CCsParams[I].chkPptr = &(config_check_CCparams[I]); } - for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) { eMTCParams[I].chkPptr = &(config_check_eMTCparams[I]); } @@ -417,10 +337,17 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr); } - LOG_I(ENB_APP,"RRC %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr)); - - if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) { - } else if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) { + LOG_I(RRC,"Instance %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr)); + + if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) { + paramdef_t SCTPParams[] = SCTPPARAMS_DESC; + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,i,ENB_CONFIG_STRING_SCTP_CONFIG); + config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); + rrc->node_id = *(ENBParamList.paramarray[0][ENB_ENB_ID_IDX].uptr); + LOG_I(ENB_APP,"F1AP: gNB_CU_id[%d] %d\n",k,rrc->node_id); + rrc->node_name = strdup(*(ENBParamList.paramarray[0][ENB_ENB_NAME_IDX].strptr)); + LOG_I(ENB_APP,"F1AP: gNB_CU_name[%d] %s\n",k,rrc->node_name); rrc->eth_params_s.local_if_name = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_IF_NAME_IDX].strptr)); rrc->eth_params_s.my_addr = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_ADDRESS_IDX].strptr)); rrc->eth_params_s.remote_addr = strdup(*(ENBParamList.paramarray[i][ENB_REMOTE_S_ADDRESS_IDX].strptr)); @@ -429,9 +356,23 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { rrc->eth_params_s.my_portd = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTD_IDX].uptr); rrc->eth_params_s.remote_portd = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTD_IDX].uptr); rrc->eth_params_s.transp_preference = ETH_UDP_MODE; - } else { // other midhaul + rrc->node_type = ngran_eNB_CU; + rrc->sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); + rrc->sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); + } else { + // set to ngran_eNB for now, it will get set to ngran_eNB_DU if macrlc entity which uses F1 is present + // Note: we will have to handle the case of ngran_ng_eNB_DU + if (macrlc_has_f1 == 0) { + rrc->node_type = ngran_eNB; + LOG_I(RRC,"Setting node_type to ngran_eNB\n"); + } else { + rrc->node_type = ngran_eNB_DU; + LOG_I(RRC,"Setting node_type to ngran_eNB_DU\n"); + } } + rrc->nr_cellid = (uint64_t)*(ENBParamList.paramarray[i][ENB_NRCELLID_IDX].u64ptr); + // search if in active list for (k=0; k <num_enbs ; k++) { @@ -490,870 +431,872 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { //printf("Component carrier %d\n",component_carrier); nb_cc++; - RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = ccparams_lte.tdd_config; - AssertFatal (ccparams_lte.tdd_config <= LTE_TDD_Config__subframeAssignment_sa6, - "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!", - RC.config_file_name, i, ccparams_lte.tdd_config, LTE_TDD_Config__subframeAssignment_sa6); - RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = ccparams_lte.tdd_config_s; - AssertFatal (ccparams_lte.tdd_config_s <= LTE_TDD_Config__specialSubframePatterns_ssp8, - "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!", - RC.config_file_name, i, ccparams_lte.tdd_config_s, LTE_TDD_Config__specialSubframePatterns_ssp8); - if (!ccparams_lte.prefix_type) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE); - else if (strcmp(ccparams_lte.prefix_type, "NORMAL") == 0) { - RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL; - } else if (strcmp(ccparams_lte.prefix_type, "EXTENDED") == 0) { - RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n", - RC.config_file_name, i, ccparams_lte.prefix_type); - } + if (!NODE_IS_CU(rrc->node_type)) { + // Cell params, MIB/SIB1 in DU + RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = ccparams_lte.tdd_config; + AssertFatal (ccparams_lte.tdd_config <= LTE_TDD_Config__subframeAssignment_sa6, + "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!", + RC.config_file_name, i, ccparams_lte.tdd_config, LTE_TDD_Config__subframeAssignment_sa6); + RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = ccparams_lte.tdd_config_s; + AssertFatal (ccparams_lte.tdd_config_s <= LTE_TDD_Config__specialSubframePatterns_ssp8, + "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!", + RC.config_file_name, i, ccparams_lte.tdd_config_s, LTE_TDD_Config__specialSubframePatterns_ssp8); + + if (!ccparams_lte.prefix_type) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: NORMAL,EXTENDED!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PREFIX_TYPE); + else if (strcmp(ccparams_lte.prefix_type, "NORMAL") == 0) { + RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = NORMAL; + } else if (strcmp(ccparams_lte.prefix_type, "EXTENDED") == 0) { + RRC_CONFIGURATION_REQ (msg_p).prefix_type[j] = EXTENDED; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prefix_type choice: NORMAL or EXTENDED !\n", + RC.config_file_name, i, ccparams_lte.prefix_type); + } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (!ccparams_lte.pbch_repetition) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION); - else if (strcmp(ccparams_lte.pbch_repetition, "TRUE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 1; - } else if (strcmp(ccparams_lte.pbch_repetition, "FALSE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 0; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n", - RC.config_file_name, i, ccparams_lte.pbch_repetition); - } + if (!ccparams_lte.pbch_repetition) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PBCH_REPETITION); + else if (strcmp(ccparams_lte.pbch_repetition, "TRUE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 1; + } else if (strcmp(ccparams_lte.pbch_repetition, "FALSE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).pbch_repetition[j] = 0; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pbch_repetition choice: TRUE or FALSE !\n", + RC.config_file_name, i, ccparams_lte.pbch_repetition); + } #endif - RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = ccparams_lte.eutra_band; - RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) ccparams_lte.downlink_frequency; - RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) ccparams_lte.uplink_frequency_offset; + RRC_CONFIGURATION_REQ (msg_p).eutra_band[j] = ccparams_lte.eutra_band; + RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j] = (uint32_t) ccparams_lte.downlink_frequency; + RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) ccparams_lte.uplink_frequency_offset; + RRC_CONFIGURATION_REQ (msg_p).Nid_cell[j]= ccparams_lte.Nid_cell; + if (ccparams_lte.Nid_cell>503) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n", + RC.config_file_name, i, ccparams_lte.Nid_cell); + } - RRC_CONFIGURATION_REQ (msg_p).Nid_cell[j]= ccparams_lte.Nid_cell; + RRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= ccparams_lte.N_RB_DL; - if (ccparams_lte.Nid_cell>503) { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n", - RC.config_file_name, i, ccparams_lte.Nid_cell); - } + if ((ccparams_lte.N_RB_DL!=6) && + (ccparams_lte.N_RB_DL!=15) && + (ccparams_lte.N_RB_DL!=25) && + (ccparams_lte.N_RB_DL!=50) && + (ccparams_lte.N_RB_DL!=75) && + (ccparams_lte.N_RB_DL!=100)) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n", + RC.config_file_name, i, ccparams_lte.N_RB_DL); + } - RRC_CONFIGURATION_REQ (msg_p).N_RB_DL[j]= ccparams_lte.N_RB_DL; + if (strcmp(ccparams_lte.frame_type, "FDD") == 0) { + RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = FDD; + } else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) { + RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = TDD; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", + RC.config_file_name, i, ccparams_lte.frame_type); + } - if ((ccparams_lte.N_RB_DL!=6) && - (ccparams_lte.N_RB_DL!=15) && - (ccparams_lte.N_RB_DL!=25) && - (ccparams_lte.N_RB_DL!=50) && - (ccparams_lte.N_RB_DL!=75) && - (ccparams_lte.N_RB_DL!=100)) { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n", - RC.config_file_name, i, ccparams_lte.N_RB_DL); - } + if (config_check_band_frequencies(j, + RRC_CONFIGURATION_REQ (msg_p).eutra_band[j], + RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j], + RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j], + RRC_CONFIGURATION_REQ (msg_p).frame_type[j])) { + AssertFatal(0, "error calling enb_check_band_frequencies\n"); + } - if (strcmp(ccparams_lte.frame_type, "FDD") == 0) { - RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = FDD; - } else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) { - RRC_CONFIGURATION_REQ (msg_p).frame_type[j] = TDD; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", - RC.config_file_name, i, ccparams_lte.frame_type); - } + if ((ccparams_lte.nb_antenna_ports <1) || (ccparams_lte.nb_antenna_ports > 2)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n", + RC.config_file_name, i, ccparams_lte.nb_antenna_ports); - if (config_check_band_frequencies(j, - RRC_CONFIGURATION_REQ (msg_p).eutra_band[j], - RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j], - RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j], - RRC_CONFIGURATION_REQ (msg_p).frame_type[j])) { - AssertFatal(0, "error calling enb_check_band_frequencies\n"); + RRC_CONFIGURATION_REQ (msg_p).nb_antenna_ports[j] = ccparams_lte.nb_antenna_ports; } + if (!NODE_IS_DU(rrc->node_type)) { //this is CU or eNB, SIB2-20 in CU + // Radio Resource Configuration (SIB2) + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_root = ccparams_lte.prach_root; - if ((ccparams_lte.nb_antenna_ports <1) || (ccparams_lte.nb_antenna_ports > 2)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for nb_antenna_ports choice: 1..2 !\n", - RC.config_file_name, i, ccparams_lte.nb_antenna_ports); - - RRC_CONFIGURATION_REQ (msg_p).nb_antenna_ports[j] = ccparams_lte.nb_antenna_ports; - - // Radio Resource Configuration (SIB2) - - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_root = ccparams_lte.prach_root; - - if ((ccparams_lte.prach_root <0) || (ccparams_lte.prach_root > 1023)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_root choice: 0..1023 !\n", - RC.config_file_name, i, ccparams_lte.prach_root); - - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_config_index = ccparams_lte.prach_config_index; - - if ((ccparams_lte.prach_config_index <0) || (ccparams_lte.prach_config_index > 63)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_config_index choice: 0..1023 !\n", - RC.config_file_name, i, ccparams_lte.prach_config_index); - - if (!ccparams_lte.prach_high_speed) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED); - else if (strcmp(ccparams_lte.prach_high_speed, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = TRUE; - } else if (strcmp(ccparams_lte.prach_high_speed, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", - RC.config_file_name, i, ccparams_lte.prach_high_speed); - - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_zero_correlation = ccparams_lte.prach_zero_correlation; + if ((ccparams_lte.prach_root <0) || (ccparams_lte.prach_root > 1023)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_root choice: 0..1023 !\n", + RC.config_file_name, i, ccparams_lte.prach_root); - if ((ccparams_lte.prach_zero_correlation <0) || - (ccparams_lte.prach_zero_correlation > 15)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n", - RC.config_file_name, i, ccparams_lte.prach_zero_correlation); + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_config_index = ccparams_lte.prach_config_index; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_freq_offset = ccparams_lte.prach_freq_offset; + if ((ccparams_lte.prach_config_index <0) || (ccparams_lte.prach_config_index > 63)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_config_index choice: 0..1023 !\n", + RC.config_file_name, i, ccparams_lte.prach_config_index); - if ((ccparams_lte.prach_freq_offset <0) || - (ccparams_lte.prach_freq_offset > 94)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n", - RC.config_file_name, i, ccparams_lte.prach_freq_offset); + if (!ccparams_lte.prach_high_speed) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED); + else if (strcmp(ccparams_lte.prach_high_speed, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = TRUE; + } else if (strcmp(ccparams_lte.prach_high_speed, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", + RC.config_file_name, i, ccparams_lte.prach_high_speed); - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_delta_shift = ccparams_lte.pucch_delta_shift-1; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_zero_correlation = ccparams_lte.prach_zero_correlation; - if ((ccparams_lte.pucch_delta_shift <1) || - (ccparams_lte.pucch_delta_shift > 3)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n", - RC.config_file_name, i, ccparams_lte.pucch_delta_shift); + if ((ccparams_lte.prach_zero_correlation <0) || + (ccparams_lte.prach_zero_correlation > 15)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n", + RC.config_file_name, i, ccparams_lte.prach_zero_correlation); - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_nRB_CQI = ccparams_lte.pucch_nRB_CQI; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_freq_offset = ccparams_lte.prach_freq_offset; - if ((ccparams_lte.pucch_nRB_CQI <0) || - (ccparams_lte.pucch_nRB_CQI > 98)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n", - RC.config_file_name, i, ccparams_lte.pucch_nRB_CQI); + if ((ccparams_lte.prach_freq_offset <0) || + (ccparams_lte.prach_freq_offset > 94)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n", + RC.config_file_name, i, ccparams_lte.prach_freq_offset); - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_nCS_AN = ccparams_lte.pucch_nCS_AN; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_delta_shift = ccparams_lte.pucch_delta_shift-1; - if ((ccparams_lte.pucch_nCS_AN <0) || - (ccparams_lte.pucch_nCS_AN > 7)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n", - RC.config_file_name, i, ccparams_lte.pucch_nCS_AN); + if ((ccparams_lte.pucch_delta_shift <1) || + (ccparams_lte.pucch_delta_shift > 3)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n", + RC.config_file_name, i, ccparams_lte.pucch_delta_shift); + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_nRB_CQI = ccparams_lte.pucch_nRB_CQI; - //#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_n1_AN = ccparams_lte.pucch_n1_AN; + if ((ccparams_lte.pucch_nRB_CQI <0) || + (ccparams_lte.pucch_nRB_CQI > 98)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n", + RC.config_file_name, i, ccparams_lte.pucch_nRB_CQI); - if ((ccparams_lte.pucch_n1_AN <0) || - (ccparams_lte.pucch_n1_AN > 2047)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n", - RC.config_file_name, i, ccparams_lte.pucch_n1_AN); + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_nCS_AN = ccparams_lte.pucch_nCS_AN; - //#endif - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pdsch_referenceSignalPower = ccparams_lte.pdsch_referenceSignalPower; + if ((ccparams_lte.pucch_nCS_AN <0) || + (ccparams_lte.pucch_nCS_AN > 7)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n", + RC.config_file_name, i, ccparams_lte.pucch_nCS_AN); - if ((ccparams_lte.pdsch_referenceSignalPower <-60) || - (ccparams_lte.pdsch_referenceSignalPower > 50)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n", - RC.config_file_name, i, ccparams_lte.pdsch_referenceSignalPower); + //#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_n1_AN = ccparams_lte.pucch_n1_AN; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pdsch_p_b = ccparams_lte.pdsch_p_b; + if ((ccparams_lte.pucch_n1_AN <0) || + (ccparams_lte.pucch_n1_AN > 2047)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n", + RC.config_file_name, i, ccparams_lte.pucch_n1_AN); - if ((ccparams_lte.pdsch_p_b <0) || - (ccparams_lte.pdsch_p_b > 3)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_p_b choice: 0..3!\n", - RC.config_file_name, i, ccparams_lte.pdsch_p_b); + //#endif + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pdsch_referenceSignalPower = ccparams_lte.pdsch_referenceSignalPower; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_n_SB = ccparams_lte.pusch_n_SB; + if ((ccparams_lte.pdsch_referenceSignalPower <-60) || + (ccparams_lte.pdsch_referenceSignalPower > 50)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n", + RC.config_file_name, i, ccparams_lte.pdsch_referenceSignalPower); - if ((ccparams_lte.pusch_n_SB <1) || - (ccparams_lte.pusch_n_SB > 4)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_n_SB choice: 1..4!\n", - RC.config_file_name, i, ccparams_lte.pusch_n_SB); + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pdsch_p_b = ccparams_lte.pdsch_p_b; - if (!ccparams_lte.pusch_hoppingMode) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE); - - else if (strcmp(ccparams_lte.pusch_hoppingMode,"interSubFrame")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; - } - else if (strcmp(ccparams_lte.pusch_hoppingMode,"intraAndInterSubFrame")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n", - RC.config_file_name, i, ccparams_lte.pusch_hoppingMode); + if ((ccparams_lte.pdsch_p_b <0) || + (ccparams_lte.pdsch_p_b > 3)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_p_b choice: 0..3!\n", + RC.config_file_name, i, ccparams_lte.pdsch_p_b); - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingOffset = ccparams_lte.pusch_hoppingOffset; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_n_SB = ccparams_lte.pusch_n_SB; - if ((ccparams_lte.pusch_hoppingOffset<0) || - (ccparams_lte.pusch_hoppingOffset>98)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n", - RC.config_file_name, i, ccparams_lte.pusch_hoppingMode); + if ((ccparams_lte.pusch_n_SB <1) || + (ccparams_lte.pusch_n_SB > 4)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_n_SB choice: 1..4!\n", + RC.config_file_name, i, ccparams_lte.pusch_n_SB); - if (!ccparams_lte.pusch_enable64QAM) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM); - else if (strcmp(ccparams_lte.pusch_enable64QAM, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = TRUE; - } - else if (strcmp(ccparams_lte.pusch_enable64QAM, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = FALSE; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", - RC.config_file_name, i, ccparams_lte.pusch_enable64QAM); + if (!ccparams_lte.pusch_hoppingMode) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE); + else if (strcmp(ccparams_lte.pusch_hoppingMode,"interSubFrame")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; + } else if (strcmp(ccparams_lte.pusch_hoppingMode,"intraAndInterSubFrame")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingMode = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n", + RC.config_file_name, i, ccparams_lte.pusch_hoppingMode); - if (!ccparams_lte.pusch_groupHoppingEnabled) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN); - else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled = TRUE; - } - else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled= FALSE; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", - RC.config_file_name, i, ccparams_lte.pusch_groupHoppingEnabled); + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_hoppingOffset = ccparams_lte.pusch_hoppingOffset; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupAssignment = ccparams_lte.pusch_groupAssignment; + if ((ccparams_lte.pusch_hoppingOffset<0) || + (ccparams_lte.pusch_hoppingOffset>98)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n", + RC.config_file_name, i, ccparams_lte.pusch_hoppingMode); - if ((ccparams_lte.pusch_groupAssignment<0)|| - (ccparams_lte.pusch_groupAssignment>29)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n", - RC.config_file_name, i, ccparams_lte.pusch_groupAssignment); + if (!ccparams_lte.pusch_enable64QAM) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM); + else if (strcmp(ccparams_lte.pusch_enable64QAM, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = TRUE; + } else if (strcmp(ccparams_lte.pusch_enable64QAM, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", + RC.config_file_name, i, ccparams_lte.pusch_enable64QAM); - if (!ccparams_lte.pusch_sequenceHoppingEnabled) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", - RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN); - else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = TRUE; - } - else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", - RC.config_file_name, i, ccparams_lte.pusch_sequenceHoppingEnabled); + if (!ccparams_lte.pusch_groupHoppingEnabled) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN); + else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled = TRUE; + } else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled= FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", + RC.config_file_name, i, ccparams_lte.pusch_groupHoppingEnabled); - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_nDMRS1= ccparams_lte.pusch_nDMRS1; //cyclic_shift in RRC! + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupAssignment = ccparams_lte.pusch_groupAssignment; - if ((ccparams_lte.pusch_nDMRS1 <0) || - (ccparams_lte.pusch_nDMRS1>7)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n", - RC.config_file_name, i, ccparams_lte.pusch_nDMRS1); + if ((ccparams_lte.pusch_groupAssignment<0)|| + (ccparams_lte.pusch_groupAssignment>29)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n", + RC.config_file_name, i, ccparams_lte.pusch_groupAssignment); + if (!ccparams_lte.pusch_sequenceHoppingEnabled) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", + RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN); + else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = TRUE; + } else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", + RC.config_file_name, i, ccparams_lte.pusch_sequenceHoppingEnabled); - if (strcmp(ccparams_lte.phich_duration,"NORMAL")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration= LTE_PHICH_Config__phich_Duration_normal; - } else if (strcmp(ccparams_lte.phich_duration,"EXTENDED")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration= LTE_PHICH_Config__phich_Duration_extended; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n", - RC.config_file_name, i, ccparams_lte.phich_duration); - - if (strcmp(ccparams_lte.phich_resource,"ONESIXTH")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_oneSixth ; - } - else if (strcmp(ccparams_lte.phich_resource,"HALF")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_half; - } - else if (strcmp(ccparams_lte.phich_resource,"ONE")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_one; - } - else if (strcmp(ccparams_lte.phich_resource,"TWO")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_two; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n", - RC.config_file_name, i, ccparams_lte.phich_resource); - - printf("phich.resource %ld (%s), phich.duration %ld (%s)\n", - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource,ccparams_lte.phich_resource, - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration,ccparams_lte.phich_duration); - - if (strcmp(ccparams_lte.srs_enable, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= TRUE; - } - else if (strcmp(ccparams_lte.srs_enable, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= FALSE; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", - RC.config_file_name, i, ccparams_lte.srs_enable); + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_nDMRS1= ccparams_lte.pusch_nDMRS1; //cyclic_shift in RRC! - if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable== TRUE) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_BandwidthConfig= ccparams_lte.srs_BandwidthConfig; + if ((ccparams_lte.pusch_nDMRS1 <0) || + (ccparams_lte.pusch_nDMRS1>7)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n", + RC.config_file_name, i, ccparams_lte.pusch_nDMRS1); - if ((ccparams_lte.srs_BandwidthConfig < 0) || - (ccparams_lte.srs_BandwidthConfig >7)) - AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value %d for srs_BandwidthConfig choice: 0...7\n", - RC.config_file_name, i, ccparams_lte.srs_BandwidthConfig); + if (strcmp(ccparams_lte.phich_duration,"NORMAL")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration= LTE_PHICH_Config__phich_Duration_normal; + } else if (strcmp(ccparams_lte.phich_duration,"EXTENDED")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration= LTE_PHICH_Config__phich_Duration_extended; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n", + RC.config_file_name, i, ccparams_lte.phich_duration); + + if (strcmp(ccparams_lte.phich_resource,"ONESIXTH")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_oneSixth ; + } else if (strcmp(ccparams_lte.phich_resource,"HALF")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_half; + } else if (strcmp(ccparams_lte.phich_resource,"ONE")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_one; + } else if (strcmp(ccparams_lte.phich_resource,"TWO")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource= LTE_PHICH_Config__phich_Resource_two; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n", + RC.config_file_name, i, ccparams_lte.phich_resource); - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_SubframeConfig= ccparams_lte.srs_SubframeConfig; + printf("phich.resource %ld (%s), phich.duration %ld (%s)\n", + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_resource,ccparams_lte.phich_resource, + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration,ccparams_lte.phich_duration); - if ((ccparams_lte.srs_SubframeConfig<0) || - (ccparams_lte.srs_SubframeConfig>15)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n", - RC.config_file_name, i, ccparams_lte.srs_SubframeConfig); - - if (strcmp(ccparams_lte.srs_ackNackST, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= TRUE; - } - else if (strcmp(ccparams_lte.srs_ackNackST, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= FALSE; + if (strcmp(ccparams_lte.srs_enable, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= TRUE; + } else if (strcmp(ccparams_lte.srs_enable, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= FALSE; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", - RC.config_file_name, i, ccparams_lte.srs_ackNackST); - - if (strcmp(ccparams_lte.srs_MaxUpPts, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= TRUE; - } - else if (strcmp(ccparams_lte.srs_MaxUpPts, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= FALSE; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", - RC.config_file_name, i, ccparams_lte.srs_MaxUpPts); - } + RC.config_file_name, i, ccparams_lte.srs_enable); + + if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable== TRUE) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_BandwidthConfig= ccparams_lte.srs_BandwidthConfig; + + if ((ccparams_lte.srs_BandwidthConfig < 0) || + (ccparams_lte.srs_BandwidthConfig >7)) + AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value %d for srs_BandwidthConfig choice: 0...7\n", + RC.config_file_name, i, ccparams_lte.srs_BandwidthConfig); + + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_SubframeConfig= ccparams_lte.srs_SubframeConfig; + + if ((ccparams_lte.srs_SubframeConfig<0) || + (ccparams_lte.srs_SubframeConfig>15)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n", + RC.config_file_name, i, ccparams_lte.srs_SubframeConfig); + + if (strcmp(ccparams_lte.srs_ackNackST, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= TRUE; + } else if (strcmp(ccparams_lte.srs_ackNackST, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", + RC.config_file_name, i, ccparams_lte.srs_ackNackST); + + if (strcmp(ccparams_lte.srs_MaxUpPts, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= TRUE; + } else if (strcmp(ccparams_lte.srs_MaxUpPts, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", + RC.config_file_name, i, ccparams_lte.srs_MaxUpPts); + } - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_p0_Nominal= ccparams_lte.pusch_p0_Nominal; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_p0_Nominal= ccparams_lte.pusch_p0_Nominal; - if ((ccparams_lte.pusch_p0_Nominal<-126) || - (ccparams_lte.pusch_p0_Nominal>24)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n", - RC.config_file_name, i, ccparams_lte.pusch_p0_Nominal); + if ((ccparams_lte.pusch_p0_Nominal<-126) || + (ccparams_lte.pusch_p0_Nominal>24)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n", + RC.config_file_name, i, ccparams_lte.pusch_p0_Nominal); #if (LTE_RRC_VERSION <= MAKE_VERSION(12, 0, 0)) - if (strcmp(ccparams_lte.pusch_alpha,"AL0")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al0; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL04")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al04; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL05")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al05; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL06")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al06; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL07")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al07; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL08")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al08; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL09")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al09; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL1")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al1; - } + if (strcmp(ccparams_lte.pusch_alpha,"AL0")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al0; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL04")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al04; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL05")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al05; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL06")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al06; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL07")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al07; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL08")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al08; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL09")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al09; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL1")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_UplinkPowerControlCommon__alpha_al1; + } #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(12, 0, 0)) - if (strcmp(ccparams_lte.pusch_alpha,"AL0")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al0; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL04")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al04; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL05")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al05; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL06")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al06; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL07")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al07; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL08")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al08; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL09")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al09; - } - else if (strcmp(ccparams_lte.pusch_alpha,"AL1")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al1; - } + if (strcmp(ccparams_lte.pusch_alpha,"AL0")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al0; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL04")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al04; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL05")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al05; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL06")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al06; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL07")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al07; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL08")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al08; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL09")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al09; + } else if (strcmp(ccparams_lte.pusch_alpha,"AL1")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_alpha= LTE_Alpha_r12_al1; + } #endif - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n", - RC.config_file_name, i, ccparams_lte.pusch_alpha); + else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n", + RC.config_file_name, i, ccparams_lte.pusch_alpha); - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_p0_Nominal= ccparams_lte.pucch_p0_Nominal; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_p0_Nominal= ccparams_lte.pucch_p0_Nominal; - if ((ccparams_lte.pucch_p0_Nominal<-127) || - (ccparams_lte.pucch_p0_Nominal>-96)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n", - RC.config_file_name, i, ccparams_lte.pucch_p0_Nominal); + if ((ccparams_lte.pucch_p0_Nominal<-127) || + (ccparams_lte.pucch_p0_Nominal>-96)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n", + RC.config_file_name, i, ccparams_lte.pucch_p0_Nominal); - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].msg3_delta_Preamble= ccparams_lte.msg3_delta_Preamble; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].msg3_delta_Preamble= ccparams_lte.msg3_delta_Preamble; - if ((ccparams_lte.msg3_delta_Preamble<-1) || - (ccparams_lte.msg3_delta_Preamble>6)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n", - RC.config_file_name, i, ccparams_lte.msg3_delta_Preamble); - - if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF0; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n", - RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1); - - if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF1")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF3")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF5")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF5; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n", - RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1b); - - if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF1")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF1; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF2; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n", - RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2); + if ((ccparams_lte.msg3_delta_Preamble<-1) || + (ccparams_lte.msg3_delta_Preamble>6)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n", + RC.config_file_name, i, ccparams_lte.msg3_delta_Preamble); + + if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF_2")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF0")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF0; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format1,"deltaF2")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n", + RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1); + + if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF1")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF3")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format1b,"deltaF5")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF5; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n", + RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format1b); + + if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF_2")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF0")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF1")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF1; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format2,"deltaF2")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF2; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n", + RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2); + + if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF_2")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF0")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF2")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF2; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n", + RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2a); + + if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF_2")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF0")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0; + } else if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF2")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF2; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n", + RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2b); - if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format2a,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF2; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n", - RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2a); - - if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0; - } - else if (strcmp(ccparams_lte.pucch_deltaF_Format2b,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF2; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n", - RC.config_file_name, i, ccparams_lte.pucch_deltaF_Format2b); + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_numberOfRA_Preambles= (ccparams_lte.rach_numberOfRA_Preambles/4)-1; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_numberOfRA_Preambles= (ccparams_lte.rach_numberOfRA_Preambles/4)-1; + if ((ccparams_lte.rach_numberOfRA_Preambles <4) || + (ccparams_lte.rach_numberOfRA_Preambles>64) || + ((ccparams_lte.rach_numberOfRA_Preambles&3)!=0)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n", + RC.config_file_name, i, ccparams_lte.rach_numberOfRA_Preambles); + + if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "ENABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_sizeOfRA_PreamblesGroupA= (ccparams_lte.rach_sizeOfRA_PreamblesGroupA/4)-1; + + if ((ccparams_lte.rach_numberOfRA_Preambles <4) || + (ccparams_lte.rach_numberOfRA_Preambles>60) || + ((ccparams_lte.rach_numberOfRA_Preambles&3)!=0)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n", + RC.config_file_name, i, ccparams_lte.rach_sizeOfRA_PreamblesGroupA); + + switch (ccparams_lte.rach_messageSizeGroupA) { + case 56: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b56; + break; + + case 144: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b144; + break; + + case 208: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b208; + break; + + case 256: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b256; + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_messageSizeGroupA choice: 56,144,208,256!\n", + RC.config_file_name, i, ccparams_lte.rach_messageSizeGroupA); + break; + } - if ((ccparams_lte.rach_numberOfRA_Preambles <4) || - (ccparams_lte.rach_numberOfRA_Preambles>64) || - ((ccparams_lte.rach_numberOfRA_Preambles&3)!=0)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n", - RC.config_file_name, i, ccparams_lte.rach_numberOfRA_Preambles); + if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"minusinfinity")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity; + } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB0")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB0; + } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB5")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB5; + } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB8")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB8; + } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB10")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB10; + } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB12")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB12; + } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB15")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB15; + } else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB18")==0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB18; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", + RC.config_file_name, i, ccparams_lte.rach_messagePowerOffsetGroupB); + } else if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "DISABLE") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= FALSE; + } else + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", + RC.config_file_name, i, ccparams_lte.rach_preamblesGroupAConfig); - if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= TRUE; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_sizeOfRA_PreamblesGroupA= (ccparams_lte.rach_sizeOfRA_PreamblesGroupA/4)-1; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleInitialReceivedTargetPower= (ccparams_lte.rach_preambleInitialReceivedTargetPower+120)/2; - if ((ccparams_lte.rach_numberOfRA_Preambles <4) || - (ccparams_lte.rach_numberOfRA_Preambles>60) || - ((ccparams_lte.rach_numberOfRA_Preambles&3)!=0)) + if ((ccparams_lte.rach_preambleInitialReceivedTargetPower<-120) || + (ccparams_lte.rach_preambleInitialReceivedTargetPower>-90) || + ((ccparams_lte.rach_preambleInitialReceivedTargetPower&1)!=0)) AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n", - RC.config_file_name, i, ccparams_lte.rach_sizeOfRA_PreamblesGroupA); + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n", + RC.config_file_name, i, ccparams_lte.rach_preambleInitialReceivedTargetPower); - switch (ccparams_lte.rach_messageSizeGroupA) { - case 56: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b56; - break; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_powerRampingStep= ccparams_lte.rach_powerRampingStep/2; - case 144: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b144; - break; + if ((ccparams_lte.rach_powerRampingStep<0) || + (ccparams_lte.rach_powerRampingStep>6) || + ((ccparams_lte.rach_powerRampingStep&1)!=0)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n", + RC.config_file_name, i, ccparams_lte.rach_powerRampingStep); - case 208: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b208; - break; + switch (ccparams_lte.rach_preambleTransMax) { +#if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) - case 256: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b256; - break; + case 3: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3; + break; - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_messageSizeGroupA choice: 56,144,208,256!\n", - RC.config_file_name, i, ccparams_lte.rach_messageSizeGroupA); - break; - } + case 4: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4; + break; - if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"minusinfinity")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity; - } - else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB0")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB0; - } - else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB5")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB5; - } - else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB8")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB8; - } - else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB10")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB10; - } - else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB12")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB12; - } - else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB15")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB15; - } - else if (strcmp(ccparams_lte.rach_messagePowerOffsetGroupB,"dB18")==0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB18; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", - RC.config_file_name, i, ccparams_lte.rach_messagePowerOffsetGroupB); - } else if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= FALSE; - } else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", - RC.config_file_name, i, ccparams_lte.rach_preamblesGroupAConfig); + case 5: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5; + break; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleInitialReceivedTargetPower= (ccparams_lte.rach_preambleInitialReceivedTargetPower+120)/2; + case 6: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6; + break; - if ((ccparams_lte.rach_preambleInitialReceivedTargetPower<-120) || - (ccparams_lte.rach_preambleInitialReceivedTargetPower>-90) || - ((ccparams_lte.rach_preambleInitialReceivedTargetPower&1)!=0)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n", - RC.config_file_name, i, ccparams_lte.rach_preambleInitialReceivedTargetPower); + case 7: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7; + break; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_powerRampingStep= ccparams_lte.rach_powerRampingStep/2; + case 8: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8; + break; - if ((ccparams_lte.rach_powerRampingStep<0) || - (ccparams_lte.rach_powerRampingStep>6) || - ((ccparams_lte.rach_powerRampingStep&1)!=0)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n", - RC.config_file_name, i, ccparams_lte.rach_powerRampingStep); + case 10: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10; + break; - switch (ccparams_lte.rach_preambleTransMax) { -#if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) + case 20: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20; + break; - case 3: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3; - break; + case 50: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50; + break; - case 4: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4; - break; + case 100: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100; + break; - case 5: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5; - break; + case 200: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200; + break; +#else - case 6: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6; - break; + case 3: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n3; + break; - case 7: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7; - break; + case 4: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n4; + break; - case 8: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8; - break; + case 5: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n5; + break; - case 10: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10; - break; + case 6: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n6; + break; - case 20: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20; - break; + case 7: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n7; + break; - case 50: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50; - break; + case 8: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n8; + break; - case 100: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100; - break; + case 10: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n10; + break; - case 200: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200; - break; -#else + case 20: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n20; + break; - case 3: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n3; - break; + case 50: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n50; + break; - case 4: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n4; - break; + case 100: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n100; + break; - case 5: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n5; - break; + case 200: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n200; + break; +#endif - case 6: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n6; - break; + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleTransMax choice: 3,4,5,6,7,8,10,20,50,100,200!\n", + RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); + break; + } - case 7: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n7; - break; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_raResponseWindowSize= (ccparams_lte.rach_raResponseWindowSize==10)?7:ccparams_lte.rach_raResponseWindowSize-2; - case 8: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n8; - break; + if ((ccparams_lte.rach_raResponseWindowSize<0)|| + (ccparams_lte.rach_raResponseWindowSize==9)|| + (ccparams_lte.rach_raResponseWindowSize>10)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n", + RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); - case 10: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n10; - break; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_macContentionResolutionTimer= (ccparams_lte.rach_macContentionResolutionTimer/8)-1; - case 20: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n20; - break; + if ((ccparams_lte.rach_macContentionResolutionTimer<8) || + (ccparams_lte.rach_macContentionResolutionTimer>64) || + ((ccparams_lte.rach_macContentionResolutionTimer&7)!=0)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n", + RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); - case 50: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n50; - break; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_maxHARQ_Msg3Tx= ccparams_lte.rach_maxHARQ_Msg3Tx; - case 100: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n100; - break; + if ((ccparams_lte.rach_maxHARQ_Msg3Tx<0) || + (ccparams_lte.rach_maxHARQ_Msg3Tx>8)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n", + RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); + + switch (ccparams_lte.pcch_defaultPagingCycle) { + case 32: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf32; + break; + + case 64: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf64; + break; + + case 128: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf128; + break; + + case 256: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf256; + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_defaultPagingCycle choice: 32,64,128,256!\n", + RC.config_file_name, i, ccparams_lte.pcch_defaultPagingCycle); + break; + } - case 200: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preambleTransMax= LTE_PreambleTransMax_n200; - break; + if (strcmp(ccparams_lte.pcch_nB, "fourT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_fourT; + } + else if (strcmp(ccparams_lte.pcch_nB, "twoT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_twoT; + } + else if (strcmp(ccparams_lte.pcch_nB, "oneT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneT; + } + else if (strcmp(ccparams_lte.pcch_nB, "halfT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_halfT; + } + else if (strcmp(ccparams_lte.pcch_nB, "quarterT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_quarterT; + } + else if (strcmp(ccparams_lte.pcch_nB, "oneEighthT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneEighthT; + } + else if (strcmp(ccparams_lte.pcch_nB, "oneSixteenthT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneSixteenthT; + } + else if (strcmp(ccparams_lte.pcch_nB, "oneThirtySecondT") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneThirtySecondT; + } + else { + AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n", + RC.config_file_name, + i, + ccparams_lte.pcch_nB); + } -#endif + if (strcmp(ccparams_lte.drx_Config_present, "prNothing") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_Config_present = LTE_DRX_Config_PR_NOTHING; + } else if (strcmp(ccparams_lte.drx_Config_present, "prRelease") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_Config_present = LTE_DRX_Config_PR_release; + } else if (strcmp(ccparams_lte.drx_Config_present, "prSetup") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_Config_present = LTE_DRX_Config_PR_setup; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_Config_present choice: prNothing, prRelease, prSetup!\n", + RC.config_file_name, i, ccparams_lte.drx_Config_present); + } - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleTransMax choice: 3,4,5,6,7,8,10,20,50,100,200!\n", - RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); - break; + if (strcmp(ccparams_lte.drx_onDurationTimer, "psf1") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf1; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf2") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf2; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf3") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf3; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf4") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf4; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf5") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf5; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf6") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf6; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf8") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf8; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf10") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf10; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf20") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf20; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf30") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf30; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf40") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf40; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf50") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf50; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf60") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf60; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf80") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf80; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf100") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf100; + } else if (strcmp(ccparams_lte.drx_onDurationTimer, "psf200") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_onDurationTimer = (long) LTE_DRX_Config__setup__onDurationTimer_psf200; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_onDurationTimer choice !\n", + RC.config_file_name, i, ccparams_lte.drx_onDurationTimer); + break; } - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_raResponseWindowSize= (ccparams_lte.rach_raResponseWindowSize==10)?7:ccparams_lte.rach_raResponseWindowSize-2; + if (strcmp(ccparams_lte.drx_InactivityTimer, "psf1") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf1; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf2") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf2; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf3") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf3; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf4") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf4; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf5") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf5; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf6") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf6; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf8") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf8; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf10") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf10; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf20") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf20; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf30") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf30; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf40") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf40; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf50") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf50; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf60") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf60; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf80") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf80; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf100") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf100; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf200") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf200; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf300") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf300; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf500") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf500; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf750") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf750; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf1280") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf1280; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf1920") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf1920; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf2560") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf2560; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "psf0-v1020") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_psf0_v1020; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare9") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare9; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare8") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare8; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare7") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare7; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare6") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare6; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare5") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare5; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare4") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare4; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare3") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare3; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare2") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare2; + } else if (strcmp(ccparams_lte.drx_InactivityTimer, "spare1") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_InactivityTimer = (long) LTE_DRX_Config__setup__drx_InactivityTimer_spare1; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_InactivityTimer choice !\n", + RC.config_file_name, i, ccparams_lte.drx_InactivityTimer); + break; + } - if ((ccparams_lte.rach_raResponseWindowSize<0)|| - (ccparams_lte.rach_raResponseWindowSize==9)|| - (ccparams_lte.rach_raResponseWindowSize>10)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n", - RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_multiple_max= ccparams_lte.ue_multiple_max; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_macContentionResolutionTimer= (ccparams_lte.rach_macContentionResolutionTimer/8)-1; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if ((ccparams_lte.rach_macContentionResolutionTimer<8) || - (ccparams_lte.rach_macContentionResolutionTimer>64) || - ((ccparams_lte.rach_macContentionResolutionTimer&7)!=0)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n", - RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); - - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_maxHARQ_Msg3Tx= ccparams_lte.rach_maxHARQ_Msg3Tx; - - if ((ccparams_lte.rach_maxHARQ_Msg3Tx<0) || - (ccparams_lte.rach_maxHARQ_Msg3Tx>8)) - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n", - RC.config_file_name, i, ccparams_lte.rach_preambleTransMax); - - switch (ccparams_lte.pcch_defaultPagingCycle) { - case 32: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf32; - break; - - case 64: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf64; - break; - - case 128: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf128; - break; - - case 256: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf256; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_defaultPagingCycle choice: 32,64,128,256!\n", - RC.config_file_name, i, ccparams_lte.pcch_defaultPagingCycle); - break; - } - - if (strcmp(ccparams_lte.pcch_nB, "fourT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_fourT; - } - else if (strcmp(ccparams_lte.pcch_nB, "twoT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_twoT; - } - else if (strcmp(ccparams_lte.pcch_nB, "oneT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneT; - } - else if (strcmp(ccparams_lte.pcch_nB, "halfT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_halfT; - } - else if (strcmp(ccparams_lte.pcch_nB, "quarterT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_quarterT; - } - else if (strcmp(ccparams_lte.pcch_nB, "oneEighthT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneEighthT; - } - else if (strcmp(ccparams_lte.pcch_nB, "oneSixteenthT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneSixteenthT; - } - else if (strcmp(ccparams_lte.pcch_nB, "oneThirtySecondT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pcch_nB= LTE_PCCH_Config__nB_oneThirtySecondT; - } - else - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n", - RC.config_file_name, i, ccparams_lte.pcch_nB); - - switch (ccparams_lte.bcch_modificationPeriodCoeff) { - case 2: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n2; - break; - - case 4: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n4; - break; - - case 8: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n8; - break; - - case 16: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n16; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for bcch_modificationPeriodCoeff choice: 2,4,8,16", - RC.config_file_name, i, ccparams_lte.bcch_modificationPeriodCoeff); - break; - } - - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t300= ccparams_lte.ue_TimersAndConstants_t300; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t301= ccparams_lte.ue_TimersAndConstants_t301; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t310= ccparams_lte.ue_TimersAndConstants_t310; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t311= ccparams_lte.ue_TimersAndConstants_t311; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_n310= ccparams_lte.ue_TimersAndConstants_n310; - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_n311= ccparams_lte.ue_TimersAndConstants_n311; - - switch (ccparams_lte.ue_TransmissionMode) { - case 1: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm1; - break; - - case 2: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm2; - break; - - case 3: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm3; - break; - - case 4: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm4; - break; - - case 5: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm5; - break; - - case 6: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm6; - break; - - case 7: - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm7; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TransmissionMode choice: 1,2,3,4,5,6,7", - RC.config_file_name, i, ccparams_lte.ue_TransmissionMode); - break; - } - - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_multiple_max= ccparams_lte.ue_multiple_max; - -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - - if (!ccparams_lte.mbms_dedicated_serving_cell) + if (!ccparams_lte.mbms_dedicated_serving_cell) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d define %s: TRUE,FALSE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL); @@ -1403,340 +1346,752 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n", RC.config_file_name, i, ccparams_lte.N_RB_DL); break; + } + + if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf1") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf1; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf2") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf2; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf4") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf4; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf6") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf6; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf8") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf8; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf16") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf16; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf24") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf24; + } else if (strcmp(ccparams_lte.drx_RetransmissionTimer, "psf33") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_RetransmissionTimer = (long) LTE_DRX_Config__setup__drx_RetransmissionTimer_psf33; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for drx_RetransmissionTimer choice !\n", + RC.config_file_name, i, ccparams_lte.drx_RetransmissionTimer); + break; } - // eMBMS configuration - RRC_CONFIGURATION_REQ(msg_p).eMBMS_configured = 0; - printf("No eMBMS configuration, skipping it\n"); - - // eMTC configuration - char brparamspath[MAX_OPTNAME_SIZE*2 + 16]; - sprintf(brparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_EMTC_PARAMETERS); - config_get(eMTCParams, sizeof(eMTCParams)/sizeof(paramdef_t), brparamspath); - RRC_CONFIGURATION_REQ(msg_p).eMTC_configured = eMTCconfig.eMTC_configured&1; - - if (eMTCconfig.eMTC_configured > 0) fill_eMTC_configuration(msg_p,&eMTCconfig, i,j,RC.config_file_name,brparamspath); - else printf("No eMTC configuration, skipping it\n"); - - - // Sidelink configuration - char SLparamspath[MAX_OPTNAME_SIZE*2 + 16]; - sprintf(SLparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_SL_PARAMETERS); - config_get( SLParams, sizeof(SLParams)/sizeof(paramdef_t), SLparamspath); - - // Sidelink Resource pool information - RRC_CONFIGURATION_REQ (msg_p).SL_configured=SLconfig.sidelink_configured&1; - if (SLconfig.sidelink_configured==1) fill_SL_configuration(msg_p,&SLconfig,i,j,RC.config_file_name); - else printf("No SL configuration skipping it\n"); - } - } - - char srb1path[MAX_OPTNAME_SIZE*2 + 8]; - sprintf(srb1path,"%s.%s",enbpath,ENB_CONFIG_STRING_SRB1); - config_get( SRB1Params,sizeof(SRB1Params)/sizeof(paramdef_t), srb1path); - - - switch (srb1_params.srb1_max_retx_threshold) { - case 1: - rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t1; - break; - - case 2: - rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t2; - break; - - case 3: - rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t3; - break; - - case 4: - rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t4; - break; - - case 6: - rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t6; - break; - - case 8: - rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; - break; - - case 16: - rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t16; - break; - - case 32: - rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; - break; - - default: - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_max_retx_threshold %u!\n", - RC.config_file_name, i, srb1_params.srb1_max_retx_threshold); - } - - switch (srb1_params.srb1_poll_pdu) { - case 4: - rrc->srb1_poll_pdu = LTE_PollPDU_p4; - break; - - case 8: - rrc->srb1_poll_pdu = LTE_PollPDU_p8; - break; - - case 16: - rrc->srb1_poll_pdu = LTE_PollPDU_p16; - break; - - case 32: - rrc->srb1_poll_pdu = LTE_PollPDU_p32; - break; - - case 64: - rrc->srb1_poll_pdu = LTE_PollPDU_p64; - break; - - case 128: - rrc->srb1_poll_pdu = LTE_PollPDU_p128; - break; - - case 256: - rrc->srb1_poll_pdu = LTE_PollPDU_p256; - break; - - default: - if (srb1_params.srb1_poll_pdu >= 10000) - rrc->srb1_poll_pdu = LTE_PollPDU_pInfinity; - else - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_pdu %u!\n", - RC.config_file_name, i, srb1_params.srb1_poll_pdu); - } - - rrc->srb1_poll_byte = srb1_params.srb1_poll_byte; - - switch (srb1_params.srb1_poll_byte) { - case 25: - rrc->srb1_poll_byte = LTE_PollByte_kB25; - break; - - case 50: - rrc->srb1_poll_byte = LTE_PollByte_kB50; - break; - - case 75: - rrc->srb1_poll_byte = LTE_PollByte_kB75; - break; - - case 100: - rrc->srb1_poll_byte = LTE_PollByte_kB100; - break; - - case 125: - rrc->srb1_poll_byte = LTE_PollByte_kB125; - break; - - case 250: - rrc->srb1_poll_byte = LTE_PollByte_kB250; - break; - - case 375: - rrc->srb1_poll_byte = LTE_PollByte_kB375; - break; - - case 500: - rrc->srb1_poll_byte = LTE_PollByte_kB500; - break; - - case 750: - rrc->srb1_poll_byte = LTE_PollByte_kB750; - break; - - case 1000: - rrc->srb1_poll_byte = LTE_PollByte_kB1000; - break; - - case 1250: - rrc->srb1_poll_byte = LTE_PollByte_kB1250; - break; - - case 1500: - rrc->srb1_poll_byte = LTE_PollByte_kB1500; - break; - - case 2000: - rrc->srb1_poll_byte = LTE_PollByte_kB2000; - break; - - case 3000: - rrc->srb1_poll_byte = LTE_PollByte_kB3000; - break; - - default: - if (srb1_params.srb1_poll_byte >= 10000) - rrc->srb1_poll_byte = LTE_PollByte_kBinfinity; - else - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_byte %u!\n", - RC.config_file_name, i, srb1_params.srb1_poll_byte); - } - - if (srb1_params.srb1_timer_poll_retransmit <= 250) { - rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 5)/5; - } else if (srb1_params.srb1_timer_poll_retransmit <= 500) { - rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 300)/50 + 50; - } else { - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_poll_retransmit %u!\n", - RC.config_file_name, i, srb1_params.srb1_timer_poll_retransmit); - } - - if (srb1_params.srb1_timer_status_prohibit <= 250) { - rrc->srb1_timer_status_prohibit = srb1_params.srb1_timer_status_prohibit/5; - } else if ((srb1_params.srb1_timer_poll_retransmit >= 300) && (srb1_params.srb1_timer_poll_retransmit <= 500)) { - rrc->srb1_timer_status_prohibit = (srb1_params.srb1_timer_status_prohibit - 300)/50 + 51; - } else { - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_status_prohibit %u!\n", - RC.config_file_name, i, srb1_params.srb1_timer_status_prohibit); - } - - switch (srb1_params.srb1_timer_reordering) { - case 0: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms0; - break; - - case 5: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms5; - break; - - case 10: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms10; - break; - - case 15: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms15; - break; - - case 20: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms20; - break; - - case 25: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms25; - break; - - case 30: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms30; - break; - - case 35: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms35; - break; - - case 40: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms40; - break; - - case 45: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms45; - break; - - case 50: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms50; - break; - - case 55: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms55; - break; - - case 60: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms60; - break; - - case 65: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms65; - break; - - case 70: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms70; - break; - - case 75: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms75; - break; - - case 80: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms80; - break; - - case 85: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms85; - break; - - case 90: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms90; - break; - - case 95: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms95; - break; - - case 100: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms100; - break; - - case 110: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms110; - break; - - case 120: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms120; - break; - - case 130: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms130; - break; - - case 140: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms140; - break; - - case 150: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms150; - break; - - case 160: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms160; - break; - - case 170: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms170; - break; - - case 180: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms180; - break; - - case 190: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms190; - break; - - case 200: - rrc->srb1_timer_reordering = LTE_T_Reordering_ms200; - break; - - default: - AssertFatal (0, - "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_reordering %u!\n", - RC.config_file_name, i, srb1_params.srb1_timer_reordering); - } + if (ccparams_lte.drx_longDrx_CycleStartOffset_present == NULL || strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prNothing") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_NOTHING; + } else { + if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf10") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10; + offsetMaxLimit = 10; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf20") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20; + offsetMaxLimit = 20; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf32") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32; + offsetMaxLimit = 32; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf40") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40; + offsetMaxLimit = 40; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf64") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64; + offsetMaxLimit = 64; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf80") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80; + offsetMaxLimit = 80; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf128") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128; + offsetMaxLimit = 128; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf160") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160; + offsetMaxLimit = 160; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf256") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256; + offsetMaxLimit = 256; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf320") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320; + offsetMaxLimit = 320; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf512") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512; + offsetMaxLimit = 512; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf640") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640; + offsetMaxLimit = 640; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf1024") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024; + offsetMaxLimit = 1024; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf1280") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280; + offsetMaxLimit = 1280; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf2048") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048; + offsetMaxLimit = 2048; + } else if (strcmp(ccparams_lte.drx_longDrx_CycleStartOffset_present, "prSf2560") == 0) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset_present = LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560; + offsetMaxLimit = 2560; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file \"%s\", enb %d unknown string value \"%s\" for drx_longDrx_CycleStartOffset_present choice !\n", + RC.config_file_name, i, ccparams_lte.drx_longDrx_CycleStartOffset_present); + } + + if (ccparams_lte.drx_longDrx_CycleStartOffset >= 0 && ccparams_lte.drx_longDrx_CycleStartOffset < offsetMaxLimit) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_longDrx_CycleStartOffset = ccparams_lte.drx_longDrx_CycleStartOffset; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d incoherent value \"%d\" for drx_longDrx_CycleStartOffset !\n", + RC.config_file_name, i, ccparams_lte.drx_longDrx_CycleStartOffset); + } + } + + if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "") == 0 || ccparams_lte.drx_shortDrx_ShortCycleTimer == 0) { + if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "") != 0 || ccparams_lte.drx_shortDrx_ShortCycleTimer != 0) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d incoherent values \"%s\" - \"%d\" for drx_shortDrx_Cycle or drx_shortDrx_ShortCycleTimer choice !\n", + RC.config_file_name, i, ccparams_lte.drx_shortDrx_Cycle, ccparams_lte.drx_shortDrx_ShortCycleTimer); + } else { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = -1; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_ShortCycleTimer = 0; + } + } else { + if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf2") == 0) { + cycleNb = 2; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf2; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf5") == 0) { + cycleNb = 5; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf5; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf8") == 0) { + cycleNb = 8; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf8; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf10") == 0) { + cycleNb = 10; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf10; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf16") == 0) { + cycleNb = 16; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf16; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf20") == 0) { + cycleNb = 20; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf20; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf32") == 0) { + cycleNb = 32; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf32; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf40") == 0) { + cycleNb = 40; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf40; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf64") == 0) { + cycleNb = 64; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf64; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf80") == 0) { + cycleNb = 80; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf80; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf128") == 0) { + cycleNb = 128; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf128; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf160") == 0) { + cycleNb = 160; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf160; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf256") == 0) { + cycleNb = 256; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf256; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf320") == 0) { + cycleNb = 320; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf320; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf512") == 0) { + cycleNb = 512; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf512; + } else if (strcmp(ccparams_lte.drx_shortDrx_Cycle, "sf640") == 0) { + cycleNb = 640; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_Cycle = LTE_DRX_Config__setup__shortDRX__shortDRX_Cycle_sf640; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d incoherent value \"%s\" for drx_shortDrx_Cycle !\n", + RC.config_file_name, i, ccparams_lte.drx_shortDrx_Cycle); + } + + if (cycleNb > 0 && (offsetMaxLimit % cycleNb != 0 || cycleNb == offsetMaxLimit)) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d incompatible (not multiple) values \"%d\" - \"%d\" for drx_shortDrx_Cycle and drx_longDrx_CycleStartOffset choice !\n", + RC.config_file_name, i, cycleNb, offsetMaxLimit); + } + + if (ccparams_lte.drx_shortDrx_ShortCycleTimer >= 1 && ccparams_lte.drx_shortDrx_ShortCycleTimer <= 16 ) { + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].drx_shortDrx_ShortCycleTimer = ccparams_lte.drx_shortDrx_ShortCycleTimer; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for drx_shortDrx_ShortCycleTimer choice !\n", + RC.config_file_name, i, ccparams_lte.drx_shortDrx_ShortCycleTimer ); + } + } + + switch (ccparams_lte.bcch_modificationPeriodCoeff) { + case 2: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n2; + break; + + case 4: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n4; + break; + + case 8: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n8; + break; + + case 16: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n16; + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for bcch_modificationPeriodCoeff choice: 2,4,8,16", + RC.config_file_name, i, ccparams_lte.bcch_modificationPeriodCoeff); + break; + } + + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t300= ccparams_lte.ue_TimersAndConstants_t300; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t301= ccparams_lte.ue_TimersAndConstants_t301; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t310= ccparams_lte.ue_TimersAndConstants_t310; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_t311= ccparams_lte.ue_TimersAndConstants_t311; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_n310= ccparams_lte.ue_TimersAndConstants_n310; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TimersAndConstants_n311= ccparams_lte.ue_TimersAndConstants_n311; + + switch (ccparams_lte.ue_TransmissionMode) { + case 1: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm1; + break; + + case 2: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm2; + break; + + case 3: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm3; + break; + + case 4: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm4; + break; + + case 5: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm5; + break; + + case 6: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm6; + break; + + case 7: + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm7; + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TransmissionMode choice: 1,2,3,4,5,6,7", + RC.config_file_name, i, ccparams_lte.ue_TransmissionMode); + break; + } + + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].ue_multiple_max= ccparams_lte.ue_multiple_max; + + switch (ccparams_lte.N_RB_DL) { + case 25: + if ((ccparams_lte.ue_multiple_max < 1) || + (ccparams_lte.ue_multiple_max > 4)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..4!\n", + RC.config_file_name, i, ccparams_lte.ue_multiple_max); + + break; + + case 50: + if ((ccparams_lte.ue_multiple_max < 1) || + (ccparams_lte.ue_multiple_max > 8)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..8!\n", + RC.config_file_name, i, ccparams_lte.ue_multiple_max); + + break; + + case 100: + if ((ccparams_lte.ue_multiple_max < 1) || + (ccparams_lte.ue_multiple_max > 16)) + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..16!\n", + RC.config_file_name, i, ccparams_lte.ue_multiple_max); + + break; + + default: + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n", + RC.config_file_name, i, ccparams_lte.N_RB_DL); + break; + } + + // eMBMS configuration + RRC_CONFIGURATION_REQ(msg_p).eMBMS_configured = 0; + printf("No eMBMS configuration, skipping it\n"); + // eMTC configuration + char brparamspath[MAX_OPTNAME_SIZE*2 + 16]; + sprintf(brparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_EMTC_PARAMETERS); + config_get(eMTCParams, sizeof(eMTCParams)/sizeof(paramdef_t), brparamspath); + RRC_CONFIGURATION_REQ(msg_p).eMTC_configured = eMTCconfig.eMTC_configured&1; + + if (eMTCconfig.eMTC_configured > 0) fill_eMTC_configuration(msg_p,&eMTCconfig, i,j,RC.config_file_name,brparamspath); + else printf("No eMTC configuration, skipping it\n"); + + // Sidelink configuration + char SLparamspath[MAX_OPTNAME_SIZE*2 + 16]; + sprintf(SLparamspath,"%s.%s", ccspath, ENB_CONFIG_STRING_SL_PARAMETERS); + config_get( SLParams, sizeof(SLParams)/sizeof(paramdef_t), SLparamspath); + // Sidelink Resource pool information + RRC_CONFIGURATION_REQ (msg_p).SL_configured=SLconfig.sidelink_configured&1; + + if (SLconfig.sidelink_configured==1) fill_SL_configuration(msg_p,&SLconfig,i,j,RC.config_file_name); + else printf("No SL configuration skipping it\n"); + } // !NODE_IS_DU(node_type) + } + + if (!NODE_IS_DU(rrc->node_type)) { + char srb1path[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(srb1path,"%s.%s",enbpath,ENB_CONFIG_STRING_SRB1); + config_get( SRB1Params,sizeof(SRB1Params)/sizeof(paramdef_t), srb1path); + + switch (srb1_params.srb1_max_retx_threshold) { + case 1: + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t1; + break; + + case 2: + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t2; + break; + + case 3: + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t3; + break; + + case 4: + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t4; + break; + + case 6: + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t6; + break; + + case 8: + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; + break; + + case 16: + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t16; + break; + + case 32: + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; + break; + + default: + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_max_retx_threshold %u!\n", + RC.config_file_name, i, srb1_params.srb1_max_retx_threshold); + } + + switch (srb1_params.srb1_poll_pdu) { + case 4: + rrc->srb1_poll_pdu = LTE_PollPDU_p4; + break; + + case 8: + rrc->srb1_poll_pdu = LTE_PollPDU_p8; + break; + + case 16: + rrc->srb1_poll_pdu = LTE_PollPDU_p16; + break; + + case 32: + rrc->srb1_poll_pdu = LTE_PollPDU_p32; + break; + + case 64: + rrc->srb1_poll_pdu = LTE_PollPDU_p64; + break; + + case 128: + rrc->srb1_poll_pdu = LTE_PollPDU_p128; + break; + + case 256: + rrc->srb1_poll_pdu = LTE_PollPDU_p256; + break; + + default: + if (srb1_params.srb1_poll_pdu >= 10000) + rrc->srb1_poll_pdu = LTE_PollPDU_pInfinity; + else + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_pdu %u!\n", + RC.config_file_name, i, srb1_params.srb1_poll_pdu); + } + + rrc->srb1_poll_byte = srb1_params.srb1_poll_byte; + + switch (srb1_params.srb1_poll_byte) { + case 25: + rrc->srb1_poll_byte = LTE_PollByte_kB25; + break; + + case 50: + rrc->srb1_poll_byte = LTE_PollByte_kB50; + break; + + case 75: + rrc->srb1_poll_byte = LTE_PollByte_kB75; + break; + + case 100: + rrc->srb1_poll_byte = LTE_PollByte_kB100; + break; + + case 125: + rrc->srb1_poll_byte = LTE_PollByte_kB125; + break; + + case 250: + rrc->srb1_poll_byte = LTE_PollByte_kB250; + break; + + case 375: + rrc->srb1_poll_byte = LTE_PollByte_kB375; + break; + + case 500: + rrc->srb1_poll_byte = LTE_PollByte_kB500; + break; + + case 750: + rrc->srb1_poll_byte = LTE_PollByte_kB750; + break; + + case 1000: + rrc->srb1_poll_byte = LTE_PollByte_kB1000; + break; + + case 1250: + rrc->srb1_poll_byte = LTE_PollByte_kB1250; + break; + + case 1500: + rrc->srb1_poll_byte = LTE_PollByte_kB1500; + break; + + case 2000: + rrc->srb1_poll_byte = LTE_PollByte_kB2000; + break; + + case 3000: + rrc->srb1_poll_byte = LTE_PollByte_kB3000; + break; + + default: + if (srb1_params.srb1_poll_byte >= 10000) + rrc->srb1_poll_byte = LTE_PollByte_kBinfinity; + else + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_byte %u!\n", + RC.config_file_name, i, srb1_params.srb1_poll_byte); + } + + if (srb1_params.srb1_timer_poll_retransmit <= 250) { + rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 5)/5; + } else if (srb1_params.srb1_timer_poll_retransmit <= 500) { + rrc->srb1_timer_poll_retransmit = (srb1_params.srb1_timer_poll_retransmit - 300)/50 + 50; + } else { + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_poll_retransmit %u!\n", + RC.config_file_name, i, srb1_params.srb1_timer_poll_retransmit); + } + + if (srb1_params.srb1_timer_status_prohibit <= 250) { + rrc->srb1_timer_status_prohibit = srb1_params.srb1_timer_status_prohibit/5; + } else if ((srb1_params.srb1_timer_poll_retransmit >= 300) && (srb1_params.srb1_timer_poll_retransmit <= 500)) { + rrc->srb1_timer_status_prohibit = (srb1_params.srb1_timer_status_prohibit - 300)/50 + 51; + } else { + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_status_prohibit %u!\n", + RC.config_file_name, i, srb1_params.srb1_timer_status_prohibit); + } + + switch (srb1_params.srb1_timer_reordering) { + case 0: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms0; + break; + + case 5: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms5; + break; + + case 10: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms10; + break; + + case 15: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms15; + break; + + case 20: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms20; + break; + + case 25: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms25; + break; + + case 30: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms30; + break; + + case 35: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms35; + break; + + case 40: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms40; + break; + + case 45: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms45; + break; + + case 50: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms50; + break; + + case 55: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms55; + break; + + case 60: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms60; + break; + + case 65: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms65; + break; + + case 70: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms70; + break; + + case 75: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms75; + break; + + case 80: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms80; + break; + + case 85: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms85; + break; + + case 90: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms90; + break; + + case 95: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms95; + break; + + case 100: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms100; + break; + + case 110: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms110; + break; + + case 120: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms120; + break; + + case 130: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms130; + break; + + case 140: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms140; + break; + + case 150: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms150; + break; + + case 160: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms160; + break; + + case 170: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms170; + break; + + case 180: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms180; + break; + + case 190: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms190; + break; + + case 200: + rrc->srb1_timer_reordering = LTE_T_Reordering_ms200; + break; + + default: + AssertFatal (0, + "Bad config value when parsing eNB configuration file %s, enb %d srb1_timer_reordering %u!\n", + RC.config_file_name, i, srb1_params.srb1_timer_reordering); + } + } + } } } + + memcpy(&rrc->configuration, &RRC_CONFIGURATION_REQ(msg_p), sizeof(RRC_CONFIGURATION_REQ(msg_p))); } + LOG_I(RRC,"Node type %d \n ", rrc->node_type); return 0; +} + +int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i) { + int k; + paramdef_t ENBSParams[] = ENBSPARAMS_DESC; + paramdef_t ENBParams[] = ENBPARAMS_DESC; + paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0}; + config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); + int num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; + AssertFatal (i<num_enbs, + "Failed to parse config file no %ith element in %s \n",i, ENB_CONFIG_STRING_ACTIVE_ENBS); + + if (num_enbs>0) { + // Output a list of all eNBs. + config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); + AssertFatal(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr != NULL, + "eNB id %d is not defined in configuration file\n",i); + F1AP_SETUP_REQ (msg_p).num_cells_available = 0; + + for (k=0; k <num_enbs ; k++) { + if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[k], *(ENBParamList.paramarray[i][ENB_ENB_NAME_IDX].strptr) )== 0) { + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + paramdef_t PLMNParams[] = PLMNPARAMS_DESC; + paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0}; + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; + + for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) + PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); + paramdef_t SCTPParams[] = SCTPPARAMS_DESC; + F1AP_SETUP_REQ (msg_p).num_cells_available++; + F1AP_SETUP_REQ (msg_p).gNB_DU_id = *(ENBParamList.paramarray[0][ENB_ENB_ID_IDX].uptr); + LOG_I(ENB_APP,"F1AP: gNB_DU_id[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_id); + F1AP_SETUP_REQ (msg_p).gNB_DU_name = strdup(*(ENBParamList.paramarray[0][ENB_ENB_NAME_IDX].strptr)); + LOG_I(ENB_APP,"F1AP: gNB_DU_name[%d] %s\n",k,F1AP_SETUP_REQ (msg_p).gNB_DU_name); + F1AP_SETUP_REQ (msg_p).tac[k] = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr; + LOG_I(ENB_APP,"F1AP: tac[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).tac[k]); + F1AP_SETUP_REQ (msg_p).mcc[k] = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; + LOG_I(ENB_APP,"F1AP: mcc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mcc[k]); + F1AP_SETUP_REQ (msg_p).mnc[k] = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr; + LOG_I(ENB_APP,"F1AP: mnc[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mnc[k]); + F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr; + LOG_I(ENB_APP,"F1AP: mnc_digit_length[%d] %d\n",k,F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]); + AssertFatal((F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 2) || + (F1AP_SETUP_REQ (msg_p).mnc_digit_length[k] == 3), + "BAD MNC DIGIT LENGTH %d", + F1AP_SETUP_REQ (msg_p).mnc_digit_length[k]); + F1AP_SETUP_REQ (msg_p).nr_cellid[k] = (uint64_t)*(ENBParamList.paramarray[i][ENB_NRCELLID_IDX].u64ptr); + LOG_I(ENB_APP,"F1AP: nr_cellid[%d] %ld\n",k,F1AP_SETUP_REQ (msg_p).nr_cellid[k]); + LOG_I(ENB_APP,"F1AP: CU_ip4_address in DU %s\n",RC.mac[k]->eth_params_n.remote_addr); + LOG_I(ENB_APP,"FIAP: CU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4_address,(int)strlen(RC.mac[k]->eth_params_n.remote_addr)); + F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv6 = 0; + F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4 = 1; + //strcpy(F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv6_address, ""); + strcpy(F1AP_SETUP_REQ (msg_p).CU_f1_ip_address.ipv4_address, RC.mac[k]->eth_params_n.remote_addr); + LOG_I(ENB_APP,"F1AP: DU_ip4_address in DU %s\n",RC.mac[k]->eth_params_n.my_addr); + LOG_I(ENB_APP,"FIAP: DU_ip4_address in DU %p, strlen %d\n",F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4_address,(int)strlen(RC.mac[k]->eth_params_n.my_addr)); + F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv6 = 0; + F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4 = 1; + //strcpy(F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv6_address, ""); + strcpy(F1AP_SETUP_REQ (msg_p).DU_f1_ip_address.ipv4_address, RC.mac[k]->eth_params_n.my_addr); + //strcpy(F1AP_SETUP_REQ (msg_p).CU_ip_address[l].ipv6_address,*(F1ParamList.paramarray[l][ENB_CU_IPV6_ADDRESS_IDX].strptr)); + //F1AP_SETUP_REQ (msg_p).CU_port = RC.mac[k]->eth_params_n.remote_portc; // maybe we dont need it + sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG); + config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); + F1AP_SETUP_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); + F1AP_SETUP_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); + eNB_RRC_INST *rrc = RC.rrc[k]; + // wait until RRC cell information is configured + int cell_info_configured=0; + + do { + LOG_I(ENB_APP,"ngran_eNB_DU: Waiting for basic cell configuration\n"); + usleep(100000); + pthread_mutex_lock(&rrc->cell_info_mutex); + cell_info_configured = rrc->cell_info_configured; + pthread_mutex_unlock(&rrc->cell_info_mutex); + } while (cell_info_configured ==0); + + rrc->configuration.mcc[0] = F1AP_SETUP_REQ (msg_p).mcc[k]; + rrc->configuration.mnc[0] = F1AP_SETUP_REQ (msg_p).mnc[k]; + rrc->configuration.tac = F1AP_SETUP_REQ (msg_p).tac[k]; + rrc->nr_cellid = F1AP_SETUP_REQ (msg_p).nr_cellid[k]; + F1AP_SETUP_REQ (msg_p).nr_pci[k] = rrc->carrier[0].physCellId; + F1AP_SETUP_REQ (msg_p).num_ssi[k] = 0; + + if (rrc->carrier[0].sib1->tdd_Config) { + LOG_I(ENB_APP,"ngran_DU: Configuring Cell %d for TDD\n",k); + F1AP_SETUP_REQ (msg_p).fdd_flag = 0; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nr_arfcn = freq_to_arfcn10(rrc->carrier[0].sib1->freqBandIndicator, + rrc->carrier[0].dl_CarrierFreq); + // For LTE use scs field to carry prefix type and number of antennas + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.scs = (rrc->carrier[0].Ncp<<2)+rrc->carrier[0].p_eNB;; + // use nrb field to hold LTE N_RB_DL (0...5) + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nrb = rrc->carrier[0].mib.message.dl_Bandwidth; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nrb = rrc->carrier[0].mib.message.dl_Bandwidth; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.num_frequency_bands = 1; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].tdd.nr_band[0] = rrc->carrier[0].sib1->freqBandIndicator; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.sul_active = 0; + } else { + LOG_I(ENB_APP,"ngran_DU: Configuring Cell %d for FDD\n",k); + F1AP_SETUP_REQ (msg_p).fdd_flag = 1; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_arfcn = freq_to_arfcn10(rrc->carrier[0].sib1->freqBandIndicator, + rrc->carrier[0].dl_CarrierFreq); + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_arfcn = F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_arfcn; + // For LTE use scs field to carry prefix type and number of antennas + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_scs = (rrc->carrier[0].Ncp<<2)+rrc->carrier[0].p_eNB;; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_scs = rrc->carrier[0].Ncp; + // use nrb field to hold LTE N_RB_DL (0...5) + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nrb = rrc->carrier[0].mib.message.dl_Bandwidth; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nrb = rrc->carrier[0].mib.message.dl_Bandwidth; + // RK: we need to check there value for FDD's frequency_bands DL/UL + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_num_frequency_bands = 1; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_band[0] = rrc->carrier[0].sib1->freqBandIndicator; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_num_frequency_bands = 1; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_band[0] = rrc->carrier[0].sib1->freqBandIndicator; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_num_sul_frequency_bands = 0; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.ul_nr_sul_band[0] = rrc->carrier[0].sib1->freqBandIndicator; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_num_sul_frequency_bands = 0; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.dl_nr_sul_band[0] = rrc->carrier[0].sib1->freqBandIndicator; + F1AP_SETUP_REQ (msg_p).nr_mode_info[k].fdd.sul_active = 0; + } + + F1AP_SETUP_REQ (msg_p).measurement_timing_information[k] = "0"; + F1AP_SETUP_REQ (msg_p).ranac[k] = 0; + F1AP_SETUP_REQ (msg_p).mib[k] = rrc->carrier[0].MIB; + F1AP_SETUP_REQ (msg_p).sib1[k] = rrc->carrier[0].SIB1; + F1AP_SETUP_REQ (msg_p).mib_length[k] = rrc->carrier[0].sizeof_MIB; + F1AP_SETUP_REQ (msg_p).sib1_length[k] = rrc->carrier[0].sizeof_SIB1; + break; + } // if + } // for + } // if + + return 0; } int RCconfig_gtpu(void ) { @@ -1788,12 +2143,8 @@ int RCconfig_S1( const char *active_enb[MAX_ENB]; char *address = NULL; char *cidr = NULL; - ccparams_lte_t ccparams_lte; - - memset((void*)&ccparams_lte,0,sizeof(ccparams_lte_t)); - - + memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t)); // for no gcc warnings (void)my_int; memset((char *)active_enb, 0, MAX_ENB * sizeof(char *)); @@ -1928,7 +2279,7 @@ int RCconfig_S1( default: { LOG_E(S1AP, "Default I-DRX value in conf file is invalid (%i). Should be 32, 64, 128 or 256. \ - Default DRX set to 32 in MME configuration\n", + Default DRX set to 32 in MME configuration\n", ccparams_lte.pcch_defaultPagingCycle); S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0; } @@ -1946,7 +2297,9 @@ int RCconfig_S1( if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; + S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 0; } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { + S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 0; S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; @@ -2019,18 +2372,13 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { int enb_id; char *address = NULL; char *cidr = NULL; - ccparams_lte_t ccparams_lte; - - memset((void*)&ccparams_lte,0,sizeof(ccparams_lte_t)); - - + memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t)); paramdef_t ENBSParams[] = ENBSPARAMS_DESC; paramdef_t ENBParams[] = ENBPARAMS_DESC; paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0}; /* get global parameters, defined outside any section in the config file */ config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); - checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte); paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0}; @@ -2040,225 +2388,229 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { CCsParams[I].chkPptr = &(config_check_CCparams[I]); } - /*#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) - if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) { - asn_debug = 0; - asn1_xer_print = 0; - } else if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) { - asn_debug = 1; - asn1_xer_print = 1; - } else if (strcasecmp(*(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr) , ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) { - asn_debug = 1; - asn1_xer_print = 2; - } else { - asn_debug = 0; - asn1_xer_print = 0; - } - #endif */ AssertFatal(i < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt, - "Failed to parse config file %s, %uth attribute %s \n", - RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS); + "Failed to parse config file %s, %uth attribute %s \n", + RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS); if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt > 0) { // Output a list of all eNBs. config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); - + if (ENBParamList.numelt > 0) { for (k = 0; k < ENBParamList.numelt; k++) { - if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) { - // Calculate a default eNB ID -# if defined(ENABLE_USE_MME) - uint32_t hash; - hash = s1ap_generate_eNB_id (); - enb_id = k + (hash & 0xFFFF8); -# else - enb_id = k; -# endif - } else { - enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr); - } - - // search if in active list - for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) { - if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) { - paramdef_t PLMNParams[] = PLMNPARAMS_DESC; - paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0}; - /* map parameter checking array instances to parameter definition array instances */ - checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; - - for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) - PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - - paramdef_t X2Params[] = X2PARAMS_DESC; - paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0}; - paramdef_t SCTPParams[] = SCTPPARAMS_DESC; - paramdef_t NETParams[] = NETPARAMS_DESC; - /* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */ - /* this is most probably a problem with the config module */ - char aprefix[MAX_OPTNAME_SIZE*80 + 8]; - sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); - /* Some default/random parameters */ - X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; - - if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB; - } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", - RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr)); - } - - X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); - X2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; - config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); - - if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) - AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", - PLMNParamList.numelt); - - - if (PLMNParamList.numelt > 1) - LOG_W(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n"); - - X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; - X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr; - X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr; - AssertFatal(X2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3 - || X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100, - "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", - X2AP_REGISTER_ENB_REQ(msg_p).mnc); - /* CC params */ - config_getlist(&CCsParamList, NULL, 0, aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt; - - if (CCsParamList.numelt > 0) { - //char ccspath[MAX_OPTNAME_SIZE*2 + 16]; - for (J = 0; J < CCsParamList.numelt ; J++) { - sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J); - config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = ccparams_lte.eutra_band; - X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency; - X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset; - X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell; - - if (ccparams_lte.Nid_cell>503) { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n", - RC.config_file_name, k, ccparams_lte.Nid_cell); - } - - X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL; - - if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n", - RC.config_file_name, k, ccparams_lte.N_RB_DL); - } - - if (strcmp(ccparams_lte.frame_type, "FDD") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD; - } else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; - } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", - RC.config_file_name, k, ccparams_lte.frame_type); - } - - X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL); - X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL); - } - } - - sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); - config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix); - AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS, - "value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n", - X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS); - X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0; - - for (l = 0; l < X2ParamList.numelt; l++) { - X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1; - strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr)); - strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr)); - - if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1; - } else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1; - } else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { - X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1; - X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1; - } - } - - - // SCTP SETTING - X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; - X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; -# if defined(ENABLE_USE_MME) - sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG); - config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); - X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); -#endif - sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - // NETWORK_INTERFACES - config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[ENB_PORT_FOR_X2C_IDX].uptr); - - if ((NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) { - LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n"); - exit(1); - } - - cidr = *(NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr); - address = strtok(cidr, "/"); - X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv6 = 0; - X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4 = 1; - strcpy(X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4_address, address); - } - } + if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) { + // Calculate a default eNB ID + if (EPC_MODE_ENABLED) { + uint32_t hash; + hash = s1ap_generate_eNB_id (); + enb_id = k + (hash & 0xFFFF8); + } else { + enb_id = k; + } + } else { + enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr); + } + + // search if in active list + for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) { + if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) { + paramdef_t PLMNParams[] = PLMNPARAMS_DESC; + paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0}; + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; + + for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) + PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + + paramdef_t X2Params[] = X2PARAMS_DESC; + paramlist_def_t X2ParamList = {ENB_CONFIG_STRING_TARGET_ENB_X2_IP_ADDRESS,NULL,0}; + paramdef_t SCTPParams[] = SCTPPARAMS_DESC; + paramdef_t NETParams[] = NETPARAMS_DESC; + /* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */ + /* this is most probably a problem with the config module */ + char aprefix[MAX_OPTNAME_SIZE*80 + 8]; + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + /* Some default/random parameters */ + X2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; + + if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB; + } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", + RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr)); + } + + X2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); + X2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); + + if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) + AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", + PLMNParamList.numelt); + + if (PLMNParamList.numelt > 1) + LOG_W(X2AP, "X2AP currently handles only one PLMN, ignoring the others!\n"); + + X2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; + X2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr; + X2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal(X2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3 + || X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100, + "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", + X2AP_REGISTER_ENB_REQ(msg_p).mnc); + /* CC params */ + config_getlist(&CCsParamList, NULL, 0, aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt; + + if (CCsParamList.numelt > 0) { + //char ccspath[MAX_OPTNAME_SIZE*2 + 16]; + for (J = 0; J < CCsParamList.numelt ; J++) { + sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J); + config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = ccparams_lte.eutra_band; + X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency; + X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset; + X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell; + + if (ccparams_lte.Nid_cell>503) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n", + RC.config_file_name, k, ccparams_lte.Nid_cell); + } + + X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL; + + if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n", + RC.config_file_name, k, ccparams_lte.N_RB_DL); + } + + if (strcmp(ccparams_lte.frame_type, "FDD") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD; + } else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; + } else { + AssertFatal (0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n", + RC.config_file_name, k, ccparams_lte.frame_type); + } + + X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL); + X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL); + } + } + + sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix); + AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS, + "value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n", + X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS); + X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0; + + for (l = 0; l < X2ParamList.numelt; l++) { + X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 += 1; + strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4_address,*(X2ParamList.paramarray[l][ENB_X2_IPV4_ADDRESS_IDX].strptr)); + strcpy(X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6_address,*(X2ParamList.paramarray[l][ENB_X2_IPV6_ADDRESS_IDX].strptr)); + + if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1; + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 0; + } else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 0; + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1; + } else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1; + X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1; + } + } + + // timers + { + int t_reloc_prep = 0; + int tx2_reloc_overall = 0; + paramdef_t p[] = { + { "t_reloc_prep", "t_reloc_prep", 0, iptr:&t_reloc_prep, defintval:0, TYPE_INT, 0 }, + { "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 } + }; + config_get(p, sizeof(p)/sizeof(paramdef_t), aprefix); + + if (t_reloc_prep <= 0 || t_reloc_prep > 10000 || + tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000) { + LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000]\n"); + exit(1); + } + + X2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep; + X2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall; + } + // SCTP SETTING + X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; + X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; + + if (EPC_MODE_ENABLED) { + sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG); + config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); + X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); + } + + sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + // NETWORK_INTERFACES + config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); + X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C = (uint32_t)*(NETParams[ENB_PORT_FOR_X2C_IDX].uptr); + + if ((NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr == NULL) || (X2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_X2C == 0)) { + LOG_E(RRC,"Add eNB IPv4 address and/or port for X2C in the CONF file!\n"); + exit(1); + } + + cidr = *(NETParams[ENB_IPV4_ADDR_FOR_X2C_IDX].strptr); + address = strtok(cidr, "/"); + X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv6 = 0; + X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4 = 1; + strcpy(X2AP_REGISTER_ENB_REQ (msg_p).enb_x2_ip_address.ipv4_address, address); + } + } } } } - + return 0; } int RCconfig_parallel(void) { char *parallel_conf = NULL; char *worker_conf = NULL; - - paramdef_t ThreadParams[] = THREAD_CONF_DESC; paramlist_def_t THREADParamList = {THREAD_CONFIG_STRING_THREAD_STRUCT,NULL,0}; config_getlist( &THREADParamList,NULL,0,NULL); - if(parallel_config == NULL){ + if(parallel_config == NULL) { if(THREADParamList.numelt>0) { config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr)); } else { parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT"); } + set_parallel_conf(parallel_conf); } - if(worker_config == NULL){ + if(worker_config == NULL) { if(THREADParamList.numelt>0) { config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); worker_conf = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr)); } else { worker_conf = strdup("WORKER_ENABLE"); } + set_worker_conf(worker_conf); } - - return 0; } @@ -2272,13 +2624,12 @@ void RCConfig(void) { /* get global parameters, defined outside any section in the config file */ printf("Getting ENBSParams\n"); config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); -# if defined(ENABLE_USE_MME) - EPC_MODE_ENABLED = ((*ENBSParams[ENB_NOS1_IDX].uptr) == 0); -#endif + //EPC_MODE_ENABLED = ((*ENBSParams[ENB_NOS1_IDX].uptr) == 0); RC.nb_inst = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; if (RC.nb_inst > 0) { RC.nb_CC = (int *)malloc((1+RC.nb_inst)*sizeof(int)); + for (int i=0; i<RC.nb_inst; i++) { sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,i); config_getlist( &CCsParamList,NULL,0, aprefix); @@ -2286,9 +2637,10 @@ void RCConfig(void) { } } - // Get num MACRLC instances config_getlist( &MACRLCParamList,NULL,0, NULL); RC.nb_macrlc_inst = MACRLCParamList.numelt; + AssertFatal(RC.nb_macrlc_inst <= MAX_MAC_INST, + "Too many macrlc instances %d\n",RC.nb_macrlc_inst); // Get num L1 instances config_getlist( &L1ParamList,NULL,0, NULL); RC.nb_L1_inst = L1ParamList.numelt; @@ -2297,3 +2649,291 @@ void RCConfig(void) { RC.nb_RU = RUParamList.numelt; RCconfig_parallel(); } + +int check_plmn_identity(rrc_eNB_carrier_data_t *carrier,uint16_t mcc,uint16_t mnc,uint8_t mnc_digit_length) { + AssertFatal(carrier->sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count > 0, + "plmn info isn't there\n"); + AssertFatal(mnc_digit_length ==2 || mnc_digit_length == 3, + "impossible mnc_digit_length %d\n",mnc_digit_length); + LTE_PLMN_IdentityInfo_t *plmn_Identity_info = carrier->sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]; + + // check if mcc is different and return failure if so + if (mcc != + (*plmn_Identity_info->plmn_Identity.mcc->list.array[0]*100)+ + (*plmn_Identity_info->plmn_Identity.mcc->list.array[1]*10) + + (*plmn_Identity_info->plmn_Identity.mcc->list.array[2])) return(0); + + // check that mnc digit length is different and return failure if so + if (mnc_digit_length != plmn_Identity_info->plmn_Identity.mnc.list.count) return 0; + + // check that 2 digit mnc is different and return failure if so + if (mnc_digit_length == 2 && + (mnc != + (*plmn_Identity_info->plmn_Identity.mnc.list.array[0]*10) + + (*plmn_Identity_info->plmn_Identity.mnc.list.array[1]))) return(0); + else if (mnc_digit_length == 3 && + (mnc != + (*plmn_Identity_info->plmn_Identity.mnc.list.array[0]*100) + + (*plmn_Identity_info->plmn_Identity.mnc.list.array[1]*10) + + (*plmn_Identity_info->plmn_Identity.mnc.list.array[2]))) return(0); + + // if we're here, the mcc/mnc match so return success + return(1); +} + +void extract_and_decode_SI(int inst,int si_ind,uint8_t *si_container,int si_container_length) { + eNB_RRC_INST *rrc = RC.rrc[inst]; + rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0]; + LTE_BCCH_DL_SCH_Message_t *bcch_message ; + AssertFatal(si_ind==0,"Can only handle a single SI block for now\n"); + LOG_I(ENB_APP, "rrc inst %d: Trying to decode SI block %d @ %p, length %d\n",inst,si_ind,si_container,si_container_length); + // point to first SI block + bcch_message = &carrier->systemInformation; + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_LTE_BCCH_DL_SCH_Message, + (void **)&bcch_message, + (const void *)si_container, + si_container_length); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0, "[ENB_APP][RRC inst %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", + inst, + dec_rval.consumed ); + } + + if (bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_PR_c1) { + switch (bcch_message->message.choice.c1.present) { + case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: + AssertFatal(1==0,"Should have received SIB1 from CU\n"); + break; + + case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: { + LTE_SystemInformation_t *si = &bcch_message->message.choice.c1.choice.systemInformation; + + for (int i=0; i<si->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) { + LOG_I(ENB_APP,"Extracting SI %d/%d\n",i,si->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count); + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo; + typeandinfo = si->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i]; + + switch(typeandinfo->present) { + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: + carrier->sib2 = &typeandinfo->choice.sib2; + carrier->SIB23 = (uint8_t *)malloc(64); + memcpy((void *)carrier->SIB23,(void *)si_container,si_container_length); + carrier->sizeof_SIB23 = si_container_length; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB2 in CU F1AP_SETUP_RESP message\n", inst); + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3: + carrier->sib3 = &typeandinfo->choice.sib3; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB3 in CU F1AP_SETUP_RESP message\n", inst); + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4: + //carrier->sib4 = &typeandinfo->choice.sib4; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB4 in CU F1AP_SETUP_RESP message\n", inst); + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5: + //carrier->sib5 = &typeandinfo->choice.sib5; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB5 in CU F1AP_SETUP_RESP message\n", inst); + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6: + //carrier->sib6 = &typeandinfo->choice.sib6; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB6 in CU F1AP_SETUP_RESP message\n", inst); + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7: + //carrier->sib7 = &typeandinfo->choice.sib7; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB7 in CU F1AP_SETUP_RESP message\n", inst); + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8: + //carrier->sib8 = &typeandinfo->choice.sib8; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB8 in CU F1AP_SETUP_RESP message\n", inst); + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9: + //carrier->sib9 = &typeandinfo->choice.sib9; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB9 in CU F1AP_SETUP_RESP message\n", inst); + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10: + //carrier->sib10 = &typeandinfo->choice.sib10; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB10 in CU F1AP_SETUP_RESP message\n", inst); + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11: + //carrier->sib11 = &typeandinfo->choice.sib11; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB11 in CU F1AP_SETUP_RESP message\n", inst); + break; +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 2, 0)) + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920: + //carrier->sib12 = &typeandinfo->choice.sib12; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB12 in CU F1AP_SETUP_RESP message\n", inst); + break; + + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920: + carrier->sib13 = &typeandinfo->choice.sib13_v920; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB13 in CU F1AP_SETUP_RESP message\n", inst); + break; +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + + //SIB18 + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250: + carrier->sib18 = &typeandinfo->choice.sib18_v1250; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB18 in CU F1AP_SETUP_RESP message\n", inst); + break; + + //SIB19 + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250: + carrier->sib19 = &typeandinfo->choice.sib19_v1250; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB19 in CU F1AP_SETUP_RESP message\n", inst); + break; + + //SIB21 + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: + carrier->sib21 = &typeandinfo->choice.sib21_v1430; + LOG_I( ENB_APP, "[RRC %"PRIu8"] Found SIB21 in CU F1AP_SETUP_RESP message\n", inst); + break; +#endif + + default: + AssertFatal(1==0,"Shouldn't have received this SI %d\n",typeandinfo->present); + break; + } + } + + break; + } + + case LTE_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: + AssertFatal(0, "Should have received SIB1 from CU\n"); + break; + } + } else AssertFatal(1==0,"No SI messages\n"); +} + +void configure_du_mac(int inst) { + eNB_RRC_INST *rrc = RC.rrc[inst]; + rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0]; + LOG_I(ENB_APP,"Configuring MAC/L1 %d, carrier->sib2 %p\n",inst,&carrier->sib2->radioResourceConfigCommon); + rrc_mac_config_req_eNB(inst, 0, + carrier->physCellId, + carrier->p_eNB, + carrier->Ncp, + carrier->sib1->freqBandIndicator, + carrier->dl_CarrierFreq, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + carrier->pbch_repetition, +#endif + 0, // rnti + (LTE_BCCH_BCH_Message_t *) &carrier->mib, + (LTE_RadioResourceConfigCommonSIB_t *) &carrier->sib2->radioResourceConfigCommon, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) &carrier->sib2_BR->radioResourceConfigCommon, +#endif + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, +#endif + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + carrier->sib1->tdd_Config, + NULL, + &carrier->sib1->schedulingInfoList, + carrier->ul_CarrierFreq, + carrier->sib2->freqInfo.ul_Bandwidth, + &carrier->sib2->freqInfo.additionalSpectrumEmission, + (LTE_MBSFN_SubframeConfigList_t *) carrier->sib2->mbsfn_SubframeConfigList +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , + carrier->MBMS_flag, + (LTE_MBSFN_AreaInfoList_r9_t *) & carrier->sib13->mbsfn_AreaInfoList_r9, + (LTE_PMCH_InfoList_r9_t *) NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + , + NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL +#endif + ); +} + +void handle_f1ap_setup_resp(f1ap_setup_resp_t *resp) { + int i,j,si_ind; + LOG_I(ENB_APP, "cells_to_activated %d, RRC instances %d\n", + resp->num_cells_to_activate,RC.nb_inst); + + for (j=0; j<resp->num_cells_to_activate; j++) { + for (i=0; i<RC.nb_inst; i++) { + rrc_eNB_carrier_data_t *carrier = &RC.rrc[i]->carrier[0]; + // identify local index of cell j by nr_cellid, plmn identity and physical cell ID + LOG_I(ENB_APP, "Checking cell %d, rrc inst %d : rrc->nr_cellid %lx, resp->nr_cellid %lx\n", + j,i,RC.rrc[i]->nr_cellid,resp->nr_cellid[j]); + + if (RC.rrc[i]->nr_cellid == resp->nr_cellid[j] && + (check_plmn_identity(carrier, resp->mcc[j], resp->mnc[j], resp->mnc_digit_length[j])>0 && + resp->nrpci[j] == carrier->physCellId)) { + // copy system information and decode it + for (si_ind=0; si_ind<resp->num_SI[j]; si_ind++) { + //printf("SI %d size %d: ", si_ind, resp->SI_container_length[j][si_ind]); + //for (int n=0;n<resp->SI_container_length[j][si_ind];n++) + // printf("%02x ",resp->SI_container[j][si_ind][n]); + //printf("\n"); + extract_and_decode_SI(i, + si_ind, + resp->SI_container[j][si_ind], + resp->SI_container_length[j][si_ind]); + } + + // perform MAC/L1 common configuration + configure_du_mac(i); + } else { + LOG_E(ENB_APP, "F1 Setup Response not matching\n"); + } + } + } +} + +void read_config_and_init(void) { + int macrlc_has_f1[MAX_MAC_INST]; + memset(macrlc_has_f1, 0, MAX_MAC_INST*sizeof(int)); + + if (RC.nb_macrlc_inst > 0) + AssertFatal(RC.nb_macrlc_inst == RC.nb_inst, + "Number of MACRLC instances %d != number of RRC instances %d\n", + RC.nb_macrlc_inst, RC.nb_inst); + + RCconfig_L1(); + LOG_I(PHY, "%s() RC.nb_L1_inst: %d\n", __FUNCTION__, RC.nb_L1_inst); + RCconfig_macrlc(macrlc_has_f1); + LOG_I(MAC, "%s() RC.nb_macrlc_inst: %d\n", __FUNCTION__, RC.nb_macrlc_inst); + + if (RC.nb_L1_inst > 0) + AssertFatal(l1_north_init_eNB() == 0, "could not initialize L1 north interface\n"); + + RC.rrc = malloc(RC.nb_inst * sizeof(eNB_RRC_INST *)); + AssertFatal(RC.rrc, "could not allocate memory for RC.rrc\n"); + + for (uint32_t enb_id = 0; enb_id < RC.nb_inst; enb_id++) { + RC.rrc[enb_id] = malloc(sizeof(eNB_RRC_INST)); + AssertFatal(RC.rrc[enb_id], "RRC context for eNB %d not allocated\n", enb_id); + memset((void *)RC.rrc[enb_id], 0, sizeof(eNB_RRC_INST)); + RCconfig_RRC(enb_id, RC.rrc[enb_id],macrlc_has_f1[enb_id]); + } +} diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 0edb84039ba9b5ea3f5c3b0ba08aedbe0da63995..a204a47652f6292858e9080b5a61fe3c93652fe9 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -40,6 +40,7 @@ #include "PHY/impl_defs_lte.h" #include "PHY/defs_eNB.h" #include "s1ap_messages_types.h" +#include "f1ap_messages_types.h" #include "LTE_SystemInformationBlockType2.h" #include "rrc_messages_types.h" #include "RRC/LTE/rrc_defs.h" @@ -63,6 +64,9 @@ // Hard to find a defined value for max enb... #define MAX_ENB 16 +#define MAX_DU 4 +#define CU_BALANCING_ALL 127 +#define CU_BALANCING_ROUND_ROBIN 126 typedef struct mme_ip_address_s { unsigned ipv4:1; @@ -72,6 +76,13 @@ typedef struct mme_ip_address_s { char *ipv6_address; } mme_ip_address_t; +typedef struct cu_params { + const char *local_ipv4_address; + const uint16_t local_port; + const char *remote_ipv4_address; + const int16_t remote_port; +} cudu_params_t; + typedef struct ru_config_s { // indicates if local or remote rf is used (1 == LOCAL) unsigned local_rf:1; @@ -93,7 +104,7 @@ typedef struct ru_config_s { extern void RCconfig_RU(void); extern void RCconfig_flexran(void); extern void RCconfig_L1(void); -extern void RCconfig_macrlc(void); +extern void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]); extern void UE_config_stub_pnf(void); extern int RCconfig_gtpu(void ); extern void RCConfig(void); @@ -101,12 +112,17 @@ extern void RCConfig(void); void enb_config_display(void); void ru_config_display(void); -int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc); +int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1); int RCconfig_S1(MessageDef *msg_p, uint32_t i); + +void read_config_and_init(void); int RCconfig_X2(MessageDef *msg_p, uint32_t i); void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int cell_idx,int cc_idx,char *config_fname); void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, int cell_idx,int cc_idx,char *config_fname,char *brparamspath); +int RCconfig_DU_F1(MessageDef *msg_p, uint32_t i); +void handle_f1ap_setup_resp(f1ap_setup_resp_t *resp); + #endif /* ENB_CONFIG_H_ */ /** @} */ diff --git a/openair2/ENB_APP/enb_config_SL.c b/openair2/ENB_APP/enb_config_SL.c index e9f2515f81603abebc44a0aeb5e5f955057c7589..aecede2db8da25fe465e53f5129a4aec16c2e615 100644 --- a/openair2/ENB_APP/enb_config_SL.c +++ b/openair2/ENB_APP/enb_config_SL.c @@ -39,7 +39,7 @@ #include "RRC_config_tools.h" #include "enb_paramdef.h" #include "enb_paramdef_sidelink.h" - + void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int cell_idx,int cc_idx,char *config_fname) { printf("Configuring SL\n"); @@ -52,7 +52,7 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_CP_Len choice: normal,extended!\n", config_fname, cell_idx, SLconfig->rxPool_sc_CP_Len); - + if (strcmp(SLconfig->rxPool_sc_Period,"sf40")==0) { RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[cc_idx] = LTE_SL_PeriodComm_r12_sf40; } else if (strcmp(SLconfig->rxPool_sc_Period,"sf60")==0) { @@ -89,7 +89,7 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_Period choice: sf40,sf60,sf70,sf80,sf120,sf140,sf160,sf240,sf280,sf320,spare6,spare5,spare4,spare3,spare2,spare!\n", config_fname, cell_idx, SLconfig->rxPool_sc_Period); - + if (strcmp(SLconfig->rxPool_data_CP_Len,"normal")==0) { RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[cc_idx] = LTE_SL_CP_Len_r12_normal; } else if (strcmp(SLconfig->rxPool_data_CP_Len,"extended")==0) { @@ -98,11 +98,11 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_data_CP_Len choice: normal,extended!\n", config_fname, cell_idx, SLconfig->rxPool_data_CP_Len); - + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_Num[cc_idx] = SLconfig->rxPool_ResourceConfig_prb_Num; RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_Start[cc_idx] = SLconfig->rxPool_ResourceConfig_prb_Start; RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_End[cc_idx] = SLconfig->rxPool_ResourceConfig_prb_End; - + if (strcmp(SLconfig->rxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) { RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[cc_idx] = LTE_SL_OffsetIndicator_r12_PR_NOTHING; } else if (strcmp(SLconfig->rxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) { @@ -113,9 +113,9 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", config_fname, cell_idx, SLconfig->rxPool_ResourceConfig_offsetIndicator_present); - + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_choice[cc_idx] = SLconfig->rxPool_ResourceConfig_offsetIndicator_choice; - + if (strcmp(SLconfig->rxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) { RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[cc_idx] = LTE_SubframeBitmapSL_r12_PR_NOTHING; } else if (strcmp(SLconfig->rxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) { @@ -136,11 +136,11 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", config_fname, cell_idx, SLconfig->rxPool_ResourceConfig_subframeBitmap_present); - + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[cc_idx] = SLconfig->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf; RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_size[cc_idx] = SLconfig->rxPool_ResourceConfig_subframeBitmap_choice_bs_size; RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[cc_idx] = SLconfig->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; - + //SIB19 - for discRxPool if (strcmp(SLconfig->discRxPool_cp_Len,"normal")==0) { RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[cc_idx] = LTE_SL_CP_Len_r12_normal; @@ -150,7 +150,7 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_cp_Len choice: normal,extended!\n", config_fname, cell_idx, SLconfig->discRxPool_cp_Len); - + if (strcmp(SLconfig->discRxPool_discPeriod,"rf32")==0) { RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[cc_idx] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf32; } else if (strcmp(SLconfig->discRxPool_discPeriod,"rf64")==0) { @@ -171,13 +171,13 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n", config_fname, cell_idx, SLconfig->discRxPool_discPeriod); - + RRC_CONFIGURATION_REQ (msg_p).discRxPool_numRetx[cc_idx] = SLconfig->discRxPool_numRetx; RRC_CONFIGURATION_REQ (msg_p).discRxPool_numRepetition[cc_idx] = SLconfig->discRxPool_numRepetition; RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_Num[cc_idx] = SLconfig->discRxPool_ResourceConfig_prb_Num; RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_Start[cc_idx] = SLconfig->discRxPool_ResourceConfig_prb_Start; RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_End[cc_idx] = SLconfig->discRxPool_ResourceConfig_prb_End; - + if (strcmp(SLconfig->discRxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) { RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[cc_idx] = LTE_SL_OffsetIndicator_r12_PR_NOTHING; } else if (strcmp(SLconfig->discRxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) { @@ -188,9 +188,9 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", config_fname, cell_idx, SLconfig->discRxPool_ResourceConfig_offsetIndicator_present); - + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_choice[cc_idx] = SLconfig->discRxPool_ResourceConfig_offsetIndicator_choice; - + if (strcmp(SLconfig->discRxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) { RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[cc_idx] = LTE_SubframeBitmapSL_r12_PR_NOTHING; } else if (strcmp(SLconfig->discRxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) { @@ -211,11 +211,11 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", config_fname, cell_idx, SLconfig->discRxPool_ResourceConfig_subframeBitmap_present); - + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[cc_idx] = SLconfig->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf; RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[cc_idx] = SLconfig->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size; RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[cc_idx] = SLconfig->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused; - + //SIB19 - For discRxPoolPS if (strcmp(SLconfig->discRxPoolPS_cp_Len,"normal")==0) { RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[cc_idx] = LTE_SL_CP_Len_r12_normal; @@ -225,7 +225,7 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_cp_Len choice: normal,extended!\n", config_fname, cell_idx, SLconfig->discRxPoolPS_cp_Len); - + if (strcmp(SLconfig->discRxPoolPS_discPeriod,"rf32")==0) { RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[cc_idx] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf32; } else if (strcmp(SLconfig->discRxPoolPS_discPeriod,"rf64")==0) { @@ -246,13 +246,13 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n", config_fname, cell_idx, SLconfig->discRxPoolPS_discPeriod); - + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_numRetx[cc_idx] = SLconfig->discRxPoolPS_numRetx; RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_numRepetition[cc_idx] = SLconfig->discRxPoolPS_numRepetition; RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_Num[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_prb_Num; RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_Start[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_prb_Start; RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_End[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_prb_End; - + if (strcmp(SLconfig->discRxPoolPS_ResourceConfig_offsetIndicator_present,"prNothing")==0) { RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[cc_idx] = LTE_SL_OffsetIndicator_r12_PR_NOTHING; } else if (strcmp(SLconfig->discRxPoolPS_ResourceConfig_offsetIndicator_present,"prSmall")==0) { @@ -263,9 +263,9 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", config_fname, cell_idx, SLconfig->discRxPoolPS_ResourceConfig_offsetIndicator_present); - + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_choice[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_offsetIndicator_choice; - + if (strcmp(SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_present,"prNothing")==0) { RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[cc_idx] = LTE_SubframeBitmapSL_r12_PR_NOTHING; } else if (strcmp(SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs4")==0) { @@ -286,7 +286,7 @@ void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", config_fname, cell_idx, SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_present); - + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf; RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size; RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[cc_idx] = SLconfig->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused; diff --git a/openair2/ENB_APP/enb_config_eMTC.c b/openair2/ENB_APP/enb_config_eMTC.c index f0a829c42487d3126592940b08a33a123591838e..effc93d244ebdb47e36c72f20070a318505d0e7a 100644 --- a/openair2/ENB_APP/enb_config_eMTC.c +++ b/openair2/ENB_APP/enb_config_eMTC.c @@ -38,7 +38,7 @@ #include "common/config/config_userapi.h" #include "RRC_config_tools.h" #include "enb_paramdef.h" - + void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, int cell_idx,int cc_idx,char *config_fname,char *brparamspath) { paramdef_t schedulingInfoBrParams[] = SI_INFO_BR_DESC(eMTCconfig); @@ -58,8 +58,8 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in printf("Found parameters for eMTC from %s : %s\n",config_fname,brparamspath); RRC_CONFIGURATION_REQ(msg_p).schedulingInfoSIB1_BR_r13[cc_idx] = eMTCconfig->schedulingInfoSIB1_BR_r13; - - + + if (!strcmp(eMTCconfig->cellSelectionInfoCE_r13, "ENABLE")) { RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = TRUE; RRC_CONFIGURATION_REQ(msg_p).q_RxLevMinCE_r13[cc_idx]= eMTCconfig->q_RxLevMinCE_r13; @@ -68,14 +68,14 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in } else { RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = FALSE; } - - - + + + if (!strcmp(eMTCconfig->bandwidthReducedAccessRelatedInfo_r13, "ENABLE")) { RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = TRUE; - - - + + + if (!strcmp(eMTCconfig->si_WindowLength_BR_r13, "ms20")) { RRC_CONFIGURATION_REQ(msg_p).si_WindowLength_BR_r13[cc_idx] = 0; } else if (!strcmp(eMTCconfig->si_WindowLength_BR_r13, "ms40")) { @@ -93,8 +93,8 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in } else if (!strcmp(eMTCconfig->si_WindowLength_BR_r13, "spare")) { RRC_CONFIGURATION_REQ(msg_p).si_WindowLength_BR_r13[cc_idx] = 7; } - - + + if (!strcmp(eMTCconfig->si_RepetitionPattern_r13, "everyRF")) { RRC_CONFIGURATION_REQ(msg_p).si_RepetitionPattern_r13[cc_idx] = 0; } else if (!strcmp(eMTCconfig->si_RepetitionPattern_r13, "every2ndRF")) { @@ -104,11 +104,11 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in } else if (!strcmp(eMTCconfig->si_RepetitionPattern_r13, "every8thRF")) { RRC_CONFIGURATION_REQ(msg_p).si_RepetitionPattern_r13[cc_idx] = 3; } - + } else { RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = FALSE; } - + char schedulingInfoBrPath[MAX_OPTNAME_SIZE * 2]; config_getlist(&schedulingInfoBrParamList, NULL, 0, brparamspath); RRC_CONFIGURATION_REQ (msg_p).scheduling_info_br_size[cc_idx] = schedulingInfoBrParamList.numelt; @@ -119,12 +119,12 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in RRC_CONFIGURATION_REQ (msg_p).si_Narrowband_r13[cc_idx][siInfoindex] = eMTCconfig->si_Narrowband_r13; RRC_CONFIGURATION_REQ (msg_p).si_TBS_r13[cc_idx][siInfoindex] = eMTCconfig->si_TBS_r13; } - - - + + + // RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[cc_idx].system_info_value_tag_SI_size[cc_idx] = 0; - - + + RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = CALLOC(1, sizeof(BOOLEAN_t)); if (!strcmp(eMTCconfig->fdd_DownlinkOrTddSubframeBitmapBR_r13, "subframePattern40-r13")) { *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = FALSE; @@ -133,17 +133,17 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = TRUE; RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_val_r13[cc_idx] = eMTCconfig->fdd_DownlinkOrTddSubframeBitmapBR_val_r13; } - + RRC_CONFIGURATION_REQ(msg_p).startSymbolBR_r13[cc_idx] = eMTCconfig->startSymbolBR_r13; - - + + if (!strcmp(eMTCconfig->si_HoppingConfigCommon_r13, "off")) { RRC_CONFIGURATION_REQ(msg_p).si_HoppingConfigCommon_r13[cc_idx] = 1; } else if (!strcmp(eMTCconfig->si_HoppingConfigCommon_r13, "on")) { RRC_CONFIGURATION_REQ(msg_p).si_HoppingConfigCommon_r13[cc_idx] = 0; } - - + + RRC_CONFIGURATION_REQ(msg_p).si_ValidityTime_r13[cc_idx] = calloc(1, sizeof(long)); if (!strcmp(eMTCconfig->si_ValidityTime_r13, "true")) { *RRC_CONFIGURATION_REQ(msg_p).si_ValidityTime_r13[cc_idx] = 0; @@ -152,24 +152,24 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d si_ValidityTime_r13 unknown value!\n", config_fname, cell_idx); } - - + + if (!strcmp(eMTCconfig->freqHoppingParametersDL_r13, "ENABLE")) { RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = TRUE; - + if (!strcmp(eMTCconfig->interval_DLHoppingConfigCommonModeA_r13, "interval-TDD-r13")) RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = FALSE; else RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = TRUE; RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13_val[cc_idx] = eMTCconfig->interval_DLHoppingConfigCommonModeA_r13_val; - + if (!strcmp(eMTCconfig->interval_DLHoppingConfigCommonModeB_r13, "interval-TDD-r13")) RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = FALSE; else RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = TRUE; RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13_val[cc_idx] = eMTCconfig->interval_DLHoppingConfigCommonModeB_r13_val; - + RRC_CONFIGURATION_REQ(msg_p).mpdcch_pdsch_HoppingNB_r13[cc_idx] = calloc(1, sizeof(long)); if (!strcmp(eMTCconfig->mpdcch_pdsch_HoppingNB_r13, "nb2")) { *RRC_CONFIGURATION_REQ(msg_p).mpdcch_pdsch_HoppingNB_r13[cc_idx] = 0; @@ -184,30 +184,30 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in RRC_CONFIGURATION_REQ(msg_p).mpdcch_pdsch_HoppingOffset_r13[cc_idx] = calloc(1, sizeof(long)); *RRC_CONFIGURATION_REQ(msg_p).mpdcch_pdsch_HoppingOffset_r13[cc_idx] = eMTCconfig->mpdcch_pdsch_HoppingOffset_r13; - + } else { RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = FALSE; } - + /** ------------------------------SIB2/3 BR------------------------------------------ */ - - + + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_root = eMTCconfig->ccparams.prach_root; - + if ((eMTCconfig->ccparams.prach_root <0) || (eMTCconfig->ccparams.prach_root > 1023)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_root choice: 0..1023 !\n", config_fname, cell_idx,eMTCconfig->ccparams.prach_root); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_config_index = eMTCconfig->ccparams.prach_config_index; - + if ((eMTCconfig->ccparams.prach_config_index <0) || (eMTCconfig->ccparams.prach_config_index > 63)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_config_index choice: 0..1023 !\n", config_fname, cell_idx,eMTCconfig->ccparams.prach_config_index); - + if (!eMTCconfig->ccparams.prach_high_speed) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", @@ -220,71 +220,71 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", config_fname, cell_idx,eMTCconfig->ccparams.prach_high_speed); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_zero_correlation = eMTCconfig->ccparams.prach_zero_correlation; - + if ((eMTCconfig->ccparams.prach_zero_correlation <0) || (eMTCconfig->ccparams.prach_zero_correlation > 15)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_zero_correlation choice: 0..15!\n", config_fname, cell_idx,eMTCconfig->ccparams.prach_zero_correlation); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_freq_offset = eMTCconfig->ccparams.prach_freq_offset; - + if ((eMTCconfig->ccparams.prach_freq_offset <0) || (eMTCconfig->ccparams.prach_freq_offset > 94)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n", config_fname, cell_idx,eMTCconfig->ccparams.prach_freq_offset); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_delta_shift = eMTCconfig->ccparams.pucch_delta_shift-1; - + if ((eMTCconfig->ccparams.pucch_delta_shift <1) || (eMTCconfig->ccparams.pucch_delta_shift > 3)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_delta_shift choice: 1..3!\n", config_fname, cell_idx,eMTCconfig->ccparams.pucch_delta_shift); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_nRB_CQI = eMTCconfig->ccparams.pucch_nRB_CQI; - + if ((eMTCconfig->ccparams.pucch_nRB_CQI <0) || (eMTCconfig->ccparams.pucch_nRB_CQI > 98)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nRB_CQI choice: 0..98!\n", config_fname, cell_idx,eMTCconfig->ccparams.pucch_nRB_CQI); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_nCS_AN = eMTCconfig->ccparams.pucch_nCS_AN; - + if ((eMTCconfig->ccparams.pucch_nCS_AN <0) || (eMTCconfig->ccparams.pucch_nCS_AN > 7)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n", config_fname, cell_idx,eMTCconfig->ccparams.pucch_nCS_AN); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_n1_AN = eMTCconfig->ccparams.pucch_n1_AN; - + if ((eMTCconfig->ccparams.pucch_n1_AN <0) || (eMTCconfig->ccparams.pucch_n1_AN > 2047)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n", config_fname, cell_idx,eMTCconfig->ccparams.pucch_n1_AN); - + //#endif RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pdsch_referenceSignalPower = eMTCconfig->ccparams.pdsch_referenceSignalPower; - + if ((eMTCconfig->ccparams.pdsch_referenceSignalPower <-60) || (eMTCconfig->ccparams.pdsch_referenceSignalPower > 50)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_referenceSignalPower choice:-60..50!\n", config_fname, cell_idx,eMTCconfig->ccparams.pdsch_referenceSignalPower); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pdsch_p_b = eMTCconfig->ccparams.pdsch_p_b; - + if ((eMTCconfig->ccparams.pdsch_p_b <0) || (eMTCconfig->ccparams.pdsch_p_b > 3)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pdsch_p_b choice: 0..3!\n", config_fname, cell_idx,eMTCconfig->ccparams.pdsch_p_b); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_n_SB = eMTCconfig->ccparams.pusch_n_SB; - + if ((eMTCconfig->ccparams.pusch_n_SB <1) || (eMTCconfig->ccparams.pusch_n_SB > 4)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_n_SB choice: 1..4!\n", config_fname, cell_idx,eMTCconfig->ccparams.pusch_n_SB); - + if (!eMTCconfig->ccparams.pusch_hoppingMode) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n", @@ -297,14 +297,14 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n", config_fname, cell_idx,eMTCconfig->ccparams.pusch_hoppingMode); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_hoppingOffset = eMTCconfig->ccparams.pusch_hoppingOffset; - + if ((eMTCconfig->ccparams.pusch_hoppingOffset<0) || (eMTCconfig->ccparams.pusch_hoppingOffset>98)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingOffset choice: 0..98!\n", config_fname, cell_idx,eMTCconfig->ccparams.pusch_hoppingMode); - + if (!eMTCconfig->ccparams.pusch_enable64QAM) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", @@ -317,7 +317,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", config_fname, cell_idx,eMTCconfig->ccparams.pusch_enable64QAM); - + if (!eMTCconfig->ccparams.pusch_groupHoppingEnabled) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", @@ -330,14 +330,14 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", config_fname, cell_idx,eMTCconfig->ccparams.pusch_groupHoppingEnabled); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_groupAssignment = eMTCconfig->ccparams.pusch_groupAssignment; - + if ((eMTCconfig->ccparams.pusch_groupAssignment<0)||(eMTCconfig->ccparams.pusch_groupAssignment>29)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_groupAssignment choice: 0..29!\n", config_fname, cell_idx,eMTCconfig->ccparams.pusch_groupAssignment); - + if (!eMTCconfig->ccparams.pusch_sequenceHoppingEnabled) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", @@ -350,14 +350,14 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", config_fname, cell_idx,eMTCconfig->ccparams.pusch_sequenceHoppingEnabled); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_nDMRS1= eMTCconfig->ccparams.pusch_nDMRS1; //cyclic_shift in RRC! - + if ((eMTCconfig->ccparams.pusch_nDMRS1 <0) || (eMTCconfig->ccparams.pusch_nDMRS1>7)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_nDMRS1 choice: 0..7!\n", config_fname, cell_idx,eMTCconfig->ccparams.pusch_nDMRS1); - + if (strcmp(eMTCconfig->ccparams.phich_duration,"NORMAL")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].phich_duration= LTE_PHICH_Config__phich_Duration_normal; } else if (strcmp(eMTCconfig->ccparams.phich_duration,"EXTENDED")==0) { @@ -366,7 +366,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n", config_fname, cell_idx,eMTCconfig->ccparams.phich_duration); - + if (strcmp(eMTCconfig->ccparams.phich_resource,"ONESIXTH")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].phich_resource= LTE_PHICH_Config__phich_Resource_oneSixth ; } else if (strcmp(eMTCconfig->ccparams.phich_resource,"HALF")==0) { @@ -379,11 +379,11 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n", config_fname, cell_idx,eMTCconfig->ccparams.phich_resource); - + printf("phich.resource eMTC %ld (%s), phich.duration eMTC %ld (%s)\n", RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].phich_resource,eMTCconfig->ccparams.phich_resource, RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].phich_duration,eMTCconfig->ccparams.phich_duration); - + if (strcmp(eMTCconfig->ccparams.srs_enable, "ENABLE") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable= TRUE; } else if (strcmp(eMTCconfig->ccparams.srs_enable, "DISABLE") == 0) { @@ -392,21 +392,21 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", config_fname, cell_idx,eMTCconfig->ccparams.srs_enable); - + if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable== TRUE) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_BandwidthConfig= eMTCconfig->ccparams.srs_BandwidthConfig; - + if ((eMTCconfig->ccparams.srs_BandwidthConfig < 0) || (eMTCconfig->ccparams.srs_BandwidthConfig >7)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value %d for srs_BandwidthConfig choice: 0...7\n", config_fname, cell_idx,eMTCconfig->ccparams.srs_BandwidthConfig); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_SubframeConfig= eMTCconfig->ccparams.srs_SubframeConfig; - + if ((eMTCconfig->ccparams.srs_SubframeConfig<0) || (eMTCconfig->ccparams.srs_SubframeConfig>15)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for srs_SubframeConfig choice: 0..15 !\n", config_fname, cell_idx,eMTCconfig->ccparams.srs_SubframeConfig); - + if (strcmp(eMTCconfig->ccparams.srs_ackNackST, "ENABLE") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_ackNackST= TRUE; } else if (strcmp(eMTCconfig->ccparams.srs_ackNackST, "DISABLE") == 0) { @@ -415,7 +415,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", config_fname, cell_idx,eMTCconfig->ccparams.srs_ackNackST); - + if (strcmp(eMTCconfig->ccparams.srs_MaxUpPts, "ENABLE") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_MaxUpPts= TRUE; } else if (strcmp(eMTCconfig->ccparams.srs_MaxUpPts, "DISABLE") == 0) { @@ -425,14 +425,14 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", config_fname, cell_idx,eMTCconfig->ccparams.srs_MaxUpPts); } - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_p0_Nominal= eMTCconfig->ccparams.pusch_p0_Nominal; - + if ((eMTCconfig->ccparams.pusch_p0_Nominal<-126) || (eMTCconfig->ccparams.pusch_p0_Nominal>24)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n", config_fname, cell_idx,eMTCconfig->ccparams.pusch_p0_Nominal); - + if (strcmp(eMTCconfig->ccparams.pusch_alpha,"AL0")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_alpha= LTE_Alpha_r12_al0; } else if (strcmp(eMTCconfig->ccparams.pusch_alpha,"AL04")==0) { @@ -450,26 +450,26 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in } else if (strcmp(eMTCconfig->ccparams.pusch_alpha,"AL1")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_alpha= LTE_Alpha_r12_al1; } - + else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_Alpha choice: AL0,AL04,AL05,AL06,AL07,AL08,AL09,AL1!\n", config_fname, cell_idx,eMTCconfig->ccparams.pusch_alpha); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_p0_Nominal= eMTCconfig->ccparams.pucch_p0_Nominal; - + if ((eMTCconfig->ccparams.pucch_p0_Nominal<-127) || (eMTCconfig->ccparams.pucch_p0_Nominal>-96)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_p0_Nominal choice: -127..-96 !\n", config_fname, cell_idx,eMTCconfig->ccparams.pucch_p0_Nominal); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].msg3_delta_Preamble= eMTCconfig->ccparams.msg3_delta_Preamble; - + if ((eMTCconfig->ccparams.msg3_delta_Preamble<-1) || (eMTCconfig->ccparams.msg3_delta_Preamble>6)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for msg3_delta_Preamble choice: -1..6 !\n", config_fname, cell_idx,eMTCconfig->ccparams.msg3_delta_Preamble); - + if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format1,"deltaF_2")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_deltaF_Format1= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2; } else if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format1,"deltaF0")==0) { @@ -480,7 +480,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n", config_fname, cell_idx,eMTCconfig->ccparams.pucch_deltaF_Format1); - + if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format1b,"deltaF1")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_deltaF_Format1b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1; } else if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format1b,"deltaF3")==0) { @@ -491,7 +491,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n", config_fname, cell_idx,eMTCconfig->ccparams.pucch_deltaF_Format1b); - + if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2,"deltaF_2")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_deltaF_Format2= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2; } else if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2,"deltaF0")==0) { @@ -504,7 +504,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n", config_fname, cell_idx,eMTCconfig->ccparams.pucch_deltaF_Format2); - + if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2a,"deltaF_2")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_deltaF_Format2a= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2; } else if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2a,"deltaF0")==0) { @@ -515,7 +515,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n", config_fname, cell_idx,eMTCconfig->ccparams.pucch_deltaF_Format2a); - + if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2b,"deltaF_2")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pucch_deltaF_Format2b= LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2; } else if (strcmp(eMTCconfig->ccparams.pucch_deltaF_Format2b,"deltaF0")==0) { @@ -526,47 +526,47 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n", config_fname, cell_idx,eMTCconfig->ccparams.pucch_deltaF_Format2b); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_numberOfRA_Preambles= (eMTCconfig->ccparams.rach_numberOfRA_Preambles/4)-1; - + if ((eMTCconfig->ccparams.rach_numberOfRA_Preambles <4) || (eMTCconfig->ccparams.rach_numberOfRA_Preambles >64) || ((eMTCconfig->ccparams.rach_numberOfRA_Preambles&3)!=0)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_numberOfRA_Preambles choice: 4,8,12,...,64!\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_numberOfRA_Preambles); - + if (strcmp(eMTCconfig->ccparams.rach_preamblesGroupAConfig, "ENABLE") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preamblesGroupAConfig= TRUE; RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_sizeOfRA_PreamblesGroupA= (eMTCconfig->ccparams.rach_sizeOfRA_PreamblesGroupA/4)-1; - + if ((eMTCconfig->ccparams.rach_numberOfRA_Preambles <4) || (eMTCconfig->ccparams.rach_numberOfRA_Preambles>60) || ((eMTCconfig->ccparams.rach_numberOfRA_Preambles&3)!=0)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_sizeOfRA_PreamblesGroupA choice: 4,8,12,...,60!\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_sizeOfRA_PreamblesGroupA); - + switch (eMTCconfig->ccparams.rach_messageSizeGroupA) { case 56: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b56; break; - + case 144: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b144; break; - + case 208: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b208; break; - + case 256: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_messageSizeGroupA= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b256; break; - + default: AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_messageSizeGroupA choice: 56,144,208,256!\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_messageSizeGroupA); break; } - + if (strcmp(eMTCconfig->ccparams.rach_messagePowerOffsetGroupB,"minusinfinity")==0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_messagePowerOffsetGroupB= LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity; } else if (strcmp(eMTCconfig->ccparams.rach_messagePowerOffsetGroupB,"dB0")==0) { @@ -593,118 +593,118 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_preamblesGroupAConfig); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleInitialReceivedTargetPower= (eMTCconfig->ccparams.rach_preambleInitialReceivedTargetPower+120)/2; - + if ((eMTCconfig->ccparams.rach_preambleInitialReceivedTargetPower<-120) || (eMTCconfig->ccparams.rach_preambleInitialReceivedTargetPower>-90) || ((eMTCconfig->ccparams.rach_preambleInitialReceivedTargetPower&1)!=0)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleInitialReceivedTargetPower choice: -120,-118,...,-90 !\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_preambleInitialReceivedTargetPower); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_powerRampingStep= eMTCconfig->ccparams.rach_powerRampingStep/2; - + if ((eMTCconfig->ccparams.rach_powerRampingStep<0) || (eMTCconfig->ccparams.rach_powerRampingStep>6) || ((eMTCconfig->ccparams.rach_powerRampingStep&1)!=0)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_powerRampingStep choice: 0,2,4,6 !\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_powerRampingStep); - + switch (eMTCconfig->ccparams.rach_preambleTransMax) { case 3: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n3; break; - + case 4: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n4; break; - + case 5: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n5; break; - + case 6: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n6; break; - + case 7: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n7; break; - + case 8: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n8; break; - + case 10: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n10; break; - + case 20: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n20; break; - + case 50: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n50; break; - + case 100: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n100; break; - + case 200: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preambleTransMax= LTE_PreambleTransMax_n200; break; - + default: AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleTransMax choice: 3,4,5,6,7,8,10,20,50,100,200!\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_preambleTransMax); break; } - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_raResponseWindowSize= (eMTCconfig->ccparams.rach_raResponseWindowSize==10)?7:eMTCconfig->ccparams.rach_raResponseWindowSize-2; - + if ((eMTCconfig->ccparams.rach_raResponseWindowSize<0)||(eMTCconfig->ccparams.rach_raResponseWindowSize==9)||(eMTCconfig->ccparams.rach_raResponseWindowSize>10)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_raResponseWindowSize choice: 2,3,4,5,6,7,8,10!\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_raResponseWindowSize); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_macContentionResolutionTimer= (eMTCconfig->ccparams.rach_macContentionResolutionTimer/8)-1; - + if ((eMTCconfig->ccparams.rach_macContentionResolutionTimer<8) || (eMTCconfig->ccparams.rach_macContentionResolutionTimer>64) || ((eMTCconfig->ccparams.rach_macContentionResolutionTimer&7)!=0)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_macContentionResolutionTimer choice: 8,16,...,56,64!\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_macContentionResolutionTimer); - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_maxHARQ_Msg3Tx= eMTCconfig->ccparams.rach_maxHARQ_Msg3Tx; - + if ((eMTCconfig->ccparams.rach_maxHARQ_Msg3Tx<0) || (eMTCconfig->ccparams.rach_maxHARQ_Msg3Tx>8)) AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_maxHARQ_Msg3Tx); - + switch (eMTCconfig->ccparams.pcch_defaultPagingCycle) { case 32: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf32; break; - + case 64: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf64; break; - + case 128: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf128; break; - + case 256: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf256; break; - + default: AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_defaultPagingCycle choice: 32,64,128,256!\n", config_fname, cell_idx,eMTCconfig->ccparams.pcch_defaultPagingCycle); break; } - + if (strcmp(eMTCconfig->ccparams.pcch_nB, "fourT") == 0) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_nB= LTE_PCCH_Config__nB_fourT; } else if (strcmp(eMTCconfig->ccparams.pcch_nB, "twoT") == 0) { @@ -725,86 +725,86 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n", config_fname, cell_idx,eMTCconfig->ccparams.pcch_nB); - + switch (eMTCconfig->ccparams.bcch_modificationPeriodCoeff) { case 2: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n2; break; - + case 4: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n4; break; - + case 8: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n8; break; - + case 16: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].bcch_modificationPeriodCoeff= LTE_BCCH_Config__modificationPeriodCoeff_n16; break; - + default: AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for bcch_modificationPeriodCoeff choice: 2,4,8,16", config_fname, cell_idx,eMTCconfig->ccparams.bcch_modificationPeriodCoeff); break; } - + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_t300= eMTCconfig->ccparams.ue_TimersAndConstants_t300; RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_t301= eMTCconfig->ccparams.ue_TimersAndConstants_t301; RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_t310= eMTCconfig->ccparams.ue_TimersAndConstants_t310; RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_t311= eMTCconfig->ccparams.ue_TimersAndConstants_t311; RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_n310= eMTCconfig->ccparams.ue_TimersAndConstants_n310; RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TimersAndConstants_n311= eMTCconfig->ccparams.ue_TimersAndConstants_n311; - + switch (eMTCconfig->ccparams.ue_TransmissionMode) { case 1: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm1; break; - + case 2: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm2; break; - + case 3: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm3; break; - + case 4: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm4; break; - + case 5: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm5; break; - + case 6: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm6; break; - + case 7: RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].ue_TransmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm7; break; - + default: AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TransmissionMode choice: 1,2,3,4,5,6,7", config_fname, cell_idx, eMTCconfig->ccparams.ue_TransmissionMode); break; } - - + + if (!strcmp(eMTCconfig->prach_ConfigCommon_v1310, "ENABLE")) { RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = TRUE; - + RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = calloc(1, sizeof(BOOLEAN_t)); - + if (!strcmp(eMTCconfig->mpdcch_startSF_CSS_RA_r13, "tdd-r13")) { *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = FALSE; } else { *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = TRUE; } - + if (!strcmp(eMTCconfig->mpdcch_startSF_CSS_RA_r13_val, "v1")) { RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13_val = 0; } else if (!strcmp(eMTCconfig->mpdcch_startSF_CSS_RA_r13_val, "v1dot5")) { @@ -832,8 +832,8 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in } else { RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = FALSE; } - - + + RRC_CONFIGURATION_REQ(msg_p).pdsch_maxNumRepetitionCEmodeA_r13[cc_idx] = CALLOC(1, sizeof(long)); if (!strcmp(eMTCconfig->pdsch_maxNumRepetitionCEmodeA_r13, "r16")) { *RRC_CONFIGURATION_REQ(msg_p).pdsch_maxNumRepetitionCEmodeA_r13[cc_idx] = 0; @@ -844,8 +844,8 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, pdsch_maxNumRepetitionCEmodeA_r13 unknown value!\n", config_fname); } - - + + RRC_CONFIGURATION_REQ(msg_p).pusch_maxNumRepetitionCEmodeA_r13[cc_idx] = CALLOC(1, sizeof(long)); if (!strcmp(eMTCconfig->pusch_maxNumRepetitionCEmodeA_r13, "r8")) { *RRC_CONFIGURATION_REQ(msg_p).pusch_maxNumRepetitionCEmodeA_r13[cc_idx] = 0; @@ -858,7 +858,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, pusch_maxNumRepetitionCEmodeA_r13 unknown value!\n", config_fname); } - + char rachCELevelInfoListPath[MAX_OPTNAME_SIZE * 2]; config_getlist(&rachcelevellist, NULL, 0, brparamspath); RRC_CONFIGURATION_REQ (msg_p).rach_CE_LevelInfoList_r13_size[cc_idx] = rachcelevellist.numelt; @@ -866,7 +866,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in for (rachCEInfoIndex = 0; rachCEInfoIndex < rachcelevellist.numelt; rachCEInfoIndex++) { sprintf(rachCELevelInfoListPath, "%s.%s.[%i]", brparamspath, ENB_CONFIG_STRING_RACH_CE_LEVELINFOLIST_R13, rachCEInfoIndex); config_get(rachcelevelParams, sizeof(rachcelevelParams) / sizeof(paramdef_t), rachCELevelInfoListPath); - + RRC_CONFIGURATION_REQ (msg_p).firstPreamble_r13[cc_idx][rachCEInfoIndex] = eMTCconfig->firstPreamble_r13; RRC_CONFIGURATION_REQ (msg_p).lastPreamble_r13[cc_idx][rachCEInfoIndex] = eMTCconfig->lastPreamble_r13; @@ -899,7 +899,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal(1==0, "Illegal ra_ResponseWindowSize_r13 %d\n",eMTCconfig->ra_ResponseWindowSize_r13); } - + switch(eMTCconfig->mac_ContentionResolutionTimer_r13) { case 80: @@ -932,36 +932,37 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in break; } RRC_CONFIGURATION_REQ (msg_p).rar_HoppingConfig_r13[cc_idx][rachCEInfoIndex] = eMTCconfig->rar_HoppingConfig_r13; + AssertFatal(eMTCconfig->rar_HoppingConfig_r13 == 0 || eMTCconfig->rar_HoppingConfig_r13 == 1, - "illegal rar_HoppingConfig_r13 %d\n",eMTCconfig->rar_HoppingConfig_r13); + "illegal rar_HoppingConfig_r13 %d\n",eMTCconfig->rar_HoppingConfig_r13); } // end for loop (rach ce level info) - + char rsrpRangeListPath[MAX_OPTNAME_SIZE * 2]; config_getlist(&rsrprangelist, NULL, 0, brparamspath); RRC_CONFIGURATION_REQ (msg_p).rsrp_range_list_size[cc_idx] = rsrprangelist.numelt; - - + + int rsrprangeindex; for (rsrprangeindex = 0; rsrprangeindex < rsrprangelist.numelt; rsrprangeindex++) { sprintf(rsrpRangeListPath, "%s.%s.[%i]", brparamspath, ENB_CONFIG_STRING_RSRP_RANGE_LIST, rsrprangeindex); config_get(rsrprangeParams, sizeof(rsrprangeParams) / sizeof(paramdef_t), rsrpRangeListPath); RRC_CONFIGURATION_REQ (msg_p).rsrp_range[cc_idx][rsrprangeindex] = eMTCconfig->rsrp_range_br; - + } - - + + char prachparameterscePath[MAX_OPTNAME_SIZE * 2]; config_getlist(&prachParamslist, NULL, 0, brparamspath); RRC_CONFIGURATION_REQ (msg_p).prach_parameters_list_size[cc_idx] = prachParamslist.numelt; - + int prachparamsindex; for (prachparamsindex = 0; prachparamsindex < prachParamslist.numelt; prachparamsindex++) { sprintf(prachparameterscePath, "%s.%s.[%i]", brparamspath, ENB_CONFIG_STRING_PRACH_PARAMETERS_CE_R13, prachparamsindex); config_get(prachParams, sizeof(prachParams) / sizeof(paramdef_t), prachparameterscePath); - + RRC_CONFIGURATION_REQ (msg_p).prach_config_index[cc_idx][prachparamsindex] = eMTCconfig->prach_config_index_br; RRC_CONFIGURATION_REQ (msg_p).prach_freq_offset[cc_idx][prachparamsindex] = eMTCconfig->prach_freq_offset_br; - + RRC_CONFIGURATION_REQ (msg_p).prach_StartingSubframe_r13[cc_idx][prachparamsindex] = calloc(1, sizeof(long)); switch(eMTCconfig->prach_StartingSubframe_r13) { case 2: @@ -1000,9 +1001,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in AssertFatal(eMTCconfig->maxNumPreambleAttemptCE_r13 > 2 && eMTCconfig->maxNumPreambleAttemptCE_r13 <11, "prachparamsindex %d: Illegal maxNumPreambleAttemptCE_r13 %d\n", prachparamsindex,eMTCconfig->maxNumPreambleAttemptCE_r13); - - switch(eMTCconfig->numRepetitionPerPreambleAttempt_r13) { + + switch(eMTCconfig->numRepetitionPerPreambleAttempt_r13) { case 1: RRC_CONFIGURATION_REQ (msg_p).numRepetitionPerPreambleAttempt_r13[cc_idx][prachparamsindex] = LTE_PRACH_ParametersCE_r13__numRepetitionPerPreambleAttempt_r13_n1; break; @@ -1067,15 +1068,15 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in eMTCconfig->mpdcch_NumRepetition_RA_r13); break; } - + RRC_CONFIGURATION_REQ (msg_p).prach_HoppingConfig_r13[cc_idx][prachparamsindex] = eMTCconfig->prach_HoppingConfig_r13; - + AssertFatal (eMTCconfig->prach_HoppingConfig_r13 >=0 && eMTCconfig->prach_HoppingConfig_r13 < 2, "Illegal prach_HoppingConfig_r13 %d\n",eMTCconfig->prach_HoppingConfig_r13); - - + + int maxavailablenarrowband_count = prachParams[7].numelt; - + RRC_CONFIGURATION_REQ (msg_p).max_available_narrow_band_size[cc_idx][prachparamsindex] = maxavailablenarrowband_count; int narrow_band_index; for (narrow_band_index = 0; narrow_band_index < maxavailablenarrowband_count; narrow_band_index++) { @@ -1086,26 +1087,27 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in char n1PUCCHInfoParamsPath[MAX_OPTNAME_SIZE * 2]; config_getlist(&n1PUCCHInfoList, NULL, 0, brparamspath); RRC_CONFIGURATION_REQ (msg_p).pucch_info_value_size[cc_idx] = n1PUCCHInfoList.numelt; - + int n1PUCCHinfolistindex; for (n1PUCCHinfolistindex = 0; n1PUCCHinfolistindex < n1PUCCHInfoList.numelt; n1PUCCHinfolistindex++) { sprintf(n1PUCCHInfoParamsPath, "%s.%s.[%i]", brparamspath, ENB_CONFIG_STRING_N1PUCCH_AN_INFOLIST_R13, n1PUCCHinfolistindex); config_get(n1PUCCH_ANR13Params, sizeof(n1PUCCH_ANR13Params) / sizeof(paramdef_t), n1PUCCHInfoParamsPath); RRC_CONFIGURATION_REQ (msg_p).pucch_info_value[cc_idx][n1PUCCHinfolistindex] = eMTCconfig->pucch_info_value; } - + char PCCHConfigv1310Path[MAX_OPTNAME_SIZE*2 + 16]; sprintf(PCCHConfigv1310Path, "%s.%s", brparamspath, ENB_CONFIG_STRING_PCCH_CONFIG_V1310); config_get(pcchv1310Params, sizeof(pcchv1310Params)/sizeof(paramdef_t), PCCHConfigv1310Path); - - - + + + /** PCCH CONFIG V1310 */ - RRC_CONFIGURATION_REQ(msg_p).pcch_config_v1310[cc_idx] = TRUE; RRC_CONFIGURATION_REQ(msg_p).paging_narrowbands_r13[cc_idx] = eMTCconfig->paging_narrowbands_r13; RRC_CONFIGURATION_REQ(msg_p).mpdcch_numrepetition_paging_r13[cc_idx] = eMTCconfig->mpdcch_numrepetition_paging_r13; - AssertFatal (eMTCconfig->mpdcch_numrepetition_paging_r13 == 1 || + + AssertFatal (eMTCconfig->mpdcch_numrepetition_paging_r13 == 0 || + eMTCconfig->mpdcch_numrepetition_paging_r13 == 1 || eMTCconfig->mpdcch_numrepetition_paging_r13 == 2 || eMTCconfig->mpdcch_numrepetition_paging_r13 == 4 || eMTCconfig->mpdcch_numrepetition_paging_r13 == 8 || @@ -1116,8 +1118,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in eMTCconfig->mpdcch_numrepetition_paging_r13 == 256, "illegal mpdcch_numrepetition_paging_r13 %d\n", eMTCconfig->mpdcch_numrepetition_paging_r13); - - + // RRC_CONFIGURATION_REQ(msg_p).nb_v1310[cc_idx] = CALLOC(1, sizeof(long)); // if (!strcmp(nb_v1310, "one64thT")) { // *RRC_CONFIGURATION_REQ(msg_p).nb_v1310[cc_idx] = 0; @@ -1130,9 +1131,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in // "Failed to parse eNB configuration file %s, nb_v1310, unknown value !\n", // config_fname); // } - - - + + + RRC_CONFIGURATION_REQ (msg_p).pucch_NumRepetitionCE_Msg4_Level0_r13[cc_idx] = CALLOC(1, sizeof(long)); // ++cnt; // check this ,, the conter is up above if (!strcmp(eMTCconfig->pucch_NumRepetitionCE_Msg4_Level0_r13, "n1")) { @@ -1148,21 +1149,21 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, pucch_NumRepetitionCE_Msg4_Level0_r13 unknown value!\n", config_fname); } - - - + + + /** SIB2 FREQ HOPPING PARAMETERS R13 */ RRC_CONFIGURATION_REQ(msg_p).sib2_freq_hoppingParameters_r13_exists[cc_idx] = TRUE; - + char sib2FreqHoppingParametersR13Path[MAX_OPTNAME_SIZE*2 + 16]; sprintf(sib2FreqHoppingParametersR13Path, "%s.%s", brparamspath, ENB_CONFIG_STRING_SIB2_FREQ_HOPPINGPARAMETERS_R13); config_get(sib2freqhoppingParams, sizeof(sib2freqhoppingParams)/sizeof(paramdef_t), sib2FreqHoppingParametersR13Path); - - + + RRC_CONFIGURATION_REQ(msg_p).sib2_interval_ULHoppingConfigCommonModeA_r13[cc_idx] = CALLOC(1, sizeof(long)); if (!strcmp(eMTCconfig->sib2_interval_ULHoppingConfigCommonModeA_r13, "FDD")) { *RRC_CONFIGURATION_REQ(msg_p).sib2_interval_ULHoppingConfigCommonModeA_r13[cc_idx] = 0; - + switch(eMTCconfig->sib2_interval_ULHoppingConfigCommonModeA_r13_val) { case 1: RRC_CONFIGURATION_REQ(msg_p).sib2_interval_ULHoppingConfigCommonModeA_r13_val[cc_idx] = 0; @@ -1207,4 +1208,4 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, sib2_interval_ULHoppingConfigCommonModeA_r13 unknown value !!\n", config_fname); } -} +} diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 9f495da07472eea6deaa113c640f92a32634e55b..a7dfaef1a93e1b723c893c1093371b9b1c613efd 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -101,6 +101,8 @@ typedef enum { #define CONFIG_STRING_RU_NBIOTRRC_LIST "NbIoT_RRC_instances" #define CONFIG_STRING_RU_SDR_ADDRS "sdr_addrs" #define CONFIG_STRING_RU_SDR_CLK_SRC "clock_src" +#define CONFIG_STRING_RU_SF_EXTENSION "sf_extension" +#define CONFIG_STRING_RU_END_OF_BURST_DELAY "end_of_burst_delay" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -122,6 +124,8 @@ typedef enum { #define RU_NBIOTRRC_LIST_IDX 17 #define RU_SDR_ADDRS 18 #define RU_SDR_CLK_SRC 19 +#define RU_SF_EXTENSION_IDX 20 +#define RU_END_OF_BURST_DELAY_IDX 21 @@ -149,7 +153,9 @@ typedef enum { {CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_SDR_ADDRS, NULL, 0, strptr:NULL, defstrval:"type=b200", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \ +{CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \ +{CONFIG_STRING_RU_SF_EXTENSION, NULL, 0, uptr:NULL, defuintval:312, TYPE_UINT, 0}, \ +{CONFIG_STRING_RU_END_OF_BURST_DELAY, NULL, 0, uptr:NULL, defuintval:400, TYPE_UINT, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ @@ -197,7 +203,7 @@ typedef enum { #define ENB_CONFIG_STRING_REMOTE_S_PORTC "remote_s_portc" #define ENB_CONFIG_STRING_LOCAL_S_PORTD "local_s_portd" #define ENB_CONFIG_STRING_REMOTE_S_PORTD "remote_s_portd" - +#define ENB_CONFIG_STRING_NR_CELLID "nr_cellid" /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* cell configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -217,6 +223,7 @@ typedef enum { {ENB_CONFIG_STRING_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_NR_CELLID, NULL, 0, u64ptr:NULL, defint64val:0, TYPE_UINT64, 0}, \ } #define ENB_ENB_ID_IDX 0 #define ENB_CELL_TYPE_IDX 1 @@ -232,6 +239,7 @@ typedef enum { #define ENB_REMOTE_S_PORTC_IDX 11 #define ENB_LOCAL_S_PORTD_IDX 12 #define ENB_REMOTE_S_PORTD_IDX 13 +#define ENB_NRCELLID_IDX 14 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define ENBPARAMS_CHECK { \ @@ -308,13 +316,12 @@ typedef enum { #define ENB_CONFIG_STRING_NB_V1310 "nb_v1310" -#define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL0 "pucch_NumRepetitionCE_Msg4_Level0_r13" +#define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL0 "pucch_NumRepetitionCE_Msg4_Level0_r13" #define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL1 "pucch_NumRepetitionCE_Msg4_Level1_r13" #define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL2 "pucch_NumRepetitionCE_Msg4_Level2_r13" #define ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL3 "pucch_NumRepetitionCE_Msg4_Level3_r13" -#define ENB_CONFIG_STRING_FREQ_HOPPING_PARAMETERS_R13 "sib2_freq_hoppingParameters_r13" - +#define ENB_CONFIG_STRING_FREQ_HOPPING_PARAMETERS_R13 "sib2_freq_hoppingParameters_r13" #define ENB_CONFIG_STRING_PDSCH_RS_EPRE "pdsch_referenceSignalPower" #define ENB_CONFIG_STRING_PDSCH_PB "pdsch_p_b" @@ -356,6 +363,14 @@ typedef enum { #define ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX "rach_maxHARQ_Msg3Tx" #define ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE "pcch_default_PagingCycle" #define ENB_CONFIG_STRING_PCCH_NB "pcch_nB" +#define ENB_CONFIG_STRING_DRX_CONFIG_PRESENT "drx_Config_present" +#define ENB_CONFIG_STRING_DRX_ONDURATIONTIMER "drx_onDurationTimer" +#define ENB_CONFIG_STRING_DRX_INACTIVITYTIMER "drx_InactivityTimer" +#define ENB_CONFIG_STRING_DRX_RETRANSMISSIONTIMER "drx_RetransmissionTimer" +#define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_PRESENT "drx_longDrx_CycleStartOffset_present" +#define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET "drx_longDrx_CycleStartOffset" +#define ENB_CONFIG_STRING_DRX_SHORTDRX_CYCLE "drx_shortDrx_Cycle" +#define ENB_CONFIG_STRING_DRX_SHORTDRX_SHORTCYCLETIMER "drx_shortDrx_ShortCycleTimer" #define ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF "bcch_modificationPeriodCoeff" #define ENB_CONFIG_STRING_UETIMERS_T300 "ue_TimersAndConstants_t300" #define ENB_CONFIG_STRING_UETIMERS_T301 "ue_TimersAndConstants_t301" @@ -377,7 +392,7 @@ typedef enum { #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13" #define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310" - + //TTN - for D2D //SIB18 #define ENB_CONFIG_STRING_RXPOOL_SC_CP_LEN "rxPool_sc_CP_Len" @@ -491,6 +506,14 @@ typedef struct ccparams_lte_s { int32_t rach_maxHARQ_Msg3Tx; int32_t pcch_defaultPagingCycle; char *pcch_nB; + char *drx_Config_present; + char *drx_onDurationTimer; + char *drx_InactivityTimer; + char *drx_RetransmissionTimer; + char *drx_longDrx_CycleStartOffset_present; + int32_t drx_longDrx_CycleStartOffset; + char *drx_shortDrx_Cycle; + int32_t drx_shortDrx_ShortCycleTimer; int32_t bcch_modificationPeriodCoeff; int32_t ue_TimersAndConstants_t300; int32_t ue_TimersAndConstants_t301; @@ -570,6 +593,14 @@ typedef struct ccparams_lte_s { { .s5= {NULL }} , \ { .s5= {NULL }} , \ { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ { .s5= {NULL }} , \ { .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} , \ { .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} , \ @@ -685,6 +716,14 @@ typedef struct ccparams_lte_s { {ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX, NULL, 0, iptr:&ccparams.rach_maxHARQ_Msg3Tx, defintval:4, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE, NULL, 0, iptr:&ccparams.pcch_defaultPagingCycle, defintval:128, TYPE_INT, 0}, \ {ENB_CONFIG_STRING_PCCH_NB, NULL, 0, strptr:&ccparams.pcch_nB, defstrval:"oneT", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_CONFIG_PRESENT, NULL, 0, strptr:&ccparams.drx_Config_present, defstrval:"prNothing", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_ONDURATIONTIMER, NULL, 0, strptr:&ccparams.drx_onDurationTimer, defstrval:"psf10", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_INACTIVITYTIMER, NULL, 0, strptr:&ccparams.drx_InactivityTimer, defstrval:"psf10", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_RETRANSMISSIONTIMER, NULL, 0, strptr:&ccparams.drx_RetransmissionTimer, defstrval:"psf8", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_PRESENT, NULL, 0, strptr:&ccparams.drx_longDrx_CycleStartOffset_present, defstrval:"prSf128", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET, NULL, 0, iptr:&ccparams.drx_longDrx_CycleStartOffset, defintval:0, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DRX_SHORTDRX_CYCLE, NULL, 0, strptr:&ccparams.drx_shortDrx_Cycle, defstrval:"sf32", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DRX_SHORTDRX_SHORTCYCLETIMER, NULL, 0, iptr:&ccparams.drx_shortDrx_ShortCycleTimer, defintval:3, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF, NULL, 0, iptr:&ccparams.bcch_modificationPeriodCoeff, defintval:2, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UETIMERS_T300, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t300, defintval:1000, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UETIMERS_T301, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_t301, defintval:1000, TYPE_UINT, 0}, \ @@ -759,15 +798,23 @@ typedef struct ccparams_lte_s { #define ENB_CONFIG_RACH_MAXHARQMSG3TX_IDX 57 #define ENB_CONFIG_PCCH_DEFAULT_PAGING_CYCLE_IDX 58 #define ENB_CONFIG_PCCH_NB_IDX 59 -#define ENB_CONFIG_BCCH_MODIFICATIONPERIODCOEFF_IDX 60 -#define ENB_CONFIG_UETIMERS_T300_IDX 61 -#define ENB_CONFIG_UETIMERS_T301_IDX 62 -#define ENB_CONFIG_UETIMERS_T310_IDX 63 -#define ENB_CONFIG_UETIMERS_T311_IDX 64 -#define ENB_CONFIG_UETIMERS_N310_IDX 65 -#define ENB_CONFIG_UETIMERS_N311_IDX 66 -#define ENB_CONFIG_UE_TRANSMISSION_MODE_IDX 67 -#define ENB_CONFIG_MBMS_DEDICATED_SERVING_CELL_IDX 68 +#define ENB_CONFIG_STRING_DRX_CONFIG_PRESENT_IDX 60 +#define ENB_CONFIG_STRING_DRX_ONDURATIONTIMER_IDX 61 +#define ENB_CONFIG_STRING_DRX_INACTIVITYTIMER_IDX 62 +#define ENB_CONFIG_STRING_DRX_RETRANSMISSIONTIMER_IDX 63 +#define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_PRESENT_IDX 64 +#define ENB_CONFIG_STRING_DRX_LONGDRX_CYCLESTARTOFFSET_IDX 65 +#define ENB_CONFIG_STRING_DRX_SHORTDRX_CYCLE_IDX 66 +#define ENB_CONFIG_STRING_DRX_SHORTDRX_SHORTCYCLETIMER_IDX 67 +#define ENB_CONFIG_BCCH_MODIFICATIONPERIODCOEFF_IDX 68 +#define ENB_CONFIG_UETIMERS_T300_IDX 69 +#define ENB_CONFIG_UETIMERS_T301_IDX 70 +#define ENB_CONFIG_UETIMERS_T310_IDX 71 +#define ENB_CONFIG_UETIMERS_T311_IDX 72 +#define ENB_CONFIG_UETIMERS_N310_IDX 73 +#define ENB_CONFIG_UETIMERS_N311_IDX 74 +#define ENB_CONFIG_UE_TRANSMISSION_MODE_IDX 75 +#define ENB_CONFIG_MBMS_DEDICATED_SERVING_CELL_IDX 76 /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* SRB1 configuration parameters section name */ @@ -964,6 +1011,58 @@ typedef struct srb1_params_s { {CONFIG_STRING_FLEXRAN_AWAIT_RECONF, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0} \ } +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* CU/DU configuration section names*/ +#define CONFIG_STRING_DU_LIST "DU" +#define CONFIG_STRING_CU_LIST "CU" +#define DU_TYPE_LTE 0 +#define DU_TYPE_WIFI 1 +#define ENB_CONFIG_STRING_CU_INTERFACES_CONFIG "CU_INTERFACES" +#define ENB_CONFIG_STRING_CU_INTERFACE_NAME_FOR_F1U "CU_INTERFACE_NAME_FOR_F1U" +#define ENB_CONFIG_STRING_CU_IPV4_ADDRESS_FOR_F1U "CU_IPV4_ADDRESS_FOR_F1U" +#define ENB_CONFIG_STRING_CU_PORT_FOR_F1U "CU_PORT_FOR_F1U" +#define ENB_CONFIG_STRING_DU_TYPE "DU_TYPE" +#define ENB_CONFIG_STRING_F1_U_CU_TRANSPORT_TYPE "F1_U_CU_TRANSPORT_TYPE" + +#define ENB_CONFIG_STRING_DU_INTERFACES_CONFIG "DU_INTERFACES" +#define ENB_CONFIG_STRING_DU_INTERFACE_NAME_FOR_F1U "DU_INTERFACE_NAME_FOR_F1U" +#define ENB_CONFIG_STRING_DU_IPV4_ADDRESS_FOR_F1U "DU_IPV4_ADDRESS_FOR_F1U" +#define ENB_CONFIG_STRING_DU_PORT_FOR_F1U "DU_PORT_FOR_F1U" +#define ENB_CONFIG_STRING_F1_U_DU_TRANSPORT_TYPE "F1_U_DU_TRANSPORT_TYPE" + +#define CONFIG_STRING_CU_BALANCING "CU_BALANCING" + +#define CUPARAMS_DESC { \ +{ENB_CONFIG_STRING_CU_INTERFACE_NAME_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"eth0", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_CU_IPV4_ADDRESS_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_CU_PORT_FOR_F1U, NULL, 0, uptr:NULL, defintval:2210, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_F1_U_CU_TRANSPORT_TYPE, NULL, 0, strptr:NULL, defstrval:"TCP", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DU_TYPE, NULL, 0, strptr:NULL, defstrval:"LTE", TYPE_STRING, 0}, \ +} + +#define DUPARAMS_DESC { \ +{ENB_CONFIG_STRING_DU_INTERFACE_NAME_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"eth0", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DU_IPV4_ADDRESS_FOR_F1U, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_DU_PORT_FOR_F1U, NULL, 0, uptr:NULL, defintval:2210, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_F1_U_DU_TRANSPORT_TYPE, NULL, 0, strptr:NULL, defstrval:"TCP", TYPE_STRING, 0}, \ +} + +#define CU_BAL_DESC { \ +{CONFIG_STRING_CU_BALANCING, NULL, 0, strptr:NULL, defstrval:"ALL", TYPE_STRING, 0}, \ +} + +#define CU_INTERFACE_F1U 0 +#define CU_ADDRESS_F1U 1 +#define CU_PORT_F1U 2 +#define CU_TYPE_F1U 3 + +#define DU_INTERFACE_F1U 0 +#define DU_ADDRESS_F1U 1 +#define DU_PORT_F1U 2 +#define DU_TYPE_F1U 3 +#define DU_TECH 4 + /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* MACRLC configuration section names */ diff --git a/openair2/ENB_APP/enb_paramdef_emtc.h b/openair2/ENB_APP/enb_paramdef_emtc.h index ba8483ef9f0fd6bb1d100098dd17bd356f802021..25ab43ccf6130cdfaa0888978195ed6a7befa170 100644 --- a/openair2/ENB_APP/enb_paramdef_emtc.h +++ b/openair2/ENB_APP/enb_paramdef_emtc.h @@ -61,13 +61,16 @@ #define ENB_CONFIG_STRING_PREAMBLE_TRANSMAX_CE_R13 "preamble_TransMax_ce_r13" #define ENB_CONFIG_STRING_PREAMBLE_TRANSMAX_CE_R13_VAL "preamble_TransMax_ce_r13_val" #define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pdsch_maxNumRepetitionCEmodeA_r13" +#define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pdsch_maxNumRepetitionCEmodeB_r13" #define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pusch_maxNumRepetitionCEmodeA_r13" +#define ENB_CONFIG_STRING_PUSCH_MAX_NUM_REPETITION_CE_MODE_B_R13 "pusch_maxNumRepetitionCEmodeB_r13" +#define ENB_CONFIG_STRING_PUSCH_HOPPING_OFFSET_V1310 "pusch_HoppingOffset_v1310" #define ENB_CONFIG_STRING_SYSTEM_INFO_VALUE_TAG_LIST "system_info_value_tag_SI" #define ENB_CONFIG_STRING_FIRST_PREAMBLE_R13 "firstPreamble_r13" #define ENB_CONFIG_STRING_LAST_PREAMBLE_R13 "lastPreamble_r13" #define ENB_CONFIG_STRING_RA_RESPONSE_WINDOW_SIZE_R13 "ra_ResponseWindowSize_r13" #define ENB_CONFIG_STRING_MAC_CONTENTION_RESOLUTION_TIMER_R13 "mac_ContentionResolutionTimer_r13" -#define ENB_CONFIG_STRING_RAR_HOPPING_CONFIG_R13 "rar_HoppingConfig_r13 " +#define ENB_CONFIG_STRING_RAR_HOPPING_CONFIG_R13 "rar_HoppingConfig_r13" #define ENB_CONFIG_STRING_RACH_CE_LEVELINFOLIST_R13 "rach_CE_LevelInfoList_r13" #define ENB_CONFIG_STRING_PRACH_CONFIG_INDEX_BR "prach_config_index_br" #define ENB_CONFIG_STRING_PRACH_FREQ_OFFSET_BR "prach_freq_offset_br" @@ -81,6 +84,9 @@ #define ENB_CONFIG_STRING_PUCCH_INFO_VALUE "pucch_info_value" #define ENB_CONFIG_STRING_N1PUCCH_AN_INFOLIST_R13 "n1PUCCH_AN_InfoList_r13" #define ENB_CONFIG_STRING_PCCH_CONFIG_V1310 "pcch_config_v1310" +#define ENB_CONFIG_STRING_PAGING_NARROWBANDS_R13 "paging_narrowbands_r13" +#define ENB_CONFIG_STRING_MPDCCH_NUMREPETITION_PAGING_R13 "mpdcch_numrepetition_paging_r13" +#define ENB_CONFIG_STRING_NB_V1310 "nb_v1310" #define ENB_CONFIG_STRING_SIB2_FREQ_HOPPINGPARAMETERS_R13 "sib2_freq_hoppingParameters_r13" typedef struct ccparams_eMTC_s { diff --git a/openair2/ENB_APP/enb_paramdef_sidelink.h b/openair2/ENB_APP/enb_paramdef_sidelink.h index 3e73ba43b738dcfbc8771e8faa8db176fae51aa7..dd3aa5f0fbb75d32131bec58d0c8fd187ffc9c63 100644 --- a/openair2/ENB_APP/enb_paramdef_sidelink.h +++ b/openair2/ENB_APP/enb_paramdef_sidelink.h @@ -20,7 +20,7 @@ */ /*! \file openair2/ENB_APP/enb_paramdef_sidelink.h - * \brief definition of configuration parameters for sidelink eNodeB modules + * \brief definition of configuration parameters for sidelink eNodeB modules * \author Raymond KNOPP * \date 2018 * \version 0.1 @@ -180,4 +180,3 @@ typedef struct ccparams_sidelink_s { {ENB_CONFIG_STRING_DISCRXPOOLPS_RC_SFBITMAP_CHOICE_BS_ASN_BITS_UNUSED,NULL, 0, iptr:(int32_t *)&SLparams.discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused, defintval:1, TYPE_UINT, 0} \ } #endif - diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index 9c0af82e900e0965a75319dd8501841d49f51f62..24ed07ac9255d0448af4d92c3f73ee1c31282e39 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -26,11 +26,12 @@ * \version 0.1 */ +#define _GNU_SOURCE #include "flexran_agent.h" +#include <pthread.h> #include <arpa/inet.h> -void *send_thread(void *args); void *receive_thread(void *args); pthread_t new_thread(void *(*f)(void *), void *b); Protocol__FlexranMessage *flexran_agent_timeout(void* args); @@ -110,10 +111,11 @@ void *receive_thread(void *args) { err_code_t err_code=0; Protocol__FlexranMessage *msg; + pthread_setname_np(pthread_self(), "flexran_rx_thr"); while (1) { - while (flexran_agent_msg_recv(d->mod_id, FLEXRAN_AGENT_DEFAULT, &data, &size, &priority) == 0) { + while ((size = flexran_agent_msg_recv(d->mod_id, FLEXRAN_AGENT_DEFAULT, &data, &priority)) > 0) { LOG_D(FLEXRAN_AGENT,"received message with size %d\n", size); @@ -201,6 +203,11 @@ int flexran_agent_start(mid_t mod_id) /*Create the async channel info*/ flexran_agent_async_channel_t *channel_info = flexran_agent_async_channel_info(mod_id, in_ip, in_port); + if (!channel_info) { + LOG_E(FLEXRAN_AGENT, "could not create channel_info\n"); + exit(1); + } + /*Create a channel using the async channel info*/ channel_id = flexran_agent_create_channel((void *) channel_info, flexran_agent_async_msg_send, @@ -209,12 +216,14 @@ int flexran_agent_start(mid_t mod_id) if (channel_id <= 0) { + LOG_E(FLEXRAN_AGENT, "could not create channel\n"); goto error; } flexran_agent_channel_t *channel = get_channel(channel_id); if (channel == NULL) { + LOG_E(FLEXRAN_AGENT, "could not get channel for channel_id %d\n", channel_id); goto error; } @@ -226,21 +235,48 @@ int flexran_agent_start(mid_t mod_id) */ /*Initialize the continuous stats update mechanism*/ - flexran_agent_init_cont_stats_update(mod_id); - + if (flexran_agent_init_cont_stats_update(mod_id) < 0) { + LOG_E(FLEXRAN_AGENT, "could not initialize continuous stats updates\n"); + goto error; + } + new_thread(receive_thread, flexran); - /*Initialize and register the mac xface. Must be modified later - *for more flexibility in agent management */ + /* Register and initialize the control modules depending on capabilities. + * After registering, calling flexran_agent_get_*_xface() tells whether a + * control module is operational */ + uint16_t caps = flexran_get_capabilities_mask(mod_id); + LOG_I(FLEXRAN_AGENT, "Agent handles BS ID %ld, capabilities=0x%x => handling%s%s%s%s%s%s%s%s\n", + flexran_get_bs_id(mod_id), caps, + FLEXRAN_CAP_LOPHY(caps) ? " LOPHY" : "", + FLEXRAN_CAP_HIPHY(caps) ? " HIPHY" : "", + FLEXRAN_CAP_LOMAC(caps) ? " LOMAC" : "", + FLEXRAN_CAP_HIMAC(caps) ? " HIMAC" : "", + FLEXRAN_CAP_RLC(caps) ? " RLC" : "", + FLEXRAN_CAP_PDCP(caps) ? " PDCP" : "", + FLEXRAN_CAP_SDAP(caps) ? " SDAP" : "", + FLEXRAN_CAP_RRC(caps) ? " RRC" : ""); + + if (FLEXRAN_CAP_LOPHY(caps) || FLEXRAN_CAP_HIPHY(caps)) { + flexran_agent_register_phy_xface(mod_id); + LOG_I(FLEXRAN_AGENT, "registered PHY interface/CM for eNB %d\n", mod_id); + } - AGENT_MAC_xface *mac_agent_xface = (AGENT_MAC_xface *) malloc(sizeof(AGENT_MAC_xface)); - flexran_agent_register_mac_xface(mod_id, mac_agent_xface); - - AGENT_RRC_xface *rrc_agent_xface = (AGENT_RRC_xface *) malloc(sizeof(AGENT_RRC_xface)); - flexran_agent_register_rrc_xface(mod_id, rrc_agent_xface); + if (FLEXRAN_CAP_LOMAC(caps) || FLEXRAN_CAP_HIMAC(caps)) { + flexran_agent_register_mac_xface(mod_id); + flexran_agent_init_mac_agent(mod_id); + LOG_I(FLEXRAN_AGENT, "registered MAC interface/CM for eNB %d\n", mod_id); + } + + if (FLEXRAN_CAP_RRC(caps)) { + flexran_agent_register_rrc_xface(mod_id); + LOG_I(FLEXRAN_AGENT, "registered RRC interface/CM for eNB %d\n", mod_id); + } - AGENT_PDCP_xface *pdcp_agent_xface = (AGENT_PDCP_xface *) malloc(sizeof(AGENT_PDCP_xface)); - flexran_agent_register_pdcp_xface(mod_id, pdcp_agent_xface); + if (FLEXRAN_CAP_PDCP(caps)) { + flexran_agent_register_pdcp_xface(mod_id); + LOG_I(FLEXRAN_AGENT, "registered PDCP interface/CM for eNB %d\n", mod_id); + } /* * initilize a timer @@ -248,11 +284,6 @@ int flexran_agent_start(mid_t mod_id) flexran_agent_init_timer(); - /* - * Initialize the mac agent - */ - flexran_agent_init_mac_agent(mod_id); - /* * start the enb agent task for tx and interaction with the underlying network function */ @@ -288,7 +319,7 @@ int flexran_agent_start(mid_t mod_id) return 0; error: - LOG_I(FLEXRAN_AGENT,"there was an error\n"); + LOG_E(FLEXRAN_AGENT, "%s(): there was an error\n", __func__); return 1; } diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index 4ce727ff1c7c89e305ccb7ff2d1641010122e64a..e50a2be4f65cf6a0e0f29541cb0333a645cc5064 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -36,6 +36,7 @@ #include "flexran_agent_defs.h" #include "flexran_agent_net_comm.h" #include "flexran_agent_ran_api.h" +#include "flexran_agent_phy.h" #include "flexran_agent_mac.h" #include "flexran_agent_rrc.h" #include "flexran_agent_pdcp.h" diff --git a/openair2/ENB_APP/flexran_agent_async.c b/openair2/ENB_APP/flexran_agent_async.c index 88be77d5bb2c93fb9c1501f7ace1222c1119478d..fa2e0c9ff583c1f5d7e697f325f2b514b5f3cffb 100644 --- a/openair2/ENB_APP/flexran_agent_async.c +++ b/openair2/ENB_APP/flexran_agent_async.c @@ -36,13 +36,18 @@ flexran_agent_async_channel_t * flexran_agent_async_channel_info(mid_t mod_id, c flexran_agent_async_channel_t *channel; channel = (flexran_agent_async_channel_t *) malloc(sizeof(flexran_agent_channel_t)); - if (channel == NULL) - goto error; + if (channel == NULL) { + LOG_E(FLEXRAN_AGENT, "could not allocate memory for flexran_agent_async_channel_t\n"); + return NULL; + } channel->enb_id = mod_id; /*Create a socket*/ channel->link = new_link_client(dst_ip, dst_port); - if (channel->link == NULL) goto error; + if (channel->link == NULL) { + LOG_E(FLEXRAN_AGENT, "could not create new link client\n"); + goto error; + } LOG_I(FLEXRAN_AGENT,"starting enb agent client for module id %d on ipv4 %s, port %d\n", channel->enb_id, @@ -53,21 +58,32 @@ flexran_agent_async_channel_t * flexran_agent_async_channel_info(mid_t mod_id, c * create a message queue */ // Set size of queues statically for now - channel->send_queue = new_message_queue(500); - if (channel->send_queue == NULL) goto error; - channel->receive_queue = new_message_queue(500); - if (channel->receive_queue == NULL) goto error; +// channel->send_queue = new_message_queue(500); + // not using the circular buffer: affects the PDCP split + channel->send_queue = new_message_queue(); + if (channel->send_queue == NULL) { + LOG_E(FLEXRAN_AGENT, "could not create send_queue\n"); + goto error; + } + // not using the circular buffer: affects the PDCP split + //channel->receive_queue = new_message_queue(500); + channel->receive_queue = new_message_queue(); + if (channel->receive_queue == NULL) { + LOG_E(FLEXRAN_AGENT, "could not create send_queue\n"); + goto error; + } - /* - * create a link manager - */ + /* create a link manager */ channel->manager = create_link_manager(channel->send_queue, channel->receive_queue, channel->link); - if (channel->manager == NULL) goto error; + if (channel->manager == NULL) { + LOG_E(FLEXRAN_AGENT, "could not create link_manager\n"); + goto error; + } return channel; error: - LOG_I(FLEXRAN_AGENT,"there was an error\n"); + LOG_I(FLEXRAN_AGENT, "%s(): there was an error\n", __func__); return NULL; } @@ -78,11 +94,11 @@ int flexran_agent_async_msg_send(void *data, int size, int priority, void *chann return message_put(channel->send_queue, data, size, priority); } -int flexran_agent_async_msg_recv(void **data, int *size, int *priority, void *channel_info) { +int flexran_agent_async_msg_recv(void **data, int *priority, void *channel_info) { flexran_agent_async_channel_t *channel; channel = (flexran_agent_async_channel_t *)channel_info; - return message_get(channel->receive_queue, data, size, priority); + return message_get(channel->receive_queue, data, priority); } void flexran_agent_async_release(flexran_agent_channel_t *channel) { diff --git a/openair2/ENB_APP/flexran_agent_async.h b/openair2/ENB_APP/flexran_agent_async.h index 03aebd0058fc6c3293baa664119124e6921f6ef2..1ebc565f62b31a5555ac00add7a9d4e50912878a 100644 --- a/openair2/ENB_APP/flexran_agent_async.h +++ b/openair2/ENB_APP/flexran_agent_async.h @@ -46,7 +46,7 @@ flexran_agent_async_channel_t * flexran_agent_async_channel_info(mid_t mod_id, c int flexran_agent_async_msg_send(void *data, int size, int priority, void *channel_info); /* Receive a message from a given channel */ -int flexran_agent_async_msg_recv(void **data, int *size, int *priority, void *channel_info); +int flexran_agent_async_msg_recv(void **data, int *priority, void *channel_info); /* Release a channel */ void flexran_agent_async_release(flexran_agent_channel_t *channel); diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 1a92c9e2621e37ae028e1ceba277d7357527db7f..72b0866fd6f0ac95763f37f2f8d58322293256a1 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -17,10 +17,10 @@ *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org - */ + */ /*! \file flexran_agent_common.c - * \brief common primitives for all agents + * \brief common primitives for all agents * \author Xenofon Foukas, Mohamed Kassem and Navid Nikaein, shahab SHARIAT BAGHERI * \date 2017 * \version 0.1 @@ -35,6 +35,9 @@ #include "flexran_agent_extern.h" #include "flexran_agent_net_comm.h" #include "flexran_agent_ran_api.h" +#include "flexran_agent_phy.h" +#include "flexran_agent_mac.h" +#include "flexran_agent_rrc.h" //#include "PHY/extern.h" #include "common/utils/LOG/log.h" #include "flexran_agent_mac_internal.h" @@ -49,18 +52,19 @@ */ int flexran_agent_serialize_message(Protocol__FlexranMessage *msg, void **buf, int *size) { - *size = protocol__flexran_message__get_packed_size(msg); - - *buf = malloc(*size); + if (buf == NULL) goto error; - + + *buf = malloc(*size); + + if (*buf == NULL) + goto error; + protocol__flexran_message__pack(msg, *buf); - return 0; - - error: +error: LOG_E(FLEXRAN_AGENT, "an error occured\n"); // change the com return -1; } @@ -71,12 +75,12 @@ int flexran_agent_serialize_message(Protocol__FlexranMessage *msg, void **buf, i Should be chekced durint Tx/Rx */ int flexran_agent_deserialize_message(void *data, int size, Protocol__FlexranMessage **msg) { *msg = protocol__flexran_message__unpack(NULL, size, data); + if (*msg == NULL) goto error; return 0; - - error: +error: //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -84,115 +88,125 @@ int flexran_agent_deserialize_message(void *data, int size, Protocol__FlexranMes int flexran_create_header(xid_t xid, Protocol__FlexType type, Protocol__FlexHeader **header) { - *header = malloc(sizeof(Protocol__FlexHeader)); + if(*header == NULL) goto error; - + protocol__flex_header__init(*header); (*header)->version = FLEXRAN_VERSION; - (*header)->has_version = 1; + (*header)->has_version = 1; // check if the type is set (*header)->type = type; (*header)->has_type = 1; (*header)->xid = xid; (*header)->has_xid = 1; return 0; - - error: +error: LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } int flexran_agent_hello(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - Protocol__FlexHeader *header = NULL; /*TODO: Need to set random xid or xid from received hello message*/ xid_t xid = 1; - Protocol__FlexHello *hello_msg; hello_msg = malloc(sizeof(Protocol__FlexHello)); + if(hello_msg == NULL) goto error; + protocol__flex_hello__init(hello_msg); if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_HELLO, &header) != 0) goto error; hello_msg->header = header; + hello_msg->bs_id = flexran_get_bs_id(mod_id); + hello_msg->has_bs_id = 1; + hello_msg->n_capabilities = flexran_get_capabilities(mod_id, &hello_msg->capabilities); *msg = malloc(sizeof(Protocol__FlexranMessage)); + if(*msg == NULL) goto error; - + protocol__flexran_message__init(*msg); (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG; (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; (*msg)->has_msg_dir = 1; (*msg)->hello_msg = hello_msg; return 0; - - error: +error: + if(header != NULL) free(header); + if(hello_msg != NULL) free(hello_msg); + if(*msg != NULL) free(*msg); + LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } int flexran_agent_destroy_hello(Protocol__FlexranMessage *msg) { - if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_HELLO_MSG) goto error; - + free(msg->hello_msg->header); + free(msg->hello_msg->capabilities); free(msg->hello_msg); free(msg); return 0; - - error: +error: LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } -int flexran_agent_echo_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) { +int flexran_agent_echo_request(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { Protocol__FlexHeader *header = NULL; /*TODO: Need to set a random xid*/ xid_t xid = 1; - Protocol__FlexEchoRequest *echo_request_msg = NULL; echo_request_msg = malloc(sizeof(Protocol__FlexEchoRequest)); + if(echo_request_msg == NULL) goto error; + protocol__flex_echo_request__init(echo_request_msg); if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_ECHO_REQUEST, &header) != 0) goto error; echo_request_msg->header = header; - *msg = malloc(sizeof(Protocol__FlexranMessage)); + if(*msg == NULL) goto error; + protocol__flexran_message__init(*msg); (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG; (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; (*msg)->echo_request_msg = echo_request_msg; return 0; +error: - error: if(header != NULL) free(header); + if(echo_request_msg != NULL) free(echo_request_msg); + if(*msg != NULL) free(*msg); + //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -201,13 +215,12 @@ int flexran_agent_echo_request(mid_t mod_id, const void* params, Protocol__Flexr int flexran_agent_destroy_echo_request(Protocol__FlexranMessage *msg) { if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REQUEST_MSG) goto error; - + free(msg->echo_request_msg->header); free(msg->echo_request_msg); free(msg); return 0; - - error: +error: LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -215,41 +228,45 @@ int flexran_agent_destroy_echo_request(Protocol__FlexranMessage *msg) { int flexran_agent_echo_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - xid_t xid; Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexEchoRequest *echo_req = input->echo_request_msg; xid = (echo_req->header)->xid; - Protocol__FlexEchoReply *echo_reply_msg = NULL; echo_reply_msg = malloc(sizeof(Protocol__FlexEchoReply)); + if(echo_reply_msg == NULL) goto error; + protocol__flex_echo_reply__init(echo_reply_msg); if (flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_ECHO_REPLY, &header) != 0) goto error; echo_reply_msg->header = header; - *msg = malloc(sizeof(Protocol__FlexranMessage)); + if(*msg == NULL) goto error; + protocol__flexran_message__init(*msg); (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG; (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; (*msg)->has_msg_dir = 1; (*msg)->echo_reply_msg = echo_reply_msg; return 0; +error: - error: if(header != NULL) free(header); + if(echo_reply_msg != NULL) free(echo_reply_msg); + if(*msg != NULL) free(*msg); + LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -258,13 +275,12 @@ int flexran_agent_echo_reply(mid_t mod_id, const void *params, Protocol__Flexran int flexran_agent_destroy_echo_reply(Protocol__FlexranMessage *msg) { if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ECHO_REPLY_MSG) goto error; - + free(msg->echo_reply_msg->header); free(msg->echo_reply_msg); free(msg); return 0; - - error: +error: LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -273,46 +289,56 @@ int flexran_agent_destroy_echo_reply(Protocol__FlexranMessage *msg) { int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG) goto error; + free(msg->enb_config_reply_msg->header); - int i, j; Protocol__FlexEnbConfigReply *reply = msg->enb_config_reply_msg; - - for(i = 0; i < reply->n_cell_config;i++) { - free(reply->cell_config[i]->mbsfn_subframe_config_rfoffset); - free(reply->cell_config[i]->mbsfn_subframe_config_rfperiod); - free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc); - if (reply->cell_config[i]->si_config != NULL) { - for(j = 0; j < reply->cell_config[i]->si_config->n_si_message;j++){ - free(reply->cell_config[i]->si_config->si_message[j]); + + for (int i = 0; i < reply->n_cell_config; i++) { + if (reply->cell_config[i]->mbsfn_subframe_config_rfoffset) + free(reply->cell_config[i]->mbsfn_subframe_config_rfoffset); + if (reply->cell_config[i]->mbsfn_subframe_config_rfperiod) + free(reply->cell_config[i]->mbsfn_subframe_config_rfperiod); + if (reply->cell_config[i]->mbsfn_subframe_config_sfalloc) + free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc); + + if (reply->cell_config[i]->si_config) { + for(int j = 0; j < reply->cell_config[i]->si_config->n_si_message; j++) { + free(reply->cell_config[i]->si_config->si_message[j]); } free(reply->cell_config[i]->si_config->si_message); free(reply->cell_config[i]->si_config); } - if (reply->cell_config[i]->slice_config != NULL) { - for (j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) { + + if (reply->cell_config[i]->slice_config) { + for (int j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) { if (reply->cell_config[i]->slice_config->dl[j]->n_sorting > 0) free(reply->cell_config[i]->slice_config->dl[j]->sorting); + free(reply->cell_config[i]->slice_config->dl[j]->scheduler_name); free(reply->cell_config[i]->slice_config->dl[j]); } + free(reply->cell_config[i]->slice_config->dl); - for (j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) { + for (int j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) { if (reply->cell_config[i]->slice_config->ul[j]->n_sorting > 0) free(reply->cell_config[i]->slice_config->ul[j]->sorting); + free(reply->cell_config[i]->slice_config->ul[j]->scheduler_name); free(reply->cell_config[i]->slice_config->ul[j]); } + free(reply->cell_config[i]->slice_config->ul); free(reply->cell_config[i]->slice_config); } + free(reply->cell_config[i]); } + free(reply->cell_config); free(reply); free(msg); - return 0; - error: +error: //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -320,20 +346,21 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { int flexran_agent_destroy_ue_config_reply(Protocol__FlexranMessage *msg) { if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG) goto error; + free(msg->ue_config_reply_msg->header); int i; Protocol__FlexUeConfigReply *reply = msg->ue_config_reply_msg; - - for(i = 0; i < reply->n_ue_config;i++){ + + for(i = 0; i < reply->n_ue_config; i++) { free(reply->ue_config[i]->capabilities); free(reply->ue_config[i]); } + free(reply->ue_config); free(reply); free(msg); - return 0; - error: +error: //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -344,18 +371,21 @@ int flexran_agent_destroy_lc_config_reply(Protocol__FlexranMessage *msg) { int i, j; free(msg->lc_config_reply_msg->header); + for (i = 0; i < msg->lc_config_reply_msg->n_lc_ue_config; i++) { for (j = 0; j < msg->lc_config_reply_msg->lc_ue_config[i]->n_lc_config; j++) { free(msg->lc_config_reply_msg->lc_ue_config[i]->lc_config[j]); } + free(msg->lc_config_reply_msg->lc_ue_config[i]->lc_config); free(msg->lc_config_reply_msg->lc_ue_config[i]); } + free(msg->lc_config_reply_msg->lc_ue_config); free(msg->lc_config_reply_msg); free(msg); return 0; - error: +error: //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -364,12 +394,12 @@ int flexran_agent_destroy_lc_config_reply(Protocol__FlexranMessage *msg) { int flexran_agent_destroy_enb_config_request(Protocol__FlexranMessage *msg) { if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG) goto error; + free(msg->enb_config_request_msg->header); free(msg->enb_config_request_msg); free(msg); return 0; - - error: +error: //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -386,24 +416,22 @@ int flexran_agent_destroy_lc_config_request(Protocol__FlexranMessage *msg) { // call this function to start a nanosecond-resolution timer struct timespec timer_start(void) { - struct timespec start_time; - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time); - return start_time; + struct timespec start_time; + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time); + return start_time; } // call this function to end a timer, returning nanoseconds elapsed as a long -long timer_end(struct timespec start_time){ - struct timespec end_time; - clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time); - long diffInNanos = end_time.tv_nsec - start_time.tv_nsec; - return diffInNanos; +long timer_end(struct timespec start_time) { + struct timespec end_time; + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time); + long diffInNanos = end_time.tv_nsec - start_time.tv_nsec; + return diffInNanos; } int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexControlDelegation *control_delegation_msg = input->control_delegation_msg; - // struct timespec vartime = timer_start(); //Write the payload lib into a file in the cache and load the lib char lib_name[120]; @@ -411,14 +439,13 @@ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol_ snprintf(lib_name, sizeof(lib_name), "/%s.so", control_delegation_msg->name); strcpy(target, RC.flexran[mod_id]->cache_name); strcat(target, lib_name); - FILE *f; f = fopen(target, "wb"); + if (f) { fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f); fclose(f); - } - else { + } else { LOG_W(FLEXRAN_AGENT, "[%d] can not write control delegation data to %s\n", mod_id, target); } @@ -426,7 +453,6 @@ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol_ // long time_elapsed_nanos = timer_end(vartime); *msg = NULL; return 0; - } int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg) { @@ -437,9 +463,7 @@ int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg) { int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexAgentReconfiguration *agent_reconfiguration_msg = input->agent_reconfiguration_msg; - apply_reconfiguration_policy(mod_id, agent_reconfiguration_msg->policy, strlen(agent_reconfiguration_msg->policy)); - *msg = NULL; return 0; } @@ -451,20 +475,17 @@ int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg) { int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - xid_t xid; Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexLcConfigRequest *lc_config_request_msg = input->lc_config_request_msg; xid = (lc_config_request_msg->header)->xid; - - int i, j; - int UE_id; - Protocol__FlexLcConfigReply *lc_config_reply_msg; lc_config_reply_msg = malloc(sizeof(Protocol__FlexLcConfigReply)); + if(lc_config_reply_msg == NULL) goto error; + protocol__flex_lc_config_reply__init(lc_config_reply_msg); if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_LC_CONFIG_REPLY, &header) != 0) @@ -472,105 +493,57 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl lc_config_reply_msg->header = header; - lc_config_reply_msg->n_lc_ue_config = flexran_get_num_ues(mod_id); + /* the lc_config_reply entirely depends on MAC except for the + * mac_eNB_get_rrc_status() function (which in the current OAI implementation + * is reachable if F1 is present). Therefore we check here wether MAC CM is + * present and the message gets properly filled if it is or remains empty if + * not */ + lc_config_reply_msg->n_lc_ue_config = + flexran_agent_get_mac_xface(mod_id) ? flexran_get_mac_num_ues(mod_id) : 0; - Protocol__FlexLcUeConfig **lc_ue_config; + Protocol__FlexLcUeConfig **lc_ue_config = NULL; if (lc_config_reply_msg->n_lc_ue_config > 0) { lc_ue_config = malloc(sizeof(Protocol__FlexLcUeConfig *) * lc_config_reply_msg->n_lc_ue_config); + if (lc_ue_config == NULL) { goto error; } + // Fill the config for each UE - for (i = 0; i < lc_config_reply_msg->n_lc_ue_config; i++) { + for (int i = 0; i < lc_config_reply_msg->n_lc_ue_config; i++) { lc_ue_config[i] = malloc(sizeof(Protocol__FlexLcUeConfig)); - protocol__flex_lc_ue_config__init(lc_ue_config[i]); + if (!lc_ue_config[i]) goto error; - UE_id = flexran_get_ue_id(mod_id, i); - - lc_ue_config[i]->has_rnti = 1; - lc_ue_config[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); - - //TODO: Set the number of LC configurations that will be reported for this UE - //Set this according to the current state of the UE. This is only a temporary fix - int status = 0; - status = mac_eNB_get_rrc_status(mod_id, flexran_get_ue_crnti(mod_id, UE_id)); - /* TODO needs to be revised and appropriate API to be implemented */ - if (status < RRC_CONNECTED) { - lc_ue_config[i]->n_lc_config = 0; - } else if (status == RRC_CONNECTED) { - lc_ue_config[i]->n_lc_config = 1; - } else { - lc_ue_config[i]->n_lc_config = 3; - } - - Protocol__FlexLcConfig **lc_config; - if (lc_ue_config[i]->n_lc_config > 0) { - lc_config = malloc(sizeof(Protocol__FlexLcConfig *) * lc_ue_config[i]->n_lc_config); - if (lc_config == NULL) { - goto error; - } - for (j = 0; j < lc_ue_config[i]->n_lc_config; j++) { - lc_config[j] = malloc(sizeof(Protocol__FlexLcConfig)); - protocol__flex_lc_config__init(lc_config[j]); - - lc_config[j]->has_lcid = 1; - lc_config[j]->lcid = j+1; - - int lcg = flexran_get_lcg(mod_id, UE_id, j+1); - if (lcg >= 0 && lcg <= 3) { - lc_config[j]->has_lcg = 1; - lc_config[j]->lcg = flexran_get_lcg(mod_id, UE_id, j+1); - } - - lc_config[j]->has_direction = 1; - lc_config[j]->direction = flexran_get_direction(UE_id, j+1); - //TODO: Bearer type. One of FLQBT_* values. Currently only default bearer supported - lc_config[j]->has_qos_bearer_type = 1; - lc_config[j]->qos_bearer_type = PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_NON_GBR; - - //TODO: Set the QCI defined in TS 23.203, coded as defined in TS 36.413 - // One less than the actual QCI value. Needs to be generalized - lc_config[j]->has_qci = 1; - lc_config[j]->qci = 1; - if (lc_config[j]->direction == PROTOCOL__FLEX_QOS_BEARER_TYPE__FLQBT_GBR) { - /* TODO all of the need to be taken from API */ - //TODO: Set the max bitrate (UL) - lc_config[j]->has_e_rab_max_bitrate_ul = 0; - lc_config[j]->e_rab_max_bitrate_ul = 0; - //TODO: Set the max bitrate (DL) - lc_config[j]->has_e_rab_max_bitrate_dl = 0; - lc_config[j]->e_rab_max_bitrate_dl = 0; - //TODO: Set the guaranteed bitrate (UL) - lc_config[j]->has_e_rab_guaranteed_bitrate_ul = 0; - lc_config[j]->e_rab_guaranteed_bitrate_ul = 0; - //TODO: Set the guaranteed bitrate (DL) - lc_config[j]->has_e_rab_guaranteed_bitrate_dl = 0; - lc_config[j]->e_rab_guaranteed_bitrate_dl = 0; - } - } - lc_ue_config[i]->lc_config = lc_config; - } + protocol__flex_lc_ue_config__init(lc_ue_config[i]); + const int UE_id = flexran_get_mac_ue_id(mod_id, i); + flexran_agent_fill_mac_lc_ue_config(mod_id, UE_id, lc_ue_config[i]); } // end for UE + lc_config_reply_msg->lc_ue_config = lc_ue_config; } // lc_config_reply_msg->n_lc_ue_config > 0 + *msg = malloc(sizeof(Protocol__FlexranMessage)); + if (*msg == NULL) goto error; + protocol__flexran_message__init(*msg); (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_LC_CONFIG_REPLY_MSG; (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; (*msg)->lc_config_reply_msg = lc_config_reply_msg; - return 0; +error: - error: // TODO: Need to make proper error handling if (header != NULL) free(header); + if (lc_config_reply_msg != NULL) free(lc_config_reply_msg); + if(*msg != NULL) free(*msg); + //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -581,21 +554,30 @@ int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__Fl * ************************************ */ -int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { +int sort_ue_config(const void *a, const void *b) +{ + const Protocol__FlexUeConfig *fa = a; + const Protocol__FlexUeConfig *fb = b; + if (fa->rnti < fb->rnti) + return -1; + else if (fa->rnti < fb->rnti) + return 1; + return 0; +} + +int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexUeConfigRequest *ue_config_request_msg = input->ue_config_request_msg; xid = (ue_config_request_msg->header)->xid; - - int i; - int UE_id; - Protocol__FlexUeConfigReply *ue_config_reply_msg; ue_config_reply_msg = malloc(sizeof(Protocol__FlexUeConfigReply)); + if(ue_config_reply_msg == NULL) goto error; + protocol__flex_ue_config_reply__init(ue_config_reply_msg); if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_UE_CONFIG_REPLY, &header) != 0) @@ -603,182 +585,68 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl ue_config_reply_msg->header = header; - ue_config_reply_msg->n_ue_config = flexran_get_num_ues(mod_id); + ue_config_reply_msg->n_ue_config = 0; + if (flexran_agent_get_rrc_xface(mod_id)) + ue_config_reply_msg->n_ue_config = flexran_get_rrc_num_ues(mod_id); + else if (flexran_agent_get_mac_xface(mod_id)) + ue_config_reply_msg->n_ue_config = flexran_get_mac_num_ues(mod_id); + + if (flexran_agent_get_rrc_xface(mod_id) && flexran_agent_get_mac_xface(mod_id) + && flexran_get_rrc_num_ues(mod_id) != flexran_get_mac_num_ues(mod_id)) { + const int nrrc = flexran_get_rrc_num_ues(mod_id); + const int nmac = flexran_get_mac_num_ues(mod_id); + ue_config_reply_msg->n_ue_config = nrrc < nmac ? nrrc : nmac; + LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %lu UEs\n", + __func__, nrrc, nmac, ue_config_reply_msg->n_ue_config); + } Protocol__FlexUeConfig **ue_config; + if (ue_config_reply_msg->n_ue_config > 0) { ue_config = malloc(sizeof(Protocol__FlexUeConfig *) * ue_config_reply_msg->n_ue_config); + if (ue_config == NULL) { goto error; } - for (i = 0; i < ue_config_reply_msg->n_ue_config; i++) { + rnti_t rntis[ue_config_reply_msg->n_ue_config]; + flexran_get_rrc_rnti_list(mod_id, rntis, ue_config_reply_msg->n_ue_config); + for (int i = 0; i < ue_config_reply_msg->n_ue_config; i++) { + const rnti_t rnti = rntis[i]; ue_config[i] = malloc(sizeof(Protocol__FlexUeConfig)); protocol__flex_ue_config__init(ue_config[i]); - UE_id = flexran_get_ue_id(mod_id, i); - ue_config[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id); - ue_config[i]->has_rnti = 1; - ue_config[i]->imsi = flexran_get_ue_imsi(mod_id, UE_id); - ue_config[i]->has_imsi = 1; - ue_config[i]->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, UE_id); - ue_config[i]->has_dl_slice_id = 1; - ue_config[i]->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, UE_id); - ue_config[i]->has_ul_slice_id = 1; - //TODO: Set the DRX configuration (optional) - //Not supported for now, so we do not set it - - if (flexran_get_time_alignment_timer(mod_id, UE_id) != -1) { - ue_config[i]->time_alignment_timer = flexran_get_time_alignment_timer(mod_id, UE_id); - ue_config[i]->has_time_alignment_timer = 1; - } - - if (flexran_get_meas_gap_config(mod_id, UE_id) != -1) { - ue_config[i]->meas_gap_config_pattern = flexran_get_meas_gap_config(mod_id, UE_id); - ue_config[i]->has_meas_gap_config_pattern = 1; - } - - if (ue_config[i]->has_meas_gap_config_pattern == 1 && - ue_config[i]->meas_gap_config_pattern != PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF) { - ue_config[i]->meas_gap_config_sf_offset = flexran_get_meas_gap_config_offset(mod_id, UE_id); - ue_config[i]->has_meas_gap_config_sf_offset = 1; - } - //TODO: Set the SPS configuration (Optional) - //Not supported for noe, so we do not set it - - //TODO: Set the SR configuration (Optional) - //We do not set it for now - - //TODO: Set the CQI configuration (Optional) - //We do not set it for now - - if (flexran_get_ue_transmission_mode(mod_id, UE_id) != -1) { - ue_config[i]->transmission_mode = flexran_get_ue_transmission_mode(mod_id, UE_id); - ue_config[i]->has_transmission_mode = 1; - } - - ue_config[i]->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id, UE_id); - ue_config[i]->has_ue_aggregated_max_bitrate_ul = 1; - - ue_config[i]->ue_aggregated_max_bitrate_dl = flexran_get_ue_aggregated_max_bitrate_dl(mod_id, UE_id); - ue_config[i]->has_ue_aggregated_max_bitrate_dl = 1; - - Protocol__FlexUeCapabilities *capabilities; - capabilities = malloc(sizeof(Protocol__FlexUeCapabilities)); - protocol__flex_ue_capabilities__init(capabilities); - capabilities->has_half_duplex = 1; - capabilities->half_duplex = flexran_get_half_duplex(mod_id, UE_id); - capabilities->has_intra_sf_hopping = 1; - capabilities->intra_sf_hopping = flexran_get_intra_sf_hopping(mod_id, UE_id); - capabilities->has_type2_sb_1 = 1; - capabilities->type2_sb_1 = flexran_get_type2_sb_1(mod_id, UE_id); - capabilities->has_ue_category = 1; - capabilities->ue_category = flexran_get_ue_category(mod_id, UE_id); - capabilities->has_res_alloc_type1 = 1; - capabilities->res_alloc_type1 = flexran_get_res_alloc_type1(mod_id, UE_id); - //Set the capabilites to the message - ue_config[i]->capabilities = capabilities; - - if (flexran_get_ue_transmission_antenna(mod_id, UE_id) != -1) { - ue_config[i]->has_ue_transmission_antenna = 1; - ue_config[i]->ue_transmission_antenna = flexran_get_ue_transmission_antenna(mod_id, UE_id); - } - - if (flexran_get_tti_bundling(mod_id, UE_id) != -1) { - ue_config[i]->has_tti_bundling = 1; - ue_config[i]->tti_bundling = flexran_get_tti_bundling(mod_id, UE_id); - } - - if (flexran_get_maxHARQ_TX(mod_id, UE_id) != -1) { - ue_config[i]->has_max_harq_tx = 1; - ue_config[i]->max_harq_tx = flexran_get_maxHARQ_TX(mod_id, UE_id); - } - - if (flexran_get_beta_offset_ack_index(mod_id, UE_id) != -1) { - ue_config[i]->has_beta_offset_ack_index = 1; - ue_config[i]->beta_offset_ack_index = flexran_get_beta_offset_ack_index(mod_id, UE_id); - } - - if (flexran_get_beta_offset_ri_index(mod_id, UE_id) != -1) { - ue_config[i]->has_beta_offset_ri_index = 1; - ue_config[i]->beta_offset_ri_index = flexran_get_beta_offset_ri_index(mod_id, UE_id); - } - - if (flexran_get_beta_offset_cqi_index(mod_id, UE_id) != -1) { - ue_config[i]->has_beta_offset_cqi_index = 1; - ue_config[i]->beta_offset_cqi_index = flexran_get_beta_offset_cqi_index(mod_id, UE_id); - } - - /* assume primary carrier */ - if (flexran_get_ack_nack_simultaneous_trans(mod_id, UE_id, 0) != -1) { - ue_config[i]->has_ack_nack_simultaneous_trans = 1; - ue_config[i]->ack_nack_simultaneous_trans = flexran_get_ack_nack_simultaneous_trans(mod_id, UE_id, 0); - } - - if (flexran_get_simultaneous_ack_nack_cqi(mod_id, UE_id) != -1) { - ue_config[i]->has_simultaneous_ack_nack_cqi = 1; - ue_config[i]->simultaneous_ack_nack_cqi = flexran_get_simultaneous_ack_nack_cqi(mod_id, UE_id); - } - - if (flexran_get_aperiodic_cqi_rep_mode(mod_id, UE_id) != -1) { - ue_config[i]->has_aperiodic_cqi_rep_mode = 1; - int mode = flexran_get_aperiodic_cqi_rep_mode(mod_id, UE_id); - if (mode > 4) { - ue_config[i]->aperiodic_cqi_rep_mode = PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; - } else { - ue_config[i]->aperiodic_cqi_rep_mode = mode; - } - } - - if (flexran_get_tdd_ack_nack_feedback_mode(mod_id, UE_id) != -1) { - ue_config[i]->has_tdd_ack_nack_feedback = 1; - ue_config[i]->tdd_ack_nack_feedback = flexran_get_tdd_ack_nack_feedback_mode(mod_id, UE_id); - } - - if(flexran_get_ack_nack_repetition_factor(mod_id, UE_id) != -1) { - ue_config[i]->has_ack_nack_repetition_factor = 1; - ue_config[i]->ack_nack_repetition_factor = flexran_get_ack_nack_repetition_factor(mod_id, UE_id); - } - - if (flexran_get_extended_bsr_size(mod_id, UE_id) != -1) { - ue_config[i]->has_extended_bsr_size = 1; - ue_config[i]->extended_bsr_size = flexran_get_extended_bsr_size(mod_id, UE_id); - } - //TODO: Set carrier aggregation support (boolean) - ue_config[i]->has_ca_support = 0; - ue_config[i]->ca_support = 0; - - ue_config[i]->has_pcell_carrier_index = 1; - ue_config[i]->pcell_carrier_index = UE_PCCID(mod_id, UE_id); - if(ue_config[i]->has_ca_support){ - //TODO: Set cross carrier scheduling support (boolean) - ue_config[i]->has_cross_carrier_sched_support = 0; - ue_config[i]->cross_carrier_sched_support = 0; - //TODO: Set secondary cells configuration - // We do not set it for now. No carrier aggregation support - //TODO: Set deactivation timer for secondary cell - ue_config[i]->has_scell_deactivation_timer = 0; - ue_config[i]->scell_deactivation_timer = 0; + if (flexran_agent_get_rrc_xface(mod_id)) + flexran_agent_fill_rrc_ue_config(mod_id, rnti, ue_config[i]); + if (flexran_agent_get_mac_xface(mod_id)) { + const int UE_id = flexran_get_mac_ue_id_rnti(mod_id, rnti); + flexran_agent_fill_mac_ue_config(mod_id, UE_id, ue_config[i]); } } ue_config_reply_msg->ue_config = ue_config; } + *msg = malloc(sizeof(Protocol__FlexranMessage)); + if (*msg == NULL) goto error; + protocol__flexran_message__init(*msg); (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_UE_CONFIG_REPLY_MSG; (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; (*msg)->ue_config_reply_msg = ue_config_reply_msg; return 0; +error: - error: // TODO: Need to make proper error handling if (header != NULL) free(header); + if (ue_config_reply_msg != NULL) free(ue_config_reply_msg); + if(*msg != NULL) free(*msg); + //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } @@ -790,345 +658,140 @@ int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__Fl * ************************************ */ -int flexran_agent_enb_config_request(mid_t mod_id, const void* params, Protocol__FlexranMessage **msg) { - - Protocol__FlexHeader *header = NULL; - xid_t xid = 1; - - Protocol__FlexEnbConfigRequest *enb_config_request_msg; - enb_config_request_msg = malloc(sizeof(Protocol__FlexEnbConfigRequest)); - if(enb_config_request_msg == NULL) - goto error; - protocol__flex_enb_config_request__init(enb_config_request_msg); - - if(flexran_create_header(xid,PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REQUEST, &header) != 0) - goto error; - - enb_config_request_msg->header = header; - - *msg = malloc(sizeof(Protocol__FlexranMessage)); - if(*msg == NULL) - goto error; - - protocol__flexran_message__init(*msg); - (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG; - (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; - (*msg)->enb_config_request_msg = enb_config_request_msg; - return 0; - - error: - // TODO: Need to make proper error handling - if (header != NULL) - free(header); - if (enb_config_request_msg != NULL) - free(enb_config_request_msg); - if(*msg != NULL) - free(*msg); - //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); - return -1; +int flexran_agent_enb_config_request(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { + Protocol__FlexHeader *header = NULL; + xid_t xid = 1; + Protocol__FlexEnbConfigRequest *enb_config_request_msg; + enb_config_request_msg = malloc(sizeof(Protocol__FlexEnbConfigRequest)); + + if(enb_config_request_msg == NULL) + goto error; + + protocol__flex_enb_config_request__init(enb_config_request_msg); + + if(flexran_create_header(xid,PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REQUEST, &header) != 0) + goto error; + + enb_config_request_msg->header = header; + *msg = malloc(sizeof(Protocol__FlexranMessage)); + + if(*msg == NULL) + goto error; + + protocol__flexran_message__init(*msg); + (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REQUEST_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; + (*msg)->enb_config_request_msg = enb_config_request_msg; + return 0; +error: + + // TODO: Need to make proper error handling + if (header != NULL) + free(header); + + if (enb_config_request_msg != NULL) + free(enb_config_request_msg); + + if(*msg != NULL) + free(*msg); + + //LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; } int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - xid_t xid; Protocol__FlexHeader *header = NULL; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexEnbConfigRequest *enb_config_req_msg = input->enb_config_request_msg; xid = (enb_config_req_msg->header)->xid; - - int i, j; - Protocol__FlexEnbConfigReply *enb_config_reply_msg; enb_config_reply_msg = malloc(sizeof(Protocol__FlexEnbConfigReply)); + if(enb_config_reply_msg == NULL) goto error; + protocol__flex_enb_config_reply__init(enb_config_reply_msg); if(flexran_create_header(xid, PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REPLY, &header) != 0) goto error; - - enb_config_reply_msg->header = header; - - enb_config_reply_msg->enb_id = RC.flexran[mod_id]->agent_id; - enb_config_reply_msg->has_enb_id = 1; + enb_config_reply_msg->header = header; enb_config_reply_msg->n_cell_config = MAX_NUM_CCs; - Protocol__FlexCellConfig **cell_conf; - if(enb_config_reply_msg->n_cell_config > 0){ + + if(enb_config_reply_msg->n_cell_config > 0) { cell_conf = malloc(sizeof(Protocol__FlexCellConfig *) * enb_config_reply_msg->n_cell_config); + if(cell_conf == NULL) goto error; - for(i = 0; i < enb_config_reply_msg->n_cell_config; i++){ + for(int i = 0; i < enb_config_reply_msg->n_cell_config; i++){ cell_conf[i] = malloc(sizeof(Protocol__FlexCellConfig)); + if (!cell_conf[i]) goto error; protocol__flex_cell_config__init(cell_conf[i]); - - cell_conf[i]->phy_cell_id = flexran_get_cell_id(mod_id,i); - cell_conf[i]->has_phy_cell_id = 1; - - cell_conf[i]->cell_id = i; - cell_conf[i]->has_cell_id = 1; - - cell_conf[i]->pusch_hopping_offset = flexran_get_hopping_offset(mod_id,i); - cell_conf[i]->has_pusch_hopping_offset = 1; - - if (flexran_get_hopping_mode(mod_id,i) == 0) { - cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER; - } else if(flexran_get_hopping_mode(mod_id,i) == 1) { - cell_conf[i]->hopping_mode = PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA; - } - cell_conf[i]->has_hopping_mode = 1; - - cell_conf[i]->n_sb = flexran_get_n_SB(mod_id,i); - cell_conf[i]->has_n_sb = 1; - - if (flexran_get_phich_resource(mod_id,i) == 0) { - cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH; //0 - } else if (flexran_get_phich_resource(mod_id,i) == 1) { - cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF; //1 - } else if (flexran_get_phich_resource(mod_id,i) == 2) { - cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE; // 2 - } else if (flexran_get_phich_resource(mod_id,i) == 3) { - cell_conf[i]->phich_resource = PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO;//3 - } - cell_conf[i]->has_phich_resource = 1; - - if (flexran_get_phich_duration(mod_id,i) == 0) { - cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL; - } else if(flexran_get_phich_duration(mod_id,i) == 1) { - cell_conf[i]->phich_duration = PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED; - } - cell_conf[i]->has_phich_duration = 1; - cell_conf[i]->init_nr_pdcch_ofdm_sym = flexran_get_num_pdcch_symb(mod_id,i); - cell_conf[i]->has_init_nr_pdcch_ofdm_sym = 1; - Protocol__FlexSiConfig *si_config; - si_config = malloc(sizeof(Protocol__FlexSiConfig)); - if(si_config == NULL) - goto error; - protocol__flex_si_config__init(si_config); - - si_config->sfn = flexran_get_current_system_frame_num(mod_id); - si_config->has_sfn = 1; - - si_config->sib1_length = flexran_get_sib1_length(mod_id,i); - si_config->has_sib1_length = 1; - - si_config->si_window_length = (uint32_t) flexran_get_si_window_length(mod_id, i); - si_config->has_si_window_length = 1; - - si_config->n_si_message = 0; - - /* Protocol__FlexSiMessage **si_message; */ - /* si_message = malloc(sizeof(Protocol__FlexSiMessage *) * si_config->n_si_message); */ - /* if(si_message == NULL) */ - /* goto error; */ - /* for(j = 0; j < si_config->n_si_message; j++){ */ - /* si_message[j] = malloc(sizeof(Protocol__FlexSiMessage)); */ - /* if(si_message[j] == NULL) */ - /* goto error; */ - /* protocol__flex_si_message__init(si_message[j]); */ - /* //TODO: Fill in with actual value, Periodicity of SI msg in radio frames */ - /* si_message[j]->periodicity = 1; //SIPeriod */ - /* si_message[j]->has_periodicity = 1; */ - /* //TODO: Fill in with actual value, rhe length of the SI message in bytes */ - /* si_message[j]->length = 10; */ - /* si_message[j]->has_length = 1; */ - /* } */ - /* if(si_config->n_si_message > 0){ */ - /* si_config->si_message = si_message; */ - /* } */ - - cell_conf[i]->si_config = si_config; - - cell_conf[i]->dl_bandwidth = flexran_get_N_RB_DL(mod_id,i); - cell_conf[i]->has_dl_bandwidth = 1; - - cell_conf[i]->ul_bandwidth = flexran_get_N_RB_UL(mod_id,i); - cell_conf[i]->has_ul_bandwidth = 1; - - if (flexran_get_ul_cyclic_prefix_length(mod_id, i) == 0) { - cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL; - } else if(flexran_get_ul_cyclic_prefix_length(mod_id, i) == 1) { - cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED; - } - cell_conf[i]->has_ul_cyclic_prefix_length = 1; - - if (flexran_get_ul_cyclic_prefix_length(mod_id,i) == 0) { - cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_NORMAL; - } else if (flexran_get_ul_cyclic_prefix_length(mod_id,i) == 1) { - cell_conf[i]->ul_cyclic_prefix_length = PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_EXTENDED; - } - - cell_conf[i]->has_dl_cyclic_prefix_length = 1; - cell_conf[i]->antenna_ports_count = flexran_get_antenna_ports(mod_id, i); - cell_conf[i]->has_antenna_ports_count = 1; - - if (flexran_get_duplex_mode(mod_id,i) == 1) { - cell_conf[i]->duplex_mode = PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD; - } else if(flexran_get_duplex_mode(mod_id,i) == 0) { - cell_conf[i]->duplex_mode = PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; - } - cell_conf[i]->has_duplex_mode = 1; - cell_conf[i]->subframe_assignment = flexran_get_subframe_assignment(mod_id, i); - cell_conf[i]->has_subframe_assignment = 1; - cell_conf[i]->special_subframe_patterns = flexran_get_special_subframe_assignment(mod_id,i); - cell_conf[i]->has_special_subframe_patterns = 1; - //TODO: Fill in with actual value, The MBSFN radio frame period - cell_conf[i]->n_mbsfn_subframe_config_rfperiod = 0; - uint32_t *elem_rfperiod; - elem_rfperiod = (uint32_t *) malloc(sizeof(uint32_t) *cell_conf[i]->n_mbsfn_subframe_config_rfperiod); - if(elem_rfperiod == NULL) - goto error; - for(j = 0; j < cell_conf[i]->n_mbsfn_subframe_config_rfperiod; j++){ - elem_rfperiod[j] = 1; - } - cell_conf[i]->mbsfn_subframe_config_rfperiod = elem_rfperiod; - - //TODO: Fill in with actual value, The MBSFN radio frame offset - cell_conf[i]->n_mbsfn_subframe_config_rfoffset = 0; - uint32_t *elem_rfoffset; - elem_rfoffset = (uint32_t *) malloc(sizeof(uint32_t) *cell_conf[i]->n_mbsfn_subframe_config_rfoffset); - if(elem_rfoffset == NULL) - goto error; - for(j = 0; j < cell_conf[i]->n_mbsfn_subframe_config_rfoffset; j++){ - elem_rfoffset[j] = 1; - } - cell_conf[i]->mbsfn_subframe_config_rfoffset = elem_rfoffset; - - //TODO: Fill in with actual value, Bitmap indicating the MBSFN subframes - cell_conf[i]->n_mbsfn_subframe_config_sfalloc = 0; - uint32_t *elem_sfalloc; - elem_sfalloc = (uint32_t *) malloc(sizeof(uint32_t) *cell_conf[i]->n_mbsfn_subframe_config_sfalloc); - if(elem_sfalloc == NULL) - goto error; - for(j = 0; j < cell_conf[i]->n_mbsfn_subframe_config_sfalloc; j++){ - elem_sfalloc[j] = 1; - } - cell_conf[i]->mbsfn_subframe_config_sfalloc = elem_sfalloc; - - cell_conf[i]->prach_config_index = flexran_get_prach_ConfigIndex(mod_id,i); - cell_conf[i]->has_prach_config_index = 1; - - cell_conf[i]->prach_freq_offset = flexran_get_prach_FreqOffset(mod_id,i); - cell_conf[i]->has_prach_freq_offset = 1; - - cell_conf[i]->ra_response_window_size = flexran_get_ra_ResponseWindowSize(mod_id,i); - cell_conf[i]->has_ra_response_window_size = 1; - - cell_conf[i]->mac_contention_resolution_timer = flexran_get_mac_ContentionResolutionTimer(mod_id,i); - cell_conf[i]->has_mac_contention_resolution_timer = 1; - - cell_conf[i]->max_harq_msg3tx = flexran_get_maxHARQ_Msg3Tx(mod_id,i); - cell_conf[i]->has_max_harq_msg3tx = 1; - - cell_conf[i]->n1pucch_an = flexran_get_n1pucch_an(mod_id,i); - cell_conf[i]->has_n1pucch_an = 1; - - cell_conf[i]->deltapucch_shift = flexran_get_deltaPUCCH_Shift(mod_id,i); - cell_conf[i]->has_deltapucch_shift = 1; - - cell_conf[i]->nrb_cqi = flexran_get_nRB_CQI(mod_id,i); - cell_conf[i]->has_nrb_cqi = 1; - - cell_conf[i]->srs_subframe_config = flexran_get_srs_SubframeConfig(mod_id,i); - cell_conf[i]->has_srs_subframe_config = 1; - - cell_conf[i]->srs_bw_config = flexran_get_srs_BandwidthConfig(mod_id,i); - cell_conf[i]->has_srs_bw_config = 1; - - cell_conf[i]->srs_mac_up_pts = flexran_get_srs_MaxUpPts(mod_id,i); - cell_conf[i]->has_srs_mac_up_pts = 1; - - cell_conf[i]->dl_freq = flexran_agent_get_operating_dl_freq (mod_id,i); - cell_conf[i]->has_dl_freq = 1; - - cell_conf[i]->ul_freq = flexran_agent_get_operating_ul_freq (mod_id, i); - cell_conf[i]->has_ul_freq = 1; - - cell_conf[i]->eutra_band = flexran_agent_get_operating_eutra_band (mod_id,i); - cell_conf[i]->has_eutra_band = 1; - - cell_conf[i]->dl_pdsch_power = flexran_agent_get_operating_pdsch_refpower(mod_id, i); - cell_conf[i]->has_dl_pdsch_power = 1; - - cell_conf[i]->ul_pusch_power = flexran_agent_get_operating_pusch_p0 (mod_id,i); - cell_conf[i]->has_ul_pusch_power = 1; - - if (flexran_get_enable64QAM(mod_id,i) == 0) { - cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM; - } else if(flexran_get_enable64QAM(mod_id,i) == 1) { - cell_conf[i]->enable_64qam = PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM; - } - cell_conf[i]->has_enable_64qam = 1; + if (flexran_agent_get_phy_xface(mod_id)) + flexran_agent_fill_phy_cell_config(mod_id, i, cell_conf[i]); + if (flexran_agent_get_rrc_xface(mod_id)) + flexran_agent_fill_rrc_cell_config(mod_id, i, cell_conf[i]); + if (flexran_agent_get_mac_xface(mod_id)) + flexran_agent_fill_mac_cell_config(mod_id, i, cell_conf[i]); cell_conf[i]->carrier_index = i; cell_conf[i]->has_carrier_index = 1; - - /* get a pointer to the config which is maintained in the agent throughout - * its lifetime */ - cell_conf[i]->slice_config = flexran_agent_get_slice_config(mod_id); } + enb_config_reply_msg->cell_config=cell_conf; } + *msg = malloc(sizeof(Protocol__FlexranMessage)); + if(*msg == NULL) goto error; + protocol__flexran_message__init(*msg); (*msg)->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG; (*msg)->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__SUCCESSFUL_OUTCOME; (*msg)->enb_config_reply_msg = enb_config_reply_msg; - return 0; - - error: +error: + // TODO: Need to make proper error handling if (header != NULL) free(header); + if (enb_config_reply_msg != NULL) free(enb_config_reply_msg); + if(*msg != NULL) free(*msg); + //LOG_E(FLEXRAN_AGENT, "%s: an error occured\n", __FUNCTION__); return -1; } int flexran_agent_rrc_measurement(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { - protocol_ctxt_t ctxt; - Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexRrcTriggering *triggering = input->rrc_triggering; - agent_reconf_rrc *reconf_param = malloc(sizeof(agent_reconf_rrc)); - - reconf_param->trigger_policy = triggering->rrc_trigger; - struct rrc_eNB_ue_context_s *ue_context_p = NULL; - - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[mod_id]->rrc_ue_head)){ - - - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id); - - flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, ue_context_p, 0, reconf_param); - + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[mod_id]->rrc_ue_head)) { + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id); + flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, ue_context_p, 0, reconf_param); } - - *msg = NULL; return 0; } -int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg){ +int flexran_agent_destroy_rrc_measurement(Protocol__FlexranMessage *msg) { // TODO return 0; } -int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) -{ +int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexEnbConfigReply *enb_config = input->enb_config_reply_msg; @@ -1141,23 +804,22 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot if (enb_config->n_cell_config > 1) LOG_W(FLEXRAN_AGENT, "ignoring slice configs for other cell except cell 0\n"); - if (enb_config->cell_config[0]->slice_config) { + if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) { prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config); - } else { - initiate_soft_restart(mod_id, enb_config->cell_config[0]); + //} else { + // initiate_soft_restart(mod_id, enb_config->cell_config[0]); } *msg = NULL; return 0; } -int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) -{ +int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { int i; Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexUeConfigReply *ue_config_reply = input->ue_config_reply_msg; - for (i = 0; i < ue_config_reply->n_ue_config; i++) + for (i = 0; flexran_agent_get_mac_xface(mod_id) && i < ue_config_reply->n_ue_config; i++) prepare_ue_slice_assoc_update(mod_id, ue_config_reply->ue_config[i]); *msg = NULL; diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index c83d3c24819ad30e0dad650a17d8c7c3d7a1c620..8419dae62d1a69c7a748d8aaa7aa3999c8fb5434 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -154,6 +154,7 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr /* Function to be used to handle reply message . */ int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *report_config, Protocol__FlexranMessage **msg); +int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg); /* Top level Statistics request protocol message constructor and destructor */ int flexran_agent_stats_request(mid_t mod_id, xid_t xid, const stats_request_config_t *report_config, Protocol__FlexranMessage **msg); @@ -161,8 +162,6 @@ int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg); err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id); -void flexran_agent_send_update_stats(mid_t mod_id); - err_code_t flexran_agent_enable_cont_stats_update(mid_t mod_id, xid_t xid, stats_request_config_t *stats_req) ; err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id); diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 9f1a1d3710a8a106400f2bd0bd4499110110c5bd..9091753f9ac9e26795e01f0a473787cf89036dbb 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -159,7 +159,7 @@ int parse_enb_id(mid_t mod_id, yaml_parser_t *parser) { } // Check what key needs to be set // use eNB egistered - if (mac_agent_registered[mod_id]) { + if (flexran_agent_get_mac_xface(mod_id)) { LOG_I(ENB_APP, "Setting parameter for eNB %s\n", event.data.scalar.value); if (strcmp((char *) event.data.scalar.tag, YAML_INT_TAG) == 0) { // if int if ((strtol((char *) event.data.scalar.value, &endptr, 10))== mod_id ) { // enb_id == mod_id: right enb instance to be configured @@ -542,7 +542,7 @@ int apply_parameter_modification(void *parameter, yaml_parser_t *parser) { void initiate_soft_restart(module_id_t mod_id, Protocol__FlexCellConfig *c) { - uint8_t cc_id = c->has_cell_id ? c->cell_id : 0; + const uint8_t cc_id = 0; if (c->has_eutra_band) { flexran_agent_set_operating_eutra_band(mod_id, cc_id, c->eutra_band); LOG_I(ENB_APP, "Setting eutra_band to %d\n", c->eutra_band); diff --git a/openair2/ENB_APP/flexran_agent_defs.h b/openair2/ENB_APP/flexran_agent_defs.h index 57265b38b74a654a60e57411125cf94aeda3a425..b97e56092da7013169633c75fdcb36d807910883 100644 --- a/openair2/ENB_APP/flexran_agent_defs.h +++ b/openair2/ENB_APP/flexran_agent_defs.h @@ -138,14 +138,14 @@ typedef enum { FLEXRAN_AGENT_TIMER_STATE_MAX, } flexran_agent_timer_state_t; -#define FLEXRAN_CAP_LOPHY 1 -#define FLEXRAN_CAP_HIPHY 2 -#define FLEXRAN_CAP_LOMAC 4 -#define FLEXRAN_CAP_HIMAC 8 -#define FLEXRAN_CAP_RLC 16 -#define FLEXRAN_CAP_PDCP 32 -#define FLEXRAN_CAP_SDAP 64 -#define FLEXRAN_CAP_RRC 128 +#define FLEXRAN_CAP_LOPHY(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY)) > 0) +#define FLEXRAN_CAP_HIPHY(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)) > 0) +#define FLEXRAN_CAP_LOMAC(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC)) > 0) +#define FLEXRAN_CAP_HIMAC(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC)) > 0) +#define FLEXRAN_CAP_RLC(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC)) > 0) +#define FLEXRAN_CAP_PDCP(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)) > 0) +#define FLEXRAN_CAP_SDAP(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)) > 0) +#define FLEXRAN_CAP_RRC(cApS) (((cApS) & (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC)) > 0) typedef enum { ENB_NORMAL_OPERATION = 0x0, @@ -162,8 +162,6 @@ typedef struct { char *cache_name; mid_t mod_id; - uint64_t agent_id; - uint8_t capability_mask; /* lock for waiting before starting or soft-restart */ pthread_cond_t cond_node_ctrl; diff --git a/openair2/ENB_APP/flexran_agent_extern.h b/openair2/ENB_APP/flexran_agent_extern.h index ae77e9227aa960afa13823ff9fe67996253d356a..e1dec8506ce6c257429d773981c3edd2bbb9d91d 100644 --- a/openair2/ENB_APP/flexran_agent_extern.h +++ b/openair2/ENB_APP/flexran_agent_extern.h @@ -31,27 +31,22 @@ #define __FLEXRAN_AGENT_EXTERN_H__ #include "flexran_agent_defs.h" +#include "flexran_agent_phy_defs.h" #include "flexran_agent_mac_defs.h" #include "flexran_agent_rrc_defs.h" #include "flexran_agent_pdcp_defs.h" -/* Control module interface for the communication of the MAC Control Module with the agent */ -extern AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; +/* Control module interface for the communication of the PHY control module with the agent */ +AGENT_PHY_xface *flexran_agent_get_phy_xface(mid_t mod_id); -/* Flag indicating whether the VSFs for the MAC control module have been registered */ -extern unsigned int mac_agent_registered[NUM_MAX_ENB]; +/* Control module interface for the communication of the MAC Control Module with the agent */ +AGENT_MAC_xface *flexran_agent_get_mac_xface(mid_t mod_id); /* Control module interface for the communication of the RRC Control Module with the agent */ -extern AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; - -/* Flag indicating whether the VSFs for the RRC control module have been registered */ -extern unsigned int rrc_agent_registered[NUM_MAX_ENB]; +AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id); /* Control module interface for the communication of the RRC Control Module with the agent */ -extern AGENT_PDCP_xface *agent_pdcp_xface[NUM_MAX_ENB]; - -/* Flag indicating whether the VSFs for the RRC control module have been registered */ -extern unsigned int pdcp_agent_registered[NUM_MAX_ENB]; +AGENT_PDCP_xface *flexran_agent_get_pdcp_xface(mid_t mod_id); /* Requried to know which UEs had a harq updated over some subframe */ extern int harq_pid_updated[NUM_MAX_UE][8]; diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index 74ea5bfa1fa80fa69d59a0af958bb7985f56aaa3..9ffb1e6cecef63c49b4f38da4d057c4954c3664b 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -63,7 +63,7 @@ flexran_agent_message_destruction_callback message_destruction_callback[] = { flexran_agent_destroy_echo_request, flexran_agent_destroy_echo_reply, flexran_agent_destroy_stats_request, - flexran_agent_mac_destroy_stats_reply, + flexran_agent_destroy_stats_reply, flexran_agent_mac_destroy_sf_trigger, flexran_agent_mac_destroy_sr_info, flexran_agent_destroy_enb_config_request, @@ -90,7 +90,8 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, uint8_t *data, uint32_t size){ - Protocol__FlexranMessage *decoded_message, *reply_message; + Protocol__FlexranMessage *decoded_message = NULL; + Protocol__FlexranMessage *reply_message = NULL; err_code_t err_code; DevAssert(data != NULL); @@ -113,7 +114,7 @@ Protocol__FlexranMessage* flexran_agent_handle_message (mid_t mod_id, err_code = ((*agent_messages_callback[decoded_message->msg_case-1][decoded_message->msg_dir-1])(mod_id, (void *) decoded_message, &reply_message)); if ( err_code < 0 ){ goto error; - } else if (err_code == 1) { //If err_code > 1, we do not want to dispose the message yet + } else if (err_code == 0) { //If err_code > 1, we do not want to dispose the message yet protocol__flexran_message__free_unpacked(decoded_message, NULL); } return reply_message; @@ -204,13 +205,12 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr // TODO: Must resolve conflicts among stats requests int i; - err_code_t err_code; + err_code_t err_code = 0; xid_t xid; uint32_t usec_interval, sec_interval; //TODO: We do not deal with multiple CCs at the moment and eNB id is 0 int enb_id = mod_id; - int UE_id; //eNB_MAC_INST *eNB = &eNB_mac_inst[enb_id]; //UE_list_t *eNB_UE_list= &eNB->UE_list; @@ -242,91 +242,115 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr //Create a list of all eNB RNTIs and cells //Set the number of UEs and create list with their RNTIs stats configs - report_config.nr_ue = flexran_get_num_ues(mod_id); //eNB_UE_list->num_UEs - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); + report_config.nr_ue = 0; + if (flexran_agent_get_rrc_xface(mod_id)) + report_config.nr_ue = flexran_get_rrc_num_ues(mod_id); + else if (flexran_agent_get_mac_xface(mod_id)) + report_config.nr_ue = flexran_get_mac_num_ues(mod_id); + + if (flexran_agent_get_rrc_xface(mod_id) && flexran_agent_get_mac_xface(mod_id) + && flexran_get_rrc_num_ues(mod_id) != flexran_get_mac_num_ues(mod_id)) { + const int nrrc = flexran_get_rrc_num_ues(mod_id); + const int nmac = flexran_get_mac_num_ues(mod_id); + report_config.nr_ue = nrrc < nmac ? nrrc : nmac; + LOG_E(FLEXRAN_AGENT, "%s(): different numbers of UEs in RRC (%d) and MAC (%d), reporting for %d UEs\n", + __func__, nrrc, nmac, report_config.nr_ue); + } + report_config.ue_report_type = malloc(sizeof(ue_report_type_t) * report_config.nr_ue); if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + if (flexran_agent_get_rrc_xface(mod_id)) { + rnti_t rntis[report_config.nr_ue]; + flexran_get_rrc_rnti_list(mod_id, rntis, report_config.nr_ue); + for (i = 0; i < report_config.nr_ue; i++) { + report_config.ue_report_type[i].ue_rnti = rntis[i]; + report_config.ue_report_type[i].ue_report_flags = ue_flags; + } } - for (i = 0; i < report_config.nr_ue; i++) { - UE_id = flexran_get_ue_id(mod_id, i); - report_config.ue_report_type[i].ue_rnti = flexran_get_ue_crnti(enb_id, UE_id); //eNB_UE_list->eNB_UE_stats[UE_PCCID(enb_id,i)][i].crnti; - report_config.ue_report_type[i].ue_report_flags = ue_flags; + if (flexran_agent_get_mac_xface(mod_id) && !flexran_agent_get_rrc_xface(mod_id)) { + for (i = 0; i < report_config.nr_ue; i++) { + const int UE_id = flexran_get_mac_ue_id(mod_id, i); + report_config.ue_report_type[i].ue_rnti = flexran_get_mac_ue_crnti(enb_id, UE_id); + report_config.ue_report_type[i].ue_report_flags = ue_flags; + } } //Set the number of CCs and create a list with the cell stats configs report_config.nr_cc = MAX_NUM_CCs; - report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc); + report_config.cc_report_type = malloc(sizeof(cc_report_type_t) * report_config.nr_cc); if (report_config.cc_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; + // TODO: Add appropriate error code + err_code = -100; + goto error; } for (i = 0; i < report_config.nr_cc; i++) { - //TODO: Must fill in the proper cell ids - report_config.cc_report_type[i].cc_id = i; - report_config.cc_report_type[i].cc_report_flags = c_flags; + //TODO: Must fill in the proper cell ids + report_config.cc_report_type[i].cc_id = i; + report_config.cc_report_type[i].cc_report_flags = c_flags; } /* Check if request was periodical */ if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_PERIODICAL) { - /* Create a one off flexran message as an argument for the periodical task */ - Protocol__FlexranMessage *timer_msg; - stats_request_config_t request_config; - request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; - request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; - request_config.period = 0; - /* Need to make sure that the ue flags are saved (Bug) */ - if (report_config.nr_ue == 0) { - report_config.nr_ue = 1; - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t)); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - report_config.ue_report_type[0].ue_rnti = 0; // Dummy value - report_config.ue_report_type[0].ue_report_flags = ue_flags; - } - request_config.config = &report_config; - flexran_agent_stats_request(enb_id, xid, &request_config, &timer_msg); - /* Create a timer */ - long timer_id = 0; - flexran_agent_timer_args_t *timer_args; - timer_args = malloc(sizeof(flexran_agent_timer_args_t)); - memset (timer_args, 0, sizeof(flexran_agent_timer_args_t)); - timer_args->mod_id = enb_id; - timer_args->msg = timer_msg; - /*Convert subframes to usec time*/ - usec_interval = 1000*comp_req->sf; - sec_interval = 0; - /*add seconds if required*/ - if (usec_interval >= 1000*1000) { - sec_interval = usec_interval/(1000*1000); - usec_interval = usec_interval%(1000*1000); - } - flexran_agent_create_timer(sec_interval, usec_interval, FLEXRAN_AGENT_DEFAULT, enb_id, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, flexran_agent_handle_timed_task,(void*) timer_args, &timer_id); + /* Create a one off flexran message as an argument for the periodical task */ + Protocol__FlexranMessage *timer_msg; + stats_request_config_t request_config; + request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; + request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; + request_config.period = 0; + /* Need to make sure that the ue flags are saved (Bug) */ + if (report_config.nr_ue == 0) { + report_config.nr_ue = 1; + report_config.ue_report_type = malloc(sizeof(ue_report_type_t)); + if (report_config.ue_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + report_config.ue_report_type[0].ue_rnti = 0; // Dummy value + report_config.ue_report_type[0].ue_report_flags = ue_flags; + } + request_config.config = &report_config; + flexran_agent_stats_request(enb_id, xid, &request_config, &timer_msg); + /* Create a timer */ + long timer_id = 0; + flexran_agent_timer_args_t *timer_args = malloc(sizeof(flexran_agent_timer_args_t)); + memset (timer_args, 0, sizeof(flexran_agent_timer_args_t)); + timer_args->mod_id = enb_id; + timer_args->msg = timer_msg; + /*Convert subframes to usec time*/ + usec_interval = 1000*comp_req->sf; + sec_interval = 0; + /*add seconds if required*/ + if (usec_interval >= 1000*1000) { + sec_interval = usec_interval/(1000*1000); + usec_interval = usec_interval%(1000*1000); + } + flexran_agent_create_timer(sec_interval, usec_interval, FLEXRAN_AGENT_DEFAULT, + enb_id, FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, xid, + flexran_agent_handle_timed_task,(void*) timer_args, &timer_id); } else if (comp_req->report_frequency == PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_CONTINUOUS) { - /*If request was for continuous updates, disable the previous configuration and - set up a new one*/ - flexran_agent_disable_cont_stats_update(mod_id); - stats_request_config_t request_config; - request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; - request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; - request_config.period = 0; - /* Need to make sure that the ue flags are saved (Bug) */ - if (report_config.nr_ue == 0) { - report_config.nr_ue = 1; - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t)); - if (report_config.ue_report_type == NULL) { - // TODO: Add appropriate error code - err_code = -100; - goto error; - } - report_config.ue_report_type[0].ue_rnti = 0; // Dummy value - report_config.ue_report_type[0].ue_report_flags = ue_flags; - } - request_config.config = &report_config; - flexran_agent_enable_cont_stats_update(enb_id, xid, &request_config); + /*If request was for continuous updates, disable the previous configuration and + set up a new one*/ + flexran_agent_disable_cont_stats_update(mod_id); + stats_request_config_t request_config; + request_config.report_type = PROTOCOL__FLEX_STATS_TYPE__FLST_COMPLETE_STATS; + request_config.report_frequency = PROTOCOL__FLEX_STATS_REPORT_FREQ__FLSRF_ONCE; + request_config.period = 0; + /* Need to make sure that the ue flags are saved (Bug) */ + if (report_config.nr_ue == 0) { + report_config.nr_ue = 1; + report_config.ue_report_type = malloc(sizeof(ue_report_type_t)); + if (report_config.ue_report_type == NULL) { + // TODO: Add appropriate error code + err_code = -100; + goto error; + } + report_config.ue_report_type[0].ue_rnti = 0; // Dummy value + report_config.ue_report_type[0].ue_report_flags = ue_flags; + } + request_config.config = &report_config; + flexran_agent_enable_cont_stats_update(enb_id, xid, &request_config); } } break; @@ -336,14 +360,14 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr report_config.nr_ue = 0; report_config.ue_report_type = NULL; report_config.nr_cc = cell_req->n_cell; - report_config.cc_report_type = (cc_report_type_t *) malloc(sizeof(cc_report_type_t) * report_config.nr_cc); + report_config.cc_report_type = malloc(sizeof(cc_report_type_t) * report_config.nr_cc); if (report_config.cc_report_type == NULL) { // TODO: Add appropriate error code err_code = -100; goto error; } for (i = 0; i < report_config.nr_cc; i++) { - //TODO: Must fill in the proper cell ids + //TODO: Must fill in the proper cell ids report_config.cc_report_type[i].cc_id = cell_req->cell[i]; report_config.cc_report_type[i].cc_report_flags = cell_req->flags; } @@ -354,14 +378,14 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr report_config.nr_cc = 0; report_config.cc_report_type = NULL; report_config.nr_ue = ue_req->n_rnti; - report_config.ue_report_type = (ue_report_type_t *) malloc(sizeof(ue_report_type_t) * report_config.nr_ue); + report_config.ue_report_type = malloc(sizeof(ue_report_type_t) * report_config.nr_ue); if (report_config.ue_report_type == NULL) { // TODO: Add appropriate error code err_code = -100; goto error; } for (i = 0; i < report_config.nr_ue; i++) { - UE_id = flexran_get_ue_id(mod_id, i); + const int UE_id = flexran_get_mac_ue_id(mod_id, i); report_config.ue_report_type[i].ue_rnti = ue_req->rnti[UE_id]; report_config.ue_report_type[i].ue_report_flags = ue_req->flags; } @@ -372,18 +396,20 @@ int flexran_agent_handle_stats(mid_t mod_id, const void *params, Protocol__Flexr goto error; } - if (flexran_agent_stats_reply(enb_id, xid, &report_config, msg )){ - err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; - goto error; - } + if (flexran_agent_stats_reply(enb_id, xid, &report_config, msg )) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } - free(report_config.ue_report_type); - free(report_config.cc_report_type); + if (report_config.ue_report_type) + free(report_config.ue_report_type); + if (report_config.cc_report_type) + free(report_config.cc_report_type); return 0; error : - LOG_E(FLEXRAN_AGENT, "errno %d occured\n", err_code); + LOG_E(FLEXRAN_AGENT, "%s(): errno %d occured\n", __func__, err_code); return err_code; } @@ -429,8 +455,7 @@ int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *re protocol__flex_ue_stats_report__init(ue_report[i]); ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; ue_report[i]->has_rnti = 1; - ue_report[i]->flags = report_config->ue_report_type[i].ue_report_flags; - ue_report[i]->has_flags = 1; + ue_report[i]->has_flags = 1; /* actual flags are filled in the CMs below */ } @@ -452,39 +477,30 @@ int flexran_agent_stats_reply(mid_t enb_id, xid_t xid, const report_config_t *re protocol__flex_cell_stats_report__init(cell_report[i]); cell_report[i]->carrier_index = report_config->cc_report_type[i].cc_id; cell_report[i]->has_carrier_index = 1; - cell_report[i]->flags = report_config->cc_report_type[i].cc_report_flags; - cell_report[i]->has_flags = 1; + cell_report[i]->has_flags = 1; /* actual flags are filled in the CMs below */ } - /* - MAC reply split - */ - - - if (flexran_agent_mac_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) { - err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; - goto error; - } - - /* - RRC reply split - */ + /* MAC reply split */ + if (flexran_agent_get_mac_xface(enb_id) + && flexran_agent_mac_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } - if (flexran_agent_rrc_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) { - err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; - goto error; - } - + /* RRC reply split */ + if (flexran_agent_get_rrc_xface(enb_id) + && flexran_agent_rrc_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } - /* - PDCP reply split - */ - - if (flexran_agent_pdcp_stats_reply(enb_id, report_config, ue_report, cell_report) < 0 ) { - err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; - goto error; - } + /* PDCP reply split */ + if (flexran_agent_get_pdcp_xface(enb_id) + && flexran_agent_pdcp_stats_reply(enb_id, report_config, ue_report, cell_report) < 0) { + err_code = PROTOCOL__FLEXRAN_ERR__MSG_BUILD; + goto error; + } stats_reply_msg->cell_report = cell_report; @@ -636,61 +652,26 @@ int flexran_agent_destroy_stats_request(Protocol__FlexranMessage *msg) { return -1; } -/* - Top Level Update - */ - -void flexran_agent_send_update_stats(mid_t mod_id) { - - Protocol__FlexranMessage *current_report = NULL; - void *data; - int size; - err_code_t err_code; - int priority = 0; - - if (pthread_mutex_lock(stats_context[mod_id].mutex)) { - goto error; +int flexran_agent_destroy_stats_reply(Protocol__FlexranMessage *msg) +{ + if (msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_STATS_REPLY_MSG) { + LOG_E(FLEXRAN_AGENT, "%s(): message is not a msg_stats_reply\n", __func__); + return -1; } - if (stats_context[mod_id].cont_update == 1) { - - /*Create a fresh report with the required flags*/ - err_code = flexran_agent_handle_stats(mod_id, (void *) stats_context[mod_id].stats_req, ¤t_report); - if (err_code < 0) { - goto error; - } - } - /* /\*TODO:Check if a previous reports exists and if yes, generate a report */ - /* *that is the diff between the old and the new report, */ - /* *respecting the thresholds. Otherwise send the new report*\/ */ - /* if (stats_context[mod_id].prev_stats_reply != NULL) { */ - - /* msg = flexran_agent_generate_diff_mac_stats_report(current_report, stats_context[mod_id].prev_stats_reply); */ - - /* /\*Destroy the old stats*\/ */ - /* flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); */ - /* } */ - /* /\*Use the current report for future comparissons*\/ */ - /* stats_context[mod_id].prev_stats_reply = current_report; */ - - - if (pthread_mutex_unlock(stats_context[mod_id].mutex)) { - goto error; - } - - if (current_report != NULL){ - data=flexran_agent_pack_message(current_report, &size); - /*Send any stats updates using the MAC channel of the eNB*/ - if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_MAC, data, size, priority)) { - err_code = PROTOCOL__FLEXRAN_ERR__MSG_ENQUEUING; - goto error; - } - - LOG_D(FLEXRAN_AGENT,"sent message with size %d\n", size); - return; - } - error: - LOG_D(FLEXRAN_AGENT, "Could not send sf trigger message\n"); + flexran_agent_mac_destroy_stats_reply(msg->stats_reply_msg); + flexran_agent_rrc_destroy_stats_reply(msg->stats_reply_msg); + flexran_agent_pdcp_destroy_stats_reply(msg->stats_reply_msg); + for (int i = 0; i < msg->stats_reply_msg->n_cell_report; ++i) + free(msg->stats_reply_msg->cell_report[i]); + for (int i = 0; i < msg->stats_reply_msg->n_ue_report; ++i) + free(msg->stats_reply_msg->ue_report[i]); + free(msg->stats_reply_msg->cell_report); + free(msg->stats_reply_msg->ue_report); + free(msg->stats_reply_msg->header); + free(msg->stats_reply_msg); + free(msg); + return 0; } err_code_t flexran_agent_disable_cont_stats_update(mid_t mod_id) { @@ -755,7 +736,7 @@ err_code_t flexran_agent_init_cont_stats_update(mid_t mod_id) { stats_context[mod_id].mutex = calloc(1, sizeof(pthread_mutex_t)); if (stats_context[mod_id].mutex == NULL) goto error; - if (pthread_mutex_init(stats_context[mod_id].mutex, NULL)) + if (pthread_mutex_init(stats_context[mod_id].mutex, NULL) != 0) goto error; return 0; @@ -772,6 +753,5 @@ err_code_t flexran_agent_destroy_cont_stats_update(mid_t mod_id) { flexran_agent_destroy_flexran_message(stats_context[mod_id].prev_stats_reply); free(stats_context[mod_id].mutex); - // mac_agent_registered[mod_id] = 0; return 1; } diff --git a/openair2/ENB_APP/flexran_agent_net_comm.c b/openair2/ENB_APP/flexran_agent_net_comm.c index d5142e5456eeb10b86c6f7cd944929c0fdaf0804..0d1c52096dce1bc277a217c0dac5e93ce60f8144 100644 --- a/openair2/ENB_APP/flexran_agent_net_comm.c +++ b/openair2/ENB_APP/flexran_agent_net_comm.c @@ -53,7 +53,7 @@ int flexran_agent_msg_send(mid_t mod_id, agent_id_t agent_id, void *data, int si return -1; } -int flexran_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *size, int *priority) { +int flexran_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *priority) { /*Check if agent id is valid*/ if (agent_id >= FLEXRAN_AGENT_MAX || agent_id < 0) { goto error; @@ -66,7 +66,7 @@ int flexran_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int * goto error; } - return channel->msg_recv(data, size, priority, channel->channel_info); + return channel->msg_recv(data, priority, channel->channel_info); error: LOG_E(FLEXRAN_AGENT, "No channel registered for agent with id %d\n", agent_id); @@ -104,7 +104,7 @@ void flexran_agent_unregister_channel(mid_t mod_id, agent_id_t agent_id) { int flexran_agent_create_channel(void *channel_info, int (*msg_send)(void *data, int size, int priority, void *channel_info), - int (*msg_recv)(void **data, int *size, int *priority, void *channel_info), + int (*msg_recv)(void **data, int *priority, void *channel_info), void (*release)(flexran_agent_channel_t *channel)) { int channel_id = ++flexran_agent_channel_id; diff --git a/openair2/ENB_APP/flexran_agent_net_comm.h b/openair2/ENB_APP/flexran_agent_net_comm.h index 2f59b0f7a379f90659e127ac2244cbba935b4919..4d012989fd80fe0788b58f8c40451f7aa78d63ef 100644 --- a/openair2/ENB_APP/flexran_agent_net_comm.h +++ b/openair2/ENB_APP/flexran_agent_net_comm.h @@ -39,7 +39,7 @@ int channel_id; void *channel_info; /*Callbacks for channel message Tx and Rx*/ int (*msg_send)(void *data, int size, int priority, void *channel_info); -int (*msg_recv)(void **data, int *size, int *priority, void *channel_info); +int (*msg_recv)(void **data, int *priority, void *channel_info); void (*release)(struct flexran_agent_channel_s *channel); } flexran_agent_channel_t; @@ -49,7 +49,7 @@ typedef struct flexran_agent_channel_instance_s{ /*Send and receive messages using the channel registered for a specific agent*/ int flexran_agent_msg_send(mid_t mod_id, agent_id_t agent_id, void *data, int size, int priority); -int flexran_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *size, int *priority); +int flexran_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *priority); /*Register a channel to an agent. Use FLEXRAN_AGENT_MAX to register the *same channel to all agents*/ @@ -61,7 +61,7 @@ void flexran_agent_unregister_channel(mid_t mod_id, agent_id_t agent_id); /*Create a new channel. Returns the id of the new channel or negative number otherwise*/ int flexran_agent_create_channel(void *channel_info, int (*msg_send)(void *data, int size, int priority, void *channel_info), - int (*msg_recv)(void **data, int *size, int *priority, void *channel_info), + int (*msg_recv)(void **data, int *priority, void *channel_info), void (*release)(flexran_agent_channel_t *channel)); /*Unregister a channel from all agents and destroy it. Returns 0 in case of success*/ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 8ada30cc82d02c36001eabe977ff1c9025f94ed5..500f4f1f3a146cdab816d697efc9a71da2c5098d 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -74,6 +74,7 @@ sub_frame_t flexran_get_current_subframe(mid_t mod_id) /* Why uint16_t, frame_t and sub_frame_t are defined as uint32_t? */ uint16_t flexran_get_sfn_sf(mid_t mod_id) { + if (!mac_is_present(mod_id)) return 0; frame_t frame = flexran_get_current_system_frame_num(mod_id); sub_frame_t subframe = flexran_get_current_subframe(mod_id); uint16_t sfn_sf, frame_mask, sf_mask; @@ -87,6 +88,7 @@ uint16_t flexran_get_sfn_sf(mid_t mod_id) uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time) { + if (!mac_is_present(mod_id)) return 0; frame_t frame = flexran_get_current_system_frame_num(mod_id); sub_frame_t subframe = flexran_get_current_subframe(mod_id); uint16_t sfn_sf, frame_mask, sf_mask; @@ -107,13 +109,42 @@ uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time) return sfn_sf; } -int flexran_get_num_ues(mid_t mod_id) +int flexran_get_mac_num_ues(mid_t mod_id) { if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.num_UEs; } -int flexran_get_ue_id(mid_t mod_id, int i) +int flexran_get_num_ue_lcs(mid_t mod_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return 0; + // Not sure whether this is needed: if (!rrc_is_present(mod_id)) return 0; + const rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id); + const int s = mac_eNB_get_rrc_status(mod_id, rnti); + if (s < RRC_CONNECTED) + return 0; + else if (s == RRC_CONNECTED) + return 1; + else + return 3; +} + +int flexran_get_mac_ue_id_rnti(mid_t mod_id, rnti_t rnti) +{ + int n; + if (!mac_is_present(mod_id)) return 0; + /* get the (active) UE with RNTI i */ + for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) { + if (RC.mac[mod_id]->UE_list.active[n] == TRUE + && rnti == UE_RNTI(mod_id, n)) { + return n; + } + } + return 0; + +} + +int flexran_get_mac_ue_id(mid_t mod_id, int i) { int n; if (!mac_is_present(mod_id)) return 0; @@ -128,8 +159,9 @@ int flexran_get_ue_id(mid_t mod_id, int i) return 0; } -rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id) +rnti_t flexran_get_mac_ue_crnti(mid_t mod_id, mid_t ue_id) { + if (!mac_is_present(mod_id)) return 0; return UE_RNTI(mod_id, ue_id); } @@ -153,7 +185,8 @@ uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id) rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { - rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id); + if (!mac_is_present(mod_id)) return 0; + rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id); frame_t frame = flexran_get_current_frame(mod_id); sub_frame_t subframe = flexran_get_current_subframe(mod_id); mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0 @@ -166,7 +199,8 @@ rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logi rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + if (!mac_is_present(mod_id)) return 0; + rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id); frame_t frame = flexran_get_current_frame(mod_id); sub_frame_t subframe = flexran_get_current_subframe(mod_id); mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0 @@ -179,7 +213,8 @@ rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, lo frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + if (!mac_is_present(mod_id)) return 0; + rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id); frame_t frame = flexran_get_current_frame(mod_id); sub_frame_t subframe = flexran_get_current_subframe(mod_id); mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0 @@ -225,7 +260,11 @@ uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) { if (!mac_is_present(mod_id)) return 0; - return RC.mac[mod_id]->eNB_stats[cc_id].total_ulsch_bytes_rx; + uint64_t bytes = 0; + for (int i = 0; i < NB_RB_MAX; ++i) { + bytes += RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_bytes_rx[i]; + } + return bytes; } uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) @@ -455,7 +494,7 @@ int flexran_get_harq(mid_t mod_id, if (mac_xface_not_ready()) return 0 ; - uint16_t rnti = flexran_get_ue_crnti(mod_id,ue_id); + uint16_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id); if (harq_flag == openair_harq_DL){ mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL); @@ -528,10 +567,16 @@ uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id) return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.pusch_HoppingOffset; } -PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id) +Protocol__FlexHoppingMode flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode; + if (!phy_is_present(mod_id, cc_id)) return -1; + switch (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode) { + case interSubFrame: + return PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER; + case intraAndInterSubFrame: + return PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA; + } + return -1; } uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id) @@ -540,33 +585,41 @@ uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id) return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB; } -uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id) +Protocol__FlexQam flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id) { if (!phy_is_present(mod_id, cc_id)) return 0; - return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM; + if (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM == TRUE) + return PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM; + else + return PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM; } -PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id) +Protocol__FlexPhichDuration flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - return RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration; + if (!phy_is_present(mod_id, cc_id)) return -1; + switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration) { + case normal: + return PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL; + case extended: + return PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED; + } + return -1; } -int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id) +Protocol__FlexPhichResource flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; + if (!phy_is_present(mod_id, cc_id)) return -1; switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) { case oneSixth: - return 0; + return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH; case half: - return 1; + return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF; case one: - return 2; + return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE; case two: - return 3; - default: - return -1; + return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO; } + return -1; } uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id) @@ -605,16 +658,28 @@ uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id) return RC.eNB[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx; } -lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) +Protocol__FlexUlCyclicPrefixLength flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - return RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL; + if (!phy_is_present(mod_id, cc_id)) return -1; + switch (RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL) { + case EXTENDED: + return PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED; + case NORMAL: + return PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL; + } + return -1; } -lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) +Protocol__FlexDlCyclicPrefixLength flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - return RC.eNB[mod_id][cc_id]->frame_parms.Ncp; + if (!phy_is_present(mod_id, cc_id)) return -1; + switch (RC.eNB[mod_id][cc_id]->frame_parms.Ncp) { + case EXTENDED: + return PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_EXTENDED; + case NORMAL: + return PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_NORMAL; + } + return -1; } uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id) @@ -721,27 +786,49 @@ uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id) * Get Messages for UE Configuration Reply * ************************************ */ +int flexran_get_rrc_num_ues(mid_t mod_id) +{ + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->Nb_ue; +} +rnti_t flexran_get_rrc_rnti_nth_ue(mid_t mod_id, int index) +{ + if (!rrc_is_present(mod_id)) return 0; + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head) { + if (index == 0) return ue_context_p->ue_context.rnti; + --index; + } + return 0; +} -LTE_TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) +int flexran_get_rrc_rnti_list(mid_t mod_id, rnti_t *list, int max_list) { - if (!rrc_is_present(mod_id)) return -1; + if (!rrc_is_present(mod_id)) return 0; + int n = 0; + struct rrc_eNB_ue_context_s* ue_context_p = NULL; + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head) { + if (n >= max_list) break; + list[n] = ue_context_p->ue_context.rnti; + ++n; + } + return n; +} - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); +LTE_TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, rnti_t rnti) +{ + if (!rrc_is_present(mod_id)) return -1; struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.mac_MainConfig) return -1; return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated; } -Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id) +Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measGapConfig) return -1; if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1; @@ -756,13 +843,10 @@ Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid } -long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) +long flexran_get_meas_gap_config_offset(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measGapConfig) return -1; if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1; @@ -776,13 +860,10 @@ long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) } } -uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id) +uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return 0; - - rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return RRC_INACTIVE; return ue_context_p->ue_context.Status; } @@ -799,13 +880,10 @@ uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id) return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; } -int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id) +int flexran_get_half_duplex(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.UE_Capability) return -1; LTE_SupportedBandListEUTRA_t *bands = &ue_context_p->ue_context.UE_Capability->rf_Parameters.supportedBandListEUTRA; @@ -815,13 +893,10 @@ int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id) return 0; } -int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id) +int flexran_get_intra_sf_hopping(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.UE_Capability) return -1; if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; @@ -833,13 +908,10 @@ int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id) return (buf >> 7) & 1; } -int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id) +int flexran_get_type2_sb_1(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.UE_Capability) return -1; if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; @@ -852,25 +924,19 @@ int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id) return (buf >> 3) & 1; } -long flexran_get_ue_category(mid_t mod_id, mid_t ue_id) +long flexran_get_ue_category(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.UE_Capability) return -1; return ue_context_p->ue_context.UE_Capability->ue_Category; } -int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id) +int flexran_get_res_alloc_type1(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.UE_Capability) return -1; if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; @@ -882,24 +948,19 @@ int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id) return (buf >> 6) & 1; } -long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id) +long flexran_get_ue_transmission_mode(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1; return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode; } -BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) +BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); if (!ue_context_p) return -1; if (!ue_context_p->ue_context.mac_MainConfig) return -1; @@ -907,65 +968,50 @@ BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id) return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling; } -long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id) +long flexran_get_maxHARQ_TX(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.mac_MainConfig) return -1; if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1; return *(ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx); } -long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id) +long flexran_get_beta_offset_ack_index(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; } -long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id) +long flexran_get_beta_offset_ri_index(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; } -long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id) +long flexran_get_beta_offset_cqi_index(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; } -BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) +BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1; @@ -973,33 +1019,46 @@ BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id) return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI; } -BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id) +BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, uint8_t cc_id) { if (!rrc_is_present(mod_id)) return -1; if (!RC.rrc[mod_id]->carrier[cc_id].sib2) return -1; return RC.rrc[mod_id]->carrier[cc_id].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; } -LTE_CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) +Protocol__FlexAperiodicCqiReportMode flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1; - return *ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; + switch (*ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) { + case LTE_CQI_ReportModeAperiodic_rm12: + return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM12; + case LTE_CQI_ReportModeAperiodic_rm20: + return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM20; + case LTE_CQI_ReportModeAperiodic_rm22: + return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM22; + case LTE_CQI_ReportModeAperiodic_rm30: + return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM30; + case LTE_CQI_ReportModeAperiodic_rm31: + return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM31; + case LTE_CQI_ReportModeAperiodic_rm32_v1250: + return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM32_v1250; + case LTE_CQI_ReportModeAperiodic_rm10_v1310: + return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM10_v1310; + case LTE_CQI_ReportModeAperiodic_rm11_v1310: + return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM11_v1310; + default: + return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; + } } -long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id) +long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1; @@ -1007,26 +1066,20 @@ long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id) return *(ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode); } -long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id) +long flexran_get_ack_nack_repetition_factor(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1; return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor; } -long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) +long flexran_get_extended_bsr_size(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.mac_MainConfig) return -1; if (!ue_context_p->ue_context.mac_MainConfig->ext2) return -1; @@ -1034,13 +1087,10 @@ long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id) return *(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10); } -int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) +int flexran_get_ue_transmission_antenna(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1; @@ -1054,16 +1104,12 @@ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) } } -uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id) +uint64_t flexran_get_ue_imsi(mid_t mod_id, rnti_t rnti) { uint64_t imsi; if (!rrc_is_present(mod_id)) return 0; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return 0; - imsi = ue_context_p->ue_context.imsi.digit15; imsi += ue_context_p->ue_context.imsi.digit14 * 10; // pow(10, 1) imsi += ue_context_p->ue_context.imsi.digit13 * 100; // pow(10, 2) @@ -1212,16 +1258,12 @@ void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_fra } /*********** PDCP *************/ -/*PDCP super frame counter flexRAN*/ -/* TODO the following is a hack. all the functions below should instead already - * receive the PDCP's uid and operate on it and the caller has the obligation - * to get the ID for this layer. - */ -static inline uint16_t flexran_get_pdcp_uid(mid_t mod_id, mid_t ue_id) +uint16_t flexran_get_pdcp_uid_from_rnti(mid_t mod_id, rnti_t rnti) { - rnti_t rnti = flexran_get_ue_crnti(mod_id, ue_id); if (rnti == NOT_A_RNTI) return 0; + if (mod_id < 0 || mod_id >= RC.nb_inst) + return 0; for (uint16_t pdcp_uid = 0; pdcp_uid < MAX_MOBILES_PER_ENB; ++pdcp_uid) { if (pdcp_enb[mod_id].rnti[pdcp_uid] == rnti) @@ -1230,189 +1272,201 @@ static inline uint16_t flexran_get_pdcp_uid(mid_t mod_id, mid_t ue_id) return 0; } +/*PDCP super frame counter flexRAN*/ uint32_t flexran_get_pdcp_sfn(mid_t mod_id) { + if (mod_id < 0 || mod_id >= RC.nb_inst) + return 0; return pdcp_enb[mod_id].sfn; } /*PDCP super frame counter flexRAN*/ -void flexran_set_pdcp_tx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window) +void flexran_set_pdcp_tx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); - if (obs_window > 0 ){ - Pdcp_stats_tx_window_ms[mod_id][uid]=obs_window; - } - else{ - Pdcp_stats_tx_window_ms[mod_id][uid]=1000; - } + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB) + return; + Pdcp_stats_tx_window_ms[mod_id][uid] = obs_window > 0 ? obs_window : 1000; } /*PDCP super frame counter flexRAN*/ -void flexran_set_pdcp_rx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window) +void flexran_set_pdcp_rx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); - if (obs_window > 0 ){ - Pdcp_stats_rx_window_ms[mod_id][uid]=obs_window; - } - else{ - Pdcp_stats_rx_window_ms[mod_id][uid]=1000; - } + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB) + return; + Pdcp_stats_rx_window_ms[mod_id][uid] = obs_window > 0 ? obs_window : 1000; } /*PDCP num tx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_tx(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_tx(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id > MAX_NUM_CCs || ue_id < 0 || ue_id > MAX_MOBILES_PER_ENB - || lcid < 0 || lcid > NB_RB_MAX) - return -1; - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_tx[mod_id][uid][lcid]; } /*PDCP num tx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_tx_bytes[mod_id][uid][lcid]; } /*PDCP number of transmit packet / second status flexRAN*/ -uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_tx_w[mod_id][uid][lcid]; } /*PDCP throughput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_tx_bytes_w[mod_id][uid][lcid]; } /*PDCP tx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_tx_sn[mod_id][uid][lcid]; } /*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_tx_aiat[mod_id][uid][lcid]; } /*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_tx_aiat_w[mod_id][uid][lcid]; } /*PDCP num rx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_rx(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_rx[mod_id][uid][lcid]; } /*PDCP num rx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_rx_bytes[mod_id][uid][lcid]; } /*PDCP number of received packet / second flexRAN*/ -uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_rx_w[mod_id][uid][lcid]; } /*PDCP gootput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_rx_bytes_w[mod_id][uid][lcid]; } /*PDCP rx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_rx_sn[mod_id][uid][lcid]; } /*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_rx_aiat[mod_id][uid][lcid]; } /*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_rx_aiat_w[mod_id][uid][lcid]; } /*PDCP num of received outoforder pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid) +uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, uint16_t uid, lcid_t lcid) { - uint16_t uid = flexran_get_pdcp_uid(mod_id, ue_id); + if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 + || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) + return 0; return Pdcp_stats_rx_outoforder[mod_id][uid][lcid]; } /******************** RRC *****************************/ -LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) +LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; return ue_context_p->ue_context.measResults->measId; } -float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id) +float flexran_get_rrc_pcell_rsrp(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult]; } -float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id) +float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult]; } /*Number of neighbouring cells for specific UE*/ -int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id) +int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti) { if (!rrc_is_present(mod_id)) return 0; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return 0; if (!ue_context_p->ue_context.measResults) return 0; if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0; @@ -1420,13 +1474,10 @@ int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id) return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count; } -LTE_PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id) +long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; @@ -1435,13 +1486,10 @@ LTE_PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, in return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId; } -float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id) +float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; @@ -1451,13 +1499,10 @@ float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id) return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)]; } -float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) +float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id) { if (!rrc_is_present(mod_id)) return -1; - - rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id); struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; @@ -1466,6 +1511,31 @@ float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)]; } +uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id) +{ + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->configuration.num_plmn; +} + +uint16_t flexran_get_rrc_mcc(mid_t mod_id, uint8_t index) +{ + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->configuration.mcc[index]; +} + +uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index) +{ + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->configuration.mnc[index]; +} + +uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index) +{ + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->configuration.mnc_digit_length[index]; +} + +/**************************** SLICING ****************************/ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; @@ -1478,7 +1548,7 @@ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) { if (!mac_is_present(mod_id)) return; - if (flexran_get_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; + if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; if (!flexran_dl_slice_exists(mod_id, slice_idx)) return; RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[ue_id] = slice_idx; } @@ -1495,7 +1565,7 @@ int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) { if (!mac_is_present(mod_id)) return; - if (flexran_get_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; + if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; if (!flexran_ul_slice_exists(mod_id, slice_idx)) return; RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[ue_id] = slice_idx; } @@ -1881,3 +1951,95 @@ int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb = dlsym(NULL, name); return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL; } + +/**************************** General BS info ****************************/ +uint64_t flexran_get_bs_id(mid_t mod_id) +{ + if (!rrc_is_present(mod_id)) return 0; + return RC.rrc[mod_id]->nr_cellid; +} + +size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps) +{ + if (!caps) return 0; + if (!rrc_is_present(mod_id)) return 0; + size_t n_caps = 0; + switch (RC.rrc[mod_id]->node_type) { + case ngran_eNB_CU: + case ngran_ng_eNB_CU: + case ngran_gNB_CU: + n_caps = 3; + *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability)); + AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n", + n_caps * sizeof(Protocol__FlexBsCapability)); + (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__PDCP; + (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP; + (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__RRC; + break; + case ngran_eNB_DU: + case ngran_gNB_DU: + n_caps = 5; + *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability)); + AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n", + n_caps * sizeof(Protocol__FlexBsCapability)); + (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__LOPHY; + (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__HIPHY; + (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__LOMAC; + (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__HIMAC; + (*caps)[4] = PROTOCOL__FLEX_BS_CAPABILITY__RLC; + break; + case ngran_eNB: + case ngran_ng_eNB: + case ngran_gNB: + n_caps = 8; + *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability)); + AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n", + n_caps * sizeof(Protocol__FlexBsCapability)); + (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__LOPHY; + (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__HIPHY; + (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__LOMAC; + (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__HIMAC; + (*caps)[4] = PROTOCOL__FLEX_BS_CAPABILITY__RLC; + (*caps)[5] = PROTOCOL__FLEX_BS_CAPABILITY__PDCP; + (*caps)[6] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP; + (*caps)[7] = PROTOCOL__FLEX_BS_CAPABILITY__RRC; + break; + } + return n_caps; +} + +uint16_t flexran_get_capabilities_mask(mid_t mod_id) +{ + if (!rrc_is_present(mod_id)) return 0; + uint16_t mask = 0; + switch (RC.rrc[mod_id]->node_type) { + case ngran_eNB_CU: + case ngran_ng_eNB_CU: + case ngran_gNB_CU: + mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC); + break; + case ngran_eNB_DU: + case ngran_gNB_DU: + mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC); + break; + case ngran_eNB: + case ngran_ng_eNB: + case ngran_gNB: + mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP) + | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC); + break; + } + return mask; +} diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 4fa05fd2f6858e0758662d46f2edc6bb252bf3f9..a60cdeb994cb0f7c0f25af76b01d8b5d8a30178e 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -70,15 +70,21 @@ uint16_t flexran_get_sfn_sf(mid_t mod_id); rest for frame */ uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time); -/* Return the number of attached UEs */ -int flexran_get_num_ues(mid_t mod_id); +/* Return the number of attached UEs for the MAC */ +int flexran_get_mac_num_ues(mid_t mod_id); + +/* Get the number of logical channels per UE. This function does not consider + * dedicated bearers yet */ +int flexran_get_num_ue_lcs(mid_t mod_id, mid_t ue_id); + +/* Get the rnti of a UE with id ue_id from MAC */ +rnti_t flexran_get_mac_ue_crnti(mid_t mod_id, mid_t ue_id); + +int flexran_get_mac_ue_id_rnti(mid_t mod_id, rnti_t rnti); /* Return the UE id of attached UE as opposed to the index [0,NUM UEs] (i.e., * the i'th active UE). Returns 0 if the i'th active UE could not be found. */ -int flexran_get_ue_id(mid_t mod_id, int i); - -/* Get the rnti of a UE with id ue_id */ -rnti_t flexran_get_ue_crnti(mid_t mod_id, mid_t ue_id); +int flexran_get_mac_ue_id(mid_t mod_id, int i); /* Get the RLC buffer status report in bytes of a ue for a designated * logical channel id */ @@ -210,10 +216,10 @@ uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id); uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id); /* Get the length of the UL cyclic prefix */ -lte_prefix_type_t flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id); +Protocol__FlexUlCyclicPrefixLength flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id); /* Get the length of the DL cyclic prefix */ -lte_prefix_type_t flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id); +Protocol__FlexDlCyclicPrefixLength flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id); /* Get the physical cell id of a cell */ uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id); @@ -287,34 +293,44 @@ int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id); uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id); -PUSCH_HOPPING_t flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id); +Protocol__FlexHoppingMode flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id); uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id); uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id); -int flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id); +Protocol__FlexPhichResource flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id); -uint8_t flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id); +Protocol__FlexQam flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id); -PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id); +Protocol__FlexPhichDuration flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id); /* * ************************************ * Get Messages for UE Configuration Reply * ************************************ */ +/* Get the number of attached UEs for the RRC */ +int flexran_get_rrc_num_ues(mid_t mod_id); + +/* Get the RNTI of UE at index 'index' in RRC list */ +rnti_t flexran_get_rrc_rnti_nth_ue(mid_t mod_id, int index); + +/* Get the list of RNTIs of up to max_list entries. When max_list >= + * flexran_get_rrc_num_ues(), gets a list of all UEs registered in the RRC. UE + * RNTIs are saved in list, returns number of saved RNTIs */ +int flexran_get_rrc_rnti_list(mid_t mod_id, rnti_t *list, int max_list); /* Get timer in subframes. Controls the synchronization status of the UE, not the actual timing advance procedure. See TS 36.321 */ -LTE_TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id); +LTE_TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, rnti_t rnti); /* Get measurement gap configuration. See TS 36.133 */ -Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id); +Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, rnti_t rnti); /* Get measurement gap configuration offset if applicable */ -long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id); +long flexran_get_meas_gap_config_offset(mid_t mod_id, rnti_t rnti); /* DL aggregated bit-rate of non-gbr bearer per UE. See TS 36.413 */ @@ -325,62 +341,62 @@ uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id); uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id); /* Only half-duplex support. FDD operation. Boolean value */ -int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id); +int flexran_get_half_duplex(mid_t mod_id, rnti_t rnti); /* Support of intra-subframe hopping. Boolean value */ -int flexran_get_intra_sf_hopping(mid_t mod_id, mid_t ue_id); +int flexran_get_intra_sf_hopping(mid_t mod_id, rnti_t rnti); /* UE support for type 2 hopping with n_sb>1 */ -int flexran_get_type2_sb_1(mid_t mod_id, mid_t ue_id); +int flexran_get_type2_sb_1(mid_t mod_id, rnti_t rnti); /* Get the UE category */ -long flexran_get_ue_category(mid_t mod_id, mid_t ue_id); +long flexran_get_ue_category(mid_t mod_id, rnti_t rnti); /* UE support for resource allocation type 1 */ -int flexran_get_res_alloc_type1(mid_t mod_id, mid_t ue_id); +int flexran_get_res_alloc_type1(mid_t mod_id, rnti_t rnti); /* Get UE transmission mode */ -long flexran_get_ue_transmission_mode(mid_t mod_id, mid_t ue_id); +long flexran_get_ue_transmission_mode(mid_t mod_id, rnti_t rnti); /* Boolean value. See TS 36.321 */ -BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, mid_t ue_id); +BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, rnti_t rnti); /* The max HARQ retransmission for UL. See TS 36.321 */ -long flexran_get_maxHARQ_TX(mid_t mod_id, mid_t ue_id); +long flexran_get_maxHARQ_TX(mid_t mod_id, rnti_t rnti); /* See TS 36.213 */ -long flexran_get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id); +long flexran_get_beta_offset_ack_index(mid_t mod_id, rnti_t rnti); /* See TS 36.213 */ -long flexran_get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id); +long flexran_get_beta_offset_ri_index(mid_t mod_id, rnti_t rnti); /* See TS 36.213 */ -long flexran_get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id); +long flexran_get_beta_offset_cqi_index(mid_t mod_id, rnti_t rnti); /* Boolean. See TS36.213, Section 10.1 */ -BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id); +BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, rnti_t rnti); /* Boolean. See TS 36.213, Section 8.2 */ -BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id); +BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, uint8_t cc_id); /* Get aperiodic CQI report mode */ -LTE_CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id); +Protocol__FlexAperiodicCqiReportMode flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id, rnti_t rnti); /* Get ACK/NACK feedback mode. TDD only */ -long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id); +long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, rnti_t rnti); /* See TS36.213, section 10.1 */ -long flexran_get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id); +long flexran_get_ack_nack_repetition_factor(mid_t mod_id, rnti_t rnti); /* Boolean. Extended buffer status report size */ -long flexran_get_extended_bsr_size(mid_t mod_id, mid_t ue_id); +long flexran_get_extended_bsr_size(mid_t mod_id, rnti_t rnti); /* Get number of UE transmission antennas */ -int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id); +int flexran_get_ue_transmission_antenna(mid_t mod_id, rnti_t rnti); /* Get the IMSI of UE */ -uint64_t flexran_get_ue_imsi(mid_t mod_id, mid_t ue_id); +uint64_t flexran_get_ue_imsi(mid_t mod_id, rnti_t rnti); /* Get logical channel group of a channel with id lc_id */ long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id); @@ -419,96 +435,110 @@ void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, lte_frame_type_t frame_type); /*RRC status flexRAN*/ -uint8_t flexran_get_rrc_status(mid_t mod_id, mid_t ue_id); +uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti); /***************************** PDCP ***********************/ +/* PDCP uid obtained through the RNTI */ +uint16_t flexran_get_pdcp_uid_from_rnti(mid_t mod_id, rnti_t rnti); /*PDCP superframe numberflexRAN*/ uint32_t flexran_get_pdcp_sfn(mid_t mod_id); /*PDCP pdcp tx stats window*/ -void flexran_set_pdcp_tx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window); +void flexran_set_pdcp_tx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window); /*PDCP pdcp rx stats window*/ -void flexran_set_pdcp_rx_stat_window(mid_t mod_id, mid_t ue_id, uint16_t obs_window); +void flexran_set_pdcp_rx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window); /*PDCP num tx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_tx(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_tx(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP num tx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP number of transmit packet / second status flexRAN*/ -uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP pdcp tx bytes in a given window flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP tx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP tx aggregated packet arrival per second flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP num rx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_rx(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP num rx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP number of received packet / second flexRAN*/ -uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP gootput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP rx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP rx aggregated packet arrival per second flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid); /*PDCP num of received outoforder pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid); +uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, uint16_t uid, lcid_t lcid); /*********************RRC**********************/ /*Get primary cell measuremeant id flexRAN*/ -LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id); +LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti); /*Get primary cell RSRP measurement flexRAN*/ -float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id); +float flexran_get_rrc_pcell_rsrp(mid_t mod_id, rnti_t rnti); /*Get primary cell RSRQ measurement flexRAN*/ -float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id); +float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti); /* Get RRC neighbouring measurement */ -int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id); +int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti); -/*Get physical cell id*/ -LTE_PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id); +/* Get physical cell id */ +long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id); -/*Get RSRP of neighbouring Cell*/ -float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id); +/* Get RSRP of neighbouring Cell */ +float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id); -/*Get RSRQ of neighbouring Cell*/ -float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id); +/* Get RSRQ of neighbouring Cell */ +float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id); /*Get MCC PLMN identity neighbouring Cell*/ /* currently not implemented -int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, mid_t ue_id, int cell_id); */ +int flexran_get_rrc_neigh_plmn_mcc(mid_t mod_id, rnti_t rnti, int cell_id); */ /*Get MNC PLMN identity neighbouring Cell*/ /* currently not implemented int flexran_get_rrc_neigh_plmn_mnc(mid_t mod_id, mid_t ue_id, int cell_id); */ +/* Get number of PLMNs that is broadcasted in SIB1 */ +uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id); + +/* Get index'th MCC broadcasted in SIB1 */ +uint16_t flexran_get_rrc_mcc(mid_t mod_id, uint8_t index); + +/* Get index'th MNC broadcasted in SIB1 */ +uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index); + +/* Get index'th MNC's digit length broadcasted in SIB1 */ +uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index); + /************************** Slice configuration **************************/ /* Get the DL slice ID for a UE */ @@ -660,3 +690,16 @@ void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs); char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx); /* Set the scheduler name for a slice in UL */ int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name); + +/********************* general information *****************/ +/* get an ID for this BS (or part of a BS) */ +uint64_t flexran_get_bs_id(mid_t mod_id); + +/* get the capabilities supported by the underlying network function, + * returns the number and stores list of this length in caps. If there are zero + * capabilities, *caps will be NULL */ +size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps); + +/* get the capabilities supported by the underlying network function as a bit + * mask. */ +uint16_t flexran_get_capabilities_mask(mid_t mod_id); diff --git a/openair2/ENB_APP/flexran_agent_timer.c b/openair2/ENB_APP/flexran_agent_timer.c index dda302735388ce56f5ce57d9e39de10a5cd712b8..143c2df889294377819bbeba08b28de2be5b8c63 100644 --- a/openair2/ENB_APP/flexran_agent_timer.c +++ b/openair2/ENB_APP/flexran_agent_timer.c @@ -17,10 +17,10 @@ *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org - */ + */ /*! \file flexran_agent_timer.c - * \brief FlexRAN Timer + * \brief FlexRAN Timer * \author shahab SHARIAT BAGHERI * \date 2017 * \version 0.1 @@ -35,23 +35,23 @@ //struct flexran_agent_map agent_map; flexran_agent_timer_instance_t timer_instance; int agent_timer_init = 0; -err_code_t flexran_agent_init_timer(void){ - +err_code_t flexran_agent_init_timer(void) { LOG_I(FLEXRAN_AGENT, "init RB tree\n"); + if (!agent_timer_init) { RB_INIT(&timer_instance.flexran_agent_head); agent_timer_init = 1; } - - return PROTOCOL__FLEXRAN_ERR__NO_ERR; + + return PROTOCOL__FLEXRAN_ERR__NO_ERR; } RB_GENERATE(flexran_agent_map, flexran_agent_timer_element_s, entry, flexran_agent_compare_timer); /* The timer_id might not be the best choice for the comparison */ -int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b){ - +int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct flexran_agent_timer_element_s *b) { if (a->timer_id < b->timer_id) return -1; + if (a->timer_id > b->timer_id) return 1; // equal timers @@ -59,52 +59,53 @@ int flexran_agent_compare_timer(struct flexran_agent_timer_element_s *a, struct } err_code_t flexran_agent_create_timer(uint32_t interval_sec, - uint32_t interval_usec, - agent_id_t agent_id, - instance_t instance, - uint32_t timer_type, - xid_t xid, - flexran_agent_timer_callback_t cb, - void* timer_args, - long *timer_id){ - + uint32_t interval_usec, + agent_id_t agent_id, + instance_t instance, + uint32_t timer_type, + xid_t xid, + flexran_agent_timer_callback_t cb, + void *timer_args, + long *timer_id) { struct flexran_agent_timer_element_s *e = calloc(1, sizeof(*e)); DevAssert(e != NULL); - -//uint32_t timer_id; + //uint32_t timer_id; int ret=-1; - - if ((interval_sec == 0) && (interval_usec == 0 )) + + if ((interval_sec == 0) && (interval_usec == 0 )) { + free(e); return TIMER_NULL; - - if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX) + } + + if (timer_type >= FLEXRAN_AGENT_TIMER_TYPE_MAX) { + free(e); return TIMER_TYPE_INVALIDE; - - if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_ONESHOT){ - ret = timer_setup(interval_sec, - interval_usec, - TASK_FLEXRAN_AGENT, - instance, - TIMER_ONE_SHOT, - timer_args, - timer_id); - - e->type = TIMER_ONE_SHOT; } - else if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_PERIODIC ){ - ret = timer_setup(interval_sec, - interval_usec, - TASK_FLEXRAN_AGENT, - instance, - TIMER_PERIODIC, - timer_args, - timer_id); - + + if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_ONESHOT) { + ret = timer_setup(interval_sec, + interval_usec, + TASK_FLEXRAN_AGENT, + instance, + TIMER_ONE_SHOT, + timer_args, + timer_id); + + e->type = TIMER_ONE_SHOT; + } else if (timer_type == FLEXRAN_AGENT_TIMER_TYPE_PERIODIC ) { + ret = timer_setup(interval_sec, + interval_usec, + TASK_FLEXRAN_AGENT, + instance, + TIMER_PERIODIC, + timer_args, + timer_id); e->type = TIMER_PERIODIC; } - + if (ret < 0 ) { - return TIMER_SETUP_FAILED; + free(e); + return TIMER_SETUP_FAILED; } e->agent_id = agent_id; @@ -112,19 +113,16 @@ err_code_t flexran_agent_create_timer(uint32_t interval_sec, e->state = FLEXRAN_AGENT_TIMER_STATE_ACTIVE; e->timer_id = *timer_id; e->xid = xid; - e->timer_args = timer_args; + e->timer_args = timer_args; e->cb = cb; /*element should be a real pointer*/ - RB_INSERT(flexran_agent_map, &timer_instance.flexran_agent_head, e); - + RB_INSERT(flexran_agent_map, &timer_instance.flexran_agent_head, e); LOG_I(FLEXRAN_AGENT,"Created a new timer with id 0x%lx for agent %d, instance %d \n", - e->timer_id, e->agent_id, e->instance); - - return 0; + e->timer_id, e->agent_id, e->instance); + return 0; } -err_code_t flexran_agent_destroy_timer(long timer_id){ - +err_code_t flexran_agent_destroy_timer(long timer_id) { struct flexran_agent_timer_element_s *e = get_timer_entry(timer_id); if (e != NULL ) { @@ -132,13 +130,12 @@ err_code_t flexran_agent_destroy_timer(long timer_id){ flexran_agent_destroy_flexran_message(e->timer_args->msg); free(e); } - - if (timer_remove(timer_id) < 0 ) + + if (timer_remove(timer_id) < 0 ) goto error; - - return 0; - error: + return 0; +error: LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); return TIMER_REMOVED_FAILED ; } @@ -152,66 +149,59 @@ err_code_t flexran_agent_destroy_timer_by_task_id(xid_t xid) { RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); flexran_agent_destroy_flexran_message(e->timer_args->msg); free(e); - if (timer_remove(timer_id) < 0 ) { - goto error; + + if (timer_remove(timer_id) < 0 ) { + goto error; } } } return 0; - - error: +error: LOG_E(FLEXRAN_AGENT, "timer can't be removed\n"); return TIMER_REMOVED_FAILED ; } -err_code_t flexran_agent_destroy_timers(void){ - +err_code_t flexran_agent_destroy_timers(void) { struct flexran_agent_timer_element_s *e = NULL; - RB_FOREACH(e, flexran_agent_map, &timer_instance.flexran_agent_head) { RB_REMOVE(flexran_agent_map, &timer_instance.flexran_agent_head, e); timer_remove(e->timer_id); flexran_agent_destroy_flexran_message(e->timer_args->msg); free(e); - } - + } return 0; - } void flexran_agent_sleep_until(struct timespec *ts, int delay) { ts->tv_nsec += delay; - if(ts->tv_nsec >= 1000*1000*1000){ + + if(ts->tv_nsec >= 1000*1000*1000) { ts->tv_nsec -= 1000*1000*1000; ts->tv_sec++; } + clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL); } -err_code_t flexran_agent_stop_timer(long timer_id){ - +err_code_t flexran_agent_stop_timer(long timer_id) { struct flexran_agent_timer_element_s *e=NULL; struct flexran_agent_timer_element_s search; memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); search.timer_id = timer_id; - e = RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); if (e != NULL ) { e->state = FLEXRAN_AGENT_TIMER_STATE_STOPPED; } - + timer_remove(timer_id); - return 0; } -struct flexran_agent_timer_element_s * get_timer_entry(long timer_id) { - +struct flexran_agent_timer_element_s *get_timer_entry(long timer_id) { struct flexran_agent_timer_element_s search; memset(&search, 0, sizeof(struct flexran_agent_timer_element_s)); search.timer_id = timer_id; - - return RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); + return RB_FIND(flexran_agent_map, &timer_instance.flexran_agent_head, &search); } diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-CommonDataTypes.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-CommonDataTypes.asn new file mode 100644 index 0000000000000000000000000000000000000000..3e4e41784553864421420058f1bee9d5cb1ee53e --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-CommonDataTypes.asn @@ -0,0 +1,32 @@ +-- ************************************************************** +-- +-- Common definitions +-- +-- ************************************************************** + +F1AP-CommonDataTypes { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-CommonDataTypes (3) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +Criticality ::= ENUMERATED { reject, ignore, notify } + +Presence ::= ENUMERATED { optional, conditional, mandatory } + +PrivateIE-ID ::= CHOICE { + local INTEGER (0..65535), + global OBJECT IDENTIFIER +} + +ProcedureCode ::= INTEGER (0..255) + +ProtocolExtensionID ::= INTEGER (0..65535) + +ProtocolIE-ID ::= INTEGER (0..65535) + +TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome } + +END \ No newline at end of file diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Constants.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Constants.asn new file mode 100644 index 0000000000000000000000000000000000000000..6840b00bf42644b78c9a1644221436291c882738 --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Constants.asn @@ -0,0 +1,179 @@ +-- ************************************************************** +-- +-- Constant definitions +-- +-- ************************************************************** + +F1AP-Constants { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Constants (4) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + ProcedureCode, + ProtocolIE-ID + +FROM F1AP-CommonDataTypes; + + +-- ************************************************************** +-- +-- Elementary Procedures +-- +-- ************************************************************** + +id-Reset ProcedureCode ::= 0 +id-F1Setup ProcedureCode ::= 1 +id-ErrorIndication ProcedureCode ::= 2 +id-gNBDUConfigurationUpdate ProcedureCode ::= 3 +id-gNBCUConfigurationUpdate ProcedureCode ::= 4 +id-UEContextSetup ProcedureCode ::= 5 +id-UEContextRelease ProcedureCode ::= 6 +id-UEContextModification ProcedureCode ::= 7 +id-UEContextModificationRequired ProcedureCode ::= 8 +id-UEMobilityCommand ProcedureCode ::= 9 +id-UEContextReleaseRequest ProcedureCode ::= 10 +id-InitialULRRCMessageTransfer ProcedureCode ::= 11 +id-DLRRCMessageTransfer ProcedureCode ::= 12 +id-ULRRCMessageTransfer ProcedureCode ::= 13 +id-privateMessage ProcedureCode ::= 14 + +-- ************************************************************** +-- +-- Extension constants +-- +-- ************************************************************** + +maxPrivateIEs INTEGER ::= 65535 +maxProtocolExtensions INTEGER ::= 65535 +maxProtocolIEs INTEGER ::= 65535 +-- ************************************************************** +-- +-- Lists +-- +-- ************************************************************** + +maxNRARFCN INTEGER ::= 3266667 +maxnoofErrors INTEGER ::= 256 +maxnoofIndividualF1ConnectionsToReset INTEGER ::= 65536 +maxCellingNBDU INTEGER ::= 512 +maxnoofSCells INTEGER ::= 64 +maxnoofSRBs INTEGER ::= 8 +maxnoofDRBs INTEGER ::= 64 +maxnoofULTunnels INTEGER ::= 2 +maxnoofDLTunnels INTEGER ::= 2 +maxnoofBPLMNs INTEGER ::= 6 +maxnoofCandidateSpCells INTEGER ::= 64 +maxnoofPotentialSpCells INTEGER ::= 64 + +-- ************************************************************** +-- +-- IEs +-- +-- ************************************************************** + +id-Cause ProtocolIE-ID ::= 0 +id-Cells-Failed-to-be-Activated-List ProtocolIE-ID ::= 1 +id-Cells-Failed-to-be-Activated-List-Item ProtocolIE-ID ::= 2 +id-Cells-to-be-Activated-List ProtocolIE-ID ::= 3 +id-Cells-to-be-Activated-List-Item ProtocolIE-ID ::= 4 +id-Cells-to-be-Deactivated-List ProtocolIE-ID ::= 5 +id-Cells-to-be-Deactivated-List-Item ProtocolIE-ID ::= 6 +id-CriticalityDiagnostics ProtocolIE-ID ::= 7 +id-CUtoDURRCInformation ProtocolIE-ID ::= 9 +id-DRBs-FailedToBeModifiedConf-Item ProtocolIE-ID ::= 10 +id-DRBs-FailedToBeModifiedConf-List ProtocolIE-ID ::= 11 +id-DRBs-FailedToBeModified-Item ProtocolIE-ID ::= 12 +id-DRBs-FailedToBeModified-List ProtocolIE-ID ::= 13 +id-DRBs-FailedToBeSetup-Item ProtocolIE-ID ::= 14 +id-DRBs-FailedToBeSetup-List ProtocolIE-ID ::= 15 +id-DRBs-FailedToBeSetupMod-Item ProtocolIE-ID ::= 16 +id-DRBs-FailedToBeSetupMod-List ProtocolIE-ID ::= 17 +id-DRBs-ModifiedConf-Item ProtocolIE-ID ::= 18 +id-DRBs-ModifiedConf-List ProtocolIE-ID ::= 19 +id-DRBs-Modified-Item ProtocolIE-ID ::= 20 +id-DRBs-Modified-List ProtocolIE-ID ::= 21 +id-DRBs-Required-ToBeModified-Item ProtocolIE-ID ::= 22 +id-DRBs-Required-ToBeModified-List ProtocolIE-ID ::= 23 +id-DRBs-Required-ToBeReleased-Item ProtocolIE-ID ::= 24 +id-DRBs-Required-ToBeReleased-List ProtocolIE-ID ::= 25 +id-DRBs-Setup-Item ProtocolIE-ID ::= 26 +id-DRBs-Setup-List ProtocolIE-ID ::= 27 +id-DRBs-SetupMod-Item ProtocolIE-ID ::= 28 +id-DRBs-SetupMod-List ProtocolIE-ID ::= 29 +id-DRBs-ToBeModified-Item ProtocolIE-ID ::= 30 +id-DRBs-ToBeModified-List ProtocolIE-ID ::= 31 +id-DRBs-ToBeReleased-Item ProtocolIE-ID ::= 32 +id-DRBs-ToBeReleased-List ProtocolIE-ID ::= 33 +id-DRBs-ToBeSetup-Item ProtocolIE-ID ::= 34 +id-DRBs-ToBeSetup-List ProtocolIE-ID ::= 35 +id-DRBs-ToBeSetupMod-Item ProtocolIE-ID ::= 36 +id-DRBs-ToBeSetupMod-List ProtocolIE-ID ::= 37 +id-DRXCycle ProtocolIE-ID ::= 38 +id-DUtoCURRCInformation ProtocolIE-ID ::= 39 +id-gNB-CU-UE-F1AP-ID ProtocolIE-ID ::= 40 +id-gNB-DU-UE-F1AP-ID ProtocolIE-ID ::= 41 +id-gNB-DU-ID ProtocolIE-ID ::= 42 +id-GNB-DU-Served-Cells-Item ProtocolIE-ID ::= 43 +id-gNB-DU-Served-Cells-List ProtocolIE-ID ::= 44 +id-gNB-DU-Name ProtocolIE-ID ::= 45 +id-NRCellID ProtocolIE-ID ::= 46 +id-oldgNB-DU-UE-F1AP-ID ProtocolIE-ID ::= 47 +id-ResetType ProtocolIE-ID ::= 48 +id-ResourceCoordinationTransferContainer ProtocolIE-ID ::= 49 +id-RRCContainer ProtocolIE-ID ::= 50 +id-SCell-ToBeRemoved-Item ProtocolIE-ID ::= 51 +id-SCell-ToBeRemoved-List ProtocolIE-ID ::= 52 +id-SCell-ToBeSetup-Item ProtocolIE-ID ::= 53 +id-SCell-ToBeSetup-List ProtocolIE-ID ::= 54 +id-SCell-ToBeSetupMod-Item ProtocolIE-ID ::= 55 +id-SCell-ToBeSetupMod-List ProtocolIE-ID ::= 56 +id-Served-Cells-To-Add-Item ProtocolIE-ID ::= 57 +id-Served-Cells-To-Add-List ProtocolIE-ID ::= 58 +id-Served-Cells-To-Delete-Item ProtocolIE-ID ::= 59 +id-Served-Cells-To-Delete-List ProtocolIE-ID ::= 60 +id-Served-Cells-To-Modify-Item ProtocolIE-ID ::= 61 +id-Served-Cells-To-Modify-List ProtocolIE-ID ::= 62 +id-SpCell-ID ProtocolIE-ID ::= 63 +id-SRBID ProtocolIE-ID ::= 64 +id-SRBs-FailedToBeSetup-Item ProtocolIE-ID ::= 65 +id-SRBs-FailedToBeSetup-List ProtocolIE-ID ::= 66 +id-SRBs-FailedToBeSetupMod-Item ProtocolIE-ID ::= 67 +id-SRBs-FailedToBeSetupMod-List ProtocolIE-ID ::= 68 +id-SRBs-Required-ToBeReleased-Item ProtocolIE-ID ::= 69 +id-SRBs-Required-ToBeReleased-List ProtocolIE-ID ::= 70 +id-SRBs-ToBeReleased-Item ProtocolIE-ID ::= 71 +id-SRBs-ToBeReleased-List ProtocolIE-ID ::= 72 +id-SRBs-ToBeSetup-Item ProtocolIE-ID ::= 73 +id-SRBs-ToBeSetup-List ProtocolIE-ID ::= 74 +id-SRBs-ToBeSetupMod-Item ProtocolIE-ID ::= 75 +id-SRBs-ToBeSetupMod-List ProtocolIE-ID ::= 76 +id-TimeToWait ProtocolIE-ID ::= 77 +id-TransactionID ProtocolIE-ID ::= 78 +id-TransmissionStopIndicator ProtocolIE-ID ::= 79 +id-UE-associatedLogicalF1-ConnectionItem ProtocolIE-ID ::= 80 +id-UE-associatedLogicalF1-ConnectionListResAck ProtocolIE-ID ::= 81 +id-gNB-CU-Name ProtocolIE-ID ::= 82 +id-SCell-FailedtoSetup-List ProtocolIE-ID ::= 83 +id-SCell-FailedtoSetup-Item ProtocolIE-ID ::= 84 +id-SCell-FailedtoSetupMod-List ProtocolIE-ID ::= 85 +id-SCell-FailedtoSetupMod-Item ProtocolIE-ID ::= 86 +id-RRCRconfigurationCompleteIndicator ProtocolIE-ID ::= 87 +id-Active-Cells-Item ProtocolIE-ID ::= 88 +id-Active-Cells-List ProtocolIE-ID ::= 89 +id-Candidate-SpCell-List ProtocolIE-ID ::= 90 +id-Candidate-SpCell-Item ProtocolIE-ID ::= 91 +id-Potential-SpCell-List ProtocolIE-ID ::= 92 +id-Potential-SpCell-Item ProtocolIE-ID ::= 93 + + +END \ No newline at end of file diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Containers.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Containers.asn new file mode 100644 index 0000000000000000000000000000000000000000..52c09d156ac108fb4b9ffc8bf033a884296bdc2a --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-Containers.asn @@ -0,0 +1,184 @@ +-- ************************************************************** +-- +-- Container definitions +-- +-- ************************************************************** + +F1AP-Containers { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Containers (5) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + Criticality, + Presence, + PrivateIE-ID, + ProtocolExtensionID, + ProtocolIE-ID + +FROM F1AP-CommonDataTypes + maxPrivateIEs, + maxProtocolExtensions, + maxProtocolIEs + +FROM F1AP-Constants; + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +F1AP-PROTOCOL-IES ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +F1AP-PROTOCOL-IES-PAIR ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &firstCriticality Criticality, + &FirstValue, + &secondCriticality Criticality, + &SecondValue, + &presence Presence +} +WITH SYNTAX { + ID &id + FIRST CRITICALITY &firstCriticality + FIRST TYPE &FirstValue + SECOND CRITICALITY &secondCriticality + SECOND TYPE &SecondValue + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol Extensions +-- +-- ************************************************************** + +F1AP-PROTOCOL-EXTENSION ::= CLASS { + &id ProtocolExtensionID UNIQUE, + &criticality Criticality, + &Extension, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + EXTENSION &Extension + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Private IEs +-- +-- ************************************************************** + +F1AP-PRIVATE-IES ::= CLASS { + &id PrivateIE-ID, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Container for Protocol IEs +-- +-- ************************************************************** + +ProtocolIE-Container {F1AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-SingleContainer {F1AP-PROTOCOL-IES : IEsSetParam} ::= + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-Field {F1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE { + id F1AP-PROTOCOL-IES.&id ({IEsSetParam}), + criticality F1AP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), + value F1AP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Protocol IE Pairs +-- +-- ************************************************************** + +ProtocolIE-ContainerPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-FieldPair {{IEsSetParam}} + +ProtocolIE-FieldPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE { + id F1AP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}), + firstCriticality F1AP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}), + firstValue F1AP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}), + secondCriticality F1AP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}), + secondValue F1AP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Protocol Extensions +-- +-- ************************************************************** + +ProtocolExtensionContainer {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= + SEQUENCE (SIZE (1..maxProtocolExtensions)) OF + ProtocolExtensionField {{ExtensionSetParam}} + +ProtocolExtensionField {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE { + id F1AP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), + criticality F1AP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), + extensionValue F1AP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Private IEs +-- +-- ************************************************************** + +PrivateIE-Container {F1AP-PRIVATE-IES : IEsSetParam } ::= + SEQUENCE (SIZE (1.. maxPrivateIEs)) OF + PrivateIE-Field {{IEsSetParam}} + +PrivateIE-Field {F1AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE { + id F1AP-PRIVATE-IES.&id ({IEsSetParam}), + criticality F1AP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}), + value F1AP-PRIVATE-IES.&Value ({IEsSetParam}{@id}) +} + +END \ No newline at end of file diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-IEs.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-IEs.asn new file mode 100644 index 0000000000000000000000000000000000000000..4a0d2abdffd1e9b6f4b5dfe14a3259989d875a01 --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-IEs.asn @@ -0,0 +1,870 @@ +-- ************************************************************** +-- +-- Information Element Definitions +-- +-- ************************************************************** + +F1AP-IEs { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-IEs (2) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + maxNRARFCN, + maxnoofErrors, + maxnoofBPLMNs, + maxnoofDLTunnels, + maxnoofULTunnels + +FROM F1AP-Constants + + Criticality, + ProcedureCode, + ProtocolIE-ID, + TriggeringMessage + +FROM F1AP-CommonDataTypes + + ProtocolExtensionContainer{}, + F1AP-PROTOCOL-EXTENSION, + ProtocolIE-SingleContainer{}, + F1AP-PROTOCOL-IES + +FROM F1AP-Containers; + +-- A + +Active-Cells-Item ::= SEQUENCE { + nRCGI NRCGI , + iE-Extensions ProtocolExtensionContainer { { Active-Cells-ItemExtIEs } } OPTIONAL, + ... +} + +Active-Cells-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +AllocationAndRetentionPriority ::= SEQUENCE { + priorityLevel PriorityLevel, + pre-emptionCapability Pre-emptionCapability, + pre-emptionVulnerability Pre-emptionVulnerability, + iE-Extensions ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL, + ... +} + +AllocationAndRetentionPriority-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} +-- B + +BitRate ::= INTEGER (0..4000000000000,...) + +BroadcastPLMNs-Item ::= SEQUENCE (SIZE(1..maxnoofBPLMNs)) OF PLMN-Identity + +-- C + +Candidate-SpCell-Item ::= SEQUENCE { + candidate-SpCell-ID NRCGI , + iE-Extensions ProtocolExtensionContainer { { Candidate-SpCell-ItemExtIEs } } OPTIONAL, + ... +} + +Candidate-SpCell-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Cause ::= CHOICE { + radioNetwork CauseRadioNetwork, + transport CauseTransport, + protocol CauseProtocol, + misc CauseMisc, + ... +} + +CauseMisc ::= ENUMERATED { + control-processing-overload, + not-enough-user-plane-processing-resources, + hardware-failure, + om-intervention, + unspecified, +... +} + +CauseProtocol ::= ENUMERATED { + transfer-syntax-error, + abstract-syntax-error-reject, + abstract-syntax-error-ignore-and-notify, + message-not-compatible-with-receiver-state, + semantic-error, + abstract-syntax-error-falsely-constructed-message, + unspecified, + ... +} + +CauseRadioNetwork ::= ENUMERATED { + unspecified, + rlc-failure, + unknown-or-already-allocated-gnb-cu-ue-f1ap-id, + unknown-or-already-allocated-gnd-du-ue-f1ap-id, + unknown-or-inconsistent-pair-of-ue-f1ap-id, + interaction-with-other-procedure, + not-supported-qci-Value, + action-desirable-for-radio-reasons, + no-radio-resources-available, + procedure-cancelled, + normal-release, + ... +} + +CauseTransport ::= ENUMERATED { + unspecified, + transport-resource-unavailable, + ... +} + + + +CellGroupConfig ::= OCTET STRING + +Cells-Failed-to-be-Activated-List-Item ::= SEQUENCE { + nRCGI NRCGI, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { Cells-Failed-to-be-Activated-List-ItemExtIEs } } OPTIONAL, + ... +} + +Cells-Failed-to-be-Activated-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Cells-to-be-Activated-List-Item ::= SEQUENCE { + nRCGI NRCGI, + nRPCI NRPCI OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Cells-to-be-Activated-List-ItemExtIEs} } OPTIONAL, + ... +} + +Cells-to-be-Activated-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Cells-to-be-Deactivated-List-Item ::= SEQUENCE { + nRCGI NRCGI , + iE-Extensions ProtocolExtensionContainer { { Cells-to-be-Deactivated-List-ItemExtIEs } } OPTIONAL, + ... +} + +Cells-to-be-Deactivated-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +CriticalityDiagnostics ::= SEQUENCE { + procedureCode ProcedureCode OPTIONAL, + triggeringMessage TriggeringMessage OPTIONAL, + procedureCriticality Criticality OPTIONAL, + transactionID TransactionID OPTIONAL, + iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer {{CriticalityDiagnostics-ExtIEs}} OPTIONAL, + ... +} + +CriticalityDiagnostics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1.. maxnoofErrors)) OF CriticalityDiagnostics-IE-Item + +CriticalityDiagnostics-IE-Item ::= SEQUENCE { + iECriticality Criticality, + iE-ID ProtocolIE-ID, + typeOfError TypeOfError, + iE-Extensions ProtocolExtensionContainer {{CriticalityDiagnostics-IE-Item-ExtIEs}} OPTIONAL, + ... +} + +CriticalityDiagnostics-IE-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +CUtoDURRCInformation ::= SEQUENCE { + cG-ConfigInfo CG-ConfigInfo OPTIONAL, + uE-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { CUtoDURRCInformation-ExtIEs} } OPTIONAL, + ... +} + +CUtoDURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- D + +DLTunnels-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDLTunnels)) OF DLTunnels-ToBeSetup-Item + +DLTunnels-ToBeSetup-Item ::= SEQUENCE { + dL-GTP-Tunnel-EndPoint GTPTunnelEndpoint , + iE-Extensions ProtocolExtensionContainer { { DLTunnels-ToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +DLTunnels-ToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBID ::= INTEGER (1..32, ...) + +DRBs-FailedToBeModified-Item ::= SEQUENCE { + dRBID DRBID , + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRBs-FailedToBeModified-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-FailedToBeModified-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-FailedToBeModifiedConf-Item ::= SEQUENCE { + dRBID DRBID , + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRBs-FailedToBeModifiedConf-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-FailedToBeModifiedConf-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-FailedToBeSetup-Item ::= SEQUENCE { + dRBID DRBID, + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRBs-FailedToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-FailedToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +DRBs-FailedToBeSetupMod-Item ::= SEQUENCE { + dRBID DRBID , + cause Cause OPTIONAL , + iE-Extensions ProtocolExtensionContainer { { DRBs-FailedToBeSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-FailedToBeSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Modified-Item ::= SEQUENCE { + dRBID DRBID, + dLTunnels-ToBeSetup-List DLTunnels-ToBeSetup-List, + iE-Extensions ProtocolExtensionContainer { { DRBs-Modified-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-Modified-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-ModifiedConf-Item ::= SEQUENCE { + dRBID DRBID, + uLTunnels-ToBeSetup-List ULTunnels-ToBeSetup-List , + iE-Extensions ProtocolExtensionContainer { { DRBs-ModifiedConf-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-ModifiedConf-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Required-ToBeModified-Item ::= SEQUENCE { + dRBID DRBID, + dLTunnels-ToBeSetup-List DLTunnels-ToBeSetup-List , + iE-Extensions ProtocolExtensionContainer { { DRBs-Required-ToBeModified-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-Required-ToBeModified-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Required-ToBeReleased-Item ::= SEQUENCE { + dRBID DRBID, + iE-Extensions ProtocolExtensionContainer { { DRBs-Required-ToBeReleased-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-Required-ToBeReleased-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Setup-Item ::= SEQUENCE { + dRBID DRBID, + dLTunnels-ToBeSetup-List DLTunnels-ToBeSetup-List , + iE-Extensions ProtocolExtensionContainer { { DRBs-Setup-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-Setup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-SetupMod-Item ::= SEQUENCE { + dRBID DRBID, + dLTunnels-ToBeSetup-List DLTunnels-ToBeSetup-List , + iE-Extensions ProtocolExtensionContainer { { DRBs-SetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-SetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +DRBs-ToBeModified-Item ::= SEQUENCE { + dRBID DRBID, + eUTRANQoS EUTRANQoS OPTIONAL, + uLTunnels-ToBeSetup-List ULTunnels-ToBeSetup-List , + uLConfiguration ULConfiguration OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRBs-ToBeModified-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-ToBeModified-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-ToBeReleased-Item ::= SEQUENCE { + dRBID DRBID, + iE-Extensions ProtocolExtensionContainer { { DRBs-ToBeReleased-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-ToBeReleased-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-ToBeSetup-Item ::= SEQUENCE { + dRBID DRBID, + eUTRANQoS EUTRANQoS OPTIONAL, + uLTunnels-ToBeSetup-List ULTunnels-ToBeSetup-List , + rLCMode RLCMode, + uLConfiguration ULConfiguration OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRBs-ToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-ToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +DRBs-ToBeSetupMod-Item ::= SEQUENCE { + dRBID DRBID, + eUTRANQoS EUTRANQoS OPTIONAL, + rLCMode RLCMode, + uLConfiguration ULConfiguration OPTIONAL, + uLTunnels-ToBeSetup-List ULTunnels-ToBeSetup-List, + iE-Extensions ProtocolExtensionContainer { { DRBs-ToBeSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-ToBeSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRXCycle ::= SEQUENCE { + longDRXCycleLength LongDRXCycleLength, + shortDRXCycleLength ShortDRXCycleLength OPTIONAL, + shortDRXCycleTimer ShortDRXCycleTimer OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRXCycle-ExtIEs} } OPTIONAL, + ... +} + +DRXCycle-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} +DUtoCURRCInformation ::= SEQUENCE { + cellGroupConfig CellGroupConfig, + gapOffset GapOffset OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DUtoCURRCInformation-ExtIEs} } OPTIONAL, + ... +} + +DUtoCURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} +-- E + +EUTRANQoS ::= SEQUENCE { + qCI QCI, + allocationAndRetentionPriority AllocationAndRetentionPriority, + gbrQosInformation GBR-QosInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { EUTRANQoS-ExtIEs} } OPTIONAL, + ... +} + +EUTRANQoS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Extended-TAC ::= OCTET STRING (SIZE(3)) + +-- F + +FDD-Info ::= SEQUENCE { + uL-NRARFCN NRARFCN, + dL-NRARFCN NRARFCN, + uL-Transmission-Bandwidth Transmission-Bandwidth, + dL-Transmission-Bandwidth Transmission-Bandwidth, + iE-Extensions ProtocolExtensionContainer { {FDD-Info-ExtIEs} } OPTIONAL, + ... +} + +FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- G + +GapOffset ::= OCTET STRING + +GBR-QosInformation ::= SEQUENCE { + e-RAB-MaximumBitrateDL BitRate, + e-RAB-MaximumBitrateUL BitRate, + e-RAB-GuaranteedBitrateDL BitRate, + e-RAB-GuaranteedBitrateUL BitRate, + iE-Extensions ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL, + ... +} + +GBR-QosInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + + + +GNB-CU-UE-F1AP-ID ::= INTEGER (0..4294967295) + +GNB-DU-UE-F1AP-ID ::= INTEGER (0..4294967295) + +GNB-DU-ID ::= INTEGER (0..68719476735) + +GNB-CU-Name ::= PrintableString(SIZE(1..150,...)) + +GNB-DU-Name ::= PrintableString(SIZE(1..150,...)) + +GNB-DU-Served-Cells-Item ::= SEQUENCE { + served-Cell-Information Served-Cell-Information, + gNB-DU-System-Information GNB-DU-System-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { GNB-DU-Served-Cells-ItemExtIEs} } OPTIONAL, + ... +} + +GNB-DU-Served-Cells-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-DU-System-Information ::= SEQUENCE { + mIB-message MIB-message, + sIB1-message SIB1-message, + iE-Extensions ProtocolExtensionContainer { { GNB-DU-System-Information-ExtIEs } } OPTIONAL, + ... +} + +GNB-DU-System-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GTP-TEID ::= OCTET STRING (SIZE (4)) + +GTPTunnelEndpoint ::= SEQUENCE { + transportLayerAddress TransportLayerAddress, + gTP-TEID GTP-TEID, + iE-Extensions ProtocolExtensionContainer { { GTPTunnelEndpoint-ExtIEs} } OPTIONAL, + ... +} + + +GTPTunnelEndpoint-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- H + +-- I + +-- J + +-- K + +-- L + +LongDRXCycleLength ::= ENUMERATED +{ms10, ms20, ms32, ms40, ms60, ms64, ms70, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ms1024, ms1280, ms2048, ms2560, ms5120, ms10240, ...} + +-- M + +MIB-message ::= OCTET STRING + +-- N + +NRARFCN ::= INTEGER (0..maxNRARFCN) + +NRCGI ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + nRCellIdentity NRCellIdentity, + iE-Extensions ProtocolExtensionContainer { {NRCGI-ExtIEs} } OPTIONAL, + ... +} + +NRCGI-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +NR-Mode-Info ::= CHOICE { + fDD FDD-Info, + tDD TDD-Info, + ... +} + +NRCellIdentity ::= BIT STRING (SIZE(36)) + +NRNRB ::= ENUMERATED { nrb11, nrb18, nrb24, nrb25, nrb31, nrb32, nrb38, nrb51, nrb52, nrb65, nrb66, nrb78, nrb79, nrb93, nrb106, nrb107, nrb121, nrb132, nrb133, nrb135, nrb160, nrb162, nrb189, nrb216, nrb217, nrb245, nrb264, nrb270, nrb273, ...} + +NRPCI ::= INTEGER(0..1007) + +NRSCS ::= ENUMERATED { scs15, scs30, scs60, scs120, ...} + +-- O + +-- P + +PLMN-Identity ::= OCTET STRING (SIZE(3)) + +Pre-emptionCapability ::= ENUMERATED { + shall-not-trigger-pre-emption, + may-trigger-pre-emption +} + +Pre-emptionVulnerability ::= ENUMERATED { + not-pre-emptable, + pre-emptable +} + +PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15) + +Potential-SpCell-Item ::= SEQUENCE { + potential-SpCell-ID NRCGI , + iE-Extensions ProtocolExtensionContainer { { Potential-SpCell-ItemExtIEs } } OPTIONAL, + ... +} + +Potential-SpCell-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- Q + +QCI ::= INTEGER (0..255) + +-- R + +ResourceCoordinationTransferContainer ::= OCTET STRING + +RLCMode ::= ENUMERATED { + rlc-am, + rlc-um +} + +RRCContainer ::= OCTET STRING + +RRCRconfigurationCompleteIndicator ::= ENUMERATED {true, ...} + +-- S + +SCell-FailedtoSetup-Item ::= SEQUENCE { + sCell-ID NRCGI , + cause Cause OPTIONAL , + iE-Extensions ProtocolExtensionContainer { { SCell-FailedtoSetup-ItemExtIEs } } OPTIONAL, + ... +} + +SCell-FailedtoSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SCell-FailedtoSetupMod-Item ::= SEQUENCE { + sCell-ID NRCGI , + cause Cause OPTIONAL , + iE-Extensions ProtocolExtensionContainer { { SCell-FailedtoSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +SCell-FailedtoSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SCell-ToBeRemoved-Item ::= SEQUENCE { + sCell-ID NRCGI , + iE-Extensions ProtocolExtensionContainer { { SCell-ToBeRemoved-ItemExtIEs } } OPTIONAL, + ... +} + +SCell-ToBeRemoved-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SCell-ToBeSetup-Item ::= SEQUENCE { + sCell-ID NRCGI , + sCellIndex SCellIndex, + iE-Extensions ProtocolExtensionContainer { { SCell-ToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +SCell-ToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SCell-ToBeSetupMod-Item ::= SEQUENCE { + sCell-ID NRCGI , + sCellIndex SCellIndex, + iE-Extensions ProtocolExtensionContainer { { SCell-ToBeSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +SCell-ToBeSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SCellIndex ::=INTEGER (0..31, ...) + +CG-ConfigInfo ::= OCTET STRING + +Served-Cell-Information ::= SEQUENCE { + nRCGI NRCGI, + nRPCI NRPCI, + extended-TAC Extended-TAC, + broadcastPLMNs BroadcastPLMNs-Item, + nR-Mode-Info NR-Mode-Info, + sUL-Information SUL-Information OPTIONAL, + measurementTimingConfiguration OCTET STRING, + iE-Extensions ProtocolExtensionContainer { {Served-Cell-Information-ExtIEs} } OPTIONAL, + ... +} + +Served-Cell-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Served-Cells-To-Add-Item ::= SEQUENCE { + served-Cell-Information Served-Cell-Information, + gNB-DU-System-Information GNB-DU-System-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Served-Cells-To-Add-ItemExtIEs} } OPTIONAL, + ... +} + +Served-Cells-To-Add-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Served-Cells-To-Delete-Item ::= SEQUENCE { + oldNRCGI NRCGI , + iE-Extensions ProtocolExtensionContainer { { Served-Cells-To-Delete-ItemExtIEs } } OPTIONAL, + ... +} + +Served-Cells-To-Delete-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Served-Cells-To-Modify-Item ::= SEQUENCE { + oldNRCGI NRCGI , + served-Cell-Information Served-Cell-Information , + gNB-DU-System-Information GNB-DU-System-Information OPTIONAL , + iE-Extensions ProtocolExtensionContainer { { Served-Cells-To-Modify-ItemExtIEs } } OPTIONAL, + ... +} + +Served-Cells-To-Modify-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +ShortDRXCycleLength ::= ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms10, ms14, ms16, ms20, ms30, ms32, ms35, ms40, ms64, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ...} + +ShortDRXCycleTimer ::= INTEGER (1..16) + +SIB1-message ::= OCTET STRING + +SRBID ::= INTEGER (1..3, ...) + +SRBs-FailedToBeSetup-Item ::= SEQUENCE { + sRBID SRBID , + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SRBs-FailedToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-FailedToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SRBs-FailedToBeSetupMod-Item ::= SEQUENCE { + sRBID SRBID , + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SRBs-FailedToBeSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-FailedToBeSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +SRBs-Required-ToBeReleased-Item ::= SEQUENCE { + sRBID SRBID, + iE-Extensions ProtocolExtensionContainer { { SRBs-Required-ToBeReleased-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-Required-ToBeReleased-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SRBs-ToBeReleased-Item ::= SEQUENCE { + sRBID SRBID, + iE-Extensions ProtocolExtensionContainer { { SRBs-ToBeReleased-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-ToBeReleased-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SRBs-ToBeSetup-Item ::= SEQUENCE { + sRBID SRBID , + iE-Extensions ProtocolExtensionContainer { { SRBs-ToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-ToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SRBs-ToBeSetupMod-Item ::= SEQUENCE { + sRBID SRBID, + iE-Extensions ProtocolExtensionContainer { { SRBs-ToBeSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-ToBeSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SUL-Information ::= SEQUENCE { + sUL-NRARFCN NRARFCN, + sUL-transmission-Bandwidth Transmission-Bandwidth, + iE-Extensions ProtocolExtensionContainer { { SUL-InformationExtIEs} } OPTIONAL, + ... +} + +SUL-InformationExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- T + +TDD-Info ::= SEQUENCE { + nRARFCN NRARFCN, + transmission-Bandwidth Transmission-Bandwidth, + iE-Extensions ProtocolExtensionContainer { {TDD-Info-ExtIEs} } OPTIONAL, + ... +} + +TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...} + +TransportLayerAddress ::= BIT STRING (SIZE(1..160, ...)) + +TransactionID ::= INTEGER (0..255, ...) + +Transmission-Bandwidth ::= SEQUENCE { + nRSCS NRSCS, + nRNRB NRNRB, + iE-Extensions ProtocolExtensionContainer { { Transmission-Bandwidth-ExtIEs} } OPTIONAL, + ... +} + +Transmission-Bandwidth-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +TransmissionStopIndicator ::= ENUMERATED {true, ...} + +TypeOfError ::= ENUMERATED { + not-understood, + missing, + ... +} + +-- U + +UE-associatedLogicalF1-ConnectionItem ::= SEQUENCE { + gNB-CU-UE-F1AP-ID GNB-CU-UE-F1AP-ID OPTIONAL, + gNB-DU-UE-F1AP-ID GNB-DU-UE-F1AP-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { UE-associatedLogicalF1-ConnectionItemExtIEs} } OPTIONAL, + ... +} + +UE-associatedLogicalF1-ConnectionItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +UE-CapabilityRAT-ContainerList::= OCTET STRING + +ULConfiguration ::= SEQUENCE { + uLUEConfiguration ULUEConfiguration, + iE-Extensions ProtocolExtensionContainer { { ULConfigurationExtIEs } } OPTIONAL, + ... +} +ULConfigurationExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +ULUEConfiguration ::= ENUMERATED {no-data, shared, only, ...} + + +ULTunnels-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofULTunnels)) OF ULTunnels-ToBeSetup-Item + +ULTunnels-ToBeSetup-Item ::=SEQUENCE { + uL-GTP-Tunnel-EndPoint GTPTunnelEndpoint, + iE-Extensions ProtocolExtensionContainer { { ULTunnels-ToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +ULTunnels-ToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- V + +-- W + +-- X + +-- Y + +-- Z + +END \ No newline at end of file diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Contents.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Contents.asn new file mode 100644 index 0000000000000000000000000000000000000000..813c79ac544ebe67c515ae5f833d9aa4072cae40 --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Contents.asn @@ -0,0 +1,1076 @@ +-- ************************************************************** +-- +-- PDU definitions for F1AP. +-- +-- ************************************************************** + +F1AP-PDU-Contents { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Contents (1) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + Active-Cells-Item, + Candidate-SpCell-Item, + Cause, + Cells-Failed-to-be-Activated-List-Item, + Cells-to-be-Activated-List-Item, + Cells-to-be-Deactivated-List-Item, + CriticalityDiagnostics, + CUtoDURRCInformation, + DRBID, + DRBs-FailedToBeModifiedConf-Item, + DRBs-FailedToBeModified-Item, + DRBs-FailedToBeSetup-Item, + DRBs-FailedToBeSetupMod-Item, + DRBs-ModifiedConf-Item, + DRBs-Modified-Item, + DRBs-Required-ToBeModified-Item, + DRBs-Required-ToBeReleased-Item, + DRBs-Setup-Item, + DRBs-SetupMod-Item, + DRBs-ToBeModified-Item, + DRBs-ToBeReleased-Item, + DRBs-ToBeSetup-Item, + DRBs-ToBeSetupMod-Item, + DRXCycle, + DUtoCURRCInformation, + EUTRANQoS, + GNB-CU-UE-F1AP-ID, + GNB-DU-UE-F1AP-ID, + GNB-DU-ID, + GNB-DU-Served-Cells-Item, + GNB-DU-System-Information, + GNB-CU-Name, + GNB-DU-Name, + GTPTunnelEndpoint, + NRCGI, + NRPCI, + Potential-SpCell-Item, + ResourceCoordinationTransferContainer, + RRCContainer, + RRCRconfigurationCompleteIndicator, + SCellIndex, + SCell-ToBeRemoved-Item, + SCell-ToBeSetup-Item, + SCell-ToBeSetupMod-Item, + SCell-FailedtoSetup-Item, + SCell-FailedtoSetupMod-Item, + Served-Cell-Information, + Served-Cells-To-Add-Item, + Served-Cells-To-Delete-Item, + Served-Cells-To-Modify-Item, + SRBID, + SRBs-FailedToBeSetup-Item, + SRBs-FailedToBeSetupMod-Item, + SRBs-Required-ToBeReleased-Item, + SRBs-ToBeReleased-Item, + SRBs-ToBeSetup-Item, + SRBs-ToBeSetupMod-Item, + TimeToWait, + TransactionID, + TransmissionStopIndicator, + UE-associatedLogicalF1-ConnectionItem, + ULTunnels-ToBeSetup-Item + +FROM F1AP-IEs + + PrivateIE-Container{}, + ProtocolExtensionContainer{}, + ProtocolIE-Container{}, + ProtocolIE-ContainerPair{}, + ProtocolIE-SingleContainer{}, + F1AP-PRIVATE-IES, + F1AP-PROTOCOL-EXTENSION, + F1AP-PROTOCOL-IES, + F1AP-PROTOCOL-IES-PAIR + +FROM F1AP-Containers + + id-Active-Cells-Item, + id-Active-Cells-List, + id-Candidate-SpCell-Item, + id-Candidate-SpCell-List, + id-Cause, + id-Cells-Failed-to-be-Activated-List, + id-Cells-Failed-to-be-Activated-List-Item, + id-Cells-to-be-Activated-List, + id-Cells-to-be-Activated-List-Item, + id-Cells-to-be-Deactivated-List, + id-Cells-to-be-Deactivated-List-Item, + id-CriticalityDiagnostics, + id-CUtoDURRCInformation, + id-DRBs-FailedToBeModifiedConf-Item, + id-DRBs-FailedToBeModifiedConf-List, + id-DRBs-FailedToBeModified-Item, + id-DRBs-FailedToBeModified-List, + id-DRBs-FailedToBeSetup-Item, + id-DRBs-FailedToBeSetup-List, + id-DRBs-FailedToBeSetupMod-Item, + id-DRBs-FailedToBeSetupMod-List, + id-DRBs-ModifiedConf-Item, + id-DRBs-ModifiedConf-List, + id-DRBs-Modified-Item, + id-DRBs-Modified-List, + id-DRBs-Required-ToBeModified-Item, + id-DRBs-Required-ToBeModified-List, + id-DRBs-Required-ToBeReleased-Item, + id-DRBs-Required-ToBeReleased-List, + id-DRBs-Setup-Item, + id-DRBs-Setup-List, + id-DRBs-SetupMod-Item, + id-DRBs-SetupMod-List, + id-DRBs-ToBeModified-Item, + id-DRBs-ToBeModified-List, + id-DRBs-ToBeReleased-Item, + id-DRBs-ToBeReleased-List, + id-DRBs-ToBeSetup-Item, + id-DRBs-ToBeSetup-List, + id-DRBs-ToBeSetupMod-Item, + id-DRBs-ToBeSetupMod-List, + id-DRXCycle, + id-DUtoCURRCInformation, + id-gNB-CU-UE-F1AP-ID, + id-gNB-DU-UE-F1AP-ID, + id-gNB-DU-ID, + id-GNB-DU-Served-Cells-Item, + id-gNB-DU-Served-Cells-List, + id-gNB-CU-Name, + id-gNB-DU-Name, + id-oldgNB-DU-UE-F1AP-ID, + id-Potential-SpCell-Item, + id-Potential-SpCell-List, + id-ResetType, + id-ResourceCoordinationTransferContainer, + id-RRCContainer, + id-RRCRconfigurationCompleteIndicator, + id-SCell-FailedtoSetup-List, + id-SCell-FailedtoSetup-Item, + id-SCell-FailedtoSetupMod-List, + id-SCell-FailedtoSetupMod-Item, + id-SCell-ToBeRemoved-Item, + id-SCell-ToBeRemoved-List, + id-SCell-ToBeSetup-Item, + id-SCell-ToBeSetup-List, + id-SCell-ToBeSetupMod-Item, + id-SCell-ToBeSetupMod-List, + id-Served-Cells-To-Add-Item, + id-Served-Cells-To-Add-List, + id-Served-Cells-To-Delete-Item, + id-Served-Cells-To-Delete-List, + id-Served-Cells-To-Modify-Item, + id-Served-Cells-To-Modify-List, + id-SpCell-ID, + id-SRBID, + id-SRBs-FailedToBeSetup-Item, + id-SRBs-FailedToBeSetup-List, + id-SRBs-FailedToBeSetupMod-Item, + id-SRBs-FailedToBeSetupMod-List, + id-SRBs-Required-ToBeReleased-Item, + id-SRBs-Required-ToBeReleased-List, + id-SRBs-ToBeReleased-Item, + id-SRBs-ToBeReleased-List, + id-SRBs-ToBeSetup-Item, + id-SRBs-ToBeSetup-List, + id-SRBs-ToBeSetupMod-Item, + id-SRBs-ToBeSetupMod-List, + id-TimeToWait, + id-TransactionID, + id-TransmissionStopIndicator, + id-UE-associatedLogicalF1-ConnectionItem, + id-UE-associatedLogicalF1-ConnectionListResAck, + maxCellingNBDU, + maxnoofCandidateSpCells, + maxnoofDRBs, + maxnoofErrors, + maxnoofIndividualF1ConnectionsToReset, + maxnoofPotentialSpCells, + maxnoofSCells, + maxnoofSRBs + +FROM F1AP-Constants; + + +-- ************************************************************** +-- +-- RESET ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Reset +-- +-- ************************************************************** + +Reset ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ResetIEs} }, + ... +} + +ResetIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-ResetType CRITICALITY reject TYPE ResetType PRESENCE mandatory }, + ... +} + +ResetType ::= CHOICE { + f1-Interface ResetAll, + partOfF1-Interface UE-associatedLogicalF1-ConnectionListRes, + ... +} + + +ResetAll ::= ENUMERATED { + reset-all, + ... +} + +UE-associatedLogicalF1-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemRes } } + +UE-associatedLogicalF1-ConnectionItemRes F1AP-PROTOCOL-IES ::= { + { ID id-UE-associatedLogicalF1-ConnectionItem CRITICALITY reject TYPE UE-associatedLogicalF1-ConnectionItem PRESENCE mandatory}, + ... +} + + + + +-- ************************************************************** +-- +-- Reset Acknowledge +-- +-- ************************************************************** + +ResetAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} }, + ... +} + +ResetAcknowledgeIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-UE-associatedLogicalF1-ConnectionListResAck CRITICALITY ignore TYPE UE-associatedLogicalF1-ConnectionListResAck PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +UE-associatedLogicalF1-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemResAck } } + +UE-associatedLogicalF1-ConnectionItemResAck F1AP-PROTOCOL-IES ::= { + { ID id-UE-associatedLogicalF1-ConnectionItem CRITICALITY ignore TYPE UE-associatedLogicalF1-ConnectionItem PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- ERROR INDICATION ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Error Indication +-- +-- ************************************************************** + +ErrorIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ErrorIndicationIEs}}, + ... +} + +ErrorIndicationIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory}| + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY ignore TYPE GNB-CU-UE-F1AP-ID PRESENCE optional }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY ignore TYPE GNB-DU-UE-F1AP-ID PRESENCE optional }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- F1 SETUP ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- F1 Setup Request +-- +-- ************************************************************** + +F1SetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {F1SetupRequestIEs} }, + ... +} + +F1SetupRequestIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-DU-ID CRITICALITY reject TYPE GNB-DU-ID PRESENCE mandatory }| + { ID id-gNB-DU-Name CRITICALITY ignore TYPE GNB-DU-Name PRESENCE optional }| + { ID id-gNB-DU-Served-Cells-List CRITICALITY reject TYPE GNB-DU-Served-Cells-List PRESENCE mandatory }, + ... +} + + +GNB-DU-Served-Cells-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { GNB-DU-Served-Cells-ItemIEs } } + +GNB-DU-Served-Cells-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-GNB-DU-Served-Cells-Item CRITICALITY reject TYPE GNB-DU-Served-Cells-Item PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- F1 Setup Response +-- +-- ************************************************************** + +F1SetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {F1SetupResponseIEs} }, + ... +} + + +F1SetupResponseIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-CU-Name CRITICALITY ignore TYPE GNB-CU-Name PRESENCE optional }| + { ID id-Cells-to-be-Activated-List CRITICALITY reject TYPE Cells-to-be-Activated-List PRESENCE optional }, + ... +} + + +Cells-to-be-Activated-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-to-be-Activated-List-ItemIEs } } + +Cells-to-be-Activated-List-ItemIEs F1AP-PROTOCOL-IES::= { + { ID id-Cells-to-be-Activated-List-Item CRITICALITY reject TYPE Cells-to-be-Activated-List-Item PRESENCE mandatory}, + ... +} + + + +-- ************************************************************** +-- +-- F1 Setup Failure +-- +-- ************************************************************** + +F1SetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {F1SetupFailureIEs} }, + ... +} + +F1SetupFailureIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- GNB-DU CONFIGURATION UPDATE ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- GNB-DU CONFIGURATION UPDATE +-- +-- ************************************************************** + +GNBDUConfigurationUpdate::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNBDUConfigurationUpdateIEs} }, + ... +} + +GNBDUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Served-Cells-To-Add-List CRITICALITY reject TYPE Served-Cells-To-Add-List PRESENCE optional }| + { ID id-Served-Cells-To-Modify-List CRITICALITY reject TYPE Served-Cells-To-Modify-List PRESENCE optional }| + { ID id-Served-Cells-To-Delete-List CRITICALITY reject TYPE Served-Cells-To-Delete-List PRESENCE optional }| + { ID id-Active-Cells-List CRITICALITY reject TYPE Active-Cells-List PRESENCE optional }, + ... +} +Served-Cells-To-Add-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Served-Cells-To-Add-ItemIEs } } +Served-Cells-To-Modify-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Served-Cells-To-Modify-ItemIEs } } +Served-Cells-To-Delete-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Served-Cells-To-Delete-ItemIEs } } +Active-Cells-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Active-Cells-ItemIEs } } + +Served-Cells-To-Add-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Served-Cells-To-Add-Item CRITICALITY reject TYPE Served-Cells-To-Add-Item PRESENCE mandatory }, + ... +} + +Served-Cells-To-Modify-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Served-Cells-To-Modify-Item CRITICALITY reject TYPE Served-Cells-To-Modify-Item PRESENCE mandatory }, + ... +} + +Served-Cells-To-Delete-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Served-Cells-To-Delete-Item CRITICALITY reject TYPE Served-Cells-To-Delete-Item PRESENCE mandatory }, +... +} + +Active-Cells-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Active-Cells-Item CRITICALITY reject TYPE Active-Cells-Item PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- GNB-DU CONFIGURATION UPDATE ACKNOWLEDGE +-- +-- ************************************************************** + +GNBDUConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNBDUConfigurationUpdateAcknowledgeIEs} }, + ... +} + + +GNBDUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cells-to-be-Activated-List CRITICALITY reject TYPE Cells-to-be-Activated-List PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-DU CONFIGURATION UPDATE FAILURE +-- +-- ************************************************************** + +GNBDUConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNBDUConfigurationUpdateFailureIEs} }, + ... +} + +GNBDUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-CU CONFIGURATION UPDATE ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- GNB-CU CONFIGURATION UPDATE +-- +-- ************************************************************** + +GNBCUConfigurationUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { GNBCUConfigurationUpdateIEs} }, + ... +} + +GNBCUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cells-to-be-Activated-List CRITICALITY reject TYPE Cells-to-be-Activated-List PRESENCE optional }| + { ID id-Cells-to-be-Deactivated-List CRITICALITY reject TYPE Cells-to-be-Deactivated-List PRESENCE optional }, + ... +} + +Cells-to-be-Deactivated-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-to-be-Deactivated-List-ItemIEs } } + +Cells-to-be-Deactivated-List-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Cells-to-be-Deactivated-List-Item CRITICALITY reject TYPE Cells-to-be-Deactivated-List-Item PRESENCE mandatory }, +...} + + +-- ************************************************************** +-- +-- GNB-CU CONFIGURATION UPDATE ACKNOWLEDGE +-- +-- ************************************************************** + +GNBCUConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { GNBCUConfigurationUpdateAcknowledgeIEs} }, + ... +} + + +GNBCUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cells-Failed-to-be-Activated-List CRITICALITY reject TYPE Cells-Failed-to-be-Activated-List PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +Cells-Failed-to-be-Activated-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-Failed-to-be-Activated-List-ItemIEs } } + +Cells-Failed-to-be-Activated-List-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Cells-Failed-to-be-Activated-List-Item CRITICALITY reject TYPE Cells-Failed-to-be-Activated-List-Item PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- GNB-CU CONFIGURATION UPDATE FAILURE +-- +-- ************************************************************** + +GNBCUConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { GNBCUConfigurationUpdateFailureIEs} }, + ... +} + +GNBCUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- UE Context Setup ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT SETUP REQUEST +-- +-- ************************************************************** + +UEContextSetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextSetupRequestIEs} }, + ... +} + +UEContextSetupRequestIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY ignore TYPE GNB-DU-UE-F1AP-ID PRESENCE optional }| + { ID id-SpCell-ID CRITICALITY reject TYPE NRCGI PRESENCE mandatory }| + { ID id-CUtoDURRCInformation CRITICALITY reject TYPE CUtoDURRCInformation PRESENCE mandatory}| + { ID id-Candidate-SpCell-List CRITICALITY ignore TYPE Candidate-SpCell-List PRESENCE optional }| + { ID id-DRXCycle CRITICALITY ignore TYPE DRXCycle PRESENCE optional }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-SCell-ToBeSetup-List CRITICALITY ignore TYPE SCell-ToBeSetup-List PRESENCE optional }| + { ID id-SRBs-ToBeSetup-List CRITICALITY reject TYPE SRBs-ToBeSetup-List PRESENCE optional }| + { ID id-DRBs-ToBeSetup-List CRITICALITY reject TYPE DRBs-ToBeSetup-List PRESENCE mandatory }, + ... +} + +Candidate-SpCell-List::= SEQUENCE (SIZE(1..maxnoofCandidateSpCells)) OF ProtocolIE-SingleContainer { { Candidate-SpCell-ItemIEs} } +SCell-ToBeSetup-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetup-ItemIEs} } +SRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetup-ItemIEs} } +DRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetup-ItemIEs} } + + +Candidate-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Candidate-SpCell-Item CRITICALITY ignore TYPE Candidate-SpCell-Item PRESENCE mandatory }, + ... +} + + +SCell-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SCell-ToBeSetup-Item CRITICALITY ignore TYPE SCell-ToBeSetup-Item PRESENCE mandatory }, + ... +} + +SRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-ToBeSetup-Item CRITICALITY reject TYPE SRBs-ToBeSetup-Item PRESENCE mandatory}, + ... +} + +DRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-ToBeSetup-Item CRITICALITY reject TYPE DRBs-ToBeSetup-Item PRESENCE mandatory}, + ... +} + + + +-- ************************************************************** +-- +-- UE CONTEXT SETUP RESPONSE +-- +-- ************************************************************** + +UEContextSetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextSetupResponseIEs} }, + ... +} + + +UEContextSetupResponseIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-DUtoCURRCInformation CRITICALITY reject TYPE DUtoCURRCInformation PRESENCE mandatory }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-DRBs-Setup-List CRITICALITY ignore TYPE DRBs-Setup-List PRESENCE mandatory}| + { ID id-SRBs-FailedToBeSetup-List CRITICALITY ignore TYPE SRBs-FailedToBeSetup-List PRESENCE optional }| + { ID id-DRBs-FailedToBeSetup-List CRITICALITY ignore TYPE DRBs-FailedToBeSetup-List PRESENCE optional }| + { ID id-SCell-FailedtoSetup-List CRITICALITY ignore TYPE SCell-FailedtoSetup-List PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +DRBs-Setup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Setup-ItemIEs} } +SRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetup-ItemIEs} } +DRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetup-ItemIEs} } +SCell-FailedtoSetup-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetup-ItemIEs} } + +DRBs-Setup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-Setup-Item CRITICALITY ignore TYPE DRBs-Setup-Item PRESENCE mandatory}, + ... +} + +SRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-FailedToBeSetup-Item CRITICALITY ignore TYPE SRBs-FailedToBeSetup-Item PRESENCE mandatory}, + ... +} + + +DRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-FailedToBeSetup-Item CRITICALITY ignore TYPE DRBs-FailedToBeSetup-Item PRESENCE mandatory}, + ... +} + +SCell-FailedtoSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SCell-FailedtoSetup-Item CRITICALITY ignore TYPE SCell-FailedtoSetup-Item PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT SETUP FAILURE +-- +-- ************************************************************** + +UEContextSetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextSetupFailureIEs} }, + ... +} + +UEContextSetupFailureIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY ignore TYPE GNB-DU-UE-F1AP-ID PRESENCE optional }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }| + { ID id-Potential-SpCell-List CRITICALITY ignore TYPE Potential-SpCell-List PRESENCE optional }, + ... +} + +Potential-SpCell-List::= SEQUENCE (SIZE(0..maxnoofPotentialSpCells)) OF ProtocolIE-SingleContainer { { Potential-SpCell-ItemIEs} } + +Potential-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Potential-SpCell-Item CRITICALITY ignore TYPE Potential-SpCell-Item PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UE Context Release Request ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE Context Release Request +-- +-- ************************************************************** + +UEContextReleaseRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ UEContextReleaseRequestIEs}}, + ... +} + +UEContextReleaseRequestIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- UE Context Release (gNB-CU initiated) ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT RELEASE COMMAND +-- +-- ************************************************************** + +UEContextReleaseCommand ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextReleaseCommandIEs} }, + ... +} + +UEContextReleaseCommandIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT RELEASE COMPLETE +-- +-- ************************************************************** + +UEContextReleaseComplete ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextReleaseCompleteIEs} }, + ... +} + + +UEContextReleaseCompleteIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, ... +} + +-- ************************************************************** +-- +-- UE Context Modification ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION REQUEST +-- +-- ************************************************************** + +UEContextModificationRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextModificationRequestIEs} }, + ... +} + +UEContextModificationRequestIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-SpCell-ID CRITICALITY ignore TYPE NRCGI PRESENCE optional }| + { ID id-DRXCycle CRITICALITY ignore TYPE DRXCycle PRESENCE optional }| + { ID id-CUtoDURRCInformation CRITICALITY reject TYPE CUtoDURRCInformation PRESENCE optional }| + { ID id-TransmissionStopIndicator CRITICALITY ignore TYPE TransmissionStopIndicator PRESENCE optional }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-RRCRconfigurationCompleteIndicator CRITICALITY ignore TYPE RRCRconfigurationCompleteIndicator PRESENCE optional }| + { ID id-RRCContainer CRITICALITY reject TYPE RRCContainer PRESENCE optional }| + { ID id-SCell-ToBeSetupMod-List CRITICALITY ignore TYPE SCell-ToBeSetupMod-List PRESENCE optional }| + { ID id-SCell-ToBeRemoved-List CRITICALITY ignore TYPE SCell-ToBeRemoved-List PRESENCE optional }| + { ID id-SRBs-ToBeSetupMod-List CRITICALITY reject TYPE SRBs-ToBeSetupMod-List PRESENCE optional }| + { ID id-DRBs-ToBeSetupMod-List CRITICALITY reject TYPE DRBs-ToBeSetupMod-List PRESENCE optional }| + { ID id-DRBs-ToBeModified-List CRITICALITY reject TYPE DRBs-ToBeModified-List PRESENCE optional }| + { ID id-SRBs-ToBeReleased-List CRITICALITY reject TYPE SRBs-ToBeReleased-List PRESENCE optional }| + { ID id-DRBs-ToBeReleased-List CRITICALITY reject TYPE DRBs-ToBeReleased-List PRESENCE optional }, + ... +} + +SCell-ToBeSetupMod-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetupMod-ItemIEs} } +SCell-ToBeRemoved-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeRemoved-ItemIEs} } +SRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetupMod-ItemIEs} } +DRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetupMod-ItemIEs} } + +DRBs-ToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeModified-ItemIEs} } +SRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeReleased-ItemIEs} } +DRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeReleased-ItemIEs} } + +SCell-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SCell-ToBeSetupMod-Item CRITICALITY ignore TYPE SCell-ToBeSetupMod-Item PRESENCE mandatory }, + ... +} + +SCell-ToBeRemoved-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SCell-ToBeRemoved-Item CRITICALITY ignore TYPE SCell-ToBeRemoved-Item PRESENCE mandatory }, + ... +} + + +SRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-ToBeSetupMod-Item CRITICALITY reject TYPE SRBs-ToBeSetupMod-Item PRESENCE mandatory}, + ... +} + + +DRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-ToBeSetupMod-Item CRITICALITY reject TYPE DRBs-ToBeSetupMod-Item PRESENCE mandatory}, + ... +} + +DRBs-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-ToBeModified-Item CRITICALITY reject TYPE DRBs-ToBeModified-Item PRESENCE mandatory}, + ... +} + + +SRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-ToBeReleased-Item CRITICALITY reject TYPE SRBs-ToBeReleased-Item PRESENCE mandatory}, + ... +} + +DRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-ToBeReleased-Item CRITICALITY reject TYPE DRBs-ToBeReleased-Item PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION RESPONSE +-- +-- ************************************************************** + +UEContextModificationResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextModificationResponseIEs} }, + ... +} + + +UEContextModificationResponseIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-DUtoCURRCInformation CRITICALITY reject TYPE DUtoCURRCInformation PRESENCE optional}| + { ID id-DRBs-SetupMod-List CRITICALITY ignore TYPE DRBs-SetupMod-List PRESENCE optional}| + { ID id-DRBs-Modified-List CRITICALITY ignore TYPE DRBs-Modified-List PRESENCE optional}| + { ID id-SRBs-FailedToBeSetupMod-List CRITICALITY ignore TYPE SRBs-FailedToBeSetupMod-List PRESENCE optional }| + { ID id-DRBs-FailedToBeSetupMod-List CRITICALITY ignore TYPE DRBs-FailedToBeSetupMod-List PRESENCE optional }| + { ID id-SCell-FailedtoSetupMod-List CRITICALITY ignore TYPE SCell-FailedtoSetupMod-List PRESENCE optional }| + { ID id-DRBs-FailedToBeModified-List CRITICALITY ignore TYPE DRBs-FailedToBeModified-List PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +DRBs-SetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-SetupMod-ItemIEs} } +DRBs-Modified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Modified-ItemIEs } } +DRBs-FailedToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeModified-ItemIEs} } +SRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetupMod-ItemIEs} } +DRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetupMod-ItemIEs} } +SCell-FailedtoSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetupMod-ItemIEs} } + +DRBs-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-SetupMod-Item CRITICALITY ignore TYPE DRBs-SetupMod-Item PRESENCE mandatory}, + ... +} + + +DRBs-Modified-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-Modified-Item CRITICALITY ignore TYPE DRBs-Modified-Item PRESENCE mandatory}, + ... +} + +SRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-FailedToBeSetupMod-Item CRITICALITY ignore TYPE SRBs-FailedToBeSetupMod-Item PRESENCE mandatory}, + ... +} + + + +DRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-FailedToBeSetupMod-Item CRITICALITY ignore TYPE DRBs-FailedToBeSetupMod-Item PRESENCE mandatory}, + ... +} + + +DRBs-FailedToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-FailedToBeModified-Item CRITICALITY ignore TYPE DRBs-FailedToBeModified-Item PRESENCE mandatory}, + ... +} + +SCell-FailedtoSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SCell-FailedtoSetupMod-Item CRITICALITY ignore TYPE SCell-FailedtoSetupMod-Item PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION FAILURE +-- +-- ************************************************************** + +UEContextModificationFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextModificationFailureIEs} }, + ... +} + +UEContextModificationFailureIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- UE Context Modification Required (gNB-DU initiated) ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION REQUIRED +-- +-- ************************************************************** + +UEContextModificationRequired ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextModificationRequiredIEs} }, + ... +} + +UEContextModificationRequiredIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-DUtoCURRCInformation CRITICALITY reject TYPE DUtoCURRCInformation PRESENCE optional}| + { ID id-DRBs-Required-ToBeModified-List CRITICALITY reject TYPE DRBs-Required-ToBeModified-List PRESENCE optional}| + { ID id-SRBs-Required-ToBeReleased-List CRITICALITY reject TYPE SRBs-Required-ToBeReleased-List PRESENCE optional}| + { ID id-DRBs-Required-ToBeReleased-List CRITICALITY reject TYPE DRBs-Required-ToBeReleased-List PRESENCE optional}| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +DRBs-Required-ToBeModified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeModified-ItemIEs } } +DRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeReleased-ItemIEs } } + +SRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-Required-ToBeReleased-ItemIEs } } + +DRBs-Required-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-Required-ToBeModified-Item CRITICALITY reject TYPE DRBs-Required-ToBeModified-Item PRESENCE mandatory}, + ... +} + +DRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-Required-ToBeReleased-Item CRITICALITY reject TYPE DRBs-Required-ToBeReleased-Item PRESENCE mandatory}, + ... +} + +SRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-Required-ToBeReleased-Item CRITICALITY reject TYPE SRBs-Required-ToBeReleased-Item PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION CONFIRM +-- +-- ************************************************************** + +UEContextModificationConfirm::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextModificationConfirmIEs} }, + ... +} + + +UEContextModificationConfirmIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-DRBs-ModifiedConf-List CRITICALITY ignore TYPE DRBs-ModifiedConf-List PRESENCE optional}| + { ID id-DRBs-FailedToBeModifiedConf-List CRITICALITY ignore TYPE DRBs-FailedToBeModifiedConf-List PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +DRBs-ModifiedConf-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ModifiedConf-ItemIEs } } +DRBs-FailedToBeModifiedConf-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeModifiedConf-ItemIEs} } + +DRBs-ModifiedConf-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-ModifiedConf-Item CRITICALITY ignore TYPE DRBs-ModifiedConf-Item PRESENCE mandatory}, + ... +} + +DRBs-FailedToBeModifiedConf-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-FailedToBeModifiedConf-Item CRITICALITY ignore TYPE DRBs-FailedToBeModifiedConf-Item PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- DL RRC Message Transfer ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- DL RRC Message Transfer +-- +-- ************************************************************** + +DLRRCMessageTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ DLRRCMessageTransferIEs}}, + ... +} + +DLRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-oldgNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE optional }| + { ID id-SRBID CRITICALITY reject TYPE SRBID PRESENCE mandatory }| + { ID id-RRCContainer CRITICALITY reject TYPE RRCContainer PRESENCE mandatory }, + ... +} +-- ************************************************************** +-- +-- UL RRC Message Transfer ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UL RRC Message Transfer +-- +-- ************************************************************** + +ULRRCMessageTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ ULRRCMessageTransferIEs}}, + ... +} + +ULRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-SRBID CRITICALITY reject TYPE SRBID PRESENCE mandatory }| + { ID id-RRCContainer CRITICALITY reject TYPE RRCContainer PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- PRIVATE MESSAGE +-- +-- ************************************************************** + +PrivateMessage ::= SEQUENCE { + privateIEs PrivateIE-Container {{PrivateMessage-IEs}}, + ... +} + +PrivateMessage-IEs F1AP-PRIVATE-IES ::= { + ... +} + +END diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Descriptions.asn b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Descriptions.asn new file mode 100644 index 0000000000000000000000000000000000000000..99a67d89da1b76d2a821eac502e7c71b399184f0 --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/F1AP-PDU-Descriptions.asn @@ -0,0 +1,258 @@ +-- ************************************************************** +-- +-- Elementary Procedure definitions +-- +-- ************************************************************** + +F1AP-PDU-Descriptions { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Descriptions (0)} + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + Criticality, + ProcedureCode + +FROM F1AP-CommonDataTypes + Reset, + ResetAcknowledge, + F1SetupRequest, + F1SetupResponse, + F1SetupFailure, + GNBDUConfigurationUpdate, + GNBDUConfigurationUpdateAcknowledge, + GNBDUConfigurationUpdateFailure, + GNBCUConfigurationUpdate, + GNBCUConfigurationUpdateAcknowledge, + GNBCUConfigurationUpdateFailure, + UEContextSetupRequest, + UEContextSetupResponse, + UEContextSetupFailure, + UEContextReleaseCommand, + UEContextReleaseComplete, + UEContextModificationRequest, + UEContextModificationResponse, + UEContextModificationFailure, + UEContextModificationRequired, + UEContextModificationConfirm, + ErrorIndication, + UEContextReleaseRequest, + DLRRCMessageTransfer, + ULRRCMessageTransfer, + PrivateMessage + +FROM F1AP-PDU-Contents + id-Reset, + id-F1Setup, + id-gNBDUConfigurationUpdate, + id-gNBCUConfigurationUpdate, + id-UEContextSetup, + id-UEContextRelease, + id-UEContextModification, + id-UEContextModificationRequired, + id-ErrorIndication, + id-UEContextReleaseRequest, + id-DLRRCMessageTransfer, + id-ULRRCMessageTransfer, + id-privateMessage + + +FROM F1AP-Constants; + + +-- ************************************************************** +-- +-- Interface Elementary Procedure Class +-- +-- ************************************************************** + +F1AP-ELEMENTARY-PROCEDURE ::= CLASS { + &InitiatingMessage , + &SuccessfulOutcome OPTIONAL, + &UnsuccessfulOutcome OPTIONAL, + &procedureCode ProcedureCode UNIQUE, + &criticality Criticality DEFAULT ignore +} +WITH SYNTAX { + INITIATING MESSAGE &InitiatingMessage + [SUCCESSFUL OUTCOME &SuccessfulOutcome] + [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] + PROCEDURE CODE &procedureCode + [CRITICALITY &criticality] +} + +-- ************************************************************** +-- +-- Interface PDU Definition +-- +-- ************************************************************** + +F1AP-PDU ::= CHOICE { + initiatingMessage InitiatingMessage, + successfulOutcome SuccessfulOutcome, + unsuccessfulOutcome UnsuccessfulOutcome, + ... +} + +InitiatingMessage ::= SEQUENCE { + procedureCode F1AP-ELEMENTARY-PROCEDURE.&procedureCode ({F1AP-ELEMENTARY-PROCEDURES}), + criticality F1AP-ELEMENTARY-PROCEDURE.&criticality ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value F1AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +SuccessfulOutcome ::= SEQUENCE { + procedureCode F1AP-ELEMENTARY-PROCEDURE.&procedureCode ({F1AP-ELEMENTARY-PROCEDURES}), + criticality F1AP-ELEMENTARY-PROCEDURE.&criticality ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value F1AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +UnsuccessfulOutcome ::= SEQUENCE { + procedureCode F1AP-ELEMENTARY-PROCEDURE.&procedureCode ({F1AP-ELEMENTARY-PROCEDURES}), + criticality F1AP-ELEMENTARY-PROCEDURE.&criticality ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value F1AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +-- ************************************************************** +-- +-- Interface Elementary Procedure List +-- +-- ************************************************************** + +F1AP-ELEMENTARY-PROCEDURES F1AP-ELEMENTARY-PROCEDURE ::= { + F1AP-ELEMENTARY-PROCEDURES-CLASS-1 | + F1AP-ELEMENTARY-PROCEDURES-CLASS-2, + ... +} + + +F1AP-ELEMENTARY-PROCEDURES-CLASS-1 F1AP-ELEMENTARY-PROCEDURE ::= { + reset | + f1Setup | + gNBDUConfigurationUpdate | + gNBCUConfigurationUpdate | + uEContextSetup | + uEContextRelease | + uEContextModification | + uEContextModificationRequired , + ...} + + F1AP-ELEMENTARY-PROCEDURES-CLASS-2 F1AP-ELEMENTARY-PROCEDURE ::= { + errorIndication | + uEContextReleaseRequest | + dLRRCMessageTransfer | + uLRRCMessageTransfer | + privateMessage , + ... +} +-- ************************************************************** +-- +-- Interface Elementary Procedures +-- +-- ************************************************************** + +reset F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE Reset + SUCCESSFUL OUTCOME ResetAcknowledge + PROCEDURE CODE id-Reset + CRITICALITY reject +} + +f1Setup F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE F1SetupRequest + SUCCESSFUL OUTCOME F1SetupResponse + UNSUCCESSFUL OUTCOME F1SetupFailure + PROCEDURE CODE id-F1Setup + CRITICALITY reject +} + +gNBDUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNBDUConfigurationUpdate + SUCCESSFUL OUTCOME GNBDUConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME GNBDUConfigurationUpdateFailure + PROCEDURE CODE id-gNBDUConfigurationUpdate + CRITICALITY reject +} + +gNBCUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNBCUConfigurationUpdate + SUCCESSFUL OUTCOME GNBCUConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME GNBCUConfigurationUpdateFailure + PROCEDURE CODE id-gNBCUConfigurationUpdate + CRITICALITY reject +} + +uEContextSetup F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextSetupRequest + SUCCESSFUL OUTCOME UEContextSetupResponse + UNSUCCESSFUL OUTCOME UEContextSetupFailure + PROCEDURE CODE id-UEContextSetup + CRITICALITY reject +} + +uEContextRelease F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextReleaseCommand + SUCCESSFUL OUTCOME UEContextReleaseComplete + PROCEDURE CODE id-UEContextRelease + CRITICALITY reject +} + +uEContextModification F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextModificationRequest + SUCCESSFUL OUTCOME UEContextModificationResponse + UNSUCCESSFUL OUTCOME UEContextModificationFailure + PROCEDURE CODE id-UEContextModification + CRITICALITY reject +} + +uEContextModificationRequired F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextModificationRequired + SUCCESSFUL OUTCOME UEContextModificationConfirm + PROCEDURE CODE id-UEContextModificationRequired + CRITICALITY reject +} + + +errorIndication F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ErrorIndication + PROCEDURE CODE id-ErrorIndication + CRITICALITY ignore +} + +uEContextReleaseRequest F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextReleaseRequest + PROCEDURE CODE id-UEContextReleaseRequest + CRITICALITY ignore +} + + +dLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DLRRCMessageTransfer + PROCEDURE CODE id-DLRRCMessageTransfer + CRITICALITY ignore +} + +uLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ULRRCMessageTransfer + PROCEDURE CODE id-ULRRCMessageTransfer + CRITICALITY ignore +} + + +privateMessage F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PrivateMessage + PROCEDURE CODE id-privateMessage + CRITICALITY ignore +} + + + +END diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.1.1/asn1_constants.h b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/asn1_constants.h new file mode 100644 index 0000000000000000000000000000000000000000..5f7897148d7a783dc113250c345db9df0e23133a --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.1.1/asn1_constants.h @@ -0,0 +1,3 @@ +#ifndef __ASN1_CONSTANTS_H__ +#define __ASN1_CONSTANTS_H__ +#endif diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-CommonDataTypes.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-CommonDataTypes.asn new file mode 100644 index 0000000000000000000000000000000000000000..12dfbd12ff74eee6487a20abbc140b991e180e8a --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-CommonDataTypes.asn @@ -0,0 +1,32 @@ +-- ************************************************************** +-- +-- Common definitions +-- +-- ************************************************************** + +F1AP-CommonDataTypes { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-CommonDataTypes (3) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +Criticality ::= ENUMERATED { reject, ignore, notify } + +Presence ::= ENUMERATED { optional, conditional, mandatory } + +PrivateIE-ID ::= CHOICE { + local INTEGER (0..65535), + global OBJECT IDENTIFIER +} + +ProcedureCode ::= INTEGER (0..255) + +ProtocolExtensionID ::= INTEGER (0..65535) + +ProtocolIE-ID ::= INTEGER (0..65535) + +TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome } + +END diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Constants.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Constants.asn new file mode 100644 index 0000000000000000000000000000000000000000..de34aa8f43778b1afccd92e428fd2fd29bb96ad5 --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Constants.asn @@ -0,0 +1,256 @@ +-- ************************************************************** +-- +-- Constant definitions +-- +-- ************************************************************** + +F1AP-Constants { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Constants (4) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + ProcedureCode, + ProtocolIE-ID + +FROM F1AP-CommonDataTypes; + + +-- ************************************************************** +-- +-- Elementary Procedures +-- +-- ************************************************************** + +id-Reset ProcedureCode ::= 0 +id-F1Setup ProcedureCode ::= 1 +id-ErrorIndication ProcedureCode ::= 2 +id-gNBDUConfigurationUpdate ProcedureCode ::= 3 +id-gNBCUConfigurationUpdate ProcedureCode ::= 4 +id-UEContextSetup ProcedureCode ::= 5 +id-UEContextRelease ProcedureCode ::= 6 +id-UEContextModification ProcedureCode ::= 7 +id-UEContextModificationRequired ProcedureCode ::= 8 +id-UEMobilityCommand ProcedureCode ::= 9 +id-UEContextReleaseRequest ProcedureCode ::= 10 +id-InitialULRRCMessageTransfer ProcedureCode ::= 11 +id-DLRRCMessageTransfer ProcedureCode ::= 12 +id-ULRRCMessageTransfer ProcedureCode ::= 13 +id-privateMessage ProcedureCode ::= 14 +id-UEInactivityNotification ProcedureCode ::= 15 +id-GNBDUResourceCoordination ProcedureCode ::= 16 +id-SystemInformationDeliveryCommand ProcedureCode ::= 17 +id-Paging ProcedureCode ::= 18 +id-Notify ProcedureCode ::= 19 +id-WriteReplaceWarning ProcedureCode ::= 20 +id-PWSCancel ProcedureCode ::= 21 +id-PWSRestartIndication ProcedureCode ::= 22 +id-PWSFailureIndication ProcedureCode ::= 23 + +-- ************************************************************** +-- +-- Extension constants +-- +-- ************************************************************** + +maxPrivateIEs INTEGER ::= 65535 +maxProtocolExtensions INTEGER ::= 65535 +maxProtocolIEs INTEGER ::= 65535 +-- ************************************************************** +-- +-- Lists +-- +-- ************************************************************** + +maxNRARFCN INTEGER ::= 3279165 +maxnoofErrors INTEGER ::= 256 +maxnoofIndividualF1ConnectionsToReset INTEGER ::= 65536 +maxCellingNBDU INTEGER ::= 512 +maxnoofSCells INTEGER ::= 32 +maxnoofSRBs INTEGER ::= 8 +maxnoofDRBs INTEGER ::= 64 +maxnoofULUPTNLInformation INTEGER ::= 2 +maxnoofDLUPTNLInformation INTEGER ::= 2 +maxnoofBPLMNs INTEGER ::= 6 +maxnoofCandidateSpCells INTEGER ::= 64 +maxnoofPotentialSpCells INTEGER ::= 64 +maxnoofNrCellBands INTEGER ::= 32 +maxnoofSIBTypes INTEGER ::= 16 +maxnoofPagingCells INTEGER ::= 512 +maxnoofTNLAssociations INTEGER ::= 32 +maxnoofQoSFlows INTEGER ::= 64 +maxnoofSliceItems INTEGER ::= 1024 +maxCellineNB INTEGER ::= 256 + + +-- ************************************************************** +-- +-- IEs +-- +-- ************************************************************** + +id-Cause ProtocolIE-ID ::= 0 +id-Cells-Failed-to-be-Activated-List ProtocolIE-ID ::= 1 +id-Cells-Failed-to-be-Activated-List-Item ProtocolIE-ID ::= 2 +id-Cells-to-be-Activated-List ProtocolIE-ID ::= 3 +id-Cells-to-be-Activated-List-Item ProtocolIE-ID ::= 4 +id-Cells-to-be-Deactivated-List ProtocolIE-ID ::= 5 +id-Cells-to-be-Deactivated-List-Item ProtocolIE-ID ::= 6 +id-CriticalityDiagnostics ProtocolIE-ID ::= 7 +id-CUtoDURRCInformation ProtocolIE-ID ::= 9 +id-DRBs-FailedToBeModified-Item ProtocolIE-ID ::= 12 +id-DRBs-FailedToBeModified-List ProtocolIE-ID ::= 13 +id-DRBs-FailedToBeSetup-Item ProtocolIE-ID ::= 14 +id-DRBs-FailedToBeSetup-List ProtocolIE-ID ::= 15 +id-DRBs-FailedToBeSetupMod-Item ProtocolIE-ID ::= 16 +id-DRBs-FailedToBeSetupMod-List ProtocolIE-ID ::= 17 +id-DRBs-ModifiedConf-Item ProtocolIE-ID ::= 18 +id-DRBs-ModifiedConf-List ProtocolIE-ID ::= 19 +id-DRBs-Modified-Item ProtocolIE-ID ::= 20 +id-DRBs-Modified-List ProtocolIE-ID ::= 21 +id-DRBs-Required-ToBeModified-Item ProtocolIE-ID ::= 22 +id-DRBs-Required-ToBeModified-List ProtocolIE-ID ::= 23 +id-DRBs-Required-ToBeReleased-Item ProtocolIE-ID ::= 24 +id-DRBs-Required-ToBeReleased-List ProtocolIE-ID ::= 25 +id-DRBs-Setup-Item ProtocolIE-ID ::= 26 +id-DRBs-Setup-List ProtocolIE-ID ::= 27 +id-DRBs-SetupMod-Item ProtocolIE-ID ::= 28 +id-DRBs-SetupMod-List ProtocolIE-ID ::= 29 +id-DRBs-ToBeModified-Item ProtocolIE-ID ::= 30 +id-DRBs-ToBeModified-List ProtocolIE-ID ::= 31 +id-DRBs-ToBeReleased-Item ProtocolIE-ID ::= 32 +id-DRBs-ToBeReleased-List ProtocolIE-ID ::= 33 +id-DRBs-ToBeSetup-Item ProtocolIE-ID ::= 34 +id-DRBs-ToBeSetup-List ProtocolIE-ID ::= 35 +id-DRBs-ToBeSetupMod-Item ProtocolIE-ID ::= 36 +id-DRBs-ToBeSetupMod-List ProtocolIE-ID ::= 37 +id-DRXCycle ProtocolIE-ID ::= 38 +id-DUtoCURRCInformation ProtocolIE-ID ::= 39 +id-gNB-CU-UE-F1AP-ID ProtocolIE-ID ::= 40 +id-gNB-DU-UE-F1AP-ID ProtocolIE-ID ::= 41 +id-gNB-DU-ID ProtocolIE-ID ::= 42 +id-GNB-DU-Served-Cells-Item ProtocolIE-ID ::= 43 +id-gNB-DU-Served-Cells-List ProtocolIE-ID ::= 44 +id-gNB-DU-Name ProtocolIE-ID ::= 45 +id-NRCellID ProtocolIE-ID ::= 46 +id-oldgNB-DU-UE-F1AP-ID ProtocolIE-ID ::= 47 +id-ResetType ProtocolIE-ID ::= 48 +id-ResourceCoordinationTransferContainer ProtocolIE-ID ::= 49 +id-RRCContainer ProtocolIE-ID ::= 50 +id-SCell-ToBeRemoved-Item ProtocolIE-ID ::= 51 +id-SCell-ToBeRemoved-List ProtocolIE-ID ::= 52 +id-SCell-ToBeSetup-Item ProtocolIE-ID ::= 53 +id-SCell-ToBeSetup-List ProtocolIE-ID ::= 54 +id-SCell-ToBeSetupMod-Item ProtocolIE-ID ::= 55 +id-SCell-ToBeSetupMod-List ProtocolIE-ID ::= 56 +id-Served-Cells-To-Add-Item ProtocolIE-ID ::= 57 +id-Served-Cells-To-Add-List ProtocolIE-ID ::= 58 +id-Served-Cells-To-Delete-Item ProtocolIE-ID ::= 59 +id-Served-Cells-To-Delete-List ProtocolIE-ID ::= 60 +id-Served-Cells-To-Modify-Item ProtocolIE-ID ::= 61 +id-Served-Cells-To-Modify-List ProtocolIE-ID ::= 62 +id-SpCell-ID ProtocolIE-ID ::= 63 +id-SRBID ProtocolIE-ID ::= 64 +id-SRBs-FailedToBeSetup-Item ProtocolIE-ID ::= 65 +id-SRBs-FailedToBeSetup-List ProtocolIE-ID ::= 66 +id-SRBs-FailedToBeSetupMod-Item ProtocolIE-ID ::= 67 +id-SRBs-FailedToBeSetupMod-List ProtocolIE-ID ::= 68 +id-SRBs-Required-ToBeReleased-Item ProtocolIE-ID ::= 69 +id-SRBs-Required-ToBeReleased-List ProtocolIE-ID ::= 70 +id-SRBs-ToBeReleased-Item ProtocolIE-ID ::= 71 +id-SRBs-ToBeReleased-List ProtocolIE-ID ::= 72 +id-SRBs-ToBeSetup-Item ProtocolIE-ID ::= 73 +id-SRBs-ToBeSetup-List ProtocolIE-ID ::= 74 +id-SRBs-ToBeSetupMod-Item ProtocolIE-ID ::= 75 +id-SRBs-ToBeSetupMod-List ProtocolIE-ID ::= 76 +id-TimeToWait ProtocolIE-ID ::= 77 +id-TransactionID ProtocolIE-ID ::= 78 +id-TransmissionStopIndicator ProtocolIE-ID ::= 79 +id-UE-associatedLogicalF1-ConnectionItem ProtocolIE-ID ::= 80 +id-UE-associatedLogicalF1-ConnectionListResAck ProtocolIE-ID ::= 81 +id-gNB-CU-Name ProtocolIE-ID ::= 82 +id-SCell-FailedtoSetup-List ProtocolIE-ID ::= 83 +id-SCell-FailedtoSetup-Item ProtocolIE-ID ::= 84 +id-SCell-FailedtoSetupMod-List ProtocolIE-ID ::= 85 +id-SCell-FailedtoSetupMod-Item ProtocolIE-ID ::= 86 +id-RRCRconfigurationCompleteIndicator ProtocolIE-ID ::= 87 +id-Active-Cells-Item ProtocolIE-ID ::= 88 +id-Active-Cells-List ProtocolIE-ID ::= 89 +id-Candidate-SpCell-List ProtocolIE-ID ::= 90 +id-Candidate-SpCell-Item ProtocolIE-ID ::= 91 +id-Potential-SpCell-List ProtocolIE-ID ::= 92 +id-Potential-SpCell-Item ProtocolIE-ID ::= 93 +id-FullConfiguration ProtocolIE-ID ::= 94 +id-C-RNTI ProtocolIE-ID ::= 95 +id-SpCellULConfigured ProtocolIE-ID ::= 96 +id-InactivityMonitoringRequest ProtocolIE-ID ::= 97 +id-InactivityMonitoringResponse ProtocolIE-ID ::= 98 +id-DRB-Activity-Item ProtocolIE-ID ::= 99 +id-DRB-Activity-List ProtocolIE-ID ::= 100 +id-EUTRA-NR-CellResourceCoordinationReq-Container ProtocolIE-ID ::= 101 +id-EUTRA-NR-CellResourceCoordinationReqAck-Container ProtocolIE-ID ::= 102 +id-SpectrumSharingGroupID ProtocolIE-ID ::= 103 +id-ListofEUTRACellsinGNBDUCoordination ProtocolIE-ID ::= 104 +id-Protected-EUTRA-Resources-List ProtocolIE-ID ::= 105 +id-RequestType ProtocolIE-ID ::= 106 +id-ServCellndex ProtocolIE-ID ::= 107 +id-RAT-FrequencyPriorityInformation ProtocolIE-ID ::= 108 +id-ExecuteDuplication ProtocolIE-ID ::= 109 +id-NRCGI ProtocolIE-ID ::= 111 +id-PagingCell-Item ProtocolIE-ID ::= 112 +id-PagingCell-List ProtocolIE-ID ::= 113 +id-PagingDRX ProtocolIE-ID ::= 114 +id-PagingPriority ProtocolIE-ID ::= 115 +id-SIBtype-List ProtocolIE-ID ::= 116 +id-UEIdentityIndexValue ProtocolIE-ID ::= 117 +id-gNB-CUSystemInformation ProtocolIE-ID ::= 118 +id-HandoverPreparationInformation ProtocolIE-ID ::= 119 +id-GNB-CU-TNL-Association-To-Add-Item ProtocolIE-ID ::= 120 +id-GNB-CU-TNL-Association-To-Add-List ProtocolIE-ID ::= 121 +id-GNB-CU-TNL-Association-To-Remove-Item ProtocolIE-ID ::= 122 +id-GNB-CU-TNL-Association-To-Remove-List ProtocolIE-ID ::= 123 +id-GNB-CU-TNL-Association-To-Update-Item ProtocolIE-ID ::= 124 +id-GNB-CU-TNL-Association-To-Update-List ProtocolIE-ID ::= 125 +id-MaskedIMEISV ProtocolIE-ID ::= 126 +id-PagingIdentity ProtocolIE-ID ::= 127 +id-DUtoCURRCContainer ProtocolIE-ID ::= 128 +id-Cells-to-be-Barred-List ProtocolIE-ID ::= 129 +id-Cells-to-be-Barred-Item ProtocolIE-ID ::= 130 +id-TAISliceSupportList ProtocolIE-ID ::= 131 +id-GNB-CU-TNL-Association-Setup-List ProtocolIE-ID ::= 132 +id-GNB-CU-TNL-Association-Setup-Item ProtocolIE-ID ::= 133 +id-GNB-CU-TNL-Association-Failed-To-Setup-List ProtocolIE-ID ::= 134 +id-GNB-CU-TNL-Association-Failed-To-Setup-Item ProtocolIE-ID ::= 135 +id-DRB-Notify-Item ProtocolIE-ID ::= 136 +id-DRB-Notify-List ProtocolIE-ID ::= 137 +id-NotficationControl ProtocolIE-ID ::= 138 +id-RANAC ProtocolIE-ID ::= 139 +id-PWSSystemInformation ProtocolIE-ID ::= 140 +id-RepetitionPeriod ProtocolIE-ID ::= 141 +id-NumberofBroadcastRequest ProtocolIE-ID ::= 142 +id-ConcurrentWarningMessageIndicator ProtocolIE-ID ::= 143 +id-Cells-To-Be-Broadcast-List ProtocolIE-ID ::= 144 +id-Cells-To-Be-Broadcast-Item ProtocolIE-ID ::= 145 +id-Cells-Broadcast-Completed-List ProtocolIE-ID ::= 146 +id-Cells-Broadcast-Completed-Item ProtocolIE-ID ::= 147 +id-Broadcast-To-Be-Cancelled-List ProtocolIE-ID ::= 148 +id-Broadcast-To-Be-Cancelled-Item ProtocolIE-ID ::= 149 +id-Cells-Broadcast-Cancelled-List ProtocolIE-ID ::= 150 +id-Cells-Broadcast-Cancelled-Item ProtocolIE-ID ::= 151 +id-NR-CGI-List-For-Restart-List ProtocolIE-ID ::= 152 +id-NR-CGI-List-For-Restart-Item ProtocolIE-ID ::= 153 +id-PWS-Failed-NR-CGI-List ProtocolIE-ID ::= 154 +id-PWS-Failed-NR-CGI-Item ProtocolIE-ID ::= 155 +id-ConfirmedUEID ProtocolIE-ID ::= 156 +id-Cancel-all-Warning-Messages-Indicator ProtocolIE-ID ::= 157 + +END diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Containers.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Containers.asn new file mode 100644 index 0000000000000000000000000000000000000000..ed5dfba961e1bd315fc373d633babfdd1c4d4acb --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-Containers.asn @@ -0,0 +1,184 @@ +-- ************************************************************** +-- +-- Container definitions +-- +-- ************************************************************** + +F1AP-Containers { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-Containers (5) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + Criticality, + Presence, + PrivateIE-ID, + ProtocolExtensionID, + ProtocolIE-ID + +FROM F1AP-CommonDataTypes + maxPrivateIEs, + maxProtocolExtensions, + maxProtocolIEs + +FROM F1AP-Constants; + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +F1AP-PROTOCOL-IES ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +F1AP-PROTOCOL-IES-PAIR ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &firstCriticality Criticality, + &FirstValue, + &secondCriticality Criticality, + &SecondValue, + &presence Presence +} +WITH SYNTAX { + ID &id + FIRST CRITICALITY &firstCriticality + FIRST TYPE &FirstValue + SECOND CRITICALITY &secondCriticality + SECOND TYPE &SecondValue + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol Extensions +-- +-- ************************************************************** + +F1AP-PROTOCOL-EXTENSION ::= CLASS { + &id ProtocolExtensionID UNIQUE, + &criticality Criticality, + &Extension, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + EXTENSION &Extension + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Private IEs +-- +-- ************************************************************** + +F1AP-PRIVATE-IES ::= CLASS { + &id PrivateIE-ID, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Container for Protocol IEs +-- +-- ************************************************************** + +ProtocolIE-Container {F1AP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-SingleContainer {F1AP-PROTOCOL-IES : IEsSetParam} ::= + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-Field {F1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE { + id F1AP-PROTOCOL-IES.&id ({IEsSetParam}), + criticality F1AP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), + value F1AP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Protocol IE Pairs +-- +-- ************************************************************** + +ProtocolIE-ContainerPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-FieldPair {{IEsSetParam}} + +ProtocolIE-FieldPair {F1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE { + id F1AP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}), + firstCriticality F1AP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}), + firstValue F1AP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}), + secondCriticality F1AP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}), + secondValue F1AP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Protocol Extensions +-- +-- ************************************************************** + +ProtocolExtensionContainer {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= + SEQUENCE (SIZE (1..maxProtocolExtensions)) OF + ProtocolExtensionField {{ExtensionSetParam}} + +ProtocolExtensionField {F1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE { + id F1AP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), + criticality F1AP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), + extensionValue F1AP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Private IEs +-- +-- ************************************************************** + +PrivateIE-Container {F1AP-PRIVATE-IES : IEsSetParam } ::= + SEQUENCE (SIZE (1.. maxPrivateIEs)) OF + PrivateIE-Field {{IEsSetParam}} + +PrivateIE-Field {F1AP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE { + id F1AP-PRIVATE-IES.&id ({IEsSetParam}), + criticality F1AP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}), + value F1AP-PRIVATE-IES.&Value ({IEsSetParam}{@id}) +} + +END diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-IEs.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-IEs.asn new file mode 100644 index 0000000000000000000000000000000000000000..aa92b8d3f8af026224a7e182b15187e41d8d50c2 --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-IEs.asn @@ -0,0 +1,1441 @@ +-- ************************************************************** +-- +-- Information Element Definitions +-- +-- ************************************************************** + +F1AP-IEs { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-IEs (2) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + id-gNB-CUSystemInformation, + id-HandoverPreparationInformation, + id-TAISliceSupportList, + id-RANAC, + maxNRARFCN, + maxnoofErrors, + maxnoofBPLMNs, + maxnoofDLUPTNLInformation, + maxnoofNrCellBands, + maxnoofULUPTNLInformation, + maxnoofQoSFlows, + maxnoofSliceItems, + maxnoofSIBTypes, + maxCellineNB + +FROM F1AP-Constants + + Criticality, + ProcedureCode, + ProtocolIE-ID, + TriggeringMessage + +FROM F1AP-CommonDataTypes + + ProtocolExtensionContainer{}, + F1AP-PROTOCOL-EXTENSION, + ProtocolIE-SingleContainer{}, + F1AP-PROTOCOL-IES + +FROM F1AP-Containers; + +-- A + +Active-Cells-Item ::= SEQUENCE { + nRCGI NRCGI , + iE-Extensions ProtocolExtensionContainer { { Active-Cells-ItemExtIEs } } OPTIONAL, + ... +} + +Active-Cells-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +AllocationAndRetentionPriority ::= SEQUENCE { + priorityLevel PriorityLevel, + pre-emptionCapability Pre-emptionCapability, + pre-emptionVulnerability Pre-emptionVulnerability, + iE-Extensions ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL, + ... +} + +AllocationAndRetentionPriority-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} +AveragingWindow ::= INTEGER (0..63) -- this IE may need to be refined + +-- B + +BitRate ::= INTEGER (0..4000000000000,...) + +BroadcastPLMNs-List ::= SEQUENCE (SIZE(1..maxnoofBPLMNs)) OF BroadcastPLMNs-Item + +BroadcastPLMNs-Item ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + iE-Extensions ProtocolExtensionContainer { { BroadcastPLMNs-ItemExtIEs} } OPTIONAL, + ... +} + +BroadcastPLMNs-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { +{ ID id-TAISliceSupportList CRITICALITY ignore EXTENSION SliceSupportList PRESENCE optional }, + ... +} + + +-- C + +Cancel-all-Warning-Messages-Indicator ::= ENUMERATED {true, ...} + +Candidate-SpCell-Item ::= SEQUENCE { + candidate-SpCell-ID NRCGI , + iE-Extensions ProtocolExtensionContainer { { Candidate-SpCell-ItemExtIEs } } OPTIONAL, + ... +} + +Candidate-SpCell-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Cause ::= CHOICE { + radioNetwork CauseRadioNetwork, + transport CauseTransport, + protocol CauseProtocol, + misc CauseMisc, + ... +} + +CauseMisc ::= ENUMERATED { + control-processing-overload, + not-enough-user-plane-processing-resources, + hardware-failure, + om-intervention, + unspecified, +... +} + +CauseProtocol ::= ENUMERATED { + transfer-syntax-error, + abstract-syntax-error-reject, + abstract-syntax-error-ignore-and-notify, + message-not-compatible-with-receiver-state, + semantic-error, + abstract-syntax-error-falsely-constructed-message, + unspecified, + ... +} + +CauseRadioNetwork ::= ENUMERATED { + unspecified, + rl-failure, + unknown-or-already-allocated-gnb-cu-ue-f1ap-id, + unknown-or-already-allocated-gnd-du-ue-f1ap-id, + unknown-or-inconsistent-pair-of-ue-f1ap-id, + interaction-with-other-procedure, + not-supported-qci-Value, + action-desirable-for-radio-reasons, + no-radio-resources-available, + procedure-cancelled, + normal-release, + ... +} + +CauseTransport ::= ENUMERATED { + unspecified, + transport-resource-unavailable, + ... +} + + + +CellGroupConfig ::= OCTET STRING + +Cells-Failed-to-be-Activated-List-Item ::= SEQUENCE { + nRCGI NRCGI, + cause Cause, + iE-Extensions ProtocolExtensionContainer { { Cells-Failed-to-be-Activated-List-ItemExtIEs } } OPTIONAL, + ... +} + +Cells-Failed-to-be-Activated-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Cells-To-Be-Broadcast-Item ::= SEQUENCE { + nRCGI NRCGI, + iE-Extensions ProtocolExtensionContainer { { Cells-To-Be-Broadcast-ItemExtIEs } } OPTIONAL, + ... +} + +Cells-To-Be-Broadcast-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Cells-Broadcast-Completed-Item ::= SEQUENCE { + nRCGI NRCGI, + iE-Extensions ProtocolExtensionContainer { { Cells-Broadcast-Completed-ItemExtIEs } } OPTIONAL, + ... +} + +Cells-Broadcast-Completed-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Broadcast-To-Be-Cancelled-Item ::= SEQUENCE { + nRCGI NRCGI, + iE-Extensions ProtocolExtensionContainer { { Broadcast-To-Be-Cancelled-ItemExtIEs } } OPTIONAL, + ... +} + +Broadcast-To-Be-Cancelled-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +Cells-Broadcast-Cancelled-Item ::= SEQUENCE { + nRCGI NRCGI, + numberOfBroadcasts NumberOfBroadcasts, + iE-Extensions ProtocolExtensionContainer { { Cells-Broadcast-Cancelled-ItemExtIEs } } OPTIONAL, + ... +} + +Cells-Broadcast-Cancelled-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Cells-to-be-Activated-List-Item ::= SEQUENCE { + nRCGI NRCGI, + nRPCI NRPCI OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Cells-to-be-Activated-List-ItemExtIEs} } OPTIONAL, + ... +} + +Cells-to-be-Activated-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { +{ ID id-gNB-CUSystemInformation CRITICALITY reject EXTENSION GNB-CUSystemInformation PRESENCE optional }, + ... +} + +Cells-to-be-Deactivated-List-Item ::= SEQUENCE { + nRCGI NRCGI , + iE-Extensions ProtocolExtensionContainer { { Cells-to-be-Deactivated-List-ItemExtIEs } } OPTIONAL, + ... +} + +Cells-to-be-Deactivated-List-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Cells-to-be-Barred-Item::= SEQUENCE { + nRCGI NRCGI , + cellBarred CellBarred, + iE-Extensions ProtocolExtensionContainer { { Cells-to-be-Barred-Item-ExtIEs } } OPTIONAL +} + +Cells-to-be-Barred-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +CellBarred ::= ENUMERATED {barred, not-barred, ...} + +CellULConfigured ::= ENUMERATED {none, ul, sul, ul-and-sul, ...} + +CNUEPagingIdentity ::= CHOICE { + fiveG-S-TMSI BIT STRING (SIZE(48)), + choice-extension ProtocolExtensionContainer { { CNUEPagingIdentity-ExtIEs } }, + ... +} + +CNUEPagingIdentity-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +ConcurrentWarningMessageIndicator ::= ENUMERATED {true, ...} + +CP-TransportLayerAddress ::= CHOICE { + endpoint-IP-address TransportLayerAddress, + endpoint-IP-address-and-port Endpoint-IP-address-and-port, + choice-extension ProtocolExtensionContainer { { CP-TransportLayerAddress-ExtIEs } }, + ... +} + +CP-TransportLayerAddress-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +CriticalityDiagnostics ::= SEQUENCE { + procedureCode ProcedureCode OPTIONAL, + triggeringMessage TriggeringMessage OPTIONAL, + procedureCriticality Criticality OPTIONAL, + transactionID TransactionID OPTIONAL, + iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer {{CriticalityDiagnostics-ExtIEs}} OPTIONAL, + ... +} + +CriticalityDiagnostics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1.. maxnoofErrors)) OF CriticalityDiagnostics-IE-Item + +CriticalityDiagnostics-IE-Item ::= SEQUENCE { + iECriticality Criticality, + iE-ID ProtocolIE-ID, + typeOfError TypeOfError, + iE-Extensions ProtocolExtensionContainer {{CriticalityDiagnostics-IE-Item-ExtIEs}} OPTIONAL, + ... +} + +CriticalityDiagnostics-IE-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +C-RNTI ::= BIT STRING (SIZE (16)) + +CUtoDURRCInformation ::= SEQUENCE { + cG-ConfigInfo CG-ConfigInfo OPTIONAL, + uE-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList OPTIONAL, + measConfig MeasConfig OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { CUtoDURRCInformation-ExtIEs} } OPTIONAL, + ... +} + +CUtoDURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { +{ ID id-HandoverPreparationInformation CRITICALITY ignore EXTENSION HandoverPreparationInformation PRESENCE optional }, + ... +} + +-- D + +DLUPTNLInformation-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDLUPTNLInformation)) OF DLUPTNLInformation-ToBeSetup-Item + +DLUPTNLInformation-ToBeSetup-Item ::= SEQUENCE { + dLUPTNLInformation UPTransportLayerInformation , + iE-Extensions ProtocolExtensionContainer { { DLUPTNLInformation-ToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +DLUPTNLInformation-ToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Activity-Item ::= SEQUENCE { + dRBID DRBID, + dRB-Activity DRB-Activity OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRB-Activity-ItemExtIEs } } OPTIONAL, + ... +} + +DRB-Activity-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Activity ::= ENUMERATED {active, not-active} + +DRBID ::= INTEGER (1..32, ...) + +DRBs-FailedToBeModified-Item ::= SEQUENCE { + dRBID DRBID , + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRBs-FailedToBeModified-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-FailedToBeModified-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-FailedToBeSetup-Item ::= SEQUENCE { + dRBID DRBID, + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRBs-FailedToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-FailedToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +DRBs-FailedToBeSetupMod-Item ::= SEQUENCE { + dRBID DRBID , + cause Cause OPTIONAL , + iE-Extensions ProtocolExtensionContainer { { DRBs-FailedToBeSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-FailedToBeSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Information ::= SEQUENCE { + dRB-QoS QoSFlowLevelQoSParameters, + sNSSAI SNSSAI, + notificationControl NotificationControl OPTIONAL, + flows-Mapped-To-DRB-List Flows-Mapped-To-DRB-List, + iE-Extensions ProtocolExtensionContainer { { DRB-Information-ItemExtIEs } } OPTIONAL +} + +DRB-Information-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Modified-Item ::= SEQUENCE { + dRBID DRBID, + lCID LCID OPTIONAL, + dLUPTNLInformation-ToBeSetup-List DLUPTNLInformation-ToBeSetup-List, + iE-Extensions ProtocolExtensionContainer { { DRBs-Modified-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-Modified-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-ModifiedConf-Item ::= SEQUENCE { + dRBID DRBID, + uLUPTNLInformation-ToBeSetup-List ULUPTNLInformation-ToBeSetup-List , + iE-Extensions ProtocolExtensionContainer { { DRBs-ModifiedConf-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-ModifiedConf-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRB-Notify-Item ::= SEQUENCE { + dRBID DRBID, + notification-Cause Notification-Cause, + iE-Extensions ProtocolExtensionContainer { { DRB-Notify-ItemExtIEs } } OPTIONAL, + ... +} + +DRB-Notify-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Required-ToBeModified-Item ::= SEQUENCE { + dRBID DRBID, + dLUPTNLInformation-ToBeSetup-List DLUPTNLInformation-ToBeSetup-List , + iE-Extensions ProtocolExtensionContainer { { DRBs-Required-ToBeModified-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-Required-ToBeModified-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Required-ToBeReleased-Item ::= SEQUENCE { + dRBID DRBID, + iE-Extensions ProtocolExtensionContainer { { DRBs-Required-ToBeReleased-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-Required-ToBeReleased-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-Setup-Item ::= SEQUENCE { + dRBID DRBID, + lCID LCID OPTIONAL, + dLUPTNLInformation-ToBeSetup-List DLUPTNLInformation-ToBeSetup-List , + iE-Extensions ProtocolExtensionContainer { { DRBs-Setup-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-Setup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-SetupMod-Item ::= SEQUENCE { + dRBID DRBID, + lCID LCID OPTIONAL, + dLUPTNLInformation-ToBeSetup-List DLUPTNLInformation-ToBeSetup-List , + iE-Extensions ProtocolExtensionContainer { { DRBs-SetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-SetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +DRBs-ToBeModified-Item ::= SEQUENCE { + dRBID DRBID, + qoSInformation QoSInformation, + uLUPTNLInformation-ToBeSetup-List ULUPTNLInformation-ToBeSetup-List , + uLConfiguration ULConfiguration OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRBs-ToBeModified-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-ToBeModified-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-ToBeReleased-Item ::= SEQUENCE { + dRBID DRBID, + iE-Extensions ProtocolExtensionContainer { { DRBs-ToBeReleased-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-ToBeReleased-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBs-ToBeSetup-Item ::= SEQUENCE { + dRBID DRBID, + qoSInformation QoSInformation, + uLUPTNLInformation-ToBeSetup-List ULUPTNLInformation-ToBeSetup-List , + rLCMode RLCMode, + uLConfiguration ULConfiguration OPTIONAL, + duplicationActivation DuplicationActivation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRBs-ToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-ToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +DRBs-ToBeSetupMod-Item ::= SEQUENCE { + dRBID DRBID, + qoSInformation QoSInformation, + uLUPTNLInformation-ToBeSetup-List ULUPTNLInformation-ToBeSetup-List, + rLCMode RLCMode, + uLConfiguration ULConfiguration OPTIONAL, + duplicationActivation DuplicationActivation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRBs-ToBeSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +DRBs-ToBeSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DRXCycle ::= SEQUENCE { + longDRXCycleLength LongDRXCycleLength, + shortDRXCycleLength ShortDRXCycleLength OPTIONAL, + shortDRXCycleTimer ShortDRXCycleTimer OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DRXCycle-ExtIEs} } OPTIONAL, + ... +} + +DRXCycle-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DUtoCURRCContainer ::= OCTET STRING + +DUtoCURRCInformation ::= SEQUENCE { + cellGroupConfig CellGroupConfig, + measGapConfig MeasGapConfig OPTIONAL, + requestedP-MaxFR1 OCTET STRING OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { DUtoCURRCInformation-ExtIEs} } OPTIONAL, + ... +} + +DUtoCURRCInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +DuplicationActivation ::= ENUMERATED{active,inactive,... } + +DuplicationIndication ::= ENUMERATED {true, ...} + +Dynamic5QIDescriptor ::= SEQUENCE { + qoSPriorityLevel INTEGER (1..127), + packetDelayBudget PacketDelayBudget, + packetErrorRate PacketErrorRate, + delayCritical ENUMERATED {delay-critical, non-delay-critical} OPTIONAL, + averagingWindow AveragingWindow OPTIONAL, + maxDataBurstVolume MaxDataBurstVolume OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Dynamic5QIDescriptor-ExtIEs } } OPTIONAL +} + +Dynamic5QIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- E + +Endpoint-IP-address-and-port ::=SEQUENCE { + endpointIPAddress TransportLayerAddress, + iE-Extensions ProtocolExtensionContainer { { Endpoint-IP-address-and-port-ExtIEs} } OPTIONAL +} + +Endpoint-IP-address-and-port-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +EUTRANQoS ::= SEQUENCE { + qCI QCI, + allocationAndRetentionPriority AllocationAndRetentionPriority, + gbrQosInformation GBR-QosInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { EUTRANQoS-ExtIEs} } OPTIONAL, + ... +} + +EUTRANQoS-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +ExecuteDuplication ::= ENUMERATED{true,...} + +EUTRA-Mode-Info ::= CHOICE { + eUTRAFDD EUTRA-FDD-Info, + eUTRATDD EUTRA-TDD-Info, + ... +} + +EUTRA-NR-CellResourceCoordinationReq-Container ::= OCTET STRING + +EUTRA-NR-CellResourceCoordinationReqAck-Container ::= OCTET STRING + +EUTRA-FDD-Info ::= SEQUENCE { + uL-offsetToPointA OffsetToPointA, + dL-offsetToPointA OffsetToPointA, + iE-Extensions ProtocolExtensionContainer { {EUTRA-FDD-Info-ExtIEs} } OPTIONAL, + ... +} + +EUTRA-FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +EUTRA-TDD-Info ::= SEQUENCE { + offsetToPointA OffsetToPointA, + iE-Extensions ProtocolExtensionContainer { {EUTRA-TDD-Info-ExtIEs} } OPTIONAL, + ... +} + +EUTRA-TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- F + +FDD-Info ::= SEQUENCE { + uL-NRFreqInfo NRFreqInfo, + dL-NRFreqInfo NRFreqInfo, + uL-Transmission-Bandwidth Transmission-Bandwidth, + dL-Transmission-Bandwidth Transmission-Bandwidth, + iE-Extensions ProtocolExtensionContainer { {FDD-Info-ExtIEs} } OPTIONAL, + ... +} + +FDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +Flows-Mapped-To-DRB-List ::= SEQUENCE (SIZE(1.. maxnoofQoSFlows)) OF Flows-Mapped-To-DRB-Item + +Flows-Mapped-To-DRB-Item ::= SEQUENCE { + qoSFlowIndicator QoSFlowIndicator, + qoSFlowLevelQoSParameters QoSFlowLevelQoSParameters, + iE-Extensions ProtocolExtensionContainer { { Flows-Mapped-To-DRB-ItemExtIEs} } OPTIONAL +} + +Flows-Mapped-To-DRB-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +FreqBandNrItem ::= SEQUENCE { + freqBandIndicatorNr INTEGER (1..1024,...), + supportedSULBandList SEQUENCE (SIZE(0..maxnoofNrCellBands)) OF SupportedSULFreqBandItem, + iE-Extensions ProtocolExtensionContainer { {FreqBandNrItem-ExtIEs} } OPTIONAL, + ... +} + +FreqBandNrItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +FullConfiguration ::= ENUMERATED {full, ...} + +-- G + + +GBR-QosInformation ::= SEQUENCE { + e-RAB-MaximumBitrateDL BitRate, + e-RAB-MaximumBitrateUL BitRate, + e-RAB-GuaranteedBitrateDL BitRate, + e-RAB-GuaranteedBitrateUL BitRate, + iE-Extensions ProtocolExtensionContainer { { GBR-QosInformation-ExtIEs} } OPTIONAL, + ... +} + +GBR-QosInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GBR-QoSFlowInformation::= SEQUENCE { + maxFlowBitRateDownlink BitRate, + maxFlowBitRateUplink BitRate, + guaranteedFlowBitRateDownlink BitRate, + guaranteedFlowBitRateUplink BitRate, + maxPacketLossRateDownlink MaxPacketLossRate OPTIONAL, + maxPacketLossRateUplink MaxPacketLossRate OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { GBR-QosFlowInformation-ExtIEs} } OPTIONAL, + ... +} + +GBR-QosFlowInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +GNB-CUSystemInformation::= SEQUENCE { + sImessage OCTET STRING, + iE-Extensions ProtocolExtensionContainer { { GNB-CUSystemInformation-ExtIEs} } OPTIONAL, + ... +} + +GNB-CUSystemInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-TNL-Association-Setup-Item::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TransportLayerAddress , + iE-Extensions ProtocolExtensionContainer { { GNB-CU-TNL-Association-Setup-Item-ExtIEs} } OPTIONAL +} + +GNB-CU-TNL-Association-Setup-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-TNL-Association-Failed-To-Setup-Item ::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TransportLayerAddress , + cause Cause, + iE-Extensions ProtocolExtensionContainer { { GNB-CU-TNL-Association-Failed-To-Setup-Item-ExtIEs} } OPTIONAL +} + +GNB-CU-TNL-Association-Failed-To-Setup-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +GNB-CU-TNL-Association-To-Add-Item ::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TransportLayerAddress , + tNLAssociationUsage TNLAssociationUsage, + iE-Extensions ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Add-Item-ExtIEs} } OPTIONAL +} + +GNB-CU-TNL-Association-To-Add-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-TNL-Association-To-Remove-Item::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TransportLayerAddress , + iE-Extensions ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Remove-Item-ExtIEs} } OPTIONAL +} + +GNB-CU-TNL-Association-To-Remove-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +GNB-CU-TNL-Association-To-Update-Item::= SEQUENCE { + tNLAssociationTransportLayerAddress CP-TransportLayerAddress , + tNLAssociationUsage TNLAssociationUsage OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { GNB-CU-TNL-Association-To-Update-Item-ExtIEs} } OPTIONAL +} + +GNB-CU-TNL-Association-To-Update-Item-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-CU-UE-F1AP-ID ::= INTEGER (0..4294967295) + +GNB-DU-UE-F1AP-ID ::= INTEGER (0..4294967295) + +GNB-DU-ID ::= INTEGER (0..68719476735) + +GNB-CU-Name ::= PrintableString(SIZE(1..150,...)) + +GNB-DU-Name ::= PrintableString(SIZE(1..150,...)) + +GNB-DU-Served-Cells-Item ::= SEQUENCE { + served-Cell-Information Served-Cell-Information, + gNB-DU-System-Information GNB-DU-System-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { GNB-DU-Served-Cells-ItemExtIEs} } OPTIONAL, + ... +} + +GNB-DU-Served-Cells-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GNB-DU-System-Information ::= SEQUENCE { + mIB-message MIB-message, + sIB1-message SIB1-message, + iE-Extensions ProtocolExtensionContainer { { GNB-DU-System-Information-ExtIEs } } OPTIONAL, + ... +} + +GNB-DU-System-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +GTP-TEID ::= OCTET STRING (SIZE (4)) + +GTPTunnel ::= SEQUENCE { + transportLayerAddress TransportLayerAddress, + gTP-TEID GTP-TEID, + iE-Extensions ProtocolExtensionContainer { { GTPTunnel-ExtIEs } } OPTIONAL, + ... +} + +GTPTunnel-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- H + +HandoverPreparationInformation ::= OCTET STRING + +-- I +InactivityMonitoringRequest ::= ENUMERATED { true,...} +InactivityMonitoringResponse ::= ENUMERATED { not-supported,...} + +-- J + +-- K + +-- L + +LCID ::= INTEGER (1..32, ...) + +ListofEUTRACellsinGNBDUCoordination ::= SEQUENCE (SIZE (0.. maxCellineNB)) OF Served-EUTRA-Cells-Information + +LongDRXCycleLength ::= ENUMERATED +{ms10, ms20, ms32, ms40, ms60, ms64, ms70, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ms1024, ms1280, ms2048, ms2560, ms5120, ms10240, ...} + +-- M + +MaskedIMEISV ::= BIT STRING (SIZE (64)) + +MaxDataBurstVolume ::= INTEGER (0..63) -- this IE may need to be refined +MaxPacketLossRate ::= INTEGER (0..1000) + +MIB-message ::= OCTET STRING + +MeasConfig ::= OCTET STRING + +MeasGapConfig ::= OCTET STRING + +-- N + +NGRANAllocationAndRetentionPriority ::= SEQUENCE { + priorityLevel PriorityLevel, + pre-emptionCapability Pre-emptionCapability, + pre-emptionVulnerability Pre-emptionVulnerability, + iE-Extensions ProtocolExtensionContainer { {NGRANAllocationAndRetentionPriority-ExtIEs} } OPTIONAL +} + +NGRANAllocationAndRetentionPriority-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +NR-CGI-List-For-Restart-Item ::= SEQUENCE { + nRCGI NRCGI, + iE-Extensions ProtocolExtensionContainer { { NR-CGI-List-For-Restart-ItemExtIEs } } OPTIONAL, + ... +} + +NR-CGI-List-For-Restart-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +NonDynamic5QIDescriptor ::= SEQUENCE { + fiveQI INTEGER (0..255), + qoSPriorityLevel INTEGER (1..127) OPTIONAL, + averagingWindow AveragingWindow OPTIONAL, + maxDataBurstVolume MaxDataBurstVolume OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { NonDynamic5QIDescriptor-ExtIEs } } OPTIONAL +} + +NonDynamic5QIDescriptor-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Notification-Cause ::= ENUMERATED {fulfilled, not-fulfilled, ...} + +NotificationControl ::= ENUMERATED {active, not-active, ...} + +NRFreqInfo ::= SEQUENCE { + nRARFCN INTEGER (0..maxNRARFCN), + sul-Information SUL-Information OPTIONAL, + freqBandListNr SEQUENCE (SIZE(1..maxnoofNrCellBands)) OF FreqBandNrItem, + iE-Extensions ProtocolExtensionContainer { { NRFreqInfoExtIEs} } OPTIONAL, + ... +} + +NRFreqInfoExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +NRCGI ::= SEQUENCE { + pLMN-Identity PLMN-Identity, + nRCellIdentity NRCellIdentity, + iE-Extensions ProtocolExtensionContainer { {NRCGI-ExtIEs} } OPTIONAL, + ... +} + +NRCGI-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +NR-Mode-Info ::= CHOICE { + fDD FDD-Info, + tDD TDD-Info, + choice-extension ProtocolExtensionContainer { { NR-Mode-Info-ExtIEs} }, + ... +} + +NR-Mode-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { ... +} + + +NRCellIdentity ::= BIT STRING (SIZE(36)) + +NRNRB ::= ENUMERATED { nrb11, nrb18, nrb24, nrb25, nrb31, nrb32, nrb38, nrb51, nrb52, nrb65, nrb66, nrb78, nrb79, nrb93, nrb106, nrb107, nrb121, nrb132, nrb133, nrb135, nrb160, nrb162, nrb189, nrb216, nrb217, nrb245, nrb264, nrb270, nrb273, ...} + +NRPCI ::= INTEGER(0..1007) + +NRSCS ::= ENUMERATED { scs15, scs30, scs60, scs120, ...} + +NumberOfBroadcasts ::= INTEGER (0..65535) + +NumberofBroadcastRequest ::= INTEGER (0..65535) + +-- O + +OffsetToPointA ::= INTEGER (0..2199,...) + +-- P + +PacketDelayBudget ::= INTEGER (0..63) -- this IE may need to be refined + +PacketErrorRate ::= INTEGER (0..63) -- this IE may need to be refined + +PagingCell-Item ::= SEQUENCE { + nRCGI NRCGI , + iE-Extensions ProtocolExtensionContainer { { PagingCell-ItemExtIEs } } OPTIONAL +} + +PagingCell-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PagingDRX ::= INTEGER (0..63) -- this IE may need to be refined + +PagingIdentity ::= CHOICE { + rANUEPagingIdentity RANUEPagingIdentity, + cNUEPagingIdentity CNUEPagingIdentity, + choice-extension ProtocolExtensionContainer { { PagingIdentity-ExtIEs } }, + ... +} + +PagingIdentity-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PagingPriority ::= ENUMERATED { priolevel1, priolevel2, priolevel3, priolevel4, priolevel5, priolevel6, priolevel7, priolevel8,...} + +PLMN-Identity ::= OCTET STRING (SIZE(3)) + +Pre-emptionCapability ::= ENUMERATED { + shall-not-trigger-pre-emption, + may-trigger-pre-emption +} + +Pre-emptionVulnerability ::= ENUMERATED { + not-pre-emptable, + pre-emptable +} + +PriorityLevel ::= INTEGER { spare (0), highest (1), lowest (14), no-priority (15) } (0..15) + +ProtectedEUTRAResourceIndication ::= OCTET STRING + +Potential-SpCell-Item ::= SEQUENCE { + potential-SpCell-ID NRCGI , + iE-Extensions ProtocolExtensionContainer { { Potential-SpCell-ItemExtIEs } } OPTIONAL, + ... +} + +Potential-SpCell-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PWS-Failed-NR-CGI-Item ::= SEQUENCE { + nRCGI NRCGI, + numberOfBroadcasts NumberOfBroadcasts, + iE-Extensions ProtocolExtensionContainer { { PWS-Failed-NR-CGI-ItemExtIEs } } OPTIONAL, + ... +} + +PWS-Failed-NR-CGI-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +PWSSystemInformation ::= OCTET STRING + +-- Q + +QCI ::= INTEGER (0..255) + +QoS-Characteristics ::= CHOICE { + non-Dynamic-5QI NonDynamic5QIDescriptor, + dynamic-5QI Dynamic5QIDescriptor, + choice-extension ProtocolExtensionContainer { { QoS-Characteristics-ExtIEs } }, + ... +} + +QoS-Characteristics-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +QoSFlowIndicator ::= INTEGER (0..63) + +QoSFlowLevelQoSParameters ::= SEQUENCE { + qoS-Characteristics QoS-Characteristics, + nGRANallocationRetentionPriority NGRANAllocationAndRetentionPriority, + gBR-QoS-Flow-Information GBR-QoSFlowInformation OPTIONAL, + reflective-QoS-Attribute ENUMERATED {subject-to, ...} OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { QoSFlowLevelQoSParameters-ExtIEs } } OPTIONAL +} + +QoSFlowLevelQoSParameters-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +QoSInformation ::= CHOICE { + eUTRANQoS EUTRANQoS, + dRB-Information DRB-Information, + choice-extension ProtocolExtensionContainer { { QoSInformation-ExtIEs} }, + ... +} + +QoSInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- R + +RANAC ::= INTEGER (0..64) + +RANUEPagingIdentity ::= SEQUENCE { + iRNTI BIT STRING (SIZE(40)), + iE-Extensions ProtocolExtensionContainer { { RANUEPagingIdentity-ExtIEs } } OPTIONAL} + +RANUEPagingIdentity-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +RAT-FrequencyPriorityInformation::= CHOICE { + subscriberProfileIDforRFP SubscriberProfileIDforRFP, + rAT-FrequencySelectionPriority RAT-FrequencySelectionPriority, + choice-extension ProtocolExtensionContainer { { RAT-FrequencyPriorityInformation-ExtIEs} }, + ... +} + +RAT-FrequencyPriorityInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +RAT-FrequencySelectionPriority::= INTEGER (1.. 256, ...) + +RequestType ::= ENUMERATED {offer, execution, ...} + +ResourceCoordinationTransferContainer ::= OCTET STRING + +RepetitionPeriod ::= INTEGER (0..131071, ...) +RLCMode ::= ENUMERATED { + rlc-am, + rlc-um +} + +RRCContainer ::= OCTET STRING + +RRCRconfigurationCompleteIndicator ::= ENUMERATED {true, ...} + +-- S + +SCell-FailedtoSetup-Item ::= SEQUENCE { + sCell-ID NRCGI , + cause Cause OPTIONAL , + iE-Extensions ProtocolExtensionContainer { { SCell-FailedtoSetup-ItemExtIEs } } OPTIONAL, + ... +} + +SCell-FailedtoSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SCell-FailedtoSetupMod-Item ::= SEQUENCE { + sCell-ID NRCGI , + cause Cause OPTIONAL , + iE-Extensions ProtocolExtensionContainer { { SCell-FailedtoSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +SCell-FailedtoSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SCell-ToBeRemoved-Item ::= SEQUENCE { + sCell-ID NRCGI , + iE-Extensions ProtocolExtensionContainer { { SCell-ToBeRemoved-ItemExtIEs } } OPTIONAL, + ... +} + +SCell-ToBeRemoved-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SCell-ToBeSetup-Item ::= SEQUENCE { + sCell-ID NRCGI , + sCellIndex SCellIndex, + sCellULConfigured CellULConfigured OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SCell-ToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +SCell-ToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SCell-ToBeSetupMod-Item ::= SEQUENCE { + sCell-ID NRCGI , + sCellIndex SCellIndex, + sCellULConfigured CellULConfigured OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SCell-ToBeSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +SCell-ToBeSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SCellIndex ::=INTEGER (1..31, ...) + +CG-ConfigInfo ::= OCTET STRING + +ServCellIndex ::= INTEGER (0..31, ...) + +Served-Cell-Information ::= SEQUENCE { + nRCGI NRCGI, + nRPCI NRPCI, + fiveGS-TAC FiveGS-TAC, + configured-EPS-TAC Configured-EPS-TAC OPTIONAL, + servedPLMNs BroadcastPLMNs-List, + nR-Mode-Info NR-Mode-Info, + measurementTimingConfiguration OCTET STRING, + iE-Extensions ProtocolExtensionContainer { {Served-Cell-Information-ExtIEs} } OPTIONAL, + ... +} + +Served-Cell-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { +{ ID id-RANAC CRITICALITY ignore EXTENSION RANAC PRESENCE optional}, + ... +} + +Served-Cells-To-Add-Item ::= SEQUENCE { + served-Cell-Information Served-Cell-Information, + gNB-DU-System-Information GNB-DU-System-Information OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { Served-Cells-To-Add-ItemExtIEs} } OPTIONAL, + ... +} + +Served-Cells-To-Add-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Served-Cells-To-Delete-Item ::= SEQUENCE { + oldNRCGI NRCGI , + iE-Extensions ProtocolExtensionContainer { { Served-Cells-To-Delete-ItemExtIEs } } OPTIONAL, + ... +} + +Served-Cells-To-Delete-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Served-Cells-To-Modify-Item ::= SEQUENCE { + oldNRCGI NRCGI , + served-Cell-Information Served-Cell-Information , + gNB-DU-System-Information GNB-DU-System-Information OPTIONAL , + iE-Extensions ProtocolExtensionContainer { { Served-Cells-To-Modify-ItemExtIEs } } OPTIONAL, + ... +} + +Served-Cells-To-Modify-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +Served-EUTRA-Cells-Information::= SEQUENCE { + eUTRA-Mode-Info EUTRA-Mode-Info, + protectedEUTRAResourceIndication ProtectedEUTRAResourceIndication, + iE-Extensions ProtocolExtensionContainer { {Served-EUTRA-Cell-Information-ExtIEs} } OPTIONAL, + ... +} + +Served-EUTRA-Cell-Information-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +ShortDRXCycleLength ::= ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms10, ms14, ms16, ms20, ms30, ms32, ms35, ms40, ms64, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ...} + +ShortDRXCycleTimer ::= INTEGER (1..16) + +SIB1-message ::= OCTET STRING + +SIBtype ::= ENUMERATED { + sibtype2,sibtype3, sibtype4, sibtype5, sibtype6, sibtype7, sibtype8, sibtype9, + ... +} + +SIBtype-List ::= SEQUENCE (SIZE(1.. maxnoofSIBTypes)) OF SIBtype-Item + +SIBtype-Item ::= SEQUENCE { + sIBtype SIBtype , + iE-Extensions ProtocolExtensionContainer { { SIBtype-ItemExtIEs } } OPTIONAL +} + +SIBtype-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SliceSupportList ::= SEQUENCE (SIZE(1.. maxnoofSliceItems)) OF SliceSupportItem + +SliceSupportItem ::= SEQUENCE { + sNSSAI SNSSAI, + iE-Extensions ProtocolExtensionContainer { { SliceSupportItem-ExtIEs } } OPTIONAL +} + +SliceSupportItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SNSSAI ::= SEQUENCE { + sST OCTET STRING (SIZE(1)), + sD OCTET STRING (SIZE(3)) OPTIONAL , + iE-Extensions ProtocolExtensionContainer { { SNSSAI-ExtIEs } } OPTIONAL +} + +SNSSAI-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SpectrumSharingGroupID ::= INTEGER (1..maxCellineNB) + +SRBID ::= INTEGER (0..3, ...) + +SRBs-FailedToBeSetup-Item ::= SEQUENCE { + sRBID SRBID , + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SRBs-FailedToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-FailedToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SRBs-FailedToBeSetupMod-Item ::= SEQUENCE { + sRBID SRBID , + cause Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SRBs-FailedToBeSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-FailedToBeSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + + +SRBs-Required-ToBeReleased-Item ::= SEQUENCE { + sRBID SRBID, + iE-Extensions ProtocolExtensionContainer { { SRBs-Required-ToBeReleased-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-Required-ToBeReleased-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SRBs-ToBeReleased-Item ::= SEQUENCE { + sRBID SRBID, + iE-Extensions ProtocolExtensionContainer { { SRBs-ToBeReleased-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-ToBeReleased-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SRBs-ToBeSetup-Item ::= SEQUENCE { + sRBID SRBID , + duplicationIndication DuplicationIndication OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SRBs-ToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-ToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SRBs-ToBeSetupMod-Item ::= SEQUENCE { + sRBID SRBID, + duplicationIndication DuplicationIndication OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { SRBs-ToBeSetupMod-ItemExtIEs } } OPTIONAL, + ... +} + +SRBs-ToBeSetupMod-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SUL-Information ::= SEQUENCE { + sUL-NRARFCN INTEGER (0..maxNRARFCN), + sUL-transmission-Bandwidth Transmission-Bandwidth, + iE-Extensions ProtocolExtensionContainer { { SUL-InformationExtIEs} } OPTIONAL, + ... +} + +SUL-InformationExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +SubscriberProfileIDforRFP ::= INTEGER (1..256, ...) + +SupportedSULFreqBandItem ::= SEQUENCE { + freqBandIndicatorNr INTEGER (1..1024,...), + iE-Extensions ProtocolExtensionContainer { { SupportedSULFreqBandItem-ExtIEs} } OPTIONAL, + ... +} + +SupportedSULFreqBandItem-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +-- T + +FiveGS-TAC ::= OCTET STRING (SIZE(3)) + +Configured-EPS-TAC ::= OCTET STRING (SIZE(2)) + +TDD-Info ::= SEQUENCE { + nRFreqInfo NRFreqInfo, + transmission-Bandwidth Transmission-Bandwidth, + iE-Extensions ProtocolExtensionContainer { {TDD-Info-ExtIEs} } OPTIONAL, + ... +} + +TDD-Info-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...} + +TNLAssociationUsage ::= ENUMERATED { + ue, + non-ue, + both, +... +} + +TransportLayerAddress ::= BIT STRING (SIZE(1..160, ...)) + +TransactionID ::= INTEGER (0..255, ...) + +Transmission-Bandwidth ::= SEQUENCE { + nRSCS NRSCS, + nRNRB NRNRB, + iE-Extensions ProtocolExtensionContainer { { Transmission-Bandwidth-ExtIEs} } OPTIONAL, + ... +} + +Transmission-Bandwidth-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +TransmissionStopIndicator ::= ENUMERATED {true, ...} + +TypeOfError ::= ENUMERATED { + not-understood, + missing, + ... +} + +-- U + +UE-associatedLogicalF1-ConnectionItem ::= SEQUENCE { + gNB-CU-UE-F1AP-ID GNB-CU-UE-F1AP-ID OPTIONAL, + gNB-DU-UE-F1AP-ID GNB-DU-UE-F1AP-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { UE-associatedLogicalF1-ConnectionItemExtIEs} } OPTIONAL, + ... +} + +UE-associatedLogicalF1-ConnectionItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +UE-CapabilityRAT-ContainerList::= OCTET STRING + +UEIdentityIndexValue ::= INTEGER (0..63) -- This IE may need to be refined. + +ULConfiguration ::= SEQUENCE { + uLUEConfiguration ULUEConfiguration, + iE-Extensions ProtocolExtensionContainer { { ULConfigurationExtIEs } } OPTIONAL, + ... +} +ULConfigurationExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +ULUEConfiguration ::= ENUMERATED {no-data, shared, only, ...} + + +ULUPTNLInformation-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofULUPTNLInformation)) OF ULUPTNLInformation-ToBeSetup-Item + +ULUPTNLInformation-ToBeSetup-Item ::=SEQUENCE { + uLUPTNLInformation UPTransportLayerInformation, + iE-Extensions ProtocolExtensionContainer { { ULUPTNLInformation-ToBeSetup-ItemExtIEs } } OPTIONAL, + ... +} + +ULUPTNLInformation-ToBeSetup-ItemExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... +} + +UPTransportLayerInformation ::= CHOICE { + gTPTunnel GTPTunnel, + choice-extension ProtocolExtensionContainer { { UPTransportLayerInformation-ExtIEs} }, + ... +} + +UPTransportLayerInformation-ExtIEs F1AP-PROTOCOL-EXTENSION ::= { + ... + } +-- V + +-- W + +-- X + +-- Y + +-- Z + +END diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Contents.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Contents.asn new file mode 100644 index 0000000000000000000000000000000000000000..ec6e3733b1417c1bd6cfedbcc30eb71f7683a92b --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Contents.asn @@ -0,0 +1,1578 @@ +-- ************************************************************** +-- +-- PDU definitions for F1AP. +-- +-- ************************************************************** + +F1AP-PDU-Contents { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Contents (1) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + Active-Cells-Item, + Candidate-SpCell-Item, + Cause, + Cells-Failed-to-be-Activated-List-Item, + Cells-to-be-Activated-List-Item, + Cells-to-be-Deactivated-List-Item, + CellULConfigured, + CriticalityDiagnostics, + C-RNTI, + CUtoDURRCInformation, + DRB-Activity-Item, + DRBID, + DRBs-FailedToBeModified-Item, + DRBs-FailedToBeSetup-Item, + DRBs-FailedToBeSetupMod-Item, + DRB-Notify-Item, + DRBs-ModifiedConf-Item, + DRBs-Modified-Item, + DRBs-Required-ToBeModified-Item, + DRBs-Required-ToBeReleased-Item, + DRBs-Setup-Item, + DRBs-SetupMod-Item, + DRBs-ToBeModified-Item, + DRBs-ToBeReleased-Item, + DRBs-ToBeSetup-Item, + DRBs-ToBeSetupMod-Item, + DRXCycle, + DUtoCURRCInformation, + EUTRANQoS, + ExecuteDuplication, + FullConfiguration, + GNB-CU-UE-F1AP-ID, + GNB-DU-UE-F1AP-ID, + GNB-DU-ID, + GNB-DU-Served-Cells-Item, + GNB-DU-System-Information, + GNB-CU-Name, + GNB-DU-Name, + InactivityMonitoringRequest, + InactivityMonitoringResponse, + NotificationControl, + NRCGI, + NRPCI, + Potential-SpCell-Item, + RAT-FrequencyPriorityInformation, + ResourceCoordinationTransferContainer, + RRCContainer, + RRCRconfigurationCompleteIndicator, + SCellIndex, + SCell-ToBeRemoved-Item, + SCell-ToBeSetup-Item, + SCell-ToBeSetupMod-Item, + SCell-FailedtoSetup-Item, + SCell-FailedtoSetupMod-Item, + ServCellIndex, + Served-Cell-Information, + Served-Cells-To-Add-Item, + Served-Cells-To-Delete-Item, + Served-Cells-To-Modify-Item, + SRBID, + SRBs-FailedToBeSetup-Item, + SRBs-FailedToBeSetupMod-Item, + SRBs-Required-ToBeReleased-Item, + SRBs-ToBeReleased-Item, + SRBs-ToBeSetup-Item, + SRBs-ToBeSetupMod-Item, + TimeToWait, + TransactionID, + TransmissionStopIndicator, + UE-associatedLogicalF1-ConnectionItem, + DUtoCURRCContainer, + PagingCell-Item, + SIBtype-List, + UEIdentityIndexValue, + GNB-CU-TNL-Association-Setup-Item, + GNB-CU-TNL-Association-Failed-To-Setup-Item, + GNB-CU-TNL-Association-To-Add-Item, + GNB-CU-TNL-Association-To-Remove-Item, + GNB-CU-TNL-Association-To-Update-Item, + MaskedIMEISV, + PagingDRX, + PagingPriority, + PagingIdentity, + Cells-to-be-Barred-Item, + PWSSystemInformation, + Broadcast-To-Be-Cancelled-Item, + Cells-Broadcast-Cancelled-Item, + ConcurrentWarningMessageIndicator, + NR-CGI-List-For-Restart-Item, + PWS-Failed-NR-CGI-Item, + RepetitionPeriod, + NumberofBroadcastRequest, + Cells-To-Be-Broadcast-Item, + Cells-Broadcast-Completed-Item, + Cancel-all-Warning-Messages-Indicator, + EUTRA-NR-CellResourceCoordinationReq-Container, + EUTRA-NR-CellResourceCoordinationReqAck-Container, + ListofEUTRACellsinGNBDUCoordination, + SpectrumSharingGroupID, + RequestType + +FROM F1AP-IEs + + PrivateIE-Container{}, + ProtocolExtensionContainer{}, + ProtocolIE-Container{}, + ProtocolIE-ContainerPair{}, + ProtocolIE-SingleContainer{}, + F1AP-PRIVATE-IES, + F1AP-PROTOCOL-EXTENSION, + F1AP-PROTOCOL-IES, + F1AP-PROTOCOL-IES-PAIR + +FROM F1AP-Containers + + id-Active-Cells-Item, + id-Active-Cells-List, + id-Candidate-SpCell-Item, + id-Candidate-SpCell-List, + id-Cause, + id-Cancel-all-Warning-Messages-Indicator, + id-Cells-Failed-to-be-Activated-List, + id-Cells-Failed-to-be-Activated-List-Item, + id-Cells-to-be-Activated-List, + id-Cells-to-be-Activated-List-Item, + id-Cells-to-be-Deactivated-List, + id-Cells-to-be-Deactivated-List-Item, + id-ConfirmedUEID, + id-CriticalityDiagnostics, + id-C-RNTI, + id-CUtoDURRCInformation, + id-DRB-Activity-Item, + id-DRB-Activity-List, + id-DRBs-FailedToBeModified-Item, + id-DRBs-FailedToBeModified-List, + id-DRBs-FailedToBeSetup-Item, + id-DRBs-FailedToBeSetup-List, + id-DRBs-FailedToBeSetupMod-Item, + id-DRBs-FailedToBeSetupMod-List, + id-DRBs-ModifiedConf-Item, + id-DRBs-ModifiedConf-List, + id-DRBs-Modified-Item, + id-DRBs-Modified-List, + id-DRB-Notify-Item, + id-DRB-Notify-List, + id-DRBs-Required-ToBeModified-Item, + id-DRBs-Required-ToBeModified-List, + id-DRBs-Required-ToBeReleased-Item, + id-DRBs-Required-ToBeReleased-List, + id-DRBs-Setup-Item, + id-DRBs-Setup-List, + id-DRBs-SetupMod-Item, + id-DRBs-SetupMod-List, + id-DRBs-ToBeModified-Item, + id-DRBs-ToBeModified-List, + id-DRBs-ToBeReleased-Item, + id-DRBs-ToBeReleased-List, + id-DRBs-ToBeSetup-Item, + id-DRBs-ToBeSetup-List, + id-DRBs-ToBeSetupMod-Item, + id-DRBs-ToBeSetupMod-List, + id-DRXCycle, + id-DUtoCURRCInformation, + id-ExecuteDuplication, + id-FullConfiguration, + id-gNB-CU-UE-F1AP-ID, + id-gNB-DU-UE-F1AP-ID, + id-gNB-DU-ID, + id-GNB-DU-Served-Cells-Item, + id-gNB-DU-Served-Cells-List, + id-gNB-CU-Name, + id-gNB-DU-Name, + id-InactivityMonitoringRequest, + id-InactivityMonitoringResponse, + id-oldgNB-DU-UE-F1AP-ID, + id-Potential-SpCell-Item, + id-Potential-SpCell-List, + id-RAT-FrequencyPriorityInformation, + id-ResetType, + id-ResourceCoordinationTransferContainer, + id-RRCContainer, + id-RRCRconfigurationCompleteIndicator, + id-SCell-FailedtoSetup-List, + id-SCell-FailedtoSetup-Item, + id-SCell-FailedtoSetupMod-List, + id-SCell-FailedtoSetupMod-Item, + id-SCell-ToBeRemoved-Item, + id-SCell-ToBeRemoved-List, + id-SCell-ToBeSetup-Item, + id-SCell-ToBeSetup-List, + id-SCell-ToBeSetupMod-Item, + id-SCell-ToBeSetupMod-List, + id-Served-Cells-To-Add-Item, + id-Served-Cells-To-Add-List, + id-Served-Cells-To-Delete-Item, + id-Served-Cells-To-Delete-List, + id-Served-Cells-To-Modify-Item, + id-Served-Cells-To-Modify-List, + id-ServCellndex, + id-SpCell-ID, + id-SpCellULConfigured, + id-SRBID, + id-SRBs-FailedToBeSetup-Item, + id-SRBs-FailedToBeSetup-List, + id-SRBs-FailedToBeSetupMod-Item, + id-SRBs-FailedToBeSetupMod-List, + id-SRBs-Required-ToBeReleased-Item, + id-SRBs-Required-ToBeReleased-List, + id-SRBs-ToBeReleased-Item, + id-SRBs-ToBeReleased-List, + id-SRBs-ToBeSetup-Item, + id-SRBs-ToBeSetup-List, + id-SRBs-ToBeSetupMod-Item, + id-SRBs-ToBeSetupMod-List, + id-TimeToWait, + id-TransactionID, + id-TransmissionStopIndicator, + id-UE-associatedLogicalF1-ConnectionItem, + id-UE-associatedLogicalF1-ConnectionListResAck, + id-DUtoCURRCContainer, + id-NRCGI, + id-PagingCell-Item, + id-PagingCell-List, + id-PagingDRX, + id-PagingPriority, + id-SIBtype-List, + id-UEIdentityIndexValue, + id-GNB-CU-TNL-Association-Setup-List, + id-GNB-CU-TNL-Association-Setup-Item, + id-GNB-CU-TNL-Association-Failed-To-Setup-List, + id-GNB-CU-TNL-Association-Failed-To-Setup-Item, + id-GNB-CU-TNL-Association-To-Add-Item, + id-GNB-CU-TNL-Association-To-Add-List, + id-GNB-CU-TNL-Association-To-Remove-Item, + id-GNB-CU-TNL-Association-To-Remove-List, + id-GNB-CU-TNL-Association-To-Update-Item, + id-GNB-CU-TNL-Association-To-Update-List, + id-MaskedIMEISV, + id-PagingIdentity, + id-Cells-to-be-Barred-List, + id-Cells-to-be-Barred-Item, + id-PWSSystemInformation, + id-RepetitionPeriod, + id-NumberofBroadcastRequest, + id-ConcurrentWarningMessageIndicator, + id-Cells-To-Be-Broadcast-List, + id-Cells-To-Be-Broadcast-Item, + id-Cells-Broadcast-Completed-List, + id-Cells-Broadcast-Completed-Item, + id-Broadcast-To-Be-Cancelled-List, + id-Broadcast-To-Be-Cancelled-Item, + id-Cells-Broadcast-Cancelled-List, + id-Cells-Broadcast-Cancelled-Item, + id-NR-CGI-List-For-Restart-List, + id-NR-CGI-List-For-Restart-Item, + id-PWS-Failed-NR-CGI-List, + id-PWS-Failed-NR-CGI-Item, + id-EUTRA-NR-CellResourceCoordinationReq-Container, + id-EUTRA-NR-CellResourceCoordinationReqAck-Container, + id-SpectrumSharingGroupID, + id-ListofEUTRACellsinGNBDUCoordination, + id-Protected-EUTRA-Resources-List, + id-RequestType, + maxCellingNBDU, + maxnoofCandidateSpCells, + maxnoofDRBs, + maxnoofErrors, + maxnoofIndividualF1ConnectionsToReset, + maxnoofPotentialSpCells, + maxnoofSCells, + maxnoofSRBs, + maxnoofPagingCells, + maxnoofTNLAssociations, + maxCellineNB + +FROM F1AP-Constants; + + +-- ************************************************************** +-- +-- RESET ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Reset +-- +-- ************************************************************** + +Reset ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ResetIEs} }, + ... +} + +ResetIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-ResetType CRITICALITY reject TYPE ResetType PRESENCE mandatory }, + ... +} + +ResetType ::= CHOICE { + f1-Interface ResetAll, + partOfF1-Interface UE-associatedLogicalF1-ConnectionListRes, + ... +} + + +ResetAll ::= ENUMERATED { + reset-all, + ... +} + +UE-associatedLogicalF1-ConnectionListRes ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemRes } } + +UE-associatedLogicalF1-ConnectionItemRes F1AP-PROTOCOL-IES ::= { + { ID id-UE-associatedLogicalF1-ConnectionItem CRITICALITY reject TYPE UE-associatedLogicalF1-ConnectionItem PRESENCE mandatory}, + ... +} + + +-- ************************************************************** +-- +-- Reset Acknowledge +-- +-- ************************************************************** + +ResetAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ResetAcknowledgeIEs} }, + ... +} + +ResetAcknowledgeIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-UE-associatedLogicalF1-ConnectionListResAck CRITICALITY ignore TYPE UE-associatedLogicalF1-ConnectionListResAck PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +UE-associatedLogicalF1-ConnectionListResAck ::= SEQUENCE (SIZE(1.. maxnoofIndividualF1ConnectionsToReset)) OF ProtocolIE-SingleContainer { { UE-associatedLogicalF1-ConnectionItemResAck } } + +UE-associatedLogicalF1-ConnectionItemResAck F1AP-PROTOCOL-IES ::= { + { ID id-UE-associatedLogicalF1-ConnectionItem CRITICALITY ignore TYPE UE-associatedLogicalF1-ConnectionItem PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- ERROR INDICATION ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Error Indication +-- +-- ************************************************************** + +ErrorIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ErrorIndicationIEs}}, + ... +} + +ErrorIndicationIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory}| + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY ignore TYPE GNB-CU-UE-F1AP-ID PRESENCE optional }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY ignore TYPE GNB-DU-UE-F1AP-ID PRESENCE optional }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- F1 SETUP ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- F1 Setup Request +-- +-- ************************************************************** + +F1SetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {F1SetupRequestIEs} }, + ... +} + +F1SetupRequestIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-DU-ID CRITICALITY reject TYPE GNB-DU-ID PRESENCE mandatory }| + { ID id-gNB-DU-Name CRITICALITY ignore TYPE GNB-DU-Name PRESENCE optional }| + { ID id-gNB-DU-Served-Cells-List CRITICALITY reject TYPE GNB-DU-Served-Cells-List PRESENCE mandatory }, + ... +} + + +GNB-DU-Served-Cells-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { GNB-DU-Served-Cells-ItemIEs } } + +GNB-DU-Served-Cells-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-GNB-DU-Served-Cells-Item CRITICALITY reject TYPE GNB-DU-Served-Cells-Item PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- F1 Setup Response +-- +-- ************************************************************** + +F1SetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {F1SetupResponseIEs} }, + ... +} + + +F1SetupResponseIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-gNB-CU-Name CRITICALITY ignore TYPE GNB-CU-Name PRESENCE optional }| + { ID id-Cells-to-be-Activated-List CRITICALITY reject TYPE Cells-to-be-Activated-List PRESENCE optional }, + ... +} + + +Cells-to-be-Activated-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-to-be-Activated-List-ItemIEs } } + +Cells-to-be-Activated-List-ItemIEs F1AP-PROTOCOL-IES::= { + { ID id-Cells-to-be-Activated-List-Item CRITICALITY reject TYPE Cells-to-be-Activated-List-Item PRESENCE mandatory}, + ... +} + + + +-- ************************************************************** +-- +-- F1 Setup Failure +-- +-- ************************************************************** + +F1SetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {F1SetupFailureIEs} }, + ... +} + +F1SetupFailureIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- GNB-DU CONFIGURATION UPDATE ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- GNB-DU CONFIGURATION UPDATE +-- +-- ************************************************************** + +GNBDUConfigurationUpdate::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNBDUConfigurationUpdateIEs} }, + ... +} + +GNBDUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Served-Cells-To-Add-List CRITICALITY reject TYPE Served-Cells-To-Add-List PRESENCE optional }| + { ID id-Served-Cells-To-Modify-List CRITICALITY reject TYPE Served-Cells-To-Modify-List PRESENCE optional }| + { ID id-Served-Cells-To-Delete-List CRITICALITY reject TYPE Served-Cells-To-Delete-List PRESENCE optional }| + { ID id-Active-Cells-List CRITICALITY reject TYPE Active-Cells-List PRESENCE optional }, + ... +} +Served-Cells-To-Add-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Served-Cells-To-Add-ItemIEs } } +Served-Cells-To-Modify-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Served-Cells-To-Modify-ItemIEs } } +Served-Cells-To-Delete-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Served-Cells-To-Delete-ItemIEs } } +Active-Cells-List ::= SEQUENCE (SIZE(0.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Active-Cells-ItemIEs } } + +Served-Cells-To-Add-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Served-Cells-To-Add-Item CRITICALITY reject TYPE Served-Cells-To-Add-Item PRESENCE mandatory }, + ... +} + +Served-Cells-To-Modify-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Served-Cells-To-Modify-Item CRITICALITY reject TYPE Served-Cells-To-Modify-Item PRESENCE mandatory }, + ... +} + +Served-Cells-To-Delete-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Served-Cells-To-Delete-Item CRITICALITY reject TYPE Served-Cells-To-Delete-Item PRESENCE mandatory }, +... +} + +Active-Cells-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Active-Cells-Item CRITICALITY reject TYPE Active-Cells-Item PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- GNB-DU CONFIGURATION UPDATE ACKNOWLEDGE +-- +-- ************************************************************** + +GNBDUConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNBDUConfigurationUpdateAcknowledgeIEs} }, + ... +} + + +GNBDUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cells-to-be-Activated-List CRITICALITY reject TYPE Cells-to-be-Activated-List PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-DU CONFIGURATION UPDATE FAILURE +-- +-- ************************************************************** + +GNBDUConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {GNBDUConfigurationUpdateFailureIEs} }, + ... +} + +GNBDUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- GNB-CU CONFIGURATION UPDATE ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- GNB-CU CONFIGURATION UPDATE +-- +-- ************************************************************** + +GNBCUConfigurationUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { GNBCUConfigurationUpdateIEs} }, + ... +} + +GNBCUConfigurationUpdateIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cells-to-be-Activated-List CRITICALITY reject TYPE Cells-to-be-Activated-List PRESENCE optional }| + { ID id-Cells-to-be-Deactivated-List CRITICALITY reject TYPE Cells-to-be-Deactivated-List PRESENCE optional }| + { ID id-GNB-CU-TNL-Association-To-Add-List CRITICALITY ignore TYPE GNB-CU-TNL-Association-To-Add-List PRESENCE optional }| + { ID id-GNB-CU-TNL-Association-To-Remove-List CRITICALITY ignore TYPE GNB-CU-TNL-Association-To-Remove-List PRESENCE optional }| + { ID id-GNB-CU-TNL-Association-To-Update-List CRITICALITY ignore TYPE GNB-CU-TNL-Association-To-Update-List PRESENCE optional }| + { ID id-Cells-to-be-Barred-List CRITICALITY ignore TYPE Cells-to-be-Barred-List PRESENCE optional }| + { ID id-Protected-EUTRA-Resources-List CRITICALITY reject TYPE Protected-EUTRA-Resources-List PRESENCE optional }, + ... +} + +Cells-to-be-Deactivated-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-to-be-Deactivated-List-ItemIEs } } +GNB-CU-TNL-Association-To-Add-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Add-ItemIEs } } +GNB-CU-TNL-Association-To-Remove-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Remove-ItemIEs } } +GNB-CU-TNL-Association-To-Update-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-To-Update-ItemIEs } } +Cells-to-be-Barred-List ::= SEQUENCE(SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-to-be-Barred-ItemIEs } } + + +Cells-to-be-Deactivated-List-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Cells-to-be-Deactivated-List-Item CRITICALITY reject TYPE Cells-to-be-Deactivated-List-Item PRESENCE mandatory }, +...} + + +GNB-CU-TNL-Association-To-Add-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-GNB-CU-TNL-Association-To-Add-Item CRITICALITY reject TYPE GNB-CU-TNL-Association-To-Add-Item PRESENCE mandatory }, +...} + +GNB-CU-TNL-Association-To-Remove-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-GNB-CU-TNL-Association-To-Remove-Item CRITICALITY reject TYPE GNB-CU-TNL-Association-To-Remove-Item PRESENCE mandatory }, +...} + +GNB-CU-TNL-Association-To-Update-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-GNB-CU-TNL-Association-To-Update-Item CRITICALITY reject TYPE GNB-CU-TNL-Association-To-Update-Item PRESENCE mandatory }, +...} + +Cells-to-be-Barred-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Cells-to-be-Barred-Item CRITICALITY ignore TYPE Cells-to-be-Barred-Item PRESENCE mandatory }, + ... +} + +Protected-EUTRA-Resources-List ::= SEQUENCE (SIZE(1.. maxCellineNB)) OF ProtocolIE-SingleContainer { { Protected-EUTRA-Resources-ItemIEs } } +Protected-EUTRA-Resources-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SpectrumSharingGroupID CRITICALITY reject TYPE SpectrumSharingGroupID PRESENCE mandatory}| + { ID id-ListofEUTRACellsinGNBDUCoordination CRITICALITY reject TYPE ListofEUTRACellsinGNBDUCoordination PRESENCE mandatory }, +...} + +-- ************************************************************** +-- +-- GNB-CU CONFIGURATION UPDATE ACKNOWLEDGE +-- +-- ************************************************************** + +GNBCUConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { GNBCUConfigurationUpdateAcknowledgeIEs} }, + ... +} + + +GNBCUConfigurationUpdateAcknowledgeIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cells-Failed-to-be-Activated-List CRITICALITY reject TYPE Cells-Failed-to-be-Activated-List PRESENCE optional}| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }| + { ID id-GNB-CU-TNL-Association-Setup-List CRITICALITY ignore TYPE GNB-CU-TNL-Association-Setup-List PRESENCE optional }| + { ID id-GNB-CU-TNL-Association-Failed-To-Setup-List CRITICALITY ignore TYPE GNB-CU-TNL-Association-Failed-To-Setup-List PRESENCE optional }, + ... +} + +Cells-Failed-to-be-Activated-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-Failed-to-be-Activated-List-ItemIEs } } +GNB-CU-TNL-Association-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-Setup-ItemIEs } } +GNB-CU-TNL-Association-Failed-To-Setup-List ::= SEQUENCE (SIZE(1.. maxnoofTNLAssociations)) OF ProtocolIE-SingleContainer { { GNB-CU-TNL-Association-Failed-To-Setup-ItemIEs } } + +Cells-Failed-to-be-Activated-List-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Cells-Failed-to-be-Activated-List-Item CRITICALITY reject TYPE Cells-Failed-to-be-Activated-List-Item PRESENCE mandatory }, + ... +} + +GNB-CU-TNL-Association-Setup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-GNB-CU-TNL-Association-Setup-Item CRITICALITY reject TYPE GNB-CU-TNL-Association-Setup-Item PRESENCE mandatory }, +...} + + +GNB-CU-TNL-Association-Failed-To-Setup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-GNB-CU-TNL-Association-Failed-To-Setup-Item CRITICALITY reject TYPE GNB-CU-TNL-Association-Failed-To-Setup-Item PRESENCE mandatory }, +...} + + +-- ************************************************************** +-- +-- GNB-CU CONFIGURATION UPDATE FAILURE +-- +-- ************************************************************** + +GNBCUConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { GNBCUConfigurationUpdateFailureIEs} }, + ... +} + +GNBCUConfigurationUpdateFailureIEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- GNB-DU RESOURCE COORDINATION REQUEST +-- +-- ************************************************************** + +GNBDUResourceCoordinationRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{GNBDUResourceCoordinationRequest-IEs}}, + ... +} + +GNBDUResourceCoordinationRequest-IEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-RequestType CRITICALITY reject TYPE RequestType PRESENCE mandatory }| + { ID id-EUTRA-NR-CellResourceCoordinationReq-Container CRITICALITY reject TYPE EUTRA-NR-CellResourceCoordinationReq-Container PRESENCE mandatory}, + ... +} + + +-- ************************************************************** +-- +-- GNB-DU RESOURCE COORDINATION RESPONSE +-- +-- ************************************************************** + +GNBDUResourceCoordinationResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{GNBDUResourceCoordinationResponse-IEs}}, + ... +} + +GNBDUResourceCoordinationResponse-IEs F1AP-PROTOCOL-IES ::= { + { ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| + { ID id-EUTRA-NR-CellResourceCoordinationReqAck-Container CRITICALITY reject TYPE EUTRA-NR-CellResourceCoordinationReqAck-Container PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- UE Context Setup ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT SETUP REQUEST +-- +-- ************************************************************** + +UEContextSetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextSetupRequestIEs} }, + ... +} + +UEContextSetupRequestIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY ignore TYPE GNB-DU-UE-F1AP-ID PRESENCE optional }| + { ID id-SpCell-ID CRITICALITY reject TYPE NRCGI PRESENCE mandatory }| + { ID id-ServCellndex CRITICALITY reject TYPE ServCellIndex PRESENCE mandatory }| + { ID id-SpCellULConfigured CRITICALITY ignore TYPE CellULConfigured PRESENCE optional }| + { ID id-CUtoDURRCInformation CRITICALITY reject TYPE CUtoDURRCInformation PRESENCE mandatory}| + { ID id-Candidate-SpCell-List CRITICALITY ignore TYPE Candidate-SpCell-List PRESENCE optional }| + { ID id-DRXCycle CRITICALITY ignore TYPE DRXCycle PRESENCE optional }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-SCell-ToBeSetup-List CRITICALITY ignore TYPE SCell-ToBeSetup-List PRESENCE optional }| + { ID id-SRBs-ToBeSetup-List CRITICALITY reject TYPE SRBs-ToBeSetup-List PRESENCE optional }| + { ID id-DRBs-ToBeSetup-List CRITICALITY reject TYPE DRBs-ToBeSetup-List PRESENCE optional }| + { ID id-InactivityMonitoringRequest CRITICALITY reject TYPE InactivityMonitoringRequest PRESENCE optional }| + { ID id-RAT-FrequencyPriorityInformation CRITICALITY reject TYPE RAT-FrequencyPriorityInformation PRESENCE optional }| + { ID id-RRCContainer CRITICALITY ignore TYPE RRCContainer PRESENCE optional }| + { ID id-MaskedIMEISV CRITICALITY ignore TYPE MaskedIMEISV PRESENCE optional }, + ... +} + +Candidate-SpCell-List::= SEQUENCE (SIZE(1..maxnoofCandidateSpCells)) OF ProtocolIE-SingleContainer { { Candidate-SpCell-ItemIEs} } +SCell-ToBeSetup-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetup-ItemIEs} } +SRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetup-ItemIEs} } +DRBs-ToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetup-ItemIEs} } + + +Candidate-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Candidate-SpCell-Item CRITICALITY ignore TYPE Candidate-SpCell-Item PRESENCE mandatory }, + ... +} + + +SCell-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SCell-ToBeSetup-Item CRITICALITY ignore TYPE SCell-ToBeSetup-Item PRESENCE mandatory }, + ... +} + +SRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-ToBeSetup-Item CRITICALITY reject TYPE SRBs-ToBeSetup-Item PRESENCE mandatory}, + ... +} + +DRBs-ToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-ToBeSetup-Item CRITICALITY reject TYPE DRBs-ToBeSetup-Item PRESENCE mandatory}, + ... +} + + + +-- ************************************************************** +-- +-- UE CONTEXT SETUP RESPONSE +-- +-- ************************************************************** + +UEContextSetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextSetupResponseIEs} }, + ... +} + + +UEContextSetupResponseIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-DUtoCURRCInformation CRITICALITY reject TYPE DUtoCURRCInformation PRESENCE mandatory }| + { ID id-C-RNTI CRITICALITY ignore TYPE C-RNTI PRESENCE optional }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-FullConfiguration CRITICALITY reject TYPE FullConfiguration PRESENCE optional }| + { ID id-DRBs-Setup-List CRITICALITY ignore TYPE DRBs-Setup-List PRESENCE optional }| + { ID id-SRBs-FailedToBeSetup-List CRITICALITY ignore TYPE SRBs-FailedToBeSetup-List PRESENCE optional }| + { ID id-DRBs-FailedToBeSetup-List CRITICALITY ignore TYPE DRBs-FailedToBeSetup-List PRESENCE optional }| + { ID id-SCell-FailedtoSetup-List CRITICALITY ignore TYPE SCell-FailedtoSetup-List PRESENCE optional }| + { ID id-InactivityMonitoringResponse CRITICALITY reject TYPE InactivityMonitoringResponse PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +DRBs-Setup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Setup-ItemIEs} } +SRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetup-ItemIEs} } +DRBs-FailedToBeSetup-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetup-ItemIEs} } +SCell-FailedtoSetup-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetup-ItemIEs} } + +DRBs-Setup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-Setup-Item CRITICALITY ignore TYPE DRBs-Setup-Item PRESENCE mandatory}, + ... +} + +SRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-FailedToBeSetup-Item CRITICALITY ignore TYPE SRBs-FailedToBeSetup-Item PRESENCE mandatory}, + ... +} + + +DRBs-FailedToBeSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-FailedToBeSetup-Item CRITICALITY ignore TYPE DRBs-FailedToBeSetup-Item PRESENCE mandatory}, + ... +} + +SCell-FailedtoSetup-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SCell-FailedtoSetup-Item CRITICALITY ignore TYPE SCell-FailedtoSetup-Item PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT SETUP FAILURE +-- +-- ************************************************************** + +UEContextSetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextSetupFailureIEs} }, + ... +} + +UEContextSetupFailureIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY ignore TYPE GNB-DU-UE-F1AP-ID PRESENCE optional }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }| + { ID id-Potential-SpCell-List CRITICALITY ignore TYPE Potential-SpCell-List PRESENCE optional }, + ... +} + +Potential-SpCell-List::= SEQUENCE (SIZE(0..maxnoofPotentialSpCells)) OF ProtocolIE-SingleContainer { { Potential-SpCell-ItemIEs} } + +Potential-SpCell-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Potential-SpCell-Item CRITICALITY ignore TYPE Potential-SpCell-Item PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UE Context Release Request ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE Context Release Request +-- +-- ************************************************************** + +UEContextReleaseRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ UEContextReleaseRequestIEs}}, + ... +} + +UEContextReleaseRequestIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- UE Context Release (gNB-CU initiated) ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT RELEASE COMMAND +-- +-- ************************************************************** + +UEContextReleaseCommand ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextReleaseCommandIEs} }, + ... +} + +UEContextReleaseCommandIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-RRCContainer CRITICALITY ignore TYPE RRCContainer PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT RELEASE COMPLETE +-- +-- ************************************************************** + +UEContextReleaseComplete ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextReleaseCompleteIEs} }, + ... +} + + +UEContextReleaseCompleteIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, ... +} + +-- ************************************************************** +-- +-- UE Context Modification ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION REQUEST +-- +-- ************************************************************** + +UEContextModificationRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextModificationRequestIEs} }, + ... +} + +UEContextModificationRequestIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-SpCell-ID CRITICALITY ignore TYPE NRCGI PRESENCE optional }| + { ID id-ServCellndex CRITICALITY reject TYPE ServCellIndex PRESENCE mandatory }| + { ID id-SpCellULConfigured CRITICALITY ignore TYPE CellULConfigured PRESENCE optional }| + { ID id-DRXCycle CRITICALITY ignore TYPE DRXCycle PRESENCE optional }| + { ID id-CUtoDURRCInformation CRITICALITY reject TYPE CUtoDURRCInformation PRESENCE optional }| + { ID id-TransmissionStopIndicator CRITICALITY ignore TYPE TransmissionStopIndicator PRESENCE optional }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-RRCRconfigurationCompleteIndicator CRITICALITY ignore TYPE RRCRconfigurationCompleteIndicator PRESENCE optional }| + { ID id-RRCContainer CRITICALITY reject TYPE RRCContainer PRESENCE optional }| + { ID id-SCell-ToBeSetupMod-List CRITICALITY ignore TYPE SCell-ToBeSetupMod-List PRESENCE optional }| + { ID id-SCell-ToBeRemoved-List CRITICALITY ignore TYPE SCell-ToBeRemoved-List PRESENCE optional }| + { ID id-SRBs-ToBeSetupMod-List CRITICALITY reject TYPE SRBs-ToBeSetupMod-List PRESENCE optional }| + { ID id-DRBs-ToBeSetupMod-List CRITICALITY reject TYPE DRBs-ToBeSetupMod-List PRESENCE optional }| + { ID id-DRBs-ToBeModified-List CRITICALITY reject TYPE DRBs-ToBeModified-List PRESENCE optional }| + { ID id-SRBs-ToBeReleased-List CRITICALITY reject TYPE SRBs-ToBeReleased-List PRESENCE optional }| + { ID id-DRBs-ToBeReleased-List CRITICALITY reject TYPE DRBs-ToBeReleased-List PRESENCE optional }| + { ID id-InactivityMonitoringRequest CRITICALITY reject TYPE InactivityMonitoringRequest PRESENCE optional }| + { ID id-RAT-FrequencyPriorityInformation CRITICALITY reject TYPE RAT-FrequencyPriorityInformation PRESENCE optional }, + ... +} + +SCell-ToBeSetupMod-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeSetupMod-ItemIEs} } +SCell-ToBeRemoved-List::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-ToBeRemoved-ItemIEs} } +SRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeSetupMod-ItemIEs} } +DRBs-ToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeSetupMod-ItemIEs} } + +DRBs-ToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeModified-ItemIEs} } +SRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-ToBeReleased-ItemIEs} } +DRBs-ToBeReleased-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ToBeReleased-ItemIEs} } + +SCell-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SCell-ToBeSetupMod-Item CRITICALITY ignore TYPE SCell-ToBeSetupMod-Item PRESENCE mandatory }, + ... +} + +SCell-ToBeRemoved-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SCell-ToBeRemoved-Item CRITICALITY ignore TYPE SCell-ToBeRemoved-Item PRESENCE mandatory }, + ... +} + + +SRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-ToBeSetupMod-Item CRITICALITY reject TYPE SRBs-ToBeSetupMod-Item PRESENCE mandatory}, + ... +} + + +DRBs-ToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-ToBeSetupMod-Item CRITICALITY reject TYPE DRBs-ToBeSetupMod-Item PRESENCE mandatory}, + ... +} + +DRBs-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-ToBeModified-Item CRITICALITY reject TYPE DRBs-ToBeModified-Item PRESENCE mandatory}, + ... +} + + +SRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-ToBeReleased-Item CRITICALITY reject TYPE SRBs-ToBeReleased-Item PRESENCE mandatory}, + ... +} + +DRBs-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-ToBeReleased-Item CRITICALITY reject TYPE DRBs-ToBeReleased-Item PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION RESPONSE +-- +-- ************************************************************** + +UEContextModificationResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextModificationResponseIEs} }, + ... +} + + +UEContextModificationResponseIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-DUtoCURRCInformation CRITICALITY reject TYPE DUtoCURRCInformation PRESENCE optional}| + { ID id-DRBs-SetupMod-List CRITICALITY ignore TYPE DRBs-SetupMod-List PRESENCE optional}| + { ID id-DRBs-Modified-List CRITICALITY ignore TYPE DRBs-Modified-List PRESENCE optional}| + { ID id-SRBs-FailedToBeSetupMod-List CRITICALITY ignore TYPE SRBs-FailedToBeSetupMod-List PRESENCE optional }| + { ID id-DRBs-FailedToBeSetupMod-List CRITICALITY ignore TYPE DRBs-FailedToBeSetupMod-List PRESENCE optional }| + { ID id-SCell-FailedtoSetupMod-List CRITICALITY ignore TYPE SCell-FailedtoSetupMod-List PRESENCE optional }| + { ID id-DRBs-FailedToBeModified-List CRITICALITY ignore TYPE DRBs-FailedToBeModified-List PRESENCE optional }| + { ID id-InactivityMonitoringResponse CRITICALITY reject TYPE InactivityMonitoringResponse PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +DRBs-SetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-SetupMod-ItemIEs} } +DRBs-Modified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Modified-ItemIEs } } +DRBs-FailedToBeModified-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeModified-ItemIEs} } +SRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-FailedToBeSetupMod-ItemIEs} } +DRBs-FailedToBeSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-FailedToBeSetupMod-ItemIEs} } +SCell-FailedtoSetupMod-List ::= SEQUENCE (SIZE(1..maxnoofSCells)) OF ProtocolIE-SingleContainer { { SCell-FailedtoSetupMod-ItemIEs} } + +DRBs-SetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-SetupMod-Item CRITICALITY ignore TYPE DRBs-SetupMod-Item PRESENCE mandatory}, + ... +} + + +DRBs-Modified-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-Modified-Item CRITICALITY ignore TYPE DRBs-Modified-Item PRESENCE mandatory}, + ... +} + +SRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-FailedToBeSetupMod-Item CRITICALITY ignore TYPE SRBs-FailedToBeSetupMod-Item PRESENCE mandatory}, + ... +} + + + +DRBs-FailedToBeSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-FailedToBeSetupMod-Item CRITICALITY ignore TYPE DRBs-FailedToBeSetupMod-Item PRESENCE mandatory}, + ... +} + + +DRBs-FailedToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-FailedToBeModified-Item CRITICALITY ignore TYPE DRBs-FailedToBeModified-Item PRESENCE mandatory}, + ... +} + +SCell-FailedtoSetupMod-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SCell-FailedtoSetupMod-Item CRITICALITY ignore TYPE SCell-FailedtoSetupMod-Item PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION FAILURE +-- +-- ************************************************************** + +UEContextModificationFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextModificationFailureIEs} }, + ... +} + +UEContextModificationFailureIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- UE Context Modification Required (gNB-DU initiated) ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION REQUIRED +-- +-- ************************************************************** + +UEContextModificationRequired ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextModificationRequiredIEs} }, + ... +} + +UEContextModificationRequiredIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-DUtoCURRCInformation CRITICALITY reject TYPE DUtoCURRCInformation PRESENCE optional}| + { ID id-DRBs-Required-ToBeModified-List CRITICALITY reject TYPE DRBs-Required-ToBeModified-List PRESENCE optional}| + { ID id-SRBs-Required-ToBeReleased-List CRITICALITY reject TYPE SRBs-Required-ToBeReleased-List PRESENCE optional}| + { ID id-DRBs-Required-ToBeReleased-List CRITICALITY reject TYPE DRBs-Required-ToBeReleased-List PRESENCE optional}| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +DRBs-Required-ToBeModified-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeModified-ItemIEs } } +DRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-Required-ToBeReleased-ItemIEs } } + +SRBs-Required-ToBeReleased-List::= SEQUENCE (SIZE(1..maxnoofSRBs)) OF ProtocolIE-SingleContainer { { SRBs-Required-ToBeReleased-ItemIEs } } + +DRBs-Required-ToBeModified-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-Required-ToBeModified-Item CRITICALITY reject TYPE DRBs-Required-ToBeModified-Item PRESENCE mandatory}, + ... +} + +DRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-Required-ToBeReleased-Item CRITICALITY reject TYPE DRBs-Required-ToBeReleased-Item PRESENCE mandatory}, + ... +} + +SRBs-Required-ToBeReleased-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-SRBs-Required-ToBeReleased-Item CRITICALITY reject TYPE SRBs-Required-ToBeReleased-Item PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION CONFIRM +-- +-- ************************************************************** + +UEContextModificationConfirm::= SEQUENCE { + protocolIEs ProtocolIE-Container { { UEContextModificationConfirmIEs} }, + ... +} + + +UEContextModificationConfirmIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-ResourceCoordinationTransferContainer CRITICALITY ignore TYPE ResourceCoordinationTransferContainer PRESENCE optional }| + { ID id-DRBs-ModifiedConf-List CRITICALITY ignore TYPE DRBs-ModifiedConf-List PRESENCE optional}| + { ID id-RRCContainer CRITICALITY ignore TYPE RRCContainer PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +DRBs-ModifiedConf-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRBs-ModifiedConf-ItemIEs } } + +DRBs-ModifiedConf-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRBs-ModifiedConf-Item CRITICALITY ignore TYPE DRBs-ModifiedConf-Item PRESENCE mandatory}, + ... +} + + + +-- ************************************************************** +-- +-- WRITE-REPLACE WARNING ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Write-Replace Warning Request +-- +-- ************************************************************** + +WriteReplaceWarningRequest ::= SEQUENCE { +protocolIEs ProtocolIE-Container { {WriteReplaceWarningRequestIEs} }, +... +} +WriteReplaceWarningRequestIEs F1AP-PROTOCOL-IES ::= { +{ ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| +{ ID id-PWSSystemInformation CRITICALITY reject TYPE PWSSystemInformation PRESENCE mandatory }| +{ ID id-RepetitionPeriod CRITICALITY reject TYPE RepetitionPeriod PRESENCE mandatory }| +{ ID id-NumberofBroadcastRequest CRITICALITY reject TYPE NumberofBroadcastRequest PRESENCE mandatory }| +{ ID id-ConcurrentWarningMessageIndicator CRITICALITY reject TYPE ConcurrentWarningMessageIndicator PRESENCE optional }| +{ ID id-Cells-To-Be-Broadcast-List CRITICALITY reject TYPE Cells-To-Be-Broadcast-List PRESENCE optional }, +... +} +Cells-To-Be-Broadcast-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-To-Be-Broadcast-List-ItemIEs } } + +Cells-To-Be-Broadcast-List-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Cells-To-Be-Broadcast-Item CRITICALITY reject TYPE Cells-To-Be-Broadcast-Item PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- Write-Replace Warning Response +-- +-- ************************************************************** + +WriteReplaceWarningResponse ::= SEQUENCE { +protocolIEs ProtocolIE-Container { {WriteReplaceWarningResponseIEs} }, +... +} +WriteReplaceWarningResponseIEs F1AP-PROTOCOL-IES ::= { +{ ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| +{ ID id-Cells-Broadcast-Completed-List CRITICALITY reject TYPE Cells-Broadcast-Completed-List PRESENCE optional }| +{ ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, +... +} +Cells-Broadcast-Completed-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-Broadcast-Completed-List-ItemIEs } } + +Cells-Broadcast-Completed-List-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Cells-Broadcast-Completed-Item CRITICALITY reject TYPE Cells-Broadcast-Completed-Item PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- PWS CANCEL ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PWS Cancel Request +-- +-- ************************************************************** + +PWSCancelRequest ::= SEQUENCE { +protocolIEs ProtocolIE-Container { {PWSCancelRequestIEs} }, +... +} +PWSCancelRequestIEs F1AP-PROTOCOL-IES ::= { +{ ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| +{ ID id-NumberofBroadcastRequest CRITICALITY reject TYPE NumberofBroadcastRequest PRESENCE mandatory }| +{ ID id-Broadcast-To-Be-Cancelled-List CRITICALITY reject TYPE Broadcast-To-Be-Cancelled-List PRESENCE optional }| +{ ID id-Cancel-all-Warning-Messages-Indicator CRITICALITY reject TYPE Cancel-all-Warning-Messages-Indicator PRESENCE optional } +, +... +} +Broadcast-To-Be-Cancelled-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Broadcast-To-Be-Cancelled-List-ItemIEs } } + +Broadcast-To-Be-Cancelled-List-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Broadcast-To-Be-Cancelled-Item CRITICALITY reject TYPE Broadcast-To-Be-Cancelled-Item PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- PWS Cancel Response +-- +-- ************************************************************** + +PWSCancelResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PWSCancelResponseIEs} }, +... +} + +PWSCancelResponseIEs F1AP-PROTOCOL-IES ::= { +{ ID id-TransactionID CRITICALITY reject TYPE TransactionID PRESENCE mandatory }| +{ ID id-Cells-Broadcast-Cancelled-List CRITICALITY reject TYPE Cells-Broadcast-Cancelled-List PRESENCE optional }| +{ ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, +... +} +Cells-Broadcast-Cancelled-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { Cells-Broadcast-Cancelled-List-ItemIEs } } + +Cells-Broadcast-Cancelled-List-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-Cells-Broadcast-Cancelled-Item CRITICALITY reject TYPE Cells-Broadcast-Cancelled-Item PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UE Inactivity Notification ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE Inactivity Notification +-- +-- ************************************************************** + +UEInactivityNotification ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ UEInactivityNotificationIEs}}, + ... +} + +UEInactivityNotificationIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-DRB-Activity-List CRITICALITY reject TYPE DRB-Activity-List PRESENCE mandatory } , + ... +} + +DRB-Activity-List::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF ProtocolIE-SingleContainer { { DRB-Activity-ItemIEs } } + +DRB-Activity-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRB-Activity-Item CRITICALITY reject TYPE DRB-Activity-Item PRESENCE mandatory}, + ... +} + +-- ************************************************************** +-- +-- Initial UL RRC Message Transfer ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- INITIAL UL RRC Message Transfer +-- +-- ************************************************************** + +InitialULRRCMessageTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ InitialULRRCMessageTransferIEs}}, + ... +} + +InitialULRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-NRCGI CRITICALITY reject TYPE NRCGI PRESENCE mandatory }| + { ID id-C-RNTI CRITICALITY reject TYPE C-RNTI PRESENCE mandatory }| + { ID id-RRCContainer CRITICALITY reject TYPE RRCContainer PRESENCE mandatory }| + { ID id-DUtoCURRCContainer CRITICALITY reject TYPE DUtoCURRCContainer PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- DL RRC Message Transfer ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- DL RRC Message Transfer +-- +-- ************************************************************** + +DLRRCMessageTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ DLRRCMessageTransferIEs}}, + ... +} + +DLRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-oldgNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE optional }| + { ID id-SRBID CRITICALITY reject TYPE SRBID PRESENCE mandatory }| + { ID id-ExecuteDuplication CRITICALITY ignore TYPE ExecuteDuplication PRESENCE optional}| + { ID id-RRCContainer CRITICALITY reject TYPE RRCContainer PRESENCE mandatory }| + { ID id-RAT-FrequencyPriorityInformation CRITICALITY reject TYPE RAT-FrequencyPriorityInformation PRESENCE optional }, + ... +} +-- ************************************************************** +-- +-- UL RRC Message Transfer ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UL RRC Message Transfer +-- +-- ************************************************************** + +ULRRCMessageTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ ULRRCMessageTransferIEs}}, + ... +} + +ULRRCMessageTransferIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-SRBID CRITICALITY reject TYPE SRBID PRESENCE mandatory }| + { ID id-RRCContainer CRITICALITY reject TYPE RRCContainer PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- PRIVATE MESSAGE +-- +-- ************************************************************** + +PrivateMessage ::= SEQUENCE { + privateIEs PrivateIE-Container {{PrivateMessage-IEs}}, + ... +} + +PrivateMessage-IEs F1AP-PRIVATE-IES ::= { + ... +} + + +-- ************************************************************** +-- +-- System Information ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- System information Delivery Command +-- +-- ************************************************************** + +SystemInformationDeliveryCommand ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ SystemInformationDeliveryCommandIEs}}, + ... +} + +SystemInformationDeliveryCommandIEs F1AP-PROTOCOL-IES ::= { + { ID id-NRCGI CRITICALITY reject TYPE NRCGI PRESENCE mandatory }| + { ID id-SIBtype-List CRITICALITY reject TYPE SIBtype-List PRESENCE mandatory }| + { ID id-ConfirmedUEID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }, + ... +} + + +-- ************************************************************** +-- +-- Paging PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Paging +-- +-- ************************************************************** + +Paging ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ PagingIEs}}, + ... +} + +PagingIEs F1AP-PROTOCOL-IES ::= { + { ID id-UEIdentityIndexValue CRITICALITY reject TYPE UEIdentityIndexValue PRESENCE mandatory }| + { ID id-PagingIdentity CRITICALITY reject TYPE PagingIdentity PRESENCE optional }| + { ID id-PagingDRX CRITICALITY ignore TYPE PagingDRX PRESENCE optional }| + { ID id-PagingPriority CRITICALITY ignore TYPE PagingPriority PRESENCE optional }| + { ID id-PagingCell-List CRITICALITY ignore TYPE PagingCell-list PRESENCE optional }, + ... +} + +PagingCell-list::= SEQUENCE (SIZE(1.. maxnoofPagingCells)) OF ProtocolIE-SingleContainer { { PagingCell-ItemIEs } } + +PagingCell-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-PagingCell-Item CRITICALITY ignore TYPE PagingCell-Item PRESENCE mandatory} , + ... +} + + + +-- ************************************************************** +-- +-- Notify +-- +-- ************************************************************** + +Notify ::= SEQUENCE { + protocolIEs ProtocolIE-Container {{ NotifyIEs}}, + ... +} + +NotifyIEs F1AP-PROTOCOL-IES ::= { + { ID id-gNB-CU-UE-F1AP-ID CRITICALITY reject TYPE GNB-CU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-gNB-DU-UE-F1AP-ID CRITICALITY reject TYPE GNB-DU-UE-F1AP-ID PRESENCE mandatory }| + { ID id-DRB-Notify-List CRITICALITY reject TYPE DRB-Notify-List PRESENCE mandatory }, + ... +} + +DRB-Notify-List::= SEQUENCE (SIZE(1)) OF ProtocolIE-SingleContainer { { DRB-Notify-ItemIEs } } + +DRB-Notify-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-DRB-Notify-Item CRITICALITY reject TYPE DRB-Notify-Item PRESENCE mandatory}, + ... +} + + + +-- ************************************************************** +-- +-- PWS RESTART INDICATION ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PWS Restart Indication +-- +-- ************************************************************** + +PWSRestartIndication ::= SEQUENCE { +protocolIEs ProtocolIE-Container { { PWSRestartIndicationIEs} }, +... +} +PWSRestartIndicationIEs F1AP-PROTOCOL-IES ::= { +{ ID id-NR-CGI-List-For-Restart-List CRITICALITY reject TYPE NR-CGI-List-For-Restart-List PRESENCE optional }, +... +} +NR-CGI-List-For-Restart-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { NR-CGI-List-For-Restart-List-ItemIEs } } + +NR-CGI-List-For-Restart-List-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-NR-CGI-List-For-Restart-Item CRITICALITY reject TYPE NR-CGI-List-For-Restart-Item PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- PWS FAILURE INDICATION ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PWS Failure Indication +-- +-- ************************************************************** + +PWSFailureIndication ::= SEQUENCE { +protocolIEs ProtocolIE-Container { { PWSFailureIndicationIEs} }, +... +} +PWSFailureIndicationIEs F1AP-PROTOCOL-IES ::= { +{ ID id-PWS-Failed-NR-CGI-List CRITICALITY reject TYPE PWS-Failed-NR-CGI-List PRESENCE optional }, +... +} +PWS-Failed-NR-CGI-List ::= SEQUENCE (SIZE(1.. maxCellingNBDU)) OF ProtocolIE-SingleContainer { { PWS-Failed-NR-CGI-List-ItemIEs } } + +PWS-Failed-NR-CGI-List-ItemIEs F1AP-PROTOCOL-IES ::= { + { ID id-PWS-Failed-NR-CGI-Item CRITICALITY reject TYPE PWS-Failed-NR-CGI-Item PRESENCE mandatory }, + ... +} + +END diff --git a/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Descriptions.asn b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Descriptions.asn new file mode 100644 index 0000000000000000000000000000000000000000..6ca80a706cd012a00027d7b30f2c5042f96d7c31 --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/R15.2.1/F1AP-PDU-Descriptions.asn @@ -0,0 +1,353 @@ +-- ************************************************************** +-- +-- Elementary Procedure definitions +-- +-- ************************************************************** + +F1AP-PDU-Descriptions { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-access (22) modules (3) f1ap (3) version1 (1) f1ap-PDU-Descriptions (0)} + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + Criticality, + ProcedureCode + +FROM F1AP-CommonDataTypes + Reset, + ResetAcknowledge, + F1SetupRequest, + F1SetupResponse, + F1SetupFailure, + GNBDUConfigurationUpdate, + GNBDUConfigurationUpdateAcknowledge, + GNBDUConfigurationUpdateFailure, + GNBCUConfigurationUpdate, + GNBCUConfigurationUpdateAcknowledge, + GNBCUConfigurationUpdateFailure, + UEContextSetupRequest, + UEContextSetupResponse, + UEContextSetupFailure, + UEContextReleaseCommand, + UEContextReleaseComplete, + UEContextModificationRequest, + UEContextModificationResponse, + UEContextModificationFailure, + UEContextModificationRequired, + UEContextModificationConfirm, + ErrorIndication, + UEContextReleaseRequest, + DLRRCMessageTransfer, + ULRRCMessageTransfer, + GNBDUResourceCoordinationRequest, + GNBDUResourceCoordinationResponse, + PrivateMessage, + UEInactivityNotification, + InitialULRRCMessageTransfer, + SystemInformationDeliveryCommand, + Paging, + Notify, + WriteReplaceWarningRequest, + WriteReplaceWarningResponse, + PWSCancelRequest, + PWSCancelResponse, + PWSRestartIndication, + PWSFailureIndication + +FROM F1AP-PDU-Contents + id-Reset, + id-F1Setup, + id-gNBDUConfigurationUpdate, + id-gNBCUConfigurationUpdate, + id-UEContextSetup, + id-UEContextRelease, + id-UEContextModification, + id-UEContextModificationRequired, + id-ErrorIndication, + id-UEContextReleaseRequest, + id-DLRRCMessageTransfer, + id-ULRRCMessageTransfer, + id-GNBDUResourceCoordination, + id-privateMessage, + id-UEInactivityNotification, + id-InitialULRRCMessageTransfer, + id-SystemInformationDeliveryCommand, + id-Paging, + id-Notify, + id-WriteReplaceWarning, + id-PWSCancel, + id-PWSRestartIndication, + id-PWSFailureIndication + + +FROM F1AP-Constants; + + +-- ************************************************************** +-- +-- Interface Elementary Procedure Class +-- +-- ************************************************************** + +F1AP-ELEMENTARY-PROCEDURE ::= CLASS { + &InitiatingMessage , + &SuccessfulOutcome OPTIONAL, + &UnsuccessfulOutcome OPTIONAL, + &procedureCode ProcedureCode UNIQUE, + &criticality Criticality DEFAULT ignore +} +WITH SYNTAX { + INITIATING MESSAGE &InitiatingMessage + [SUCCESSFUL OUTCOME &SuccessfulOutcome] + [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] + PROCEDURE CODE &procedureCode + [CRITICALITY &criticality] +} + +-- ************************************************************** +-- +-- Interface PDU Definition +-- +-- ************************************************************** + +F1AP-PDU ::= CHOICE { + initiatingMessage InitiatingMessage, + successfulOutcome SuccessfulOutcome, + unsuccessfulOutcome UnsuccessfulOutcome, + ... +} + +InitiatingMessage ::= SEQUENCE { + procedureCode F1AP-ELEMENTARY-PROCEDURE.&procedureCode ({F1AP-ELEMENTARY-PROCEDURES}), + criticality F1AP-ELEMENTARY-PROCEDURE.&criticality ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value F1AP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +SuccessfulOutcome ::= SEQUENCE { + procedureCode F1AP-ELEMENTARY-PROCEDURE.&procedureCode ({F1AP-ELEMENTARY-PROCEDURES}), + criticality F1AP-ELEMENTARY-PROCEDURE.&criticality ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value F1AP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +UnsuccessfulOutcome ::= SEQUENCE { + procedureCode F1AP-ELEMENTARY-PROCEDURE.&procedureCode ({F1AP-ELEMENTARY-PROCEDURES}), + criticality F1AP-ELEMENTARY-PROCEDURE.&criticality ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value F1AP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({F1AP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +-- ************************************************************** +-- +-- Interface Elementary Procedure List +-- +-- ************************************************************** + +F1AP-ELEMENTARY-PROCEDURES F1AP-ELEMENTARY-PROCEDURE ::= { + F1AP-ELEMENTARY-PROCEDURES-CLASS-1 | + F1AP-ELEMENTARY-PROCEDURES-CLASS-2, + ... +} + + +F1AP-ELEMENTARY-PROCEDURES-CLASS-1 F1AP-ELEMENTARY-PROCEDURE ::= { + reset | + f1Setup | + gNBDUConfigurationUpdate | + gNBCUConfigurationUpdate | + uEContextSetup | + uEContextRelease | + uEContextModification | + uEContextModificationRequired | + writeReplaceWarning | + pWSCancel | + gNBDUResourceCoordination , + ...} + + F1AP-ELEMENTARY-PROCEDURES-CLASS-2 F1AP-ELEMENTARY-PROCEDURE ::= { + errorIndication | + uEContextReleaseRequest | + dLRRCMessageTransfer | + uLRRCMessageTransfer | + uEInactivityNotification | + privateMessage | + initialULRRCMessageTransfer | + systemInformationDelivery | + paging | + notify | + pWSRestartIndication | + pWSFailureIndication , + ... +} +-- ************************************************************** +-- +-- Interface Elementary Procedures +-- +-- ************************************************************** + +reset F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE Reset + SUCCESSFUL OUTCOME ResetAcknowledge + PROCEDURE CODE id-Reset + CRITICALITY reject +} + +f1Setup F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE F1SetupRequest + SUCCESSFUL OUTCOME F1SetupResponse + UNSUCCESSFUL OUTCOME F1SetupFailure + PROCEDURE CODE id-F1Setup + CRITICALITY reject +} + +gNBDUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNBDUConfigurationUpdate + SUCCESSFUL OUTCOME GNBDUConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME GNBDUConfigurationUpdateFailure + PROCEDURE CODE id-gNBDUConfigurationUpdate + CRITICALITY reject +} + +gNBCUConfigurationUpdate F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNBCUConfigurationUpdate + SUCCESSFUL OUTCOME GNBCUConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME GNBCUConfigurationUpdateFailure + PROCEDURE CODE id-gNBCUConfigurationUpdate + CRITICALITY reject +} + +uEContextSetup F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextSetupRequest + SUCCESSFUL OUTCOME UEContextSetupResponse + UNSUCCESSFUL OUTCOME UEContextSetupFailure + PROCEDURE CODE id-UEContextSetup + CRITICALITY reject +} + +uEContextRelease F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextReleaseCommand + SUCCESSFUL OUTCOME UEContextReleaseComplete + PROCEDURE CODE id-UEContextRelease + CRITICALITY reject +} + +uEContextModification F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextModificationRequest + SUCCESSFUL OUTCOME UEContextModificationResponse + UNSUCCESSFUL OUTCOME UEContextModificationFailure + PROCEDURE CODE id-UEContextModification + CRITICALITY reject +} + +uEContextModificationRequired F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextModificationRequired + SUCCESSFUL OUTCOME UEContextModificationConfirm + PROCEDURE CODE id-UEContextModificationRequired + CRITICALITY reject +} + +writeReplaceWarning F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE WriteReplaceWarningRequest + SUCCESSFUL OUTCOME WriteReplaceWarningResponse + PROCEDURE CODE id-WriteReplaceWarning + CRITICALITY reject +} + +pWSCancel F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PWSCancelRequest + SUCCESSFUL OUTCOME PWSCancelResponse + PROCEDURE CODE id-PWSCancel + CRITICALITY reject +} + +errorIndication F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ErrorIndication + PROCEDURE CODE id-ErrorIndication + CRITICALITY ignore +} + +uEContextReleaseRequest F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextReleaseRequest + PROCEDURE CODE id-UEContextReleaseRequest + CRITICALITY ignore +} + + +initialULRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE InitialULRRCMessageTransfer + PROCEDURE CODE id-InitialULRRCMessageTransfer + CRITICALITY ignore +} + +dLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DLRRCMessageTransfer + PROCEDURE CODE id-DLRRCMessageTransfer + CRITICALITY ignore +} + +uLRRCMessageTransfer F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ULRRCMessageTransfer + PROCEDURE CODE id-ULRRCMessageTransfer + CRITICALITY ignore +} + + +uEInactivityNotification F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEInactivityNotification + PROCEDURE CODE id-UEInactivityNotification + CRITICALITY ignore +} + +gNBDUResourceCoordination F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE GNBDUResourceCoordinationRequest + SUCCESSFUL OUTCOME GNBDUResourceCoordinationResponse + PROCEDURE CODE id-GNBDUResourceCoordination + CRITICALITY reject +} + +privateMessage F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PrivateMessage + PROCEDURE CODE id-privateMessage + CRITICALITY ignore +} + +systemInformationDelivery F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE SystemInformationDeliveryCommand + PROCEDURE CODE id-SystemInformationDeliveryCommand + CRITICALITY ignore +} + + +paging F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE Paging + PROCEDURE CODE id-Paging + CRITICALITY ignore +} + +notify F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE Notify + PROCEDURE CODE id-Notify + CRITICALITY ignore +} + +pWSRestartIndication F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PWSRestartIndication + PROCEDURE CODE id-PWSRestartIndication + CRITICALITY ignore +} + +pWSFailureIndication F1AP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PWSFailureIndication + PROCEDURE CODE id-PWSFailureIndication + CRITICALITY ignore +} + + +END diff --git a/openair2/F1AP/MESSAGES/ASN1/asn1tostruct.py b/openair2/F1AP/MESSAGES/ASN1/asn1tostruct.py new file mode 100644 index 0000000000000000000000000000000000000000..b5f019f486ed3a5dfe4103afeb9b07c59f31f43a --- /dev/null +++ b/openair2/F1AP/MESSAGES/ASN1/asn1tostruct.py @@ -0,0 +1,697 @@ +import re, os, sys, string +import datetime +import getopt +import getpass + +version = "1.0.2" + +lines = "" +iesDefs = {} +ieofielist = {} +outdir = './' + +filenames = [] +verbosity = 0 +prefix = "" + +FAIL = '\033[91m' +WARN = '\033[93m' +ENDC = '\033[0m' + +fileprefix = "" +fileprefix_first_upper = "" + +def printFail(string): + sys.stderr.write(FAIL + string + ENDC + "\n") + +def printWarning(string): + print WARN + string + ENDC + +def printDebug(string): + if verbosity > 0: + print string + +def outputHeaderToFile(f, filename): + now = datetime.datetime.now() + f.write("""/* + * 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 + */ + +""") + f.write("/*******************************************************************************\n") + f.write(" * This file had been created by asn1tostruct.py script v%s\n" % (version)) + f.write(" * Please do not modify this file but regenerate it via script.\n") + f.write(" * Created on: %s by %s\n * from %s\n" % (str(now), getpass.getuser(), filenames)) + f.write(" ******************************************************************************/\n") + +def lowerFirstCamelWord(word): + """ puts the first word in a CamelCase Word in lowercase. + + I.e. CustomerID becomes customerID, XMLInfoTest becomes xmlInfoTest + """ + newstr = '' + swapped = word.swapcase() + idx = 0 + + # if it's all-caps, return an all-lowered version + lowered = word.lower() + + if swapped == lowered: + return lowered + + for c in swapped: + if c in string.lowercase: + newstr += c + idx += 1 + else: + break + if idx < 2: + newstr += word[idx:] + else: + newstr = newstr[:-1]+ word[idx-1:] + + return newstr + +def usage(): + print "Python parser for asn1 v%s" % (version) + print "Usage: python asn1tostruct.py [options]" + print "Available options:" + print "-d Enable script debug" + print "-f [file] Input file to parse" + print "-o [dir] Output files to given directory" + print "-h Print this help and return" + +try: + opts, args = getopt.getopt(sys.argv[1:], "df:ho:", ["debug", "file", "help", "outdir"]) +except getopt.GetoptError as err: + # print help information and exit: + usage() + sys.exit(2) + +for o, a in opts: + if o in ("-f", "--file"): + filenames.append(a) + if o in ("-d", "--debug"): + verbosity = 1 + if o in ("-o", "--outdir"): + outdir = a + if outdir.rfind('/') != len(outdir): + outdir += '/' + if o in ("-h", "--help"): + usage() + sys.exit(2) + +for filename in filenames: + file = open(filename, 'r') + for line in file: + # Removing any comment + if line.find('--') >= 0: + line = line[:line.find('--')] + # Removing any carriage return + lines += re.sub('\r', '', line) + + for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+SEQUENCE\s+\(\s*SIZE\s*\(\s*\d+\s*\.\.\s*[0-9a-zA-Z-]+\s*\)\s*\)\s*OF\s+[a-zA-Z-]+\s*\{\s*\{\s*([0-9a-zA-Z-]+)\s*\}\s*\}', lines, re.MULTILINE): + ieofielist[m[0]] = m[1] + for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+E-RAB-IE-ContainerList\s*\{\s*\{\s*([a-zA-Z0-9-]+)\s*\}\s*\}', lines, re.MULTILINE): + ieofielist[m[0]] = m[1] + + for i in re.findall(r'([a-zA-Z0-9-]+)\s+([A-Z0-9-]+)\s*::=\s*\{\s+([\,\|\{\}\t\n\.{3}\ \-a-zA-Z0-9]+)\s+}\n?', lines, re.MULTILINE): + ies = [] + maxLength = 0 + # TODO: handle extensions + if i[1].find('EXTENSION') >= 0: + continue + if fileprefix == "": + fileprefix = i[1][:i[1].find('-')].lower() + for j in re.findall(r'\s*\{\s*([a-zA-Z0-9-\ \t]+)\s*\}\s*[\|,]*', i[2], re.MULTILINE): + for k in re.findall(r'ID\s*([a-zA-Z0-9\-]+)\s*CRITICALITY\s*([a-zA-Z0-9\-]+)\s+[A-Z]+\s+([a-zA-Z0-9\-]+)\s*PRESENCE\s*([a-zA-Z0-9\-]+)', j, re.MULTILINE): + printDebug("Got new ie for message " + i[0] + ": " + str(k)) + if len(k[2]) > maxLength: + maxLength = len(k[2]) + ies.append(k) + + if len(ies) > 0: + iesDefs[i[0]] = { "length": maxLength, "ies": ies } + else: + printWarning("Didn't find any information element for message: " + i[0]) + +if len(iesDefs) == 0: + printFail("No Information Element parsed, exiting") + sys.exit(0) + +fileprefix_first_upper = fileprefix[0].upper() + fileprefix[1:] + +f = open(outdir + fileprefix + '_ies_defs.h', 'w') +outputHeaderToFile(f, filename) +f.write("#include \"%s_common.h\"\n\n" % (fileprefix)) +f.write("#ifndef %s_IES_DEFS_H_\n#define %s_IES_DEFS_H_\n\n" % (fileprefix.upper(), fileprefix.upper())) +f.write("/* Define the version of script used to generate this file */\n") +f.write("#define %s_SCRIPT_VERSION (%s)\n\n" % (fileprefix.upper(), re.sub('\.', '', version))) + +for key in iesDefs: + + if key not in ieofielist.values(): + continue + + for (i, j) in ieofielist.items(): + if j == key: + break + + f.write("typedef struct %sIEs_s {\n" % (re.sub('-', '_', i))) + f.write(" A_SEQUENCE_OF(struct %s_s) %s;\n" % (re.sub('IEs', '', re.sub('-', '_', ieofielist[i])), lowerFirstCamelWord(re.sub('IEs', '', re.sub('-', '_', ieofielist[i]))))) + f.write("} %sIEs_t;\n\n" % (re.sub('-', '_', i))) + +for key in iesDefs: + keyupperunderscore = re.sub('-', '_', key.upper()) + keylowerunderscore = re.sub('-', '_', key.lower()) + shift = 0 + + if len(iesDefs[key]["ies"]) == 0: + continue + + # Presence mask + for ie in iesDefs[key]["ies"]: + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + + if ie[3] == "optional" or ie[3] == "conditional": + f.write("#define {0:<{pad}} {1}\n".format("%s_%s_PRESENT" % (keyupperunderscore, ieupperunderscore), "(1 << %d)" % shift, + pad=iesDefs[key]["length"] + len(keyupperunderscore) + 9)) + shift += 1 + if (shift > 0): + f.write("\n") + + f.write("typedef struct %s_s {\n" % (re.sub('-', '_', key))) + if (shift > 0): + f.write(" {0:<{pad}} {1};\n".format("uint16_t", "presenceMask", pad=iesDefs[key]["length"] + 2)) + for ie in iesDefs[key]["ies"]: + ieunderscore = re.sub('-', '_', ie[2]) + iename = re.sub('id-', '', ie[0]) + ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename)) + if ie[2] in ieofielist: + f.write(" %sIEs_t %s;" % (re.sub('-', '_', ie[2]), ienameunderscore)) + else: + f.write(" {0:<{pad}} {1};".format("%s_t" % ieunderscore, ienameunderscore, pad=iesDefs[key]["length"] + 2)) + if ie[3] == "optional": + f.write(" ///< Optional field") + elif ie[3] == "conditional": + f.write(" ///< Conditional field") + f.write("\n") + + f.write("} %s_t;\n\n" % (re.sub('-', '_', key))) + +f.write("typedef struct %s_message_s {\n" % (fileprefix)) +f.write(" %s_ProcedureCode_t procedureCode;\n" % (fileprefix_first_upper)) +f.write(" %s_Criticality_t criticality;\n" % (fileprefix_first_upper)) +f.write(" uint8_t direction;\n") +f.write(" union {\n") + +messageList = iesDefs.keys() +messageList.sort() +for message in messageList: + if message in ieofielist.values(): + continue + if len(iesDefs[message]["ies"]) == 0: + continue + f.write(" %s_t %s;\n" % (re.sub('-', '_', message), lowerFirstCamelWord(re.sub('-', '_', message)))) +f.write(" } msg;\n") +f.write("} %s_message;\n\n" % (fileprefix)) + +for key in iesDefs: + if key in ieofielist.values(): + continue + structName = re.sub('ies', '', key) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key))) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + keylowerunderscore = re.sub('-', '_', key.lower()) + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + f.write("/** \\brief Decode function for %s ies.\n" % (key)) + if len(iesDefs[key]["ies"]) != 0: + f.write(" * \\param %s Pointer to ASN1 structure in which data will be stored\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" * \\param any_p Pointer to the ANY value to decode.\n") + f.write(" **/\n") + f.write("int %s_decode_%s(\n" % (fileprefix, keylowerunderscore)) + + if len(iesDefs[key]["ies"]) != 0: + f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" ANY_t *any_p);\n\n") + + if len(iesDefs[key]["ies"]) == 0: + continue + + f.write("/** \\brief Encode function for %s ies.\n" % (key)) + f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) + f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" **/\n") + f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower)) + f.write(" %s_t *%s);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + +for key in iesDefs: + if key not in ieofielist.values(): + continue + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + f.write("/** \\brief Encode function for %s ies.\n" % (key)) + f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) + f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" **/\n") + f.write("int %s_encode_%s(\n" % (fileprefix, firstlower.lower())) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower)) + f.write(" %sIEs_t *%sIEs);\n\n" % (asn1cStruct, firstlower)) + f.write("/** \\brief Decode function for %s ies.\n" % (key)) + f.write(" * \\param any_p Pointer to the ANY value to decode.\n") + f.write(" * \\param callback Callback function called when any_p is successfully decoded.\n") + f.write(" **/\n") + f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower())) + f.write(" %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower)) + f.write(" %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct))) + +for key in iesDefs: + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + if key in ieofielist.values(): + f.write("/** \\brief Display %s encapsulated IE using XER encoding.\n" % (asn1cStruct)) + f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" * \\param file File descriptor to write output.\n") + f.write(" **/\n") + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('item', 'list', firstlower.lower()))) + f.write(" asn_app_consume_bytes_f *cb,\n") + f.write(" void *app_key,\n") + f.write(" %sIEs_t *%sIEs);\n\n" % (re.sub('item', 'list', asn1cStruct), firstlower)) + else: + f.write("/** \\brief Display %s message using XER encoding.\n" % (asn1cStruct)) + f.write(" * \\param message_p Pointer to root message.\n") + f.write(" * \\param file File descriptor to write output.\n") + f.write(" **/\n") + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, firstlower.lower())) + f.write(" asn_app_consume_bytes_f *cb,\n") + f.write(" void *app_key,\n") + f.write(" %s_message *message_p);\n\n" % (fileprefix)) + +f.write("int %s_xer__print2sp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower())) +f.write("int %s_xer__print2fp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower())) +f.write("extern size_t %s_string_total_size;\n\n" % (fileprefix.lower())) +f.write("#endif /* %s_IES_DEFS_H_ */\n\n" % (fileprefix.upper())) + +#Generate Decode functions +f = open(outdir + fileprefix + '_decoder.c', 'w') +outputHeaderToFile(f, filename) +f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix)) +for key in iesDefs: + if key in ieofielist.values(): + continue + structName = re.sub('ies', '', key) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + if asn1cStruct.rfind('_') == len(asn1cStruct) - 1: + asn1cStruct = asn1cStruct[:-1] + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + ielistname = re.sub('UE', 'ue', asn1cStruct) + ielistnamefirstlower = ielistname[:1].lower() + ielistname[1:] + asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:] + keyName = re.sub('-', '_', key) + keyupperunderscore = keyName.upper() + firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + iesaccess = "" + if key not in ieofielist.values(): + iesaccess = "%s_ies." % (firstlower) + + f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) + if len(iesDefs[key]["ies"]) != 0: + f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + f.write(" ANY_t *any_p) {\n\n") + + f.write(" %s_t %s;\n %s_t *%s_p = &%s;\n" % (asn1cStruct, asn1cStructfirstlower, asn1cStruct, asn1cStructfirstlower, asn1cStructfirstlower)) + f.write(" int i, decoded = 0;\n") + if len(iesDefs[key]["ies"]) != 0: + f.write(" int tempDecoded = 0;\n") + + f.write(" assert(any_p != NULL);\n") + if len(iesDefs[key]["ies"]) != 0: + f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))) + + f.write(" %s_DEBUG(\"Decoding message %s (%%s:%%d)\\n\", __FILE__, __LINE__);\n\n" % (fileprefix.upper(), re.sub('-', '_', keyName))) + f.write(" ANY_to_type_aper(any_p, &asn_DEF_%s, (void**)&%s_p);\n\n" % (asn1cStruct, asn1cStructfirstlower)) + f.write(" for (i = 0; i < %s_p->%slist.count; i++) {\n" % (asn1cStructfirstlower, iesaccess)) + f.write(" %s_IE_t *ie_p;\n" % (fileprefix[0].upper() + fileprefix[1:])) + f.write(" ie_p = %s_p->%slist.array[i];\n" % (asn1cStructfirstlower, iesaccess)) + f.write(" switch(ie_p->id) {\n") + for ie in iesDefs[key]["ies"]: + iename = re.sub('id-', '', ie[0]) + ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename)) + ienameunderscorefirstlower = lowerFirstCamelWord(ienameunderscore) + ietypesubst = re.sub('-', '', ie[2]) + ietypeunderscore = re.sub('-', '_', ie[2]) + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + + if ie[3] == "optional": + f.write(" /* Optional field */\n") + elif ie[3] == "conditional": + f.write(" /* Conditional field */\n") + f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" {\n") + f.write(" %s_t *%s_p = NULL;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + if ie[3] != "mandatory": + f.write(" %s->presenceMask |= %s_%s_PRESENT;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore)) + f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(ietypesubst))) + f.write(" %s_ERROR(\"Decoding of IE %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore)) + f.write(" if (%s_p)\n" % (lowerFirstCamelWord(ietypesubst))) + f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" decoded += tempDecoded;\n") + f.write(" if (asn1_xer_print)\n") + f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + if ie[2] in ieofielist.keys(): + f.write(" if (%s_decode_%s(&%s->%s, %s_p) < 0) {\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" %s_ERROR(\"Decoding of encapsulated IE %s failed\\n\");\n" % (fileprefix.upper(), lowerFirstCamelWord(ietypesubst))) + f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" }\n") + else: + f.write(" memcpy(&%s->%s, %s_p, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst), ietypeunderscore)) + #f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst))) + f.write(" } break;\n") + f.write(" default:\n") + f.write(" %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower()))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" }\n") + f.write(" return decoded;\n") + f.write("}\n\n") + +for key in iesDefs: + if key not in ieofielist.values(): + continue + + keyname = re.sub('IEs', '', re.sub('Item', 'List', key)) + + f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', keyname).lower())) + f.write(" %sIEs_t *%sIEs,\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" int i, decoded = 0;\n") + f.write(" int tempDecoded = 0;\n\n") + + f.write(" assert(%s != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)))); + f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)))); + + f.write(" for (i = 0; i < %s->list.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" %s_IE_t *ie_p = %s->list.array[i];\n" % (fileprefix[0].upper() + fileprefix[1:], lowerFirstCamelWord(re.sub('-', '_', keyname)))) + f.write(" switch (ie_p->id) {\n") + for ie in iesDefs[key]["ies"]: + iename = re.sub('id-', '', ie[0]) + ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename)) + f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" {\n") + f.write(" %s_t *%s_p = NULL;\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" %s_ERROR(\"Decoding of IE %s for message %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore, re.sub('-', '_', keyname))) + f.write(" if (%s_p)\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2])))) + #f.write(" free(%s_p);\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" decoded += tempDecoded;\n") + f.write(" if (asn1_xer_print)\n") + f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" ASN_SEQUENCE_ADD(&%sIEs->%s, %s_p);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)), + re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), lowerFirstCamelWord(re.sub('-', '', ie[2])))) + f.write(" } break;\n") + f.write(" default:\n") + f.write(" %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower()))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" }\n") + f.write(" return decoded;\n") + f.write("}\n\n") + + +#Generate IES Encode functions +f = open(outdir + fileprefix + '_encoder.c', 'w') +outputHeaderToFile(f,filename) +f.write("#include \"%s_common.h\"\n" % (fileprefix)) +f.write("#include \"%s_ies_defs.h\"\n\n" % (fileprefix)) +for key in iesDefs: + if key in ieofielist.values(): + continue + + structName = re.sub('ies', '', key) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + if asn1cStruct.rfind('_') == len(asn1cStruct) - 1: + asn1cStruct = asn1cStruct[:-1] + asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:] + firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + iesaccess = "" + if key not in ieofielist.values(): + iesaccess = "%s_ies." % (firstwordlower) + + keyName = re.sub('-', '_', key) + keyupperunderscore = keyName.upper() + # No IE to encode... + if len(iesDefs[key]["ies"]) == 0: + continue + + f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower)) + f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) + + f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper)) + + f.write(" assert(%s != NULL);\n" % (firstwordlower)); + f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))); + + for ie in iesDefs[key]["ies"]: + iename = re.sub('-', '_', re.sub('id-', '', ie[0])) + ienameunderscore = re.sub('-', '_', iename) + ienamefirstwordlower = lowerFirstCamelWord(iename) + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + ietypeunderscore = re.sub('-', '_', ie[2]) + + if ie[3] != "mandatory": + if ie[3] == "optional": + f.write(" /* Optional field */\n") + elif ie[3] == "conditional": + f.write(" /* Conditional field */\n") + f.write(" if (%s->presenceMask & %s_%s_PRESENT) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore)) + #f.write(" == %s_%s_PRESENT) {\n" % (keyupperunderscore, ieupperunderscore)) + f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1])) + f.write(" &asn_DEF_%s,\n" % (ietypeunderscore)) + f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower)) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n" % (firstwordlower, iesaccess)) + f.write(" }\n\n") + else: + if ie[2] in ieofielist.keys(): + f.write(" %s_t %s;\n\n" % (ietypeunderscore, ienamefirstwordlower)) + f.write(" memset(&%s, 0, sizeof(%s_t));\n" % (ienamefirstwordlower, ietypeunderscore)) + f.write("\n") + f.write(" if (%s_encode_%s(&%s, &%s->%s) < 0) return -1;\n" % (fileprefix, ietypeunderscore.lower(), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower)) + f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1])) + f.write(" &asn_DEF_%s,\n" % (ietypeunderscore)) + if ie[2] in ieofielist.keys(): + f.write(" &%s)) == NULL) {\n" % (ienamefirstwordlower)) + else: + f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower)) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n\n" % (firstwordlower, iesaccess)) + if ie[2] in ieofielist.keys(): + f.write(" /* Free any dynamic allocation that is no more used */\n") + f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s);\n\n" % (ietypeunderscore, ienamefirstwordlower)) + + f.write(" return 0;\n") + f.write("}\n\n") + +for (key, value) in iesDefs.items(): + if key not in ieofielist.values(): + continue + + ie = value["ies"][0] + ietypeunderscore = re.sub('-', '_', ie[2]) + asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key))) + asn1cStruct = re.sub('Item', 'List', asn1cStruct) + firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) + + for (i, j) in ieofielist.items(): + if j == key: + break + f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', i).lower())) + f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower)) + f.write(" %sIEs_t *%sIEs) {\n\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i)))) + f.write(" int i;\n") + + f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper)) + + f.write(" assert(%s != NULL);\n" % (firstwordlower)); + f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', i)))); + + f.write(" for (i = 0; i < %sIEs->%s.count; i++) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0]))) + f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1])) + f.write(" &asn_DEF_%s,\n" % (ietypeunderscore)) + f.write(" %sIEs->%s.array[i])) == NULL) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" return -1;\n") + f.write(" }\n") + f.write(" ASN_SEQUENCE_ADD(&%s->list, ie);\n" % (firstwordlower)) + f.write(" }\n") + f.write(" return 0;\n") + f.write("}\n\n") + +#Generate xer print functions +f = open(outdir + fileprefix + '_xer_print.c', 'w') +outputHeaderToFile(f, filename) +f.write("#include <stdlib.h>\n") +f.write("#include <stdio.h>\n\n") +f.write("#include <asn_application.h>\n#include <asn_internal.h>\n\n") +f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix)) + +f.write("size_t %s_string_total_size = 0;\n\n" % (fileprefix.lower())) +f.write("""int +%s_xer__print2fp(const void *buffer, size_t size, void *app_key) { + FILE *stream = (FILE *)app_key; + + if(fwrite(buffer, 1, size, stream) != size) + return -1; + + return 0; +} + +""" % (fileprefix.lower())) + +f.write("""int %s_xer__print2sp(const void *buffer, size_t size, void *app_key) { + char *string = (char *)app_key; + + /* Copy buffer to the formatted string */ + memcpy(&string[%s_string_total_size], buffer, size); + + %s_string_total_size += size; + + return 0; +} + +""" % (fileprefix.lower(), fileprefix.lower(), fileprefix.lower())) + +f.write("""static asn_enc_rval_t +xer_encode_local(asn_TYPE_descriptor_t *td, void *sptr, + asn_app_consume_bytes_f *cb, void *app_key, int indent) { + asn_enc_rval_t er, tmper; + const char *mname; + size_t mlen; + int xcan = 2; + + if(!td || !sptr) goto cb_failed; + + mname = td->xml_tag; + mlen = strlen(mname); + + _i_ASN_TEXT_INDENT(0, indent); + _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1); + + tmper = td->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key); + if(tmper.encoded == -1) return tmper; + + _ASN_CALLBACK3("</", 2, mname, mlen, ">\\n", xcan); + + er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded; + + _ASN_ENCODED_OK(er); +cb_failed: + _ASN_ENCODE_FAILED; +} +""") + +for (key, value) in iesDefs.items(): + keyName = re.sub('-', '_', key) + keyupperunderscore = keyName.upper() + iesStructName = lowerFirstCamelWord(re.sub('-', '_', key)) + + ie = value["ies"][0] + ietypeunderscore = re.sub('-', '_', ie[2]) + + if key in ieofielist.values(): + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('item', 'list', re.sub('-', '_', key).lower())))) + else: + f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', key).lower()))) + #f.write(" FILE *file,\n") + f.write(" asn_app_consume_bytes_f *cb,\n") + f.write(" void *app_key,\n") + if key in ieofielist.values(): + iesStructName = lowerFirstCamelWord(re.sub('Item', 'List', re.sub('-', '_', key))) + f.write(" %sIEs_t *%s) {\n\n" % (re.sub('IEs', '', re.sub('Item', 'List', re.sub('-', '_', key))), iesStructName)) + f.write(" int i;\n") + f.write(" asn_enc_rval_t er;\n") + else: + f.write(" %s_message *message_p)\n{\n" % (fileprefix)) + f.write(" %s_t *%s;\n" % (re.sub('-', '_', key), iesStructName)) + f.write(" asn_enc_rval_t er;\n") + #f.write(" void *app_key = (void *)file;\n") + #f.write(" asn_app_consume_bytes_f *cb = %s_xer__print2fp;\n\n" % (fileprefix.lower())) + + f.write(" %s = &message_p->msg.%s;\n\n" % (iesStructName, iesStructName)) + + if key in ieofielist.values(): + # Increase indentation level + f.write(" for (i = 0; i < %s->%s.count; i++) {\n" % (iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + #f.write(" xer_fprint(file, &asn_DEF_%s, %s->%s.array[i]);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" er = xer_encode(&asn_DEF_%s, %s->%s.array[i], XER_F_BASIC, cb, app_key);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) + f.write(" }\n") + else: + f.write(" cb(\"<%s-PDU>\\n\", %d, app_key);\n" % (key, len("<%s-PDU>\n" % (key)))) + f.write(" xer_encode_local(&asn_DEF_%s_Criticality, &message_p->criticality, cb, app_key, 1);\n" % fileprefix_first_upper) + f.write(" xer_encode_local(&asn_DEF_%s_ProcedureCode, &message_p->procedureCode, cb, app_key, 1);\n" % fileprefix_first_upper) + + f.write(" cb(\" <%s>\\n\", %d, app_key);\n" % (key, len(" <%s>\n" % (key)))) + + for ie in iesDefs[key]["ies"]: + iename = re.sub('-', '_', re.sub('id-', '', ie[0])) + ienameunderscore = re.sub('-', '_', iename) + ienamefirstwordlower = lowerFirstCamelWord(iename) + ietypeunderscore = re.sub('-', '_', ie[2]) + ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() + + if ie[3] != "mandatory": + if ie[3] == "optional": + f.write(" /* Optional field */\n") + elif ie[3] == "conditional": + f.write(" /* Conditional field */\n") + f.write(" if (%s->presenceMask & %s_%s_PRESENT)\n " % (iesStructName, keyupperunderscore, ieupperunderscore)) + + # Is it an encapsulated IE ? + if ie[2] in ieofielist.keys(): + f.write(" %s_xer_print_%s(cb, app_key, &%s->%s);\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', ie[2]).lower()), iesStructName, ienamefirstwordlower)) + else: + f.write(" xer_encode_local(&asn_DEF_%s, &%s->%s, cb, app_key, 2);\n" % (ietypeunderscore, iesStructName, ienamefirstwordlower)) + f.write(" cb(\" </%s>\\n\", %d, app_key);\n" % (key, len(" </%s>\n" % (key)))) + f.write(" cb(\"</%s-PDU>\\n\", %d, app_key);\n" % (key, len("</%s-PDU>\n" % (key)))) + + f.write(" _ASN_ENCODED_OK(er);\n") + #if key not in ieofielist.values(): + #f.write("cb_failed:\n") + #f.write(" return er;\n") + f.write("}\n\n") diff --git a/openair2/F1AP/f1ap_common.c b/openair2/F1AP/f1ap_common.c new file mode 100644 index 0000000000000000000000000000000000000000..e9e69732beab8fcfc2a1a5670c30b5b05c19f58e --- /dev/null +++ b/openair2/F1AP/f1ap_common.c @@ -0,0 +1,194 @@ +/* + * 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 f1ap_common.c + * \brief f1ap procedures for both CU and DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#include "f1ap_common.h" + +#if defined(EMIT_ASN_DEBUG_EXTERN) +int asn_debug = 0; +int asn1_xer_print = 0; + +inline void ASN_DEBUG(const char *fmt, ...) +{ + if (asn_debug) { + int adi = asn_debug_indent; + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "[ASN1]"); + + while(adi--) fprintf(stderr, " "); + + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + } +} +#endif + +uint8_t F1AP_get_next_transaction_identifier(module_id_t enb_mod_idP, module_id_t cu_mod_idP) +{ + static uint8_t transaction_identifier[NUMBER_OF_eNB_MAX]; + transaction_identifier[enb_mod_idP+cu_mod_idP] = + (transaction_identifier[enb_mod_idP+cu_mod_idP] + 1) % F1AP_TRANSACTION_IDENTIFIER_NUMBER; + //LOG_T(F1AP,"generated xid is %d\n",transaction_identifier[enb_mod_idP+cu_mod_idP]); + return transaction_identifier[enb_mod_idP+cu_mod_idP]; +} + +int f1ap_add_ue(f1ap_cudu_inst_t *f1_inst, + module_id_t module_idP, + int CC_idP, + int UE_id, + rnti_t rntiP) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (f1_inst->f1ap_ue[i].rnti == rntiP) { + f1_inst->f1ap_ue[i].f1ap_uid = i; + f1_inst->f1ap_ue[i].mac_uid = UE_id; + LOG_I(F1AP, "Updating the index of UE with RNTI %x and du_ue_f1ap_id %d\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id); + return i; + } + } + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (f1_inst->f1ap_ue[i].rnti == 0 ) { + f1_inst->f1ap_ue[i].rnti = rntiP; + f1_inst->f1ap_ue[i].f1ap_uid = i; + f1_inst->f1ap_ue[i].mac_uid = UE_id; + f1_inst->f1ap_ue[i].du_ue_f1ap_id = rntiP; + f1_inst->f1ap_ue[i].cu_ue_f1ap_id = rntiP; + f1_inst->num_ues++; + LOG_I(F1AP, "Adding a new UE with RNTI %x and cu/du ue_f1ap_id %d\n", f1_inst->f1ap_ue[i].rnti, f1_inst->f1ap_ue[i].du_ue_f1ap_id); + return i; + } + } + return -1; +} + + +int f1ap_remove_ue(f1ap_cudu_inst_t *f1_inst, + rnti_t rntiP) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (f1_inst->f1ap_ue[i].rnti == rntiP) { + f1_inst->f1ap_ue[i].rnti = 0; + break; + } + } + f1_inst->num_ues--; + return 0; +} + +int f1ap_get_du_ue_f1ap_id(f1ap_cudu_inst_t *f1_inst, + rnti_t rntiP) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (f1_inst->f1ap_ue[i].rnti == rntiP) { + return f1_inst->f1ap_ue[i].du_ue_f1ap_id; + } + } + return -1; +} + +int f1ap_get_cu_ue_f1ap_id(f1ap_cudu_inst_t *f1_inst, + rnti_t rntiP) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (f1_inst->f1ap_ue[i].rnti == rntiP) { + return f1_inst->f1ap_ue[i].cu_ue_f1ap_id; + } + } + return -1; +} + +int f1ap_get_rnti_by_du_id(f1ap_cudu_inst_t *f1_inst, + module_id_t du_ue_f1ap_id ) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) { + return f1_inst->f1ap_ue[i].rnti; + } + } + return -1; +} + +int f1ap_get_rnti_by_cu_id(f1ap_cudu_inst_t *f1_inst, + module_id_t cu_ue_f1ap_id ) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (f1_inst->f1ap_ue[i].cu_ue_f1ap_id == cu_ue_f1ap_id) { + return f1_inst->f1ap_ue[i].rnti; + } + } + return -1; +} + +int f1ap_get_du_uid(f1ap_cudu_inst_t *f1_inst, + module_id_t du_ue_f1ap_id ) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (f1_inst->f1ap_ue[i].du_ue_f1ap_id == du_ue_f1ap_id) { + return i; + } + } + return -1; +} + +int f1ap_get_cu_uid(f1ap_cudu_inst_t *f1_inst, + module_id_t cu_ue_f1ap_id ) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (f1_inst->f1ap_ue[i].cu_ue_f1ap_id == cu_ue_f1ap_id) { + return i; + } + } + return -1; +} + +int f1ap_get_uid_by_rnti(f1ap_cudu_inst_t *f1_inst, + rnti_t rntiP ) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (f1_inst->f1ap_ue[i].rnti == rntiP) { + return i; + } + } + return -1; +} + +int f1ap_du_add_cu_ue_id(f1ap_cudu_inst_t *f1_inst, + module_id_t du_ue_f1ap_id, + module_id_t cu_ue_f1ap_id) { + module_id_t f1ap_uid = f1ap_get_du_uid(f1_inst,du_ue_f1ap_id); + if (f1ap_uid < 0) return -1; + f1_inst->f1ap_ue[f1ap_uid].cu_ue_f1ap_id = cu_ue_f1ap_id; + LOG_I(F1AP, "Adding cu_ue_f1ap_id %d for UE with RNTI %x\n", cu_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti); + return 0; +} + +int f1ap_cu_add_du_ue_id(f1ap_cudu_inst_t *f1_inst, + module_id_t cu_ue_f1ap_id, + module_id_t du_ue_f1ap_id) { + module_id_t f1ap_uid = f1ap_get_cu_uid(f1_inst,cu_ue_f1ap_id); + if (f1ap_uid < 0) return -1; + f1_inst->f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id; + LOG_I(F1AP, "Adding du_ue_f1ap_id %d for UE with RNTI %x\n", du_ue_f1ap_id, f1_inst->f1ap_ue[f1ap_uid].rnti); + return 0; +} diff --git a/openair2/F1AP/f1ap_common.h b/openair2/F1AP/f1ap_common.h new file mode 100644 index 0000000000000000000000000000000000000000..ee57a7ec838e41ca4374e03a1fc1e762b1a3f345 --- /dev/null +++ b/openair2/F1AP/f1ap_common.h @@ -0,0 +1,488 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_common.h + * \brief f1ap procedures for both CU and DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#if HAVE_CONFIG_H_ +# include "config.h" +#endif + +#ifndef F1AP_COMMON_H_ +#define F1AP_COMMON_H_ + +#include "openairinterface5g_limits.h" + +#define F1AP_UE_IDENTIFIER_NUMBER 3 +#define F1AP_TRANSACTION_IDENTIFIER_NUMBER 3 + +#if defined(EMIT_ASN_DEBUG_EXTERN) +inline void ASN_DEBUG(const char *fmt, ...); +#endif + +#include "F1AP_Active-Cells-List.h" +#include "F1AP_RAT-FrequencyPriorityInformation.h" +#include "F1AP_DLUPTNLInformation-ToBeSetup-Item.h" +#include "F1AP_PrivateMessage.h" +#include "F1AP_Cause.h" +#include "F1AP_Pre-emptionVulnerability.h" +#include "F1AP_NRPCI.h" +#include "F1AP_Transmission-Bandwidth.h" +#include "F1AP_SIB1-message.h" +#include "F1AP_GNBCUConfigurationUpdateAcknowledge.h" +#include "F1AP_DRBs-Setup-Item.h" +#include "F1AP_EUTRA-NR-CellResourceCoordinationReqAck-Container.h" +#include "F1AP_NR-CGI-List-For-Restart-Item.h" +#include "F1AP_GNB-CU-Name.h" +#include "F1AP_PagingDRX.h" +#include "F1AP_RepetitionPeriod.h" +#include "F1AP_DRBs-ToBeModified-List.h" +#include "F1AP_ExecuteDuplication.h" +#include "F1AP_SCell-FailedtoSetupMod-List.h" +#include "F1AP_NRNRB.h" +#include "F1AP_SCell-ToBeSetup-List.h" +#include "F1AP_F1AP-PDU.h" +#include "F1AP_MaskedIMEISV.h" +#include "F1AP_ProtocolIE-Container.h" +#include "F1AP_GNB-CU-TNL-Association-To-Update-Item.h" +#include "F1AP_Cells-to-be-Activated-List-Item.h" +#include "F1AP_DRBs-Required-ToBeModified-Item.h" +#include "F1AP_BitRate.h" +#include "F1AP_SRBs-ToBeSetup-List.h" +#include "F1AP_ConcurrentWarningMessageIndicator.h" +#include "F1AP_CriticalityDiagnostics-IE-Item.h" +#include "F1AP_GNB-CU-TNL-Association-To-Update-List.h" +#include "F1AP_DRB-Notify-List.h" +#include "F1AP_UEContextReleaseCommand.h" +#include "F1AP_ProtocolIE-SingleContainer.h" +#include "F1AP_DRBs-ToBeReleased-List.h" +#include "F1AP_PWS-Failed-NR-CGI-List.h" +#include "F1AP_InitialULRRCMessageTransfer.h" +#include "F1AP_Served-Cell-Information.h" +#include "F1AP_Served-EUTRA-Cells-Information.h" +#include "F1AP_Cells-Broadcast-Cancelled-Item.h" +#include "F1AP_F1SetupRequest.h" +#include "F1AP_Served-Cells-To-Add-Item.h" +#include "F1AP_F1SetupFailure.h" +#include "F1AP_ULUPTNLInformation-ToBeSetup-Item.h" +#include "F1AP_GNB-CU-TNL-Association-To-Add-Item.h" +#include "F1AP_DUtoCURRCContainer.h" +#include "F1AP_GNBDUResourceCoordinationRequest.h" +#include "F1AP_DRBs-FailedToBeSetup-List.h" +#include "F1AP_UPTransportLayerInformation.h" +#include "F1AP_RRCContainer.h" +#include "F1AP_Notification-Cause.h" +#include "F1AP_UEIdentityIndexValue.h" +#include "F1AP_SRBs-ToBeSetupMod-List.h" +#include "F1AP_GNB-DU-Served-Cells-Item.h" +#include "F1AP_RLCMode.h" +#include "F1AP_NRSCS.h" +#include "F1AP_SliceSupportList.h" +#include "F1AP_GTP-TEID.h" +#include "F1AP_UEContextModificationRequest.h" +#include "F1AP_MeasConfig.h" +#include "F1AP_Flows-Mapped-To-DRB-List.h" +#include "F1AP_Cells-to-be-Deactivated-List-Item.h" +#include "F1AP_QoSFlowLevelQoSParameters.h" +#include "F1AP_GNB-CU-UE-F1AP-ID.h" +#include "F1AP_CauseTransport.h" +#include "F1AP_DRBs-ToBeReleased-Item.h" +#include "F1AP_SCell-ToBeSetupMod-Item.h" +#include "F1AP_CellGroupConfig.h" +#include "F1AP_PWSSystemInformation.h" +#include "F1AP_DRBs-Modified-List.h" +#include "F1AP_HandoverPreparationInformation.h" +#include "F1AP_InactivityMonitoringResponse.h" +#include "F1AP_Served-Cells-To-Delete-List.h" +#include "F1AP_ProtocolExtensionField.h" +#include "F1AP_GNB-CU-TNL-Association-To-Remove-List.h" +#include "F1AP_SRBID.h" +#include "F1AP_DRB-Activity-List.h" +#include "F1AP_DRBs-FailedToBeModified-Item.h" +#include "F1AP_TransactionID.h" +#include "F1AP_AllocationAndRetentionPriority.h" +#include "F1AP_ShortDRXCycleLength.h" +#include "F1AP_BroadcastPLMNs-Item.h" +#include "F1AP_DRB-Information.h" +#include "F1AP_TimeToWait.h" +#include "F1AP_NonDynamic5QIDescriptor.h" +#include "F1AP_C-RNTI.h" +#include "F1AP_MIB-message.h" +#include "F1AP_SIBtype-Item.h" +#include "F1AP_Served-Cells-To-Modify-List.h" +#include "F1AP_NRCGI.h" +#include "F1AP_DuplicationActivation.h" +#include "F1AP_CauseProtocol.h" +#include "F1AP_SCell-FailedtoSetup-Item.h" +#include "F1AP_PagingIdentity.h" +#include "F1AP_NGRANAllocationAndRetentionPriority.h" +#include "F1AP_TypeOfError.h" +#include "F1AP_GNB-CU-TNL-Association-To-Add-List.h" +#include "F1AP_DRBs-Required-ToBeReleased-Item.h" +#include "F1AP_EUTRA-Mode-Info.h" +#include "F1AP_FiveGS-TAC.h" +#include "F1AP_Cells-to-be-Activated-List.h" +#include "F1AP_PagingCell-list.h" +#include "F1AP_NotificationControl.h" +#include "F1AP_ProtectedEUTRAResourceIndication.h" +#include "F1AP_CUtoDURRCInformation.h" +#include "F1AP_SystemInformationDeliveryCommand.h" +#include "F1AP_AveragingWindow.h" +#include "F1AP_SRBs-ToBeSetupMod-Item.h" +#include "F1AP_NumberOfBroadcasts.h" +#include "F1AP_Cells-Broadcast-Completed-List.h" +#include "F1AP_GNB-CU-TNL-Association-Setup-Item.h" +#include "F1AP_PWSCancelResponse.h" +#include "F1AP_SpectrumSharingGroupID.h" +#include "F1AP_RANUEPagingIdentity.h" +#include "F1AP_CG-ConfigInfo.h" +#include "F1AP_PagingCell-Item.h" +#include "F1AP_GNB-CU-TNL-Association-To-Remove-Item.h" +#include "F1AP_UE-CapabilityRAT-ContainerList.h" +#include "F1AP_PWSCancelRequest.h" +#include "F1AP_PriorityLevel.h" +#include "F1AP_ProtocolIE-ContainerPair.h" +#include "F1AP_FullConfiguration.h" +#include "F1AP_NRCellIdentity.h" +#include "F1AP_ProtocolExtensionContainer.h" +#include "F1AP_PWSRestartIndication.h" +#include "F1AP_DRBs-ModifiedConf-List.h" +#include "F1AP_GNB-CU-TNL-Association-Failed-To-Setup-List.h" +#include "F1AP_UEContextSetupRequest.h" +#include "F1AP_PWSFailureIndication.h" +#include "F1AP_UE-associatedLogicalF1-ConnectionListResAck.h" +#include "F1AP_DRBs-ToBeSetupMod-Item.h" +#include "F1AP_SRBs-FailedToBeSetup-List.h" +#include "F1AP_Criticality.h" +#include "F1AP_UEContextModificationConfirm.h" +#include "F1AP_Broadcast-To-Be-Cancelled-List.h" +#include "F1AP_UEContextReleaseComplete.h" +#include "F1AP_PrivateIE-Container.h" +#include "F1AP_CellULConfigured.h" +#include "F1AP_DRB-Activity.h" +#include "F1AP_GNB-CU-TNL-Association-Failed-To-Setup-Item.h" +#include "F1AP_PrivateIE-ID.h" +#include "F1AP_WriteReplaceWarningResponse.h" +#include "F1AP_CauseMisc.h" +#include "F1AP_SRBs-Required-ToBeReleased-Item.h" +#include "F1AP_Cells-Broadcast-Cancelled-List.h" +#include "F1AP_ULUEConfiguration.h" +#include "F1AP_RAT-FrequencySelectionPriority.h" +#include "F1AP_UEInactivityNotification.h" +#include "F1AP_DLRRCMessageTransfer.h" +#include "F1AP_TriggeringMessage.h" +#include "F1AP_DRBs-ToBeSetup-List.h" +#include "F1AP_Cells-to-be-Barred-Item.h" +#include "F1AP_UE-associatedLogicalF1-ConnectionItem.h" +#include "F1AP_Cancel-all-Warning-Messages-Indicator.h" +#include "F1AP_SCell-FailedtoSetupMod-Item.h" +#include "F1AP_DRBs-FailedToBeSetupMod-List.h" +#include "F1AP_ProtocolIE-ID.h" +#include "F1AP_TransportLayerAddress.h" +#include "F1AP_GNB-DU-System-Information.h" +#include "F1AP_PWS-Failed-NR-CGI-Item.h" +#include "F1AP_Notify.h" +#include "F1AP_UEContextModificationResponse.h" +#include "F1AP_DRBID.h" +#include "F1AP_GNBDUResourceCoordinationResponse.h" +#include "F1AP_UEContextModificationRequired.h" +#include "F1AP_InitiatingMessage.h" +#include "F1AP_SliceSupportItem.h" +#include "F1AP_ProtocolIE-FieldPair.h" +#include "F1AP_EUTRA-TDD-Info.h" +#include "F1AP_GNBDUConfigurationUpdateFailure.h" +#include "F1AP_ULUPTNLInformation-ToBeSetup-List.h" +#include "F1AP_WriteReplaceWarningRequest.h" +#include "F1AP_ServCellIndex.h" +#include "F1AP_ResetAcknowledge.h" +#include "F1AP_SRBs-FailedToBeSetupMod-Item.h" +#include "F1AP_OffsetToPointA.h" +#include "F1AP_ProcedureCode.h" +#include "F1AP_GTPTunnel.h" +#include "F1AP_TDD-Info.h" +#include "F1AP_Pre-emptionCapability.h" +#include "F1AP_MaxDataBurstVolume.h" +#include "F1AP_SUL-Information.h" +#include "F1AP_CriticalityDiagnostics-IE-List.h" +#include "F1AP_EUTRA-FDD-Info.h" +#include "F1AP_BroadcastPLMNs-List.h" +#include "F1AP_Served-Cells-To-Delete-Item.h" +#include "F1AP_ListofEUTRACellsinGNBDUCoordination.h" +#include "F1AP_Candidate-SpCell-Item.h" +#include "F1AP_Cells-To-Be-Broadcast-List.h" +#include "F1AP_ULRRCMessageTransfer.h" +#include "F1AP_Cells-to-be-Deactivated-List.h" +#include "F1AP_DRBs-Required-ToBeReleased-List.h" +#include "F1AP_Served-Cells-To-Add-List.h" +#include "F1AP_Potential-SpCell-List.h" +#include "F1AP_EUTRANQoS.h" +#include "F1AP_Dynamic5QIDescriptor.h" +#include "F1AP_GNBCUConfigurationUpdateFailure.h" +#include "F1AP_DuplicationIndication.h" +#include "F1AP_GNB-DU-Served-Cells-List.h" +#include "F1AP_QoS-Characteristics.h" +#include "F1AP_UE-associatedLogicalF1-ConnectionListRes.h" +#include "F1AP_ResourceCoordinationTransferContainer.h" +#include "F1AP_DRXCycle.h" +#include "F1AP_DRBs-FailedToBeSetup-Item.h" +#include "F1AP_PrivateIE-Field.h" +#include "F1AP_SRBs-ToBeReleased-List.h" +#include "F1AP_MeasGapConfig.h" +#include "F1AP_NR-Mode-Info.h" +#include "F1AP_Active-Cells-Item.h" +#include "F1AP_Protected-EUTRA-Resources-List.h" +#include "F1AP_SRBs-FailedToBeSetup-Item.h" +#include "F1AP_ResetAll.h" +#include "F1AP_SCell-FailedtoSetup-List.h" +#include "F1AP_UEContextModificationFailure.h" +#include "F1AP_CNUEPagingIdentity.h" +#include "F1AP_DRBs-ToBeSetupMod-List.h" +#include "F1AP_GNBDUConfigurationUpdate.h" +#include "F1AP_DRBs-ToBeSetup-Item.h" +#include "F1AP_UnsuccessfulOutcome.h" +#include "F1AP_SRBs-FailedToBeSetupMod-List.h" +#include "F1AP_SCell-ToBeRemoved-Item.h" +#include "F1AP_InactivityMonitoringRequest.h" +#include "F1AP_Cells-Failed-to-be-Activated-List-Item.h" +#include "F1AP_DRBs-Modified-Item.h" +#include "F1AP_SRBs-Required-ToBeReleased-List.h" +#include "F1AP_GBR-QosInformation.h" +#include "F1AP_SCell-ToBeRemoved-List.h" +#include "F1AP_RANAC.h" +#include "F1AP_GNB-DU-UE-F1AP-ID.h" +#include "F1AP_CauseRadioNetwork.h" +#include "F1AP_DRB-Notify-Item.h" +#include "F1AP_GNBDUConfigurationUpdateAcknowledge.h" +#include "F1AP_GNB-CUSystemInformation.h" +#include "F1AP_ProtocolIE-Field.h" +#include "F1AP_Served-Cells-To-Modify-Item.h" +#include "F1AP_Flows-Mapped-To-DRB-Item.h" +#include "F1AP_SupportedSULFreqBandItem.h" +#include "F1AP_UEContextReleaseRequest.h" +#include "F1AP_GNB-DU-Name.h" +#include "F1AP_DRBs-ToBeModified-Item.h" +#include "F1AP_SIBtype-List.h" +#include "F1AP_EUTRA-NR-CellResourceCoordinationReq-Container.h" +#include "F1AP_DRBs-SetupMod-List.h" +#include "F1AP_DRBs-Required-ToBeModified-List.h" +#include "F1AP_DUtoCURRCInformation.h" +#include "F1AP_MaxPacketLossRate.h" +#include "F1AP_PacketDelayBudget.h" +#include "F1AP_GNBCUConfigurationUpdate.h" +#include "F1AP_Cells-Broadcast-Completed-Item.h" +#include "F1AP_RRCRconfigurationCompleteIndicator.h" +#include "F1AP_PagingPriority.h" +#include "F1AP_Cells-Failed-to-be-Activated-List.h" +#include "F1AP_Endpoint-IP-address-and-port.h" +#include "F1AP_PacketErrorRate.h" +#include "F1AP_PLMN-Identity.h" +#include "F1AP_asn_constant.h" +#include "F1AP_ResetType.h" +#include "F1AP_FDD-Info.h" +#include "F1AP_DLUPTNLInformation-ToBeSetup-List.h" +#include "F1AP_QoSFlowIndicator.h" +#include "F1AP_NR-CGI-List-For-Restart-List.h" +#include "F1AP_F1SetupResponse.h" +#include "F1AP_UEContextSetupResponse.h" +#include "F1AP_CP-TransportLayerAddress.h" +#include "F1AP_Broadcast-To-Be-Cancelled-Item.h" +#include "F1AP_ErrorIndication.h" +#include "F1AP_SubscriberProfileIDforRFP.h" +#include "F1AP_SNSSAI.h" +#include "F1AP_DRBs-ModifiedConf-Item.h" +#include "F1AP_GNB-CU-TNL-Association-Setup-List.h" +#include "F1AP_DRB-Activity-Item.h" +#include "F1AP_LCID.h" +#include "F1AP_ULConfiguration.h" +#include "F1AP_ShortDRXCycleTimer.h" +#include "F1AP_FreqBandNrItem.h" +#include "F1AP_Cells-to-be-Barred-List.h" +#include "F1AP_Presence.h" +#include "F1AP_CellBarred.h" +#include "F1AP_SIBtype.h" +#include "F1AP_RequestType.h" +#include "F1AP_NRFreqInfo.h" +#include "F1AP_Potential-SpCell-Item.h" +#include "F1AP_NumberofBroadcastRequest.h" +#include "F1AP_TNLAssociationUsage.h" +#include "F1AP_SCell-ToBeSetupMod-List.h" +#include "F1AP_DRBs-Setup-List.h" +#include "F1AP_Reset.h" +#include "F1AP_CriticalityDiagnostics.h" +#include "F1AP_Paging.h" +#include "F1AP_LongDRXCycleLength.h" +#include "F1AP_GNB-DU-ID.h" +#include "F1AP_SuccessfulOutcome.h" +#include "F1AP_Configured-EPS-TAC.h" +#include "F1AP_Candidate-SpCell-List.h" +#include "F1AP_SRBs-ToBeReleased-Item.h" +#include "F1AP_QoSInformation.h" +#include "F1AP_SCell-ToBeSetup-Item.h" +#include "F1AP_SRBs-ToBeSetup-Item.h" +#include "F1AP_GBR-QoSFlowInformation.h" +#include "F1AP_SCellIndex.h" +#include "F1AP_DRBs-SetupMod-Item.h" +#include "F1AP_TransmissionStopIndicator.h" +#include "F1AP_UEContextSetupFailure.h" +#include "F1AP_DRBs-FailedToBeModified-List.h" +#include "F1AP_DRBs-FailedToBeSetupMod-Item.h" +#include "F1AP_ProtocolExtensionID.h" +#include "F1AP_Cells-To-Be-Broadcast-Item.h" +#include "F1AP_QCI.h" + +#include "conversions.h" +#include "platform_types.h" +#include "common/utils/LOG/log.h" +#include "intertask_interface.h" +#include "sctp_messages_types.h" +#include "f1ap_messages_types.h" +#include <arpa/inet.h> +#include "T.h" +#include "common/ran_context.h" +#include "msc.h" + +/* Checking version of ASN1C compiler */ +#if (ASN1C_ENVIRONMENT_VERSION < ASN1C_MINIMUM_VERSION) +# error "You are compiling f1ap with the wrong version of ASN1C" +#endif + +#ifndef FALSE +# define FALSE (0) +#endif +#ifndef TRUE +# define TRUE (!FALSE) +#endif + +#define F1AP_UE_ID_FMT "0x%06"PRIX32 + +#include "assertions.h" + +#if defined(ENB_MODE) +# include "common/utils/LOG/log.h" +# include "f1ap_default_values.h" +# define F1AP_ERROR(x, args...) LOG_E(F1AP, x, ##args) +# define F1AP_WARN(x, args...) LOG_W(F1AP, x, ##args) +# define F1AP_TRAF(x, args...) LOG_I(F1AP, x, ##args) +# define F1AP_INFO(x, args...) LOG_I(F1AP, x, ##args) +# define F1AP_DEBUG(x, args...) LOG_I(F1AP, x, ##args) +#else +//# include "mme_default_values.h" +# define F1AP_ERROR(x, args...) do { fprintf(stdout, "[F1AP][E]"x, ##args); } while(0) +# define F1AP_WARN(x, args...) do { fprintf(stdout, "[F1AP][W]"x, ##args); } while(0) +# define F1AP_TRAF(x, args...) do { fprintf(stdout, "[F1AP][T]"x, ##args); } while(0) +# define F1AP_INFO(x, args...) do { fprintf(stdout, "[F1AP][I]"x, ##args); } while(0) +# define F1AP_DEBUG(x, args...) do { fprintf(stdout, "[F1AP][D]"x, ##args); } while(0) +#endif + +//Forward declaration +#define F1AP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \ + do {\ + IE_TYPE **ptr; \ + ie = NULL; \ + for (ptr = container->protocolIEs.list.array; \ + ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \ + ptr++) { \ + if((*ptr)->id == IE_ID) { \ + ie = *ptr; \ + break; \ + } \ + } \ + if (mandatory) DevAssert(ie != NULL); \ + } while(0) + +/** \brief Function callback prototype. + **/ +typedef int (*f1ap_message_decoded_callback)( + instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *message_p +); + +typedef struct f1ap_cudu_ue_inst_s { + // used for eNB stats generation + rnti_t rnti; + module_id_t f1ap_uid; + module_id_t mac_uid; + module_id_t du_ue_f1ap_id; + module_id_t cu_ue_f1ap_id; +} f1ap_cudu_ue_t; + +typedef struct f1ap_cudu_inst_s { + uint16_t num_ues; + f1ap_cudu_ue_t f1ap_ue[MAX_MOBILES_PER_ENB]; +} f1ap_cudu_inst_t; + + + +uint8_t F1AP_get_next_transaction_identifier(module_id_t enb_mod_idP, module_id_t cu_mod_idP); + + +int f1ap_add_ue(f1ap_cudu_inst_t *f1_inst, + module_id_t module_idP, + int CC_idP, + int UE_id, + rnti_t rntiP); + +int f1ap_remove_ue(f1ap_cudu_inst_t *f1_inst, + rnti_t rntiP); + +int f1ap_get_du_ue_f1ap_id (f1ap_cudu_inst_t *f1_inst, + rnti_t rntiP); + +int f1ap_get_cu_ue_f1ap_id (f1ap_cudu_inst_t *f1_inst, + rnti_t rntiP); + + +int f1ap_get_rnti_by_du_id(f1ap_cudu_inst_t *f1_inst, + module_id_t du_ue_f1ap_id ); + + +int f1ap_get_rnti_by_cu_id(f1ap_cudu_inst_t *f1_inst, + module_id_t cu_ue_f1ap_id ); + + +int f1ap_get_du_uid(f1ap_cudu_inst_t *f1_inst, + module_id_t du_ue_f1ap_id ); + +int f1ap_get_cu_uid(f1ap_cudu_inst_t *f1_inst, + module_id_t cu_ue_f1ap_id ); + +int f1ap_get_uid_by_rnti(f1ap_cudu_inst_t *f1_inst, + rnti_t rntiP ); + +int f1ap_du_add_cu_ue_id(f1ap_cudu_inst_t *f1_inst, + module_id_t du_ue_f1ap_id, + module_id_t cu_ue_f1ap_id); + +int f1ap_cu_add_du_ue_id(f1ap_cudu_inst_t *f1_inst, + module_id_t cu_ue_f1ap_id, + module_id_t du_ue_f1ap_id); + +#endif /* F1AP_COMMON_H_ */ diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c new file mode 100644 index 0000000000000000000000000000000000000000..b451a0145769111bec434951ef44d1989887b7a7 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -0,0 +1,905 @@ +/* + * 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 f1ap_cu_interface_management.c + * \brief f1ap interface management for CU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#include "f1ap_common.h" +#include "f1ap_encoder.h" +#include "f1ap_decoder.h" +#include "f1ap_itti_messaging.h" +#include "f1ap_cu_interface_management.h" + +extern f1ap_setup_req_t *f1ap_du_data_from_du; + +int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_send_RESET_ACKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + +/* + Error Indication +*/ +int CU_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_send_ERROR_INDICATION(instance_t instance, F1AP_ErrorIndication_t *ErrorIndication) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + +/* + F1 Setup +*/ +int CU_handle_F1_SETUP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) +{ + LOG_D(F1AP, "CU_handle_F1_SETUP_REQUEST\n"); + + MessageDef *message_p; + F1AP_F1SetupRequest_t *container; + F1AP_F1SetupRequestIEs_t *ie; + int i = 0; + + + DevAssert(pdu != NULL); + + container = &pdu->choice.initiatingMessage->value.choice.F1SetupRequest; + + /* F1 Setup Request == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + LOG_W(F1AP, "[SCTP %d] Received f1 setup request on stream != 0 (%d)\n", + assoc_id, stream); + } + + message_p = itti_alloc_new_message(TASK_RRC_ENB, F1AP_SETUP_REQ); + + /* assoc_id */ + F1AP_SETUP_REQ(message_p).assoc_id = assoc_id; + + /* gNB_DU_id */ + // this function exits if the ie is mandatory + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_ID, true); + asn_INTEGER2ulong(&ie->value.choice.GNB_DU_ID, &F1AP_SETUP_REQ(message_p).gNB_DU_id); + LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).gNB_DU_id %lu \n", F1AP_SETUP_REQ(message_p).gNB_DU_id); + + /* gNB_DU_name */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_Name, true); + F1AP_SETUP_REQ(message_p).gNB_DU_name = calloc(ie->value.choice.GNB_DU_Name.size + 1, sizeof(char)); + memcpy(F1AP_SETUP_REQ(message_p).gNB_DU_name, ie->value.choice.GNB_DU_Name.buf, + ie->value.choice.GNB_DU_Name.size); + /* Convert the mme name to a printable string */ + F1AP_SETUP_REQ(message_p).gNB_DU_name[ie->value.choice.GNB_DU_Name.size] = '\0'; + LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).gNB_DU_name %s \n", F1AP_SETUP_REQ(message_p).gNB_DU_name); + + /* GNB_DU_Served_Cells_List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_F1SetupRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List, true); + F1AP_SETUP_REQ(message_p).num_cells_available = ie->value.choice.GNB_DU_Served_Cells_List.list.count; + LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).num_cells_available %d \n", + F1AP_SETUP_REQ(message_p).num_cells_available); + + int num_cells_available = F1AP_SETUP_REQ(message_p).num_cells_available; + + for (i=0; i<num_cells_available; i++) { + F1AP_GNB_DU_Served_Cells_Item_t *served_celles_item_p; + + served_celles_item_p = &(((F1AP_GNB_DU_Served_Cells_ItemIEs_t *)ie->value.choice.GNB_DU_Served_Cells_List.list.array[i])->value.choice.GNB_DU_Served_Cells_Item); + + /* tac */ + OCTET_STRING_TO_INT16(&(served_celles_item_p->served_Cell_Information.fiveGS_TAC), F1AP_SETUP_REQ(message_p).tac[i]); + LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).tac[%d] %d \n", + i, F1AP_SETUP_REQ(message_p).tac[i]); + + /* - nRCGI */ + TBCD_TO_MCC_MNC(&(served_celles_item_p->served_Cell_Information.nRCGI.pLMN_Identity), F1AP_SETUP_REQ(message_p).mcc[i], + F1AP_SETUP_REQ(message_p).mnc[i], + F1AP_SETUP_REQ(message_p).mnc_digit_length[i]); + + + // NR cellID + BIT_STRING_TO_NR_CELL_IDENTITY(&served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity, + F1AP_SETUP_REQ(message_p).nr_cellid[i]); + LOG_D(F1AP, "[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu\n", assoc_id, + F1AP_SETUP_REQ(message_p).mcc[i], + F1AP_SETUP_REQ(message_p).mnc[i], + (long long unsigned int)F1AP_SETUP_REQ(message_p).nr_cellid[i]); + LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n", + served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[0], + served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[1], + served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[2], + served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[3], + served_celles_item_p->served_Cell_Information.nRCGI.nRCellIdentity.buf[4]); + /* - nRPCI */ + F1AP_SETUP_REQ(message_p).nr_pci[i] = served_celles_item_p->served_Cell_Information.nRPCI; + LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).nr_pci[%d] %d \n", + i, F1AP_SETUP_REQ(message_p).nr_pci[i]); + + // System Information + /* mib */ + F1AP_SETUP_REQ(message_p).mib[i] = calloc(served_celles_item_p->gNB_DU_System_Information->mIB_message.size + 1, sizeof(char)); + memcpy(F1AP_SETUP_REQ(message_p).mib[i], served_celles_item_p->gNB_DU_System_Information->mIB_message.buf, + served_celles_item_p->gNB_DU_System_Information->mIB_message.size); + /* Convert the mme name to a printable string */ + F1AP_SETUP_REQ(message_p).mib[i][served_celles_item_p->gNB_DU_System_Information->mIB_message.size] = '\0'; + F1AP_SETUP_REQ(message_p).mib_length[i] = served_celles_item_p->gNB_DU_System_Information->mIB_message.size; + LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).mib[%d] %s , len = %d \n", + i, F1AP_SETUP_REQ(message_p).mib[i], F1AP_SETUP_REQ(message_p).mib_length[i]); + + /* sib1 */ + F1AP_SETUP_REQ(message_p).sib1[i] = calloc(served_celles_item_p->gNB_DU_System_Information->sIB1_message.size + 1, sizeof(char)); + memcpy(F1AP_SETUP_REQ(message_p).sib1[i], served_celles_item_p->gNB_DU_System_Information->sIB1_message.buf, + served_celles_item_p->gNB_DU_System_Information->sIB1_message.size); + /* Convert the mme name to a printable string */ + F1AP_SETUP_REQ(message_p).sib1[i][served_celles_item_p->gNB_DU_System_Information->sIB1_message.size] = '\0'; + F1AP_SETUP_REQ(message_p).sib1_length[i] = served_celles_item_p->gNB_DU_System_Information->sIB1_message.size; + LOG_D(F1AP, "F1AP_SETUP_REQ(message_p).sib1[%d] %s , len = %d \n", + i, F1AP_SETUP_REQ(message_p).sib1[i], F1AP_SETUP_REQ(message_p).sib1_length[i]); + } + + + *f1ap_du_data_from_du = F1AP_SETUP_REQ(message_p); + // char *measurement_timing_information[F1AP_MAX_NB_CELLS]; + // uint8_t ranac[F1AP_MAX_NB_CELLS]; + + // int fdd_flag = f1ap_setup_req->fdd_flag; + + // union { + // struct { + // uint32_t ul_nr_arfcn; + // uint8_t ul_scs; + // uint8_t ul_nrb; + + // uint32_t dl_nr_arfcn; + // uint8_t dl_scs; + // uint8_t dl_nrb; + + // uint32_t sul_active; + // uint32_t sul_nr_arfcn; + // uint8_t sul_scs; + // uint8_t sul_nrb; + + // uint8_t num_frequency_bands; + // uint16_t nr_band[32]; + // uint8_t num_sul_frequency_bands; + // uint16_t nr_sul_band[32]; + // } fdd; + // struct { + + // uint32_t nr_arfcn; + // uint8_t scs; + // uint8_t nrb; + + // uint32_t sul_active; + // uint32_t sul_nr_arfcn; + // uint8_t sul_scs; + // uint8_t sul_nrb; + + // uint8_t num_frequency_bands; + // uint16_t nr_band[32]; + // uint8_t num_sul_frequency_bands; + // uint16_t nr_sul_band[32]; + + // } tdd; + // } nr_mode_info[F1AP_MAX_NB_CELLS]; + + MSC_LOG_TX_MESSAGE( + MSC_F1AP_CU, + MSC_RRC_ENB, + 0, + 0, + MSC_AS_TIME_FMT" CU_handle_F1_SETUP_REQUEST", + 0,0//MSC_AS_TIME_ARGS(ctxt_pP), + ); + + if (num_cells_available > 0) { + itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); + } else { + CU_send_F1_SETUP_FAILURE(instance); + return -1; + } + return 0; +} + +int CU_send_F1_SETUP_RESPONSE(instance_t instance, + f1ap_setup_resp_t *f1ap_setup_resp) { + + module_id_t enb_mod_idP; + module_id_t cu_mod_idP; + + // This should be fixed + enb_mod_idP = (module_id_t)0; + cu_mod_idP = (module_id_t)0; + + F1AP_F1AP_PDU_t pdu; + F1AP_F1SetupResponse_t *out; + F1AP_F1SetupResponseIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome = (F1AP_SuccessfulOutcome_t *)calloc(1, sizeof(F1AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome->procedureCode = F1AP_ProcedureCode_id_F1Setup; + pdu.choice.successfulOutcome->criticality = F1AP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = F1AP_SuccessfulOutcome__value_PR_F1SetupResponse; + out = &pdu.choice.successfulOutcome->value.choice.F1SetupResponse; + + /* mandatory */ + /* c1. Transaction ID (integer value)*/ + ie = (F1AP_F1SetupResponseIEs_t *)calloc(1, sizeof(F1AP_F1SetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_F1SetupResponseIEs__value_PR_TransactionID; + ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(enb_mod_idP, cu_mod_idP); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c2. GNB_CU_Name */ + if (f1ap_setup_resp->gNB_CU_name != NULL) { + ie = (F1AP_F1SetupResponseIEs_t *)calloc(1, sizeof(F1AP_F1SetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_Name; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name; + OCTET_STRING_fromBuf(&ie->value.choice.GNB_CU_Name, f1ap_setup_resp->gNB_CU_name, + strlen(f1ap_setup_resp->gNB_CU_name)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c3. cells to be Activated list */ + ie = (F1AP_F1SetupResponseIEs_t *)calloc(1, sizeof(F1AP_F1SetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List; + + int num_cells_to_activate = f1ap_setup_resp->num_cells_to_activate; + LOG_D(F1AP, "num_cells_to_activate = %d \n", num_cells_to_activate); + for (i=0; + i<num_cells_to_activate; + i++) { + + F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies; + cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemIEs_t)); + cells_to_be_activated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; + cells_to_be_activated_list_item_ies->criticality = F1AP_Criticality_reject; + cells_to_be_activated_list_item_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item; + + /* 3.1 cells to be Activated list item */ + F1AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item; + memset((void *)&cells_to_be_activated_list_item, 0, sizeof(F1AP_Cells_to_be_Activated_List_Item_t)); + + /* - nRCGI */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(f1ap_setup_resp->mcc[i], f1ap_setup_resp->mnc[i], f1ap_setup_resp->mnc_digit_length[i], + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(f1ap_setup_resp->nr_cellid[i], &nRCGI.nRCellIdentity); + cells_to_be_activated_list_item.nRCGI = nRCGI; + + /* optional */ + /* - nRPCI */ + if (1) { + cells_to_be_activated_list_item.nRPCI = (F1AP_NRPCI_t *)calloc(1, sizeof(F1AP_NRPCI_t)); + *cells_to_be_activated_list_item.nRPCI = f1ap_setup_resp->nrpci[i]; // int 0..1007 + } + + /* optional */ + /* - gNB-CU System Information */ + if (1) { + /* 3.1.2 gNB-CUSystem Information */ + F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *cells_to_be_activated_list_itemExtIEs; + cells_to_be_activated_list_itemExtIEs = (F1AP_Cells_to_be_Activated_List_ItemExtIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemExtIEs_t)); + cells_to_be_activated_list_itemExtIEs->id = F1AP_ProtocolIE_ID_id_gNB_CUSystemInformation; + cells_to_be_activated_list_itemExtIEs->criticality = F1AP_Criticality_reject; + cells_to_be_activated_list_itemExtIEs->extensionValue.present = F1AP_Cells_to_be_Activated_List_ItemExtIEs__extensionValue_PR_GNB_CUSystemInformation; + + F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation = (F1AP_GNB_CUSystemInformation_t *)calloc(1, sizeof(F1AP_GNB_CUSystemInformation_t)); + //LOG_I(F1AP, "%s() SI %d size %d: ", __func__, i, f1ap_setup_resp->SI_container_length[i][0]); + //for (int n = 0; n < f1ap_setup_resp->SI_container_length[i][0]; n++) + // printf("%02x ", f1ap_setup_resp->SI_container[i][0][n]); + //printf("\n"); + OCTET_STRING_fromBuf(&gNB_CUSystemInformation->sImessage, + (const char*)f1ap_setup_resp->SI_container[i][0], + f1ap_setup_resp->SI_container_length[i][0]); + + LOG_D(F1AP, "f1ap_setup_resp->SI_container_length = %d \n", f1ap_setup_resp->SI_container_length[0][0]); + cells_to_be_activated_list_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation = *gNB_CUSystemInformation; + + + F1AP_ProtocolExtensionContainer_160P9_t p_160P9_t; + memset((void *)&p_160P9_t, 0, sizeof(F1AP_ProtocolExtensionContainer_160P9_t)); + + ASN_SEQUENCE_ADD(&p_160P9_t.list, + cells_to_be_activated_list_itemExtIEs); + cells_to_be_activated_list_item.iE_Extensions = (struct F1AP_ProtocolExtensionContainer*)&p_160P9_t; + + } + /* ADD */ + cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item; + ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list, + cells_to_be_activated_list_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + cu_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data_from_du->assoc_id, buffer, len, 0); + + return 0; +} + +int CU_send_F1_SETUP_FAILURE(instance_t instance) { + LOG_D(F1AP, "CU_send_F1_SETUP_FAILURE\n"); + + module_id_t enb_mod_idP; + module_id_t cu_mod_idP; + + // This should be fixed + enb_mod_idP = (module_id_t)0; + cu_mod_idP = (module_id_t)0; + + F1AP_F1AP_PDU_t pdu; + F1AP_F1SetupFailure_t *out; + F1AP_F1SetupFailureIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_unsuccessfulOutcome; + pdu.choice.unsuccessfulOutcome = (F1AP_UnsuccessfulOutcome_t *)calloc(1, sizeof(F1AP_UnsuccessfulOutcome_t)); + pdu.choice.unsuccessfulOutcome->procedureCode = F1AP_ProcedureCode_id_F1Setup; + pdu.choice.unsuccessfulOutcome->criticality = F1AP_Criticality_reject; + pdu.choice.unsuccessfulOutcome->value.present = F1AP_UnsuccessfulOutcome__value_PR_F1SetupFailure; + out = &pdu.choice.unsuccessfulOutcome->value.choice.F1SetupFailure; + + /* mandatory */ + /* c1. Transaction ID (integer value)*/ + ie = (F1AP_F1SetupFailureIEs_t *)calloc(1, sizeof(F1AP_F1SetupFailureIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_F1SetupFailureIEs__value_PR_TransactionID; + ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(enb_mod_idP, cu_mod_idP); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. Cause */ + ie = (F1AP_F1SetupFailureIEs_t *)calloc(1, sizeof(F1AP_F1SetupFailureIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Cause; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_F1SetupFailureIEs__value_PR_Cause; + ie->value.choice.Cause.present = F1AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c3. TimeToWait */ + if (0) { + ie = (F1AP_F1SetupFailureIEs_t *)calloc(1, sizeof(F1AP_F1SetupFailureIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_TimeToWait; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_F1SetupFailureIEs__value_PR_TimeToWait; + ie->value.choice.TimeToWait = F1AP_TimeToWait_v10s; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c4. CriticalityDiagnostics*/ + if (0) { + ie = (F1AP_F1SetupFailureIEs_t *)calloc(1, sizeof(F1AP_F1SetupFailureIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_F1SetupFailureIEs__value_PR_CriticalityDiagnostics; + ie->value.choice.CriticalityDiagnostics.procedureCode = (F1AP_ProcedureCode_t *)calloc(1, sizeof(F1AP_ProcedureCode_t)); + *ie->value.choice.CriticalityDiagnostics.procedureCode = F1AP_ProcedureCode_id_UEContextSetup; + ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)calloc(1, sizeof(F1AP_TriggeringMessage_t)); + *ie->value.choice.CriticalityDiagnostics.triggeringMessage = F1AP_TriggeringMessage_initiating_message; + ie->value.choice.CriticalityDiagnostics.procedureCriticality = (F1AP_Criticality_t *)calloc(1, sizeof(F1AP_Criticality_t)); + *ie->value.choice.CriticalityDiagnostics.procedureCriticality = F1AP_Criticality_reject; + ie->value.choice.CriticalityDiagnostics.transactionID = (F1AP_TransactionID_t *)calloc(1, sizeof(F1AP_TransactionID_t)); + *ie->value.choice.CriticalityDiagnostics.transactionID = 0; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + cu_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data_from_du->assoc_id, buffer, len, 0); + + return 0; +} + + + +/* + gNB-DU Configuration Update +*/ + +int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, + F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + + +/* + gNB-CU Configuration Update +*/ + +//void CU_send_gNB_CU_CONFIGURATION_UPDATE(F1AP_GNBCUConfigurationUpdate_t *GNBCUConfigurationUpdate) { +int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP) { + F1AP_F1AP_PDU_t pdu; + F1AP_GNBCUConfigurationUpdate_t *out; + F1AP_GNBCUConfigurationUpdateIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0; + + // for test + int mcc = 208; + int mnc = 93; + int mnc_digit_length = 8; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_gNBCUConfigurationUpdate; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_GNBCUConfigurationUpdate; + out = &pdu.choice.initiatingMessage->value.choice.GNBCUConfigurationUpdate; + + /* mandatory */ + /* c1. Transaction ID (integer value) */ + ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_TransactionID; + ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(instance, du_mod_idP); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + + /* mandatory */ + /* c2. Cells_to_be_Activated_List */ + ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Activated_List; + + for (i=0; + i<1; + i++) { + + F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies; + cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Activated_List_ItemIEs_t)); + cells_to_be_activated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; + cells_to_be_activated_list_item_ies->criticality = F1AP_Criticality_reject; + cells_to_be_activated_list_item_ies->value.present = F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item; + + /* 2.1 cells to be Activated list item */ + F1AP_Cells_to_be_Activated_List_Item_t cells_to_be_activated_list_item; + memset((void *)&cells_to_be_activated_list_item, 0, sizeof(F1AP_Cells_to_be_Activated_List_Item_t)); + + /* - nRCGI */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length, + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity); + cells_to_be_activated_list_item.nRCGI = nRCGI; + + /* optional */ + /* - nRPCI */ + if (0) { + cells_to_be_activated_list_item.nRPCI = (F1AP_NRPCI_t *)calloc(1, sizeof(F1AP_NRPCI_t)); + *cells_to_be_activated_list_item.nRPCI = 321L; // int 0..1007 + } + + /* optional */ + /* - gNB-CU System Information */ + //if (1) { + + //} + /* ADD */ + cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item = cells_to_be_activated_list_item; + ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Activated_List.list, + cells_to_be_activated_list_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + + /* mandatory */ + /* c3. Cells_to_be_Deactivated_List */ + ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Deactivated_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Deactivated_List; + + for (i=0; + i<1; + i++) { + + F1AP_Cells_to_be_Deactivated_List_ItemIEs_t *cells_to_be_deactivated_list_item_ies; + cells_to_be_deactivated_list_item_ies = (F1AP_Cells_to_be_Deactivated_List_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Deactivated_List_ItemIEs_t)); + cells_to_be_deactivated_list_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; + cells_to_be_deactivated_list_item_ies->criticality = F1AP_Criticality_reject; + cells_to_be_deactivated_list_item_ies->value.present = F1AP_Cells_to_be_Deactivated_List_ItemIEs__value_PR_Cells_to_be_Deactivated_List_Item; + + /* 3.1 cells to be Deactivated list item */ + F1AP_Cells_to_be_Deactivated_List_Item_t cells_to_be_deactivated_list_item; + memset((void *)&cells_to_be_deactivated_list_item, 0, sizeof(F1AP_Cells_to_be_Deactivated_List_Item_t)); + + /* - nRCGI */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length, + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity); + cells_to_be_deactivated_list_item.nRCGI = nRCGI; + + //} + /* ADD */ + cells_to_be_deactivated_list_item_ies->value.choice.Cells_to_be_Deactivated_List_Item = cells_to_be_deactivated_list_item; + ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Deactivated_List.list, + cells_to_be_deactivated_list_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c4. GNB_CU_TNL_Association_To_Add_List */ + ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Add_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Add_List; + + for (i=0; + i<1; + i++) { + + F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t *gnb_cu_tnl_association_to_add_item_ies; + gnb_cu_tnl_association_to_add_item_ies = (F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs_t)); + gnb_cu_tnl_association_to_add_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Add_Item; + gnb_cu_tnl_association_to_add_item_ies->criticality = F1AP_Criticality_reject; + gnb_cu_tnl_association_to_add_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Add_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Add_Item; + + /* 4.1 GNB_CU_TNL_Association_To_Add_Item */ + F1AP_GNB_CU_TNL_Association_To_Add_Item_t gnb_cu_tnl_association_to_add_item; + memset((void *)&gnb_cu_tnl_association_to_add_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Add_Item_t)); + + + /* 4.1.1 tNLAssociationTransportLayerAddress */ + F1AP_CP_TransportLayerAddress_t transportLayerAddress; + memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t)); + transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address; + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address); + + // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t)); + // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port; + // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t)); + // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address); + + gnb_cu_tnl_association_to_add_item.tNLAssociationTransportLayerAddress = transportLayerAddress; + + /* 4.1.2 tNLAssociationUsage */ + gnb_cu_tnl_association_to_add_item.tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue; + + + /* ADD */ + gnb_cu_tnl_association_to_add_item_ies->value.choice.GNB_CU_TNL_Association_To_Add_Item = gnb_cu_tnl_association_to_add_item; + ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Add_List.list, + gnb_cu_tnl_association_to_add_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + + /* mandatory */ + /* c5. GNB_CU_TNL_Association_To_Remove_List */ + ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Remove_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Remove_List; + for (i=0; + i<1; + i++) { + + F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t *gnb_cu_tnl_association_to_remove_item_ies; + gnb_cu_tnl_association_to_remove_item_ies = (F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs_t)); + gnb_cu_tnl_association_to_remove_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Remove_Item; + gnb_cu_tnl_association_to_remove_item_ies->criticality = F1AP_Criticality_reject; + gnb_cu_tnl_association_to_remove_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Remove_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Remove_Item; + + /* 4.1 GNB_CU_TNL_Association_To_Remove_Item */ + F1AP_GNB_CU_TNL_Association_To_Remove_Item_t gnb_cu_tnl_association_to_remove_item; + memset((void *)&gnb_cu_tnl_association_to_remove_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Remove_Item_t)); + + + /* 4.1.1 tNLAssociationTransportLayerAddress */ + F1AP_CP_TransportLayerAddress_t transportLayerAddress; + memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t)); + transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address; + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address); + + // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t)); + // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port; + // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t)); + // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address); + + gnb_cu_tnl_association_to_remove_item.tNLAssociationTransportLayerAddress = transportLayerAddress; + + + /* ADD */ + gnb_cu_tnl_association_to_remove_item_ies->value.choice.GNB_CU_TNL_Association_To_Remove_Item = gnb_cu_tnl_association_to_remove_item; + ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Remove_List.list, + gnb_cu_tnl_association_to_remove_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c6. GNB_CU_TNL_Association_To_Update_List */ + ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Update_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_GNB_CU_TNL_Association_To_Update_List; + for (i=0; + i<1; + i++) { + + F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t *gnb_cu_tnl_association_to_update_item_ies; + gnb_cu_tnl_association_to_update_item_ies = (F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs_t)); + gnb_cu_tnl_association_to_update_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_CU_TNL_Association_To_Update_Item; + gnb_cu_tnl_association_to_update_item_ies->criticality = F1AP_Criticality_reject; + gnb_cu_tnl_association_to_update_item_ies->value.present = F1AP_GNB_CU_TNL_Association_To_Update_ItemIEs__value_PR_GNB_CU_TNL_Association_To_Update_Item; + + /* 4.1 GNB_CU_TNL_Association_To_Update_Item */ + F1AP_GNB_CU_TNL_Association_To_Update_Item_t gnb_cu_tnl_association_to_update_item; + memset((void *)&gnb_cu_tnl_association_to_update_item, 0, sizeof(F1AP_GNB_CU_TNL_Association_To_Update_Item_t)); + + + /* 4.1.1 tNLAssociationTransportLayerAddress */ + F1AP_CP_TransportLayerAddress_t transportLayerAddress; + memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t)); + transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address; + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address); + + // memset((void *)&transportLayerAddress, 0, sizeof(F1AP_CP_TransportLayerAddress_t)); + // transportLayerAddress.present = F1AP_CP_TransportLayerAddress_PR_endpoint_IP_address_and_port; + // transportLayerAddress.choice.endpoint_IP_address_and_port = (F1AP_Endpoint_IP_address_and_port_t *)calloc(1, sizeof(F1AP_Endpoint_IP_address_and_port_t)); + // TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &transportLayerAddress.choice.endpoint_IP_address_and_port.endpoint_IP_address); + + gnb_cu_tnl_association_to_update_item.tNLAssociationTransportLayerAddress = transportLayerAddress; + + + /* 4.1.2 tNLAssociationUsage */ + if (1) { + gnb_cu_tnl_association_to_update_item.tNLAssociationUsage = (F1AP_TNLAssociationUsage_t *)calloc(1, sizeof(F1AP_TNLAssociationUsage_t)); + *gnb_cu_tnl_association_to_update_item.tNLAssociationUsage = F1AP_TNLAssociationUsage_non_ue; + } + + /* ADD */ + gnb_cu_tnl_association_to_update_item_ies->value.choice.GNB_CU_TNL_Association_To_Update_Item = gnb_cu_tnl_association_to_update_item; + ASN_SEQUENCE_ADD(&ie->value.choice.GNB_CU_TNL_Association_To_Update_List.list, + gnb_cu_tnl_association_to_update_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + + /* mandatory */ + /* c7. Cells_to_be_Barred_List */ + ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Barred_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Cells_to_be_Barred_List; + for (i=0; + i<1; + i++) { + + F1AP_Cells_to_be_Barred_ItemIEs_t *cells_to_be_barred_item_ies; + cells_to_be_barred_item_ies = (F1AP_Cells_to_be_Barred_ItemIEs_t *)calloc(1, sizeof(F1AP_Cells_to_be_Barred_ItemIEs_t)); + cells_to_be_barred_item_ies->id = F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item; + cells_to_be_barred_item_ies->criticality = F1AP_Criticality_reject; + cells_to_be_barred_item_ies->value.present = F1AP_Cells_to_be_Barred_ItemIEs__value_PR_Cells_to_be_Barred_Item; + + /* 7.1 cells to be Deactivated list item */ + F1AP_Cells_to_be_Barred_Item_t cells_to_be_barred_item; + memset((void *)&cells_to_be_barred_item, 0, sizeof(F1AP_Cells_to_be_Barred_Item_t)); + + /* - nRCGI */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length, + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity); + cells_to_be_barred_item.nRCGI = nRCGI; + + /* 7.2 cellBarred*/ + cells_to_be_barred_item.cellBarred = F1AP_CellBarred_not_barred; + + /* ADD */ + cells_to_be_barred_item_ies->value.choice.Cells_to_be_Barred_Item = cells_to_be_barred_item; + ASN_SEQUENCE_ADD(&ie->value.choice.Cells_to_be_Barred_List.list, + cells_to_be_barred_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + + /* mandatory */ + /* c8. Protected_EUTRA_Resources_List */ + ie = (F1AP_GNBCUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBCUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBCUConfigurationUpdateIEs__value_PR_Protected_EUTRA_Resources_List; + + for (i=0; + i<1; + i++) { + + + F1AP_Protected_EUTRA_Resources_ItemIEs_t *protected_eutra_resources_item_ies; + + /* 8.1 SpectrumSharingGroupID */ + protected_eutra_resources_item_ies = (F1AP_Protected_EUTRA_Resources_ItemIEs_t *)calloc(1, sizeof(F1AP_Protected_EUTRA_Resources_ItemIEs_t)); + protected_eutra_resources_item_ies->id = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List; + protected_eutra_resources_item_ies->criticality = F1AP_Criticality_reject; + protected_eutra_resources_item_ies->value.present = F1AP_Protected_EUTRA_Resources_ItemIEs__value_PR_SpectrumSharingGroupID; + protected_eutra_resources_item_ies->value.choice.SpectrumSharingGroupID = 1L; + + ASN_SEQUENCE_ADD(&ie->value.choice.Protected_EUTRA_Resources_List.list, protected_eutra_resources_item_ies); + + /* 8.2 ListofEUTRACellsinGNBDUCoordination */ + protected_eutra_resources_item_ies = (F1AP_Protected_EUTRA_Resources_ItemIEs_t *)calloc(1, sizeof(F1AP_Protected_EUTRA_Resources_ItemIEs_t)); + protected_eutra_resources_item_ies->id = F1AP_ProtocolIE_ID_id_Protected_EUTRA_Resources_List; + protected_eutra_resources_item_ies->criticality = F1AP_Criticality_reject; + protected_eutra_resources_item_ies->value.present = F1AP_Protected_EUTRA_Resources_ItemIEs__value_PR_ListofEUTRACellsinGNBDUCoordination; + + F1AP_Served_EUTRA_Cells_Information_t served_eutra_cells_information; + memset((void *)&served_eutra_cells_information, 0, sizeof(F1AP_Served_EUTRA_Cells_Information_t)); + + F1AP_EUTRA_Mode_Info_t eUTRA_Mode_Info; + memset((void *)&eUTRA_Mode_Info, 0, sizeof(F1AP_EUTRA_Mode_Info_t)); + + // eUTRAFDD + eUTRA_Mode_Info.present = F1AP_EUTRA_Mode_Info_PR_eUTRAFDD; + F1AP_EUTRA_FDD_Info_t *eutra_fdd_info; + eutra_fdd_info = (F1AP_EUTRA_FDD_Info_t *)calloc(1, sizeof(F1AP_EUTRA_FDD_Info_t)); + eutra_fdd_info->uL_offsetToPointA = 123L; + eutra_fdd_info->dL_offsetToPointA = 456L; + eUTRA_Mode_Info.choice.eUTRAFDD = eutra_fdd_info; + + // eUTRATDD + // eUTRA_Mode_Info.present = F1AP_EUTRA_Mode_Info_PR_eUTRATDD; + // F1AP_EUTRA_TDD_Info_t *eutra_tdd_info; + // eutra_tdd_info = (F1AP_EUTRA_TDD_Info_t *)calloc(1, sizeof(F1AP_EUTRA_TDD_Info_t)); + // eutra_tdd_info->uL_offsetToPointA = 123L; + // eutra_tdd_info->dL_offsetToPointA = 456L; + // eUTRA_Mode_Info.choice.eUTRATDD = eutra_tdd_info; + + served_eutra_cells_information.eUTRA_Mode_Info = eUTRA_Mode_Info; + + OCTET_STRING_fromBuf(&served_eutra_cells_information.protectedEUTRAResourceIndication, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + + ASN_SEQUENCE_ADD(&protected_eutra_resources_item_ies->value.choice.ListofEUTRACellsinGNBDUCoordination.list, &served_eutra_cells_information); + + ASN_SEQUENCE_ADD(&ie->value.choice.Protected_EUTRA_Resources_List.list, protected_eutra_resources_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + cu_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data_from_du->assoc_id, buffer, len, 0); + return 0; +} + +int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + +int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(0, "Not implemented yet\n"); +} + +int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, + F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse) { + AssertFatal(0, "Not implemented yet\n"); +} diff --git a/openair2/F1AP/f1ap_cu_interface_management.h b/openair2/F1AP/f1ap_cu_interface_management.h new file mode 100644 index 0000000000000000000000000000000000000000..acad13836dea4e8043791945cb853fa3551d30ec --- /dev/null +++ b/openair2/F1AP/f1ap_cu_interface_management.h @@ -0,0 +1,111 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_cu_interface_management.h + * \brief f1ap interface management for CU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#ifndef F1AP_CU_INTERFACE_MANAGEMENT_H_ +#define F1AP_CU_INTERFACE_MANAGEMENT_H_ + +/* + * Reset + */ +int CU_send_RESET(instance_t instance, F1AP_Reset_t *Reset); +int CU_handle_RESET_ACKKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); +int CU_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); +int CU_send_RESET_ACKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge); + +/* + * Error Indication + */ +int CU_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); +int CU_send_ERROR_INDICATION(instance_t instance, F1AP_ErrorIndication_t *ErrorIndication); + +/* + * F1 Setup + */ +int CU_handle_F1_SETUP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +int CU_send_F1_SETUP_RESPONSE(instance_t instance, f1ap_setup_resp_t *f1ap_setup_resp); + +int CU_send_F1_SETUP_FAILURE(instance_t instance); + +/* + * gNB-DU Configuration Update + */ +int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +int CU_send_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, + F1AP_GNBDUConfigurationUpdateFailure_t *GNBDUConfigurationUpdateFailure); + +int CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + F1AP_GNBDUConfigurationUpdateAcknowledge_t *GNBDUConfigurationUpdateAcknowledge); + +/* + * gNB-CU Configuration Update + */ +int CU_send_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP); + +int CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +int CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +/* + * gNB-DU Resource Coordination + */ +int CU_handle_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +int CU_send_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, + F1AP_GNBDUResourceCoordinationResponse_t *GNBDUResourceCoordinationResponse); + +#endif /* F1AP_CU_INTERFACE_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/f1ap_cu_paging.c b/openair2/F1AP/f1ap_cu_paging.c new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_paging.c @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_cu_paging.h b/openair2/F1AP/f1ap_cu_paging.h new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_paging.h @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c new file mode 100644 index 0000000000000000000000000000000000000000..f32d5c8ed06b5717c6ea21c9772b5021901ba9e5 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -0,0 +1,388 @@ +/* + * 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 f1ap_cu_rrc_message_transfer.c + * \brief f1ap rrc message transfer for CU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#include "f1ap_common.h" +#include "f1ap_encoder.h" +#include "f1ap_decoder.h" +#include "f1ap_itti_messaging.h" +#include "f1ap_cu_rrc_message_transfer.h" +#include "common/ran_context.h" +#include "openair3/UTILS/conversions.h" + +// undefine C_RNTI from +// openair1/PHY/LTE_TRANSPORT/transport_common.h which +// replaces in ie->value.choice.C_RNTI, causing +// a compile error +#undef C_RNTI + + +// Bing Kai: create CU and DU context, and put all the information there. +uint64_t du_ue_f1ap_id = 0; +uint32_t f1ap_assoc_id = 0; +uint32_t f1ap_stream = 0; + + +extern f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB]; + +/* + Initial UL RRC Message Transfer +*/ + +extern RAN_CONTEXT_t RC; + +int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + + LOG_D(F1AP, "CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER\n"); + // decode the F1 message + // get the rrc message from the contauiner + // call func rrc_eNB_decode_ccch: <-- needs some update here + MessageDef *message_p; + F1AP_InitialULRRCMessageTransfer_t *container; + F1AP_InitialULRRCMessageTransferIEs_t *ie; + + rnti_t rnti; + sdu_size_t ccch_sdu_len; + int CC_id =0; + + + DevAssert(pdu != NULL); + + if (stream != 0) { + LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n", + assoc_id, stream); + return -1; + } + // TODO: use context + f1ap_stream = stream; + f1ap_assoc_id = assoc_id; + + container = &pdu->choice.initiatingMessage->value.choice.InitialULRRCMessageTransfer; + + /* GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + LOG_D(F1AP, "du_ue_f1ap_id %lu \n", du_ue_f1ap_id); + + /* NRCGI + * TODO: process NRCGI + */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_NRCGI, true); + + + uint64_t nr_cellid; + BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity,nr_cellid); + + /* RNTI */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_C_RNTI, true); + BUFFER_TO_INT16(ie->value.choice.C_RNTI.buf, rnti); + + /* RRC Container */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_RRCContainer, true); + + // create an ITTI message and copy SDU + message_p = itti_alloc_new_message (TASK_CU_F1, RRC_MAC_CCCH_DATA_IND); + memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + ccch_sdu_len = ie->value.choice.RRCContainer.size; + memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf, + ccch_sdu_len); + + //LOG_I(F1AP, "%s() RRCContainer (CCCH) size %ld: ", __func__, + // ie->value.choice.RRCContainer.size); + //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++) + // printf("%02x ", RRC_MAC_CCCH_DATA_IND (message_p).sdu[i]); + //printf("\n"); + + // Find instance from nr_cellid + int rrc_inst = -1; + for (int i=0;i<RC.nb_inst;i++) { + // first get RRC instance (note, no the ITTI instance) + eNB_RRC_INST *rrc = RC.rrc[i]; + if (rrc->nr_cellid == nr_cellid) { + rrc_inst = i; + break; + } + } + AssertFatal(rrc_inst>=0,"couldn't find an RRC instance for nr_cell %llu\n",(unsigned long long int)nr_cellid); + + int f1ap_uid = f1ap_add_ue(&f1ap_cu_inst[rrc_inst], rrc_inst, CC_id, 0, rnti); + if (f1ap_uid < 0 ) { + LOG_E(F1AP, "Failed to add UE \n"); + return -1; + } + f1ap_cu_inst[rrc_inst].f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id; + + + RRC_MAC_CCCH_DATA_IND (message_p).frame = 0; + RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0; + RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len; + RRC_MAC_CCCH_DATA_IND (message_p).enb_index = rrc_inst; // CU instance + RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; + RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id; + itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p); + + + return 0; +} + + +/* + DL RRC Message Transfer. +*/ + +//void CU_send_DL_RRC_MESSAGE_TRANSFER(F1AP_DLRRCMessageTransfer_t *DLRRCMessageTransfer) { +int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, + f1ap_dl_rrc_message_t *f1ap_dl_rrc) + { + + F1AP_F1AP_PDU_t pdu; + F1AP_DLRRCMessageTransfer_t *out; + F1AP_DLRRCMessageTransferIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_DLRRCMessageTransfer; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_DLRRCMessageTransfer; + out = &pdu.choice.initiatingMessage->value.choice.DLRRCMessageTransfer; + + /* mandatory */ + /* c1. GNB_CU_UE_F1AP_ID */ + + ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_cu_inst[instance], f1ap_dl_rrc->rnti); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + LOG_I(F1AP, "Setting GNB_CU_UE_F1AP_ID %llu associated with UE RNTI %x (instance %d)\n", + (unsigned long long int)ie->value.choice.GNB_CU_UE_F1AP_ID, f1ap_dl_rrc->rnti, instance); + + + /* mandatory */ + /* c2. GNB_DU_UE_F1AP_ID */ + ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_cu_inst[instance], f1ap_dl_rrc->rnti); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + LOG_I(F1AP, "GNB_DU_UE_F1AP_ID %llu associated with UE RNTI %x \n", (unsigned long long int)ie->value.choice.GNB_DU_UE_F1AP_ID, f1ap_dl_rrc->rnti); + + /* optional */ + /* c3. oldgNB_DU_UE_F1AP_ID */ + /* if (f1ap_dl_rrc->old_gNB_DU_ue_id != 0xFFFFFFFF) { + ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_NOTHING; + ie->value.choice.oldgNB_DU_UE_F1AP_ID = f1ap_dl_rrc->old_gNB_DU_ue_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + }*/ + + /* mandatory */ + /* c4. SRBID */ + ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SRBID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_SRBID; + ie->value.choice.SRBID = f1ap_dl_rrc->srb_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c5. ExecuteDuplication */ + if (f1ap_dl_rrc->execute_duplication) { + ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_ExecuteDuplication; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_ExecuteDuplication; + ie->value.choice.ExecuteDuplication = F1AP_ExecuteDuplication_true; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + // issue in here + /* mandatory */ + /* c6. RRCContainer */ + ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char*)f1ap_dl_rrc->rrc_container, f1ap_dl_rrc->rrc_container_length); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + //LOG_I(F1AP, "%s() RRCContainer size %d: ", __func__, f1ap_dl_rrc->rrc_container_length); + //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++) + // printf("%02x ", f1ap_dl_rrc->rrc_container[i]); + //printf("\n"); + + /* optional */ + /* c7. RAT_FrequencyPriorityInformation */ + /* TODO */ + if (0) { + ie = (F1AP_DLRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_DLRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_RAT_FrequencyPriorityInformation; + + ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_subscriberProfileIDforRFP; + ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP = 123L; + + //ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority; + //ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 123L; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + cu_f1ap_itti_send_sctp_data_req(instance, f1ap_assoc_id /* BK: fix me*/ , buffer, len, 0 /* BK: fix me*/); + + return 0; +} + +/* + UL RRC Message Transfer +*/ + +int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + + LOG_D(F1AP, "CU_handle_UL_RRC_MESSAGE_TRANSFER \n"); + + F1AP_ULRRCMessageTransfer_t *container; + F1AP_ULRRCMessageTransferIEs_t *ie; + + + uint64_t cu_ue_f1ap_id; + uint64_t du_ue_f1ap_id; + uint64_t srb_id; + + DevAssert(pdu != NULL); + + if (stream != 0) { + LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n", + assoc_id, stream); + return -1; + } + + container = &pdu->choice.initiatingMessage->value.choice.ULRRCMessageTransfer; + + + /* GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID; + LOG_D(F1AP, "cu_ue_f1ap_id %lu associated with RNTI %x\n", cu_ue_f1ap_id, f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], cu_ue_f1ap_id)); + + + /* GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + LOG_D(F1AP, "du_ue_f1ap_id %lu associated with RNTI %x\n", du_ue_f1ap_id, f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], du_ue_f1ap_id)); + + + /* mandatory */ + /* SRBID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_SRBID, true); + srb_id = ie->value.choice.SRBID; + if (srb_id < 1 ) + LOG_E(F1AP, "Unexpected UL RRC MESSAGE for srb_id %lu \n", srb_id); + else + LOG_D(F1AP, "UL RRC MESSAGE for srb_id %lu in DCCH \n", srb_id); + + + // issue in here + /* mandatory */ + /* RRC Container */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_ULRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_RRCContainer, true); + // print message in debug mode + + // create an ITTI message and copy SDU + /* + + message_p = itti_alloc_new_message (TASK_CU_F1, RRC_DCCH_DATA_IND); + + RRC_DCCH_DATA_IND (message_p).sdu_p = malloc(ie->value.choice.RRCContainer.size); + + RRC_DCCH_DATA_IND (message_p).sdu_size = ie->value.choice.RRCContainer.size; + memcpy(RRC_DCCH_DATA_IND (message_p).sdu_p, ie->value.choice.RRCContainer.buf, + ie->value.choice.RRCContainer.size); + + RRC_DCCH_DATA_IND (message_p).dcch_index = srb_id; + RRC_DCCH_DATA_IND (message_p).rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], cu_ue_f1ap_id); + RRC_DCCH_DATA_IND (message_p).module_id = instance; + RRC_DCCH_DATA_IND (message_p).eNB_index = instance; // not needed for CU + + itti_send_msg_to_task(TASK_RRC_ENB, instance, message_p); + */ + protocol_ctxt_t ctxt; + ctxt.module_id = instance; + ctxt.instance = instance; + ctxt.rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], cu_ue_f1ap_id); + ctxt.enb_flag = 1; + mem_block_t *mb = get_free_mem_block(ie->value.choice.RRCContainer.size,__func__); + memcpy((void*)mb->data,(void*)ie->value.choice.RRCContainer.buf,ie->value.choice.RRCContainer.size); + LOG_I(F1AP, "Calling pdcp_data_ind for UE RNTI %x srb_id %lu with size %ld (DCCH) \n", ctxt.rnti, srb_id, ie->value.choice.RRCContainer.size); + + //LOG_I(F1AP, "%s() RRCContainer size %lu: ", __func__, ie->value.choice.RRCContainer.size); + //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++) + // printf("%02x ", mb->data[i]); + //printf("\n"); + + pdcp_data_ind (&ctxt, + 1, // srb_flag + 0, // embms_flag + srb_id, + ie->value.choice.RRCContainer.size, + mb); + return 0; +} diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.h b/openair2/F1AP/f1ap_cu_rrc_message_transfer.h new file mode 100644 index 0000000000000000000000000000000000000000..68ebbfe41e81ad2704fd44733943cde85dd62cab --- /dev/null +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.h @@ -0,0 +1,50 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_cu_rrc_message_transfer.h + * \brief f1ap rrc message transfer for CU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#ifndef F1AP_CU_RRC_MESSAGE_TRANSFER_H_ +#define F1AP_CU_RRC_MESSAGE_TRANSFER_H_ + +int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, + f1ap_dl_rrc_message_t *f1ap_dl_rrc); + +int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + + +#endif /* F1AP_CU_RRC_MESSAGE_TRANSFER_H_ */ diff --git a/openair2/F1AP/f1ap_cu_system_information.c b/openair2/F1AP/f1ap_cu_system_information.c new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_system_information.c @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_cu_system_information.h b/openair2/F1AP/f1ap_cu_system_information.h new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_system_information.h @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c new file mode 100644 index 0000000000000000000000000000000000000000..9ab84e6bc918e9d764664e86181c6454bd614398 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_task.c @@ -0,0 +1,206 @@ +/* + * 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 openair2/F1AP/f1ap_cu_task.c +* \brief data structures for F1 interface modules +* \author EURECOM/NTUST +* \date 2018 +* \version 0.1 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr, bing-kai.hong@eurecom.fr +* \note +* \warning +*/ + +#include "f1ap_common.h" +#include "f1ap_handlers.h" +#include "f1ap_cu_interface_management.h" +#include "f1ap_cu_rrc_message_transfer.h" +#include "f1ap_cu_ue_context_management.h" +#include "f1ap_cu_task.h" +#include "proto_agent.h" + +extern RAN_CONTEXT_t RC; + +f1ap_setup_req_t *f1ap_du_data_from_du; +f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB]; + +void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) { + // Nothing +} + +void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { + + DevAssert(sctp_new_association_resp != NULL); + + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + + if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN) + proto_agent_stop(instance); + //f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + return; // exit -1 for debugging + } + + // go to an init func + f1ap_du_data_from_du = (f1ap_setup_req_t *)calloc(1, sizeof(f1ap_setup_req_t)); + // save the assoc id + f1ap_du_data_from_du->assoc_id = sctp_new_association_resp->assoc_id; + f1ap_du_data_from_du->sctp_in_streams = sctp_new_association_resp->in_streams; + f1ap_du_data_from_du->sctp_out_streams = sctp_new_association_resp->out_streams; + + /* setup parameters for F1U and start the server */ + const cudu_params_t params = { + .local_ipv4_address = RC.rrc[instance]->eth_params_s.my_addr, + .local_port = RC.rrc[instance]->eth_params_s.my_portd, + .remote_ipv4_address = RC.rrc[instance]->eth_params_s.remote_addr, + .remote_port = RC.rrc[instance]->eth_params_s.remote_portd + }; + AssertFatal(proto_agent_start(instance, ¶ms) == 0, + "could not start PROTO_AGENT for F1U on instance %d!\n", instance); +} + +void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { + int result; + + DevAssert(sctp_data_ind != NULL); + + f1ap_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length); + + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); +} + +void cu_task_send_sctp_init_req(instance_t enb_id) { + // 1. get the itti msg, and retrive the enb_id from the message + // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port + // 3. creat an itti message to init + + LOG_I(F1AP, "F1AP_CU_SCTP_REQ(create socket)\n"); + MessageDef *message_p = NULL; + + message_p = itti_alloc_new_message (TASK_CU_F1, SCTP_INIT_MSG); + message_p->ittiMsg.sctp_init.port = F1AP_PORT_NUMBER; + message_p->ittiMsg.sctp_init.ppid = F1AP_SCTP_PPID; + message_p->ittiMsg.sctp_init.ipv4 = 1; + message_p->ittiMsg.sctp_init.ipv6 = 0; + message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1; + message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr); + /* + * SR WARNING: ipv6 multi-homing fails sometimes for localhost. + * * * * Disable it for now. + */ + message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0; + message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1"; + + itti_send_msg_to_task(TASK_SCTP, enb_id, message_p); +} + + +void *F1AP_CU_task(void *arg) { + + MessageDef *received_msg = NULL; + int result; + + LOG_I(F1AP, "Starting F1AP at CU\n"); + + // no RLC in CU, initialize mem pool for PDCP + pool_buffer_init(); + + itti_mark_task_ready(TASK_CU_F1); + + cu_task_send_sctp_init_req(0); + + while (1) { + itti_receive_msg(TASK_CU_F1, &received_msg); + switch (ITTI_MSG_ID(received_msg)) { + + case SCTP_NEW_ASSOCIATION_IND: + LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_IND for instance %d\n", + ITTI_MESSAGE_GET_INSTANCE(received_msg)); + cu_task_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_ind); + break; + + case SCTP_NEW_ASSOCIATION_RESP: + LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_RESP for instance %d\n", + ITTI_MESSAGE_GET_INSTANCE(received_msg)); + cu_task_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_resp); + break; + + case SCTP_DATA_IND: + LOG_I(F1AP, "CU Task Received SCTP_DATA_IND for Instance %d\n", + ITTI_MESSAGE_GET_INSTANCE(received_msg)); + cu_task_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_data_ind); + break; + + case F1AP_SETUP_RESP: // from rrc + LOG_I(F1AP, "CU Task Received F1AP_SETUP_RESP\n"); + // CU_send_f1setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + // &F1AP_SETUP_RESP(received_msg)); + CU_send_F1_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &F1AP_SETUP_RESP(received_msg)); + break; + + case F1AP_DL_RRC_MESSAGE: // from rrc + LOG_I(F1AP, "CU Task Received F1AP_DL_RRC_MESSAGE\n"); + CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &F1AP_DL_RRC_MESSAGE(received_msg)); + break; + + case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc + LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_RELEASE_CMD\n"); + CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg)); + break; + +// case F1AP_SETUP_RESPONSE: // This is from RRC +// CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp) +// break; + +// case F1AP_SETUP_FAILURE: // This is from RRC +// CU_send_F1_SETUP_FAILURE(instance, *f1ap_setup_ind, &(F1AP_SETUP_FAILURE) f1ap_setup_failure) +// break; + + case TERMINATE_MESSAGE: + LOG_W(F1AP, " *** Exiting F1AP thread\n"); + itti_exit_task(); + break; + + default: + LOG_E(F1AP, "CU Received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } // switch + result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + + received_msg = NULL; + } // while + + return NULL; +} diff --git a/openair2/F1AP/f1ap_cu_task.h b/openair2/F1AP/f1ap_cu_task.h new file mode 100644 index 0000000000000000000000000000000000000000..dec844accfb0f00d840ff630cc0a6bcf94a66752 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_task.h @@ -0,0 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef F1AP_CU_TASK_H_ +#define F1AP_CU_TASK_H_ + +void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind); +void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); +void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind); +void cu_task_send_sctp_init_req(instance_t enb_id); + +void *F1AP_CU_task(void *arg); + +#endif /* F1AP_CU_TASK_H_ */ diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c new file mode 100644 index 0000000000000000000000000000000000000000..6f6a84e40436dec5bf91b33d782db0d66c52d29d --- /dev/null +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -0,0 +1,1504 @@ +/* + * 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 f1ap_cu_ue_context_management.c + * \brief F1AP UE Context Management, CU side + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#include "f1ap_common.h" +#include "f1ap_encoder.h" +#include "f1ap_decoder.h" +#include "f1ap_itti_messaging.h" +#include "f1ap_cu_ue_context_management.h" +#include <string.h> + +#include "openair2/LAYER2/MAC/mac_proto.h" +#include "rrc_extern.h" +#include "rrc_eNB_UE_context.h" +#include "rrc_eNB_S1AP.h" +#include "rrc_eNB_GTPV1U.h" + +extern f1ap_setup_req_t *f1ap_du_data_from_du; +extern f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB]; +extern RAN_CONTEXT_t RC; + +int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, + f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req) { + F1AP_F1AP_PDU_t pdu; + F1AP_UEContextSetupRequest_t *out; + F1AP_UEContextSetupRequestIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0, j = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_UEContextSetup; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_reject; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_UEContextSetupRequest; + out = &pdu.choice.initiatingMessage->value.choice.UEContextSetupRequest; + + /* mandatory */ + /* c1. GNB_CU_UE_F1AP_ID */ + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_CU_ue_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c2. GNB_DU_UE_F1AP_ID */ + if (f1ap_ue_context_setup_req->gNB_DU_ue_id) { + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie->value.choice.GNB_DU_UE_F1AP_ID = *f1ap_ue_context_setup_req->gNB_DU_ue_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c3. SpCell_ID */ + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SpCell_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_NRCGI; + /* - nRCGI */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(f1ap_ue_context_setup_req->mcc, + f1ap_ue_context_setup_req->mnc, + f1ap_ue_context_setup_req->mnc_digit_length, + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(f1ap_ue_context_setup_req->nr_cellid, &nRCGI.nRCellIdentity); + + ie->value.choice.NRCGI = nRCGI; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c4. ServCellIndex */ + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_ServCellndex; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_ServCellIndex; + ie->value.choice.ServCellIndex = 2; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c5. CellULConfigured */ + if (0) { + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SpCellULConfigured; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_CellULConfigured; + ie->value.choice.CellULConfigured = F1AP_CellULConfigured_ul; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c6. CUtoDURRCInformation */ + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_CUtoDURRCInformation; + + /* optional */ + /* 6.1 cG_ConfigInfo */ + ie->value.choice.CUtoDURRCInformation.cG_ConfigInfo = (F1AP_CG_ConfigInfo_t *)calloc(1, sizeof(F1AP_CG_ConfigInfo_t)); + OCTET_STRING_fromBuf(ie->value.choice.CUtoDURRCInformation.cG_ConfigInfo, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + /* optional */ + /* 6.2 uE_CapabilityRAT_ContainerList */ + ie->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList = (F1AP_UE_CapabilityRAT_ContainerList_t *)calloc(1, sizeof(F1AP_UE_CapabilityRAT_ContainerList_t)); + OCTET_STRING_fromBuf(ie->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + /* optional */ + /* 6.3 measConfig */ + ie->value.choice.CUtoDURRCInformation.measConfig = (F1AP_MeasConfig_t *)calloc(1, sizeof(F1AP_MeasConfig_t)); + OCTET_STRING_fromBuf(ie->value.choice.CUtoDURRCInformation.measConfig, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c7. Candidate_SpCell_List */ + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Candidate_SpCell_List; //90 + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_Candidate_SpCell_List; + + for (i=0; + i<0; + i++) { + + F1AP_Candidate_SpCell_ItemIEs_t *candidate_spCell_item_ies; + candidate_spCell_item_ies = (F1AP_Candidate_SpCell_ItemIEs_t *)calloc(1, sizeof(F1AP_Candidate_SpCell_ItemIEs_t)); + candidate_spCell_item_ies->id = F1AP_ProtocolIE_ID_id_Candidate_SpCell_Item; // 91 + candidate_spCell_item_ies->criticality = F1AP_Criticality_reject; + candidate_spCell_item_ies->value.present = F1AP_Candidate_SpCell_ItemIEs__value_PR_Candidate_SpCell_Item; + + /* 7.1 Candidate_SpCell_Item */ + F1AP_Candidate_SpCell_Item_t candidate_spCell_item; + memset((void *)&candidate_spCell_item, 0, sizeof(F1AP_Candidate_SpCell_Item_t)); + + /* - candidate_SpCell_ID */ + F1AP_NRCGI_t nRCGI; + /* TODO add correct mcc/mnc */ + MCC_MNC_TO_PLMNID(f1ap_ue_context_setup_req->mcc, + f1ap_ue_context_setup_req->mnc, + f1ap_ue_context_setup_req->mnc_digit_length, + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(f1ap_ue_context_setup_req->nr_cellid, &nRCGI.nRCellIdentity); + + candidate_spCell_item.candidate_SpCell_ID = nRCGI; + + /* ADD */ + candidate_spCell_item_ies->value.choice.Candidate_SpCell_Item = candidate_spCell_item; + ASN_SEQUENCE_ADD(&ie->value.choice.Candidate_SpCell_List.list, + candidate_spCell_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c8. DRXCycle */ + if (0) { + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRXCycle; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_DRXCycle; + /* 8.1 longDRXCycleLength */ + ie->value.choice.DRXCycle.longDRXCycleLength = F1AP_LongDRXCycleLength_ms10; // enum + + /* optional */ + /* 8.2 shortDRXCycleLength */ + if (0) { + ie->value.choice.DRXCycle.shortDRXCycleLength = (F1AP_ShortDRXCycleLength_t *)calloc(1, sizeof(F1AP_ShortDRXCycleLength_t)); + *ie->value.choice.DRXCycle.shortDRXCycleLength = F1AP_ShortDRXCycleLength_ms2; // enum + } + + /* optional */ + /* 8.3 shortDRXCycleTimer */ + if (0) { + ie->value.choice.DRXCycle.shortDRXCycleTimer = (F1AP_ShortDRXCycleTimer_t *)calloc(1, sizeof(F1AP_ShortDRXCycleTimer_t)); + *ie->value.choice.DRXCycle.shortDRXCycleTimer = 123L; + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c9. ResourceCoordinationTransferContainer */ + if (0) { + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_ResourceCoordinationTransferContainer; + + ie->value.choice.ResourceCoordinationTransferContainer.buf = malloc(4); + ie->value.choice.ResourceCoordinationTransferContainer.size = 4; + strncpy((char *)ie->value.choice.ResourceCoordinationTransferContainer.buf, "123", 3); + + + OCTET_STRING_fromBuf(&ie->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c10. SCell_ToBeSetup_List */ + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_List; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_SCell_ToBeSetup_List; + + for (i=0; + i<0; + i++) { + // + F1AP_SCell_ToBeSetup_ItemIEs_t *scell_toBeSetup_item_ies; + scell_toBeSetup_item_ies = (F1AP_SCell_ToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeSetup_ItemIEs_t)); + scell_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_Item; //53 + scell_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore; + scell_toBeSetup_item_ies->value.present = F1AP_SCell_ToBeSetup_ItemIEs__value_PR_SCell_ToBeSetup_Item; + + /* 10.1 SCell_ToBeSetup_Item */ + F1AP_SCell_ToBeSetup_Item_t scell_toBeSetup_item; + memset((void *)&scell_toBeSetup_item, 0, sizeof(F1AP_SCell_ToBeSetup_Item_t)); + + /* 10.1.1 sCell_ID */ + F1AP_NRCGI_t nRCGI; + /* TODO correct MCC/MNC */ + MCC_MNC_TO_PLMNID(f1ap_ue_context_setup_req->mcc, + f1ap_ue_context_setup_req->mnc, + f1ap_ue_context_setup_req->mnc_digit_length, + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity); + scell_toBeSetup_item.sCell_ID = nRCGI; + + /* 10.1.2 sCellIndex */ + scell_toBeSetup_item.sCellIndex = 3; // issue here + + /* OPTIONAL */ + /* 10.1.3 sCellULConfigured*/ + if (0) { + scell_toBeSetup_item.sCellULConfigured = (F1AP_CellULConfigured_t *)calloc(1, sizeof(F1AP_CellULConfigured_t)); + *scell_toBeSetup_item.sCellULConfigured = F1AP_CellULConfigured_ul_and_sul; // enum + } + + /* ADD */ + scell_toBeSetup_item_ies->value.choice.SCell_ToBeSetup_Item = scell_toBeSetup_item; + + ASN_SEQUENCE_ADD(&ie->value.choice.SCell_ToBeSetup_List.list, + scell_toBeSetup_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c11. SRBs_ToBeSetup_List */ + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_List; + ie->criticality = F1AP_Criticality_reject; // ? + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List; + + for (i=0; + i<0; + i++) { + // + F1AP_SRBs_ToBeSetup_ItemIEs_t *srbs_toBeSetup_item_ies; + srbs_toBeSetup_item_ies = (F1AP_SRBs_ToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_SRBs_ToBeSetup_ItemIEs_t)); + srbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item; // 73 + srbs_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore; + srbs_toBeSetup_item_ies->value.present = F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item; + + /* 11.1 SRBs_ToBeSetup_Item */ + F1AP_SRBs_ToBeSetup_Item_t srbs_toBeSetup_item; + memset((void *)&srbs_toBeSetup_item, 0, sizeof(F1AP_SRBs_ToBeSetup_Item_t)); + + /* 11.1.1 sRBID */ + srbs_toBeSetup_item.sRBID = 2L; + + /* OPTIONAL */ + /* 11.1.2 duplicationIndication */ + if (0) { + srbs_toBeSetup_item.duplicationIndication = (F1AP_DuplicationIndication_t *)calloc(1, sizeof(F1AP_DuplicationIndication_t)); + srbs_toBeSetup_item.duplicationIndication = F1AP_DuplicationIndication_true; // enum + } + + /* ADD */ + srbs_toBeSetup_item_ies->value.choice.SRBs_ToBeSetup_Item = srbs_toBeSetup_item; + ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_ToBeSetup_List.list, + srbs_toBeSetup_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c12. DRBs_ToBeSetup_List */ + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List; + + for (i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; i++) { + // + F1AP_DRBs_ToBeSetup_ItemIEs_t *drbs_toBeSetup_item_ies; + drbs_toBeSetup_item_ies = (F1AP_DRBs_ToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_ToBeSetup_ItemIEs_t)); + drbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item; + drbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeSetup_item_ies->value.present = F1AP_DRBs_ToBeSetup_ItemIEs__value_PR_DRBs_ToBeSetup_Item; + + /* 12.1 DRBs_ToBeSetup_Item */ + F1AP_DRBs_ToBeSetup_Item_t drbs_toBeSetup_item; + memset((void *)&drbs_toBeSetup_item, 0, sizeof(F1AP_DRBs_ToBeSetup_Item_t)); + + /* 12.1.1 dRBID */ + drbs_toBeSetup_item.dRBID = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id; // 9 + + /* 12.1.2 qoSInformation */ + int some_decide_qos = 1; // BK: Need Check + if (some_decide_qos) { + drbs_toBeSetup_item.qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; + + /* 12.1.2.1 eUTRANQoS */ + drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); + + /* 12.1.2.1.1 qCI */ + drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->qCI = 254L; + + /* 12.1.2.1.2 allocationAndRetentionPriority */ + { + /* 12.1.2.1.2.1 priorityLevel */ + drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->allocationAndRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + + /* 12.1.2.1.2.2 pre_emptionCapability */ + drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->allocationAndRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_may_trigger_pre_emption; // enum + + /* 12.1.2.1.2.2 pre_emptionVulnerability */ + drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->allocationAndRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + } + + /* OPTIONAL */ + /* 12.1.2.1.3 gbrQosInformation */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->gbrQosInformation = (F1AP_GBR_QosInformation_t *)calloc(1, sizeof(F1AP_GBR_QosInformation_t)); + asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateDL, 1L); + asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateUL, 1L); + asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateDL, 1L); + asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateUL, 1L); + } + + } else { + /* 12.1.2 dRB_Information */ + drbs_toBeSetup_item.qoSInformation.present = F1AP_QoSInformation_PR_dRB_Information; + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information = (F1AP_DRB_Information_t *)calloc(1, sizeof(F1AP_DRB_Information_t)); + + /* 12.1.2.1 dRB_QoS */ + { + /* qoS_Characteristics */ + { + int some_decide_qoS_characteristics = 1; // BK: Need Check + if (some_decide_qoS_characteristics) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI = (F1AP_NonDynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_NonDynamic5QIDescriptor_t)); + + /* fiveQI */ + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI = 1L; + + /* OPTIONAL */ + /* qoSPriorityLevel */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = (long *)calloc(1, sizeof(long)); + *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = 1L; + } + + /* OPTIONAL */ + /* averagingWindow */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t)); + *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = 1L; + } + + /* OPTIONAL */ + /* maxDataBurstVolume */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t)); + *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = 1L; + } + + } else { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI = (F1AP_Dynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_Dynamic5QIDescriptor_t)); + + /* qoSPriorityLevel */ + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->qoSPriorityLevel = 1L; + + /* packetDelayBudget */ + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->packetDelayBudget = 1L; + + /* packetErrorRate */ + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate = 1L; + + /* OPTIONAL */ + /* delayCritical */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical = (long *)calloc(1, sizeof(long)); + *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical = 1L; + } + + /* OPTIONAL */ + /* averagingWindow */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t)); + *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = 1L; + } + + /* OPTIONAL */ + /* maxDataBurstVolume */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t)); + *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = 1L; + } + + } // if some_decide_qoS_characteristics + + } // qoS_Characteristics + + /* nGRANallocationRetentionPriority */ + { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + } // nGRANallocationRetentionPriority + + /* OPTIONAL */ + /* gBR_QoS_Flow_Information */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information = (F1AP_GBR_QoSFlowInformation_t *)calloc(1, sizeof(F1AP_GBR_QoSFlowInformation_t)); + asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxFlowBitRateDownlink, 1L); + asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxFlowBitRateUplink, 1L); + asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->guaranteedFlowBitRateDownlink, 1L); + asn_long2INTEGER(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->guaranteedFlowBitRateUplink, 1L); + + /* OPTIONAL */ + /* maxPacketLossRateDownlink */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); + *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = 1L; + } + + /* OPTIONAL */ + /* maxPacketLossRateUplink */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); + *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink = 1L; + } + + } + + /* OPTIONAL */ + /* reflective_QoS_Attribute */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.reflective_QoS_Attribute = (long *)calloc(1, sizeof(long)); + *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->dRB_QoS.reflective_QoS_Attribute = 1L; + } + + } // dRB_QoS + + /* 12.1.2.2 sNSSAI */ + { + /* sST */ + OCTET_STRING_fromBuf(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->sNSSAI.sST, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + /* OPTIONAL */ + /* sD */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->sNSSAI.sD = (OCTET_STRING_t *)calloc(1, sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->sNSSAI.sD, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + } + } + /* OPTIONAL */ + /* 12.1.2.3 notificationControl */ + if (0) { + drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->notificationControl = (F1AP_NotificationControl_t *)calloc(1, sizeof(F1AP_NotificationControl_t)); + *drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->notificationControl = F1AP_NotificationControl_active; // enum + } + + /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy + int k; + for (k = 0; k < 1; k ++) { + + F1AP_Flows_Mapped_To_DRB_Item_t flows_mapped_to_drb_item; + memset((void *)&flows_mapped_to_drb_item, 0, sizeof(F1AP_Flows_Mapped_To_DRB_Item_t)); + + /* qoSFlowIndicator */ + flows_mapped_to_drb_item.qoSFlowIndicator = 1L; + + /* qoSFlowLevelQoSParameters */ + { + /* qoS_Characteristics */ + { + int some_decide_qoS_characteristics = 1; // BK: Need Check + if (some_decide_qoS_characteristics) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI = (F1AP_NonDynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_NonDynamic5QIDescriptor_t)); + + /* fiveQI */ + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI = 1L; + + /* OPTIONAL */ + /* qoSPriorityLevel */ + if (0) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = (long *)calloc(1, sizeof(long)); + *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->qoSPriorityLevel = 1L; + } + + /* OPTIONAL */ + /* averagingWindow */ + if (0) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t)); + *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->averagingWindow = 1L; + } + + /* OPTIONAL */ + /* maxDataBurstVolume */ + if (0) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t)); + *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->maxDataBurstVolume = 1L; + } + + } else { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI = (F1AP_Dynamic5QIDescriptor_t *)calloc(1, sizeof(F1AP_Dynamic5QIDescriptor_t)); + + /* qoSPriorityLevel */ + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->qoSPriorityLevel = 1L; + + /* packetDelayBudget */ + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->packetDelayBudget = 1L; + + /* packetErrorRate */ + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->packetErrorRate = 1L; + + /* OPTIONAL */ + /* delayCritical */ + if (0) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->delayCritical = (long *)calloc(1, sizeof(long)); + *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->delayCritical = 1L; + } + + /* OPTIONAL */ + /* averagingWindow */ + if (0) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = (F1AP_AveragingWindow_t *)calloc(1, sizeof(F1AP_AveragingWindow_t)); + *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->averagingWindow = 1L; + } + + /* OPTIONAL */ + /* maxDataBurstVolume */ + if (0) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = (F1AP_MaxDataBurstVolume_t *)calloc(1, sizeof(F1AP_MaxDataBurstVolume_t)); + *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume = 1L; + } + + } // if some_decide_qoS_characteristics + + } // qoS_Characteristics + + /* nGRANallocationRetentionPriority */ + { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + } // nGRANallocationRetentionPriority + + /* OPTIONAL */ + /* gBR_QoS_Flow_Information */ + if (0) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information = (F1AP_GBR_QoSFlowInformation_t *)calloc(1, sizeof(F1AP_GBR_QoSFlowInformation_t)); + asn_long2INTEGER(&flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxFlowBitRateDownlink, 1L); + asn_long2INTEGER(&flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxFlowBitRateUplink, 1L); + asn_long2INTEGER(&flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->guaranteedFlowBitRateDownlink, 1L); + asn_long2INTEGER(&flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->guaranteedFlowBitRateUplink, 1L); + + /* OPTIONAL */ + /* maxPacketLossRateDownlink */ + if (0) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); + *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink = 1L; + } + + /* OPTIONAL */ + /* maxPacketLossRateUplink */ + if (0) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink = (F1AP_MaxPacketLossRate_t *)calloc(1, sizeof(F1AP_MaxPacketLossRate_t)); + *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink = 1L; + } + + } + + /* OPTIONAL */ + /* reflective_QoS_Attribute */ + if (0) { + flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.reflective_QoS_Attribute = (long *)calloc(1, sizeof(long)); + *flows_mapped_to_drb_item.qoSFlowLevelQoSParameters.reflective_QoS_Attribute = 1L; + } + + } // qoSFlowLevelQoSParameters + // BK: need check + ASN_SEQUENCE_ADD(&drbs_toBeSetup_item.qoSInformation.choice.dRB_Information->flows_Mapped_To_DRB_List.list, &flows_mapped_to_drb_item); + } + + } // if some_decide_qos + + /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ + for (j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { + f1ap_up_tnl_t *up_tnl = &f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j]; + + /* 12.3.1 ULTunnels_ToBeSetup_Item */ + F1AP_ULUPTNLInformation_ToBeSetup_Item_t *uLUPTNLInformation_ToBeSetup_Item; + + /* 12.3.1.1 gTPTunnel */ + uLUPTNLInformation_ToBeSetup_Item = calloc(1, sizeof(F1AP_ULUPTNLInformation_ToBeSetup_Item_t)); + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t)); + + /* 12.3.1.1.1 transportLayerAddress */ + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(up_tnl->tl_address, &gTPTunnel->transportLayerAddress); + + /* 12.3.1.1.2 gTP_TEID */ + INT32_TO_OCTET_STRING(up_tnl->gtp_teid, &gTPTunnel->gTP_TEID); + + // Add + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel = gTPTunnel; + ASN_SEQUENCE_ADD(&drbs_toBeSetup_item.uLUPTNLInformation_ToBeSetup_List.list, uLUPTNLInformation_ToBeSetup_Item); + } + + /* 12.1.4 rLCMode */ + /* TODO use rlc_mode from f1ap_drb_to_be_setup */ + switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) { + case RLC_MODE_AM: + drbs_toBeSetup_item.rLCMode = F1AP_RLCMode_rlc_am; + break; + default: + drbs_toBeSetup_item.rLCMode = F1AP_RLCMode_rlc_um; + } + + /* OPTIONAL */ + /* 12.1.5 ULConfiguration */ + if (0) { + drbs_toBeSetup_item.uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); + drbs_toBeSetup_item.uLConfiguration->uLUEConfiguration = F1AP_ULUEConfiguration_no_data; + } + + /* OPTIONAL */ + /* 12.1.6 duplicationActivation */ + if (0) { + drbs_toBeSetup_item.duplicationActivation = (F1AP_DuplicationActivation_t *)calloc(1, sizeof(F1AP_DuplicationActivation_t)); + drbs_toBeSetup_item.duplicationActivation = F1AP_DuplicationActivation_active; // enum + } + + /* ADD */ + drbs_toBeSetup_item_ies->value.choice.DRBs_ToBeSetup_Item = drbs_toBeSetup_item; + ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_ToBeSetup_List.list, + drbs_toBeSetup_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* OPTIONAL */ + /* InactivityMonitoringRequest */ + if (0) { + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_InactivityMonitoringRequest; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_InactivityMonitoringRequest; + ie->value.choice.InactivityMonitoringRequest = F1AP_InactivityMonitoringRequest_true; // 0 + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* OPTIONAL */ + /* RAT_FrequencyPriorityInformation */ + if (0) { + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_RAT_FrequencyPriorityInformation; + + int some_decide_rat = 1; // BK: Need Check + if (some_decide_rat) { + ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_subscriberProfileIDforRFP; + ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP = 11L; + } else { + ie->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority; + ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority = 11L; + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* OPTIONAL */ + /* RRCContainer */ + if (0) { + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* OPTIONAL */ + /* MaskedIMEISV */ + if (0) { + ie = (F1AP_UEContextSetupRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_MaskedIMEISV; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupRequestIEs__value_PR_MaskedIMEISV; + MaskedIMEISV_TO_BIT_STRING(12340000l, &ie->value.choice.MaskedIMEISV); // size (64) + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + return 0; +} + +int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + +int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + F1AP_UEContextReleaseRequest_t *container; + F1AP_UEContextReleaseRequestIEs_t *ie; + + DevAssert(pdu); + + container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseRequest; + /* GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + const rnti_t rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], + ie->value.choice.GNB_CU_UE_F1AP_ID); + + /* GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + const rnti_t rnti2 = f1ap_get_rnti_by_du_id(&f1ap_cu_inst[instance], + ie->value.choice.GNB_DU_UE_F1AP_ID); + AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", + rnti2, rnti); + + /* Cause */ + /* We don't care for the moment + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_Cause, true); + + switch(ie->value.choice.Cause.present) + { + case F1AP_Cause_PR_radioNetwork: + //ie->value.choice.Cause.choice.radioNetwork + break; + case F1AP_Cause_PR_transport: + //ie->value.choice.Cause.choice.transport + break; + case F1AP_Cause_PR_protocol: + //ie->value.choice.Cause.choice.protocol + break; + case F1AP_Cause_PR_misc: + //ie->value.choice.Cause.choice.misc + break; + case F1AP_Cause_PR_NOTHING: + default: + break; + } + */ + + LOG_I(F1AP, "Received UE CONTEXT RELEASE REQUEST: Trigger RRC for RNTI %x\n", rnti); + struct rrc_eNB_ue_context_s *ue_context_pP; + ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[instance], rnti); + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ( + instance, + ue_context_pP, + S1AP_CAUSE_RADIO_NETWORK, + 21); // send cause 21: connection with ue lost + + return 0; +} + + +int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, + f1ap_ue_context_release_cmd_t *cmd) { + F1AP_F1AP_PDU_t pdu; + F1AP_UEContextReleaseCommand_t *out; + F1AP_UEContextReleaseCommandIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_UEContextRelease; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_reject; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_UEContextReleaseCommand; + out = &pdu.choice.initiatingMessage->value.choice.UEContextReleaseCommand; + + /* mandatory */ + /* c1. GNB_CU_UE_F1AP_ID */ + ie = (F1AP_UEContextReleaseCommandIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCommandIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_cu_inst[instance], cmd->rnti); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. GNB_DU_UE_F1AP_ID */ + ie = (F1AP_UEContextReleaseCommandIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCommandIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_cu_inst[instance], cmd->rnti); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c3. Cause */ + ie = (F1AP_UEContextReleaseCommandIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCommandIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Cause; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_Cause; + + switch (cmd->cause) { + case F1AP_CAUSE_RADIO_NETWORK: + ie->value.choice.Cause.present = F1AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = cmd->cause_value; + break; + case F1AP_CAUSE_TRANSPORT: + ie->value.choice.Cause.present = F1AP_Cause_PR_transport; + ie->value.choice.Cause.choice.transport = cmd->cause_value; + break; + case F1AP_CAUSE_PROTOCOL: + ie->value.choice.Cause.present = F1AP_Cause_PR_protocol; + ie->value.choice.Cause.choice.protocol = cmd->cause_value; + break; + case F1AP_CAUSE_MISC: + ie->value.choice.Cause.present = F1AP_Cause_PR_misc; + ie->value.choice.Cause.choice.misc = cmd->cause_value; + break; + case F1AP_CAUSE_NOTHING: + default: + ie->value.choice.Cause.present = F1AP_Cause_PR_NOTHING; + break; + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c4. RRCContainer */ + ie = (F1AP_UEContextReleaseCommandIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCommandIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer; + + OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char *)cmd->rrc_container, + cmd->rrc_container_length); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 context release command\n"); + return -1; + } + + cu_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data_from_du->assoc_id, buffer, len, 0); + + return 0; +} + +int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + F1AP_UEContextReleaseComplete_t *container; + F1AP_UEContextReleaseCompleteIEs_t *ie; + + DevAssert(pdu); + + container = &pdu->choice.successfulOutcome->value.choice.UEContextReleaseComplete; + /* GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + const rnti_t rnti = f1ap_get_rnti_by_cu_id(&f1ap_cu_inst[instance], + ie->value.choice.GNB_CU_UE_F1AP_ID); + + /* GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + const rnti_t rnti2 = f1ap_get_rnti_by_du_id(&f1ap_cu_inst[instance], + ie->value.choice.GNB_DU_UE_F1AP_ID); + AssertFatal(rnti == rnti2, "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", + rnti2, rnti); + + /* Optional*/ + /* CriticalityDiagnostics */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCompleteIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false); + if (ie) { + // ie->value.choice.CriticalityDiagnostics.procedureCode + // ie->value.choice.CriticalityDiagnostics.triggeringMessage + // ie->value.choice.CriticalityDiagnostics.procedureCriticality + // ie->value.choice.CriticalityDiagnostics.transactionID + + // F1AP_CriticalityDiagnostics_IE_List + } + + struct rrc_eNB_ue_context_s *ue_context_p = + rrc_eNB_get_ue_context(RC.rrc[instance], rnti); + protocol_ctxt_t ctxt; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, ENB_FLAG_YES, rnti, 0, 0, instance); + + if (ue_context_p) { + /* The following is normally done in the function rrc_rx_tx() */ + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance, + ue_context_p->ue_context.eNB_ue_s1ap_id); + + rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p); + // erase data of GTP tunnels in UE context + for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], + 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); + ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; + } + + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = + rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0, + ue_context_p->ue_context.eNB_ue_s1ap_id); + if (rrc_ue_s1ap_ids) + rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids); + + /* trigger UE release in RRC */ + rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p); + } else { + LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti); + } + + pdcp_remove_UE(&ctxt); + + /* notify the agent */ + if (flexran_agent_get_rrc_xface(instance)) + flexran_agent_get_rrc_xface(instance)->flexran_agent_notify_ue_state_change( + instance, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + + LOG_I(F1AP, "Received UE CONTEXT RELEASE COMPLETE: Removing CU UE entry for RNTI %x\n", rnti); + f1ap_remove_ue(&f1ap_cu_inst[instance], rnti); + return 0; +} + + +//void CU_send_UE_CONTEXT_MODIFICATION_REQUEST(F1AP_UEContextModificationRequest_t *UEContextModificationRequest) { +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { + F1AP_F1AP_PDU_t pdu; + F1AP_UEContextModificationRequest_t *out; + F1AP_UEContextModificationRequestIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0; + + // for test + int mcc = 208; + int mnc = 93; + int mnc_digit_length = 8; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_UEContextModification; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_reject; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_UEContextModificationRequest; + out = &pdu.choice.initiatingMessage->value.choice.UEContextModificationRequest; + + /* mandatory */ + /* c1. GNB_CU_UE_F1AP_ID */ + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie->value.choice.GNB_CU_UE_F1AP_ID = 126L; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. GNB_DU_UE_F1AP_ID */ + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie->value.choice.GNB_DU_UE_F1AP_ID = 651L; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c3. NRCGI */ + if (0) { + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SpCell_ID; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_NRCGI; + /* - nRCGI */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length, + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity); + ie->value.choice.NRCGI = nRCGI; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c4. ServCellIndex */ + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_ServCellndex; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex; + ie->value.choice.ServCellIndex = 5L; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c5. DRXCycle */ + if (0) { + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRXCycle; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRXCycle; + ie->value.choice.DRXCycle.longDRXCycleLength = F1AP_LongDRXCycleLength_ms10; // enum + if (0) { + ie->value.choice.DRXCycle.shortDRXCycleLength = (F1AP_ShortDRXCycleLength_t *)calloc(1, sizeof(F1AP_ShortDRXCycleLength_t)); + *ie->value.choice.DRXCycle.shortDRXCycleLength = F1AP_ShortDRXCycleLength_ms2; // enum + } + if (0) { + ie->value.choice.DRXCycle.shortDRXCycleTimer = (F1AP_ShortDRXCycleTimer_t *)calloc(1, sizeof(F1AP_ShortDRXCycleTimer_t)); + *ie->value.choice.DRXCycle.shortDRXCycleTimer = 123L; + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c5. CUtoDURRCInformation */ + if (1) { + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_CUtoDURRCInformation; + ie->value.choice.CUtoDURRCInformation.cG_ConfigInfo = (F1AP_CG_ConfigInfo_t *)calloc(1, sizeof(F1AP_CG_ConfigInfo_t)); + /* optional */ + OCTET_STRING_fromBuf(ie->value.choice.CUtoDURRCInformation.cG_ConfigInfo, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + ie->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList = (F1AP_UE_CapabilityRAT_ContainerList_t *)calloc(1, sizeof(F1AP_UE_CapabilityRAT_ContainerList_t)); + /* optional */ + OCTET_STRING_fromBuf(ie->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c6. TransmissionStopIndicator */ + if (1) { + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_TransmissionStopIndicator; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionStopIndicator; + ie->value.choice.TransmissionStopIndicator = F1AP_TransmissionStopIndicator_true; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c7. ResourceCoordinationTransferContainer */ + if (0) { + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ResourceCoordinationTransferContainer; + OCTET_STRING_fromBuf(&ie->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c7. RRCRconfigurationCompleteIndicator */ + if (1) { + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_RRCRconfigurationCompleteIndicator; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_RRCRconfigurationCompleteIndicator; + ie->value.choice.RRCRconfigurationCompleteIndicator = F1AP_RRCRconfigurationCompleteIndicator_true; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c8. RRCContainer */ + if (1) { + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c9. SCell_ToBeSetupMod_List */ + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_List; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeSetupMod_List; + + for (i=0; + i<1; + i++) { + // + F1AP_SCell_ToBeSetupMod_ItemIEs_t *scell_toBeSetupMod_item_ies; + scell_toBeSetupMod_item_ies = (F1AP_SCell_ToBeSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeSetupMod_ItemIEs_t)); + //memset((void *)&scell_toBeSetupMod_item_ies, 0, sizeof(F1AP_SCell_ToBeSetupMod_ItemIEs_t)); + scell_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_Item; + scell_toBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; + scell_toBeSetupMod_item_ies->value.present = F1AP_SCell_ToBeSetupMod_ItemIEs__value_PR_SCell_ToBeSetupMod_Item; + + /* 8.1 SCell_ToBeSetup_Item */ + F1AP_SCell_ToBeSetupMod_Item_t scell_toBeSetupMod_item; + memset((void *)&scell_toBeSetupMod_item, 0, sizeof(F1AP_SCell_ToBeSetupMod_Item_t)); + + // /* - sCell_ID */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length, + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity); + scell_toBeSetupMod_item.sCell_ID = nRCGI; + + /* sCellIndex */ + scell_toBeSetupMod_item.sCellIndex = 6; // issue here + + // /* ADD */ + scell_toBeSetupMod_item_ies->value.choice.SCell_ToBeSetupMod_Item = scell_toBeSetupMod_item; + ASN_SEQUENCE_ADD(&ie->value.choice.SCell_ToBeSetupMod_List.list, + scell_toBeSetupMod_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c10. SCell_ToBeRemoved_List */ + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_List; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeRemoved_List; + + for (i=0; + i<1; + i++) { + // + F1AP_SCell_ToBeRemoved_ItemIEs_t *scell_toBeRemoved_item_ies; + scell_toBeRemoved_item_ies = (F1AP_SCell_ToBeRemoved_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); + //memset((void *)&scell_toBeRemoved_item_ies, 0, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); + scell_toBeRemoved_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_Item; + scell_toBeRemoved_item_ies->criticality = F1AP_Criticality_ignore; + scell_toBeRemoved_item_ies->value.present = F1AP_SCell_ToBeRemoved_ItemIEs__value_PR_SCell_ToBeRemoved_Item; + + /* 10.1 SCell_ToBeRemoved_Item */ + F1AP_SCell_ToBeRemoved_Item_t scell_toBeRemoved_item; + memset((void *)&scell_toBeRemoved_item, 0, sizeof(F1AP_SCell_ToBeRemoved_Item_t)); + + /* - sCell_ID */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(mcc, mnc, mnc_digit_length, + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(123456, &nRCGI.nRCellIdentity); + scell_toBeRemoved_item.sCell_ID = nRCGI; + + /* ADD */ + scell_toBeRemoved_item_ies->value.choice.SCell_ToBeRemoved_Item = scell_toBeRemoved_item; + ASN_SEQUENCE_ADD(&ie->value.choice.SCell_ToBeRemoved_List.list, + scell_toBeRemoved_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c11. SRBs_ToBeSetupMod_List */ + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeSetupMod_List; + + for (i=0; + i<1; + i++) { + // + F1AP_SRBs_ToBeSetupMod_ItemIEs_t *srbs_toBeSetupMod_item_ies; + srbs_toBeSetupMod_item_ies = (F1AP_SRBs_ToBeSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_SRBs_ToBeSetupMod_ItemIEs_t)); + //memset((void *)&srbs_toBeSetupMod_item_ies, 0, sizeof(F1AP_SRBs_ToBeSetupMod_ItemIEs_t)); + srbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_Item; + srbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; + srbs_toBeSetupMod_item_ies->value.present = F1AP_SRBs_ToBeSetupMod_ItemIEs__value_PR_SRBs_ToBeSetupMod_Item; + + /* 9.1 SRBs_ToBeSetupMod_Item */ + F1AP_SRBs_ToBeSetupMod_Item_t srbs_toBeSetupMod_item; + memset((void *)&srbs_toBeSetupMod_item, 0, sizeof(F1AP_SRBs_ToBeSetupMod_Item_t)); + + /* - sRBID */ + srbs_toBeSetupMod_item.sRBID = 3L; + + /* ADD */ + srbs_toBeSetupMod_item_ies->value.choice.SRBs_ToBeSetupMod_Item = srbs_toBeSetupMod_item; + + ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_ToBeSetupMod_List.list, + srbs_toBeSetupMod_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c12. DRBs_ToBeSetupMod_List */ + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List; + + for (i=0; + i<1; + i++) { + // + F1AP_DRBs_ToBeSetupMod_ItemIEs_t *drbs_toBeSetupMod_item_ies; + drbs_toBeSetupMod_item_ies = (F1AP_DRBs_ToBeSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_ToBeSetupMod_ItemIEs_t)); + drbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item; + drbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeSetupMod_item_ies->value.present = F1AP_DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item; + + /* 12.1 DRBs_ToBeSetupMod_Item */ + F1AP_DRBs_ToBeSetupMod_Item_t drbs_toBeSetupMod_item; + memset((void *)&drbs_toBeSetupMod_item, 0, sizeof(F1AP_DRBs_ToBeSetupMod_Item_t)); + + /* dRBID */ + drbs_toBeSetupMod_item.dRBID = 30L; + + /* qoSInformation */ + drbs_toBeSetupMod_item.qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; + drbs_toBeSetupMod_item.qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); + drbs_toBeSetupMod_item.qoSInformation.choice.eUTRANQoS->qCI = 253L; + + /* uLUPTNLInformation_ToBeSetup_List */ + int j = 0; + int maxnoofULTunnels = 1; // 2; + for (j=0; + j<maxnoofULTunnels; + j++) { + /* ULTunnels_ToBeSetup_Item */ + + F1AP_ULUPTNLInformation_ToBeSetup_Item_t *uLUPTNLInformation_ToBeSetup_Item; + uLUPTNLInformation_ToBeSetup_Item = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_ULUPTNLInformation_ToBeSetup_Item_t)); + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t)); + + /* transportLayerAddress */ + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); + + /* gTP_TEID */ + OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "4567", + strlen("4567")); + + // Add + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel = gTPTunnel; + ASN_SEQUENCE_ADD(&drbs_toBeSetupMod_item.uLUPTNLInformation_ToBeSetup_List.list, uLUPTNLInformation_ToBeSetup_Item); + } + + /* rLCMode */ + drbs_toBeSetupMod_item.rLCMode = F1AP_RLCMode_rlc_um; // enum + + /* OPTIONAL */ + /* ULConfiguration */ + if (0) { + drbs_toBeSetupMod_item.uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); + } + + /* ADD */ + drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item = drbs_toBeSetupMod_item; + ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_ToBeSetupMod_List.list, + drbs_toBeSetupMod_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c13. DRBs_ToBeModified_List */ + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeModified_List; + + for (i=0; + i<1; + i++) { + // + F1AP_DRBs_ToBeModified_ItemIEs_t *drbs_toBeModified_item_ies; + drbs_toBeModified_item_ies = (F1AP_DRBs_ToBeModified_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_ToBeModified_ItemIEs_t)); + drbs_toBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_Item; + drbs_toBeModified_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeModified_item_ies->value.present = F1AP_DRBs_ToBeModified_ItemIEs__value_PR_DRBs_ToBeModified_Item; + + /* 13.1 SRBs_ToBeModified_Item */ + F1AP_DRBs_ToBeModified_Item_t drbs_toBeModified_item; + memset((void *)&drbs_toBeModified_item, 0, sizeof(F1AP_DRBs_ToBeModified_Item_t)); + + /* dRBID */ + drbs_toBeModified_item.dRBID = 30L; + + /* qoSInformation */ + drbs_toBeModified_item.qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; + drbs_toBeModified_item.qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); + drbs_toBeModified_item.qoSInformation.choice.eUTRANQoS->qCI = 254L; + + /* ULTunnels_ToBeModified_List */ + int j = 0; + int maxnoofULTunnels = 1; // 2; + for (j=0; + j<maxnoofULTunnels; + j++) { + /* ULTunnels_ToBeModified_Item */ + F1AP_ULUPTNLInformation_ToBeSetup_Item_t *uLUPTNLInformation_ToBeSetup_Item; + uLUPTNLInformation_ToBeSetup_Item = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_ULUPTNLInformation_ToBeSetup_Item_t)); + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t)); + + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); + + OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", + strlen("1204")); + + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel = gTPTunnel; + + ASN_SEQUENCE_ADD(&drbs_toBeModified_item.uLUPTNLInformation_ToBeSetup_List.list, uLUPTNLInformation_ToBeSetup_Item); + } + + /* OPTIONAL */ + /* ULConfiguration */ + if (0) { + drbs_toBeModified_item.uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); + } + + /* ADD */ + drbs_toBeModified_item_ies->value.choice.DRBs_ToBeModified_Item = drbs_toBeModified_item; + ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_ToBeModified_List.list, + drbs_toBeModified_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c14. SRBs_ToBeReleased_List */ + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeReleased_List; + + for (i=0; + i<1; + i++) { + // + F1AP_SRBs_ToBeReleased_ItemIEs_t *srbs_toBeReleased_item_ies; + srbs_toBeReleased_item_ies = (F1AP_SRBs_ToBeReleased_ItemIEs_t *)calloc(1, sizeof(F1AP_SRBs_ToBeReleased_ItemIEs_t)); + //memset((void *)&srbs_toBeReleased_item_ies, 0, sizeof(F1AP_SRBs_ToBeReleased_ItemIEs_t)); + srbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_Item; + srbs_toBeReleased_item_ies->criticality = F1AP_Criticality_ignore; + srbs_toBeReleased_item_ies->value.present = F1AP_SRBs_ToBeReleased_ItemIEs__value_PR_SRBs_ToBeReleased_Item; + + /* 9.1 SRBs_ToBeReleased_Item */ + F1AP_SRBs_ToBeReleased_Item_t srbs_toBeReleased_item; + memset((void *)&srbs_toBeReleased_item, 0, sizeof(F1AP_SRBs_ToBeReleased_Item_t)); + + /* - sRBID */ + srbs_toBeReleased_item.sRBID = 2L; + + /* ADD */ + srbs_toBeReleased_item_ies->value.choice.SRBs_ToBeReleased_Item = srbs_toBeReleased_item; + ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_ToBeReleased_List.list, + srbs_toBeReleased_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c15. DRBs_ToBeReleased_List */ + ie = (F1AP_UEContextModificationRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List; + + for (i=0; + i<1; + i++) { + // + F1AP_DRBs_ToBeReleased_ItemIEs_t *drbs_toBeReleased_item_ies; + drbs_toBeReleased_item_ies = (F1AP_DRBs_ToBeReleased_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_ToBeReleased_ItemIEs_t)); + drbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item; + drbs_toBeReleased_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeReleased_item_ies->value.present = F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item; + + /* 14.1 SRBs_ToBeReleased_Item */ + F1AP_DRBs_ToBeReleased_Item_t drbs_toBeReleased_item; + memset((void *)&drbs_toBeReleased_item, 0, sizeof(F1AP_DRBs_ToBeReleased_Item_t)); + + /* dRBID */ + drbs_toBeReleased_item.dRBID = 30L; + + /* ADD */ + drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item = drbs_toBeReleased_item; + ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_ToBeReleased_List.list, + drbs_toBeReleased_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + return 0; +} + +int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, + F1AP_UEContextModificationConfirm_t UEContextModificationConfirm_t) { + AssertFatal(1==0,"Not implemented yet\n"); +} diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h new file mode 100644 index 0000000000000000000000000000000000000000..cc4ca3e35f08cf768842e14a2410db6f4b828518 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_ue_context_management.h @@ -0,0 +1,103 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_cu_ue_context_management.h + * \brief header file of CU UE Context management + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#ifndef F1AP_CU_UE_CONTEXT_MANAGEMENT_H_ +#define F1AP_CU_UE_CONTEXT_MANAGEMENT_H_ + +/* + * UE Context Setup + */ +int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, + f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req); + +int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +int CU_handle_UE_CONTEXT_SETUP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + + +/* + * UE Context Release Request (gNB-DU initiated) + */ +int CU_handle_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +/* + * UE Context Release (gNB-CU initiated) + */ +int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, + f1ap_ue_context_release_cmd_t *cmd); + +int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +/* + * UE Context Modification (gNB-CU initiated) + */ +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance); +int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); +int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +/* + * UE Context Modification Required (gNB-DU initiated) + */ +int CU_handle_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); +int CU_send_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, + F1AP_UEContextModificationConfirm_t UEContextModificationConfirm_t); + +/* + * UE Inactivity Notification + */ + +/* + * Notify + */ + +#endif /* F1AP_CU_UE_CONTEXT_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/f1ap_cu_warning_message_transmission.c b/openair2/F1AP/f1ap_cu_warning_message_transmission.c new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_warning_message_transmission.c @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_cu_warning_message_transmission.h b/openair2/F1AP/f1ap_cu_warning_message_transmission.h new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_cu_warning_message_transmission.h @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_decoder.c b/openair2/F1AP/f1ap_decoder.c new file mode 100644 index 0000000000000000000000000000000000000000..7bd5359e29fa0665f387134c28a6a1be8c5dd837 --- /dev/null +++ b/openair2/F1AP/f1ap_decoder.c @@ -0,0 +1,181 @@ +/* + * 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 f1ap_decoder.c + * \brief f1ap pdu decode procedures + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#include "f1ap_common.h" +#include "f1ap_decoder.h" + +int asn1_decoder_xer_print = 0; + +static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu) +{ + //MessageDef *message_p; + //MessagesIds message_id; + //asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + DevAssert(pdu != NULL); + + switch(pdu->choice.initiatingMessage->procedureCode) { + + case F1AP_ProcedureCode_id_F1Setup: + //res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu); + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__); + break; + + case F1AP_ProcedureCode_id_InitialULRRCMessageTransfer: + //res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu); + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_InitialULRRCMessageTransfer\n", __func__); + break; + + case F1AP_ProcedureCode_id_DLRRCMessageTransfer: + //res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu); + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_DLRRCMessageTransfer\n", __func__); + break; + + case F1AP_ProcedureCode_id_ULRRCMessageTransfer: + //res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu); + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_ULRRCMessageTransfer\n", __func__); + break; + case F1AP_ProcedureCode_id_UEContextRelease: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextRelease\n", __func__); + break; + case F1AP_ProcedureCode_id_UEContextReleaseRequest: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextReleaseRequest\n", __func__); + break; + // case F1AP_ProcedureCode_id_InitialContextSetup: + // res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu); + // message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG; + // message_p = itti_alloc_new_message_sized(TASK_F1AP, message_id, + // res.result.encoded + sizeof (IttiMsgText)); + // message_p->ittiMsg.f1ap_initial_context_setup_log.size = res.result.encoded; + // memcpy(&message_p->ittiMsg.f1ap_initial_context_setup_log.text, res.buffer, res.result.encoded); + // itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + // free(res.buffer); + // break; + + default: + // F1AP_ERROR("Unknown procedure ID (%d) for initiating message\n", + // (int)pdu->choice.initiatingMessage->procedureCode); + LOG_E(F1AP, "Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage->procedureCode); + AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + + return 0; +} + +static int f1ap_decode_successful_outcome(F1AP_F1AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.successfulOutcome->procedureCode) { + case F1AP_ProcedureCode_id_F1Setup: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__); + break; + + case F1AP_ProcedureCode_id_UEContextRelease: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextRelease\n", __func__); + break; + + default: + LOG_E(F1AP,"Unknown procedure ID (%d) for successfull outcome message\n", + (int)pdu->choice.successfulOutcome->procedureCode); + return -1; + } + + return 0; +} + +static int f1ap_decode_unsuccessful_outcome(F1AP_F1AP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + + switch(pdu->choice.unsuccessfulOutcome->procedureCode) { + case F1AP_ProcedureCode_id_F1Setup: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_F1Setup\n", __func__); + break; + + default: + // F1AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n", + // (int)pdu->choice.unsuccessfulOutcome->procedureCode); + LOG_E(F1AP, "Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)pdu->choice.unsuccessfulOutcome->procedureCode); + return -1; + } + + return 0; +} + +int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) +{ + asn_dec_rval_t dec_ret; + + DevAssert(buffer != NULL); + + dec_ret = aper_decode(NULL, + &asn_DEF_F1AP_F1AP_PDU, + (void **)&pdu, + buffer, + length, + 0, + 0); + + if (asn1_decoder_xer_print) { + LOG_E(F1AP, "----------------- ASN1 DECODER PRINT START----------------- \n"); + xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, pdu); + LOG_E(F1AP, "----------------- ASN1 DECODER PRINT END ----------------- \n"); + } + //LOG_I(F1AP, "f1ap_decode_pdu.dec_ret.code = %d\n", dec_ret.code); + + if (dec_ret.code != RC_OK) { + LOG_E(F1AP, "Failed to decode pdu\n"); + return -1; + } + + switch(pdu->present) { + case F1AP_F1AP_PDU_PR_initiatingMessage: + return f1ap_decode_initiating_message(pdu); + + case F1AP_F1AP_PDU_PR_successfulOutcome: + return f1ap_decode_successful_outcome(pdu); + + case F1AP_F1AP_PDU_PR_unsuccessfulOutcome: + return f1ap_decode_unsuccessful_outcome(pdu); + + default: + LOG_E(F1AP, "Unknown presence (%d) or not implemented\n", (int)pdu->present); + break; + } + + + return -1; +} diff --git a/openair2/F1AP/f1ap_decoder.h b/openair2/F1AP/f1ap_decoder.h new file mode 100644 index 0000000000000000000000000000000000000000..57814db34df79c031956c94488621a2081d484b7 --- /dev/null +++ b/openair2/F1AP/f1ap_decoder.h @@ -0,0 +1,39 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_decoder.h + * \brief f1ap pdu decode procedures + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#ifndef F1AP_ENB_ENCODER_H_ +#define F1AP_ENB_ENCODER_H_ + +int f1ap_decode_pdu(F1AP_F1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length) +__attribute__ ((warn_unused_result)); + +#endif /* F1AP_ENB_ENCODER_H_ */ diff --git a/openair2/F1AP/f1ap_default_values.h b/openair2/F1AP/f1ap_default_values.h new file mode 100644 index 0000000000000000000000000000000000000000..91a11796240a85284a8388b717a16783d7a110b8 --- /dev/null +++ b/openair2/F1AP/f1ap_default_values.h @@ -0,0 +1,46 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_default_values.h + * \brief default values for f1ap procedures + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#ifndef F1AP_DEFAULT_VALUES_H_ +#define F1AP_DEFAULT_VALUES_H_ + +#define ENB_TAC (1) +#define ENB_MCC (208) +#define ENB_MNC (92) + +#define ENB_NAME "Eurecom ENB" +#define ENB_NAME_FORMAT (ENB_NAME" %u") + +#define F1AP_PORT_NUMBER (30923) +#define F1AP_SCTP_PPID (62) + +#endif /* F1AP_DEFAULT_VALUES_H_ */ diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c new file mode 100644 index 0000000000000000000000000000000000000000..f076b28a44930fe37d228ed09d0b017733dd07bd --- /dev/null +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -0,0 +1,1050 @@ +/* + * 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 f1ap_du_interface_management.c + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#include "f1ap_common.h" +#include "f1ap_encoder.h" +#include "f1ap_decoder.h" +#include "f1ap_itti_messaging.h" +#include "f1ap_du_interface_management.h" +#include "assertions.h" + +extern f1ap_setup_req_t *f1ap_du_data; + + +int DU_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int DU_send_RESET_ACKKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int DU_send_RESET(instance_t instance, F1AP_Reset_t *Reset) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + +/* + Error Indication +*/ + +int DU_send_ERROR_INDICATION(instance_t instance, F1AP_F1AP_PDU_t *pdu_p) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int DU_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + +/* + F1 Setup +*/ + +// SETUP REQUEST +int DU_send_F1_SETUP_REQUEST(instance_t instance) { + module_id_t enb_mod_idP=0; + module_id_t du_mod_idP=0; + + F1AP_F1AP_PDU_t pdu; + F1AP_F1SetupRequest_t *out; + F1AP_F1SetupRequestIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0; + int j = 0; + + /* Create */ + /* 0. pdu Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_F1Setup; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_reject; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_F1SetupRequest; + out = &pdu.choice.initiatingMessage->value.choice.F1SetupRequest; + + /* mandatory */ + /* c1. Transaction ID (integer value) */ + ie = (F1AP_F1SetupRequestIEs_t *)calloc(1, sizeof(F1AP_F1SetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_F1SetupRequestIEs__value_PR_TransactionID; + ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. GNB_DU_ID (integrer value) */ + ie = (F1AP_F1SetupRequestIEs_t *)calloc(1, sizeof(F1AP_F1SetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_ID; + asn_int642INTEGER(&ie->value.choice.GNB_DU_ID, f1ap_du_data->gNB_DU_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c3. GNB_DU_Name */ + if (f1ap_du_data->gNB_DU_name != NULL) { + ie = (F1AP_F1SetupRequestIEs_t *)calloc(1, sizeof(F1AP_F1SetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_Name; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Name; + OCTET_STRING_fromBuf(&ie->value.choice.GNB_DU_Name, f1ap_du_data->gNB_DU_name, + strlen(f1ap_du_data->gNB_DU_name)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c4. serverd cells list */ + ie = (F1AP_F1SetupRequestIEs_t *)calloc(1, sizeof(F1AP_F1SetupRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Served_Cells_List; + + int num_cells_available = f1ap_du_data->num_cells_available; + LOG_D(F1AP, "num_cells_available = %d \n", num_cells_available); + for (i=0; + i<num_cells_available; + i++) { + /* mandatory */ + /* 4.1 serverd cells item */ + + F1AP_GNB_DU_Served_Cells_ItemIEs_t *gnb_du_served_cell_list_item_ies; + gnb_du_served_cell_list_item_ies = (F1AP_GNB_DU_Served_Cells_ItemIEs_t *)calloc(1, sizeof(F1AP_GNB_DU_Served_Cells_ItemIEs_t)); + gnb_du_served_cell_list_item_ies->id = F1AP_ProtocolIE_ID_id_GNB_DU_Served_Cells_Item; + gnb_du_served_cell_list_item_ies->criticality = F1AP_Criticality_reject; + gnb_du_served_cell_list_item_ies->value.present = F1AP_GNB_DU_Served_Cells_ItemIEs__value_PR_GNB_DU_Served_Cells_Item; + + + F1AP_GNB_DU_Served_Cells_Item_t gnb_du_served_cells_item; + memset((void *)&gnb_du_served_cells_item, 0, sizeof(F1AP_GNB_DU_Served_Cells_Item_t)); + + /* 4.1.1 serverd cell Information */ + F1AP_Served_Cell_Information_t served_cell_information; + + memset((void *)&served_cell_information, 0, sizeof(F1AP_Served_Cell_Information_t)); + + /* - nRCGI */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &nRCGI.pLMN_Identity); + LOG_D(F1AP, "plmn: (%d,%d)\n",f1ap_du_data->mcc[i],f1ap_du_data->mnc[i]); + //MCC_MNC_TO_PLMNID(208, 95, 2, &nRCGI.pLMN_Identity); + + NR_CELL_ID_TO_BIT_STRING(f1ap_du_data->nr_cellid[i], &nRCGI.nRCellIdentity); + LOG_D(F1AP, "nRCellIdentity (%llx): %x.%x.%x.%x.%x\n", + (long long unsigned int)f1ap_du_data->nr_cellid[i], + nRCGI.nRCellIdentity.buf[0], + nRCGI.nRCellIdentity.buf[1], + nRCGI.nRCellIdentity.buf[2], + nRCGI.nRCellIdentity.buf[3], + nRCGI.nRCellIdentity.buf[4]); + + served_cell_information.nRCGI = nRCGI; + + /* - nRPCI */ + served_cell_information.nRPCI = f1ap_du_data->nr_pci[i]; // int 0..1007 + + /* - fiveGS_TAC */ + OCTET_STRING_fromBuf(&served_cell_information.fiveGS_TAC, + (const char*)&f1ap_du_data->tac[i], + 3); + + /* - Configured_EPS_TAC */ + if(0){ + served_cell_information.configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t)); + OCTET_STRING_fromBuf(served_cell_information.configured_EPS_TAC, + "2", + 2); + } + + /* - broadcast PLMNs */ + // RK: add the num_available_broadcast_PLMNs to the message + int num_available_broadcast_PLMNs = 1; //f1ap_du_data->num_available_broadcast_PLMNs; + LOG_D(F1AP, "num_available_broadcast_PLMNs = %d \n", num_available_broadcast_PLMNs); + for (j=0; + j<num_available_broadcast_PLMNs; // num_available_broadcast_PLMNs + j++) { + /* > PLMN BroadcastPLMNs Item */ + F1AP_BroadcastPLMNs_Item_t *broadcastPLMNs_Item = (F1AP_BroadcastPLMNs_Item_t *)calloc(1, sizeof(F1AP_BroadcastPLMNs_Item_t)); + //MCC_MNC_TO_PLMNID(208, 95, 2, &broadcastPLMNs_Item->pLMN_Identity); + MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &broadcastPLMNs_Item->pLMN_Identity); + ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, broadcastPLMNs_Item); + } + + // // /* - CHOICE NR-MODE-Info */ + F1AP_NR_Mode_Info_t nR_Mode_Info; + //f1ap_du_data->fdd_flag = 1; + if (f1ap_du_data->fdd_flag) { // FDD + nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_fDD; + F1AP_FDD_Info_t *fDD_Info = (F1AP_FDD_Info_t *)calloc(1, sizeof(F1AP_FDD_Info_t)); + + /* FDD.1 UL NRFreqInfo */ + /* FDD.1.1 UL NRFreqInfo ARFCN */ + fDD_Info->uL_NRFreqInfo.nRARFCN = f1ap_du_data->nr_mode_info[i].fdd.ul_nr_arfcn; // Integer + + /* FDD.1.2 F1AP_SUL_Information */ + if(0) { // Optional + F1AP_SUL_Information_t *fdd_sul_info = (F1AP_SUL_Information_t *)calloc(1, sizeof(F1AP_SUL_Information_t)); + fdd_sul_info->sUL_NRARFCN = 0; + fdd_sul_info->sUL_transmission_Bandwidth.nRSCS = 0; + fdd_sul_info->sUL_transmission_Bandwidth.nRNRB = 0; + fDD_Info->uL_NRFreqInfo.sul_Information = fdd_sul_info; + } + + /* FDD.1.3 freqBandListNr */ + int fdd_ul_num_available_freq_Bands = f1ap_du_data->nr_mode_info[i].fdd.ul_num_frequency_bands; + LOG_D(F1AP, "fdd_ul_num_available_freq_Bands = %d \n", fdd_ul_num_available_freq_Bands); + int fdd_ul_j; + for (fdd_ul_j=0; + fdd_ul_j<fdd_ul_num_available_freq_Bands; + fdd_ul_j++) { + + F1AP_FreqBandNrItem_t nr_freqBandNrItem; + memset((void *)&nr_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t)); + /* FDD.1.3.1 freqBandIndicatorNr*/ + nr_freqBandNrItem.freqBandIndicatorNr = f1ap_du_data->nr_mode_info[i].fdd.ul_nr_band[fdd_ul_j]; // + + /* FDD.1.3.2 supportedSULBandList*/ + int num_available_supported_SULBands = f1ap_du_data->nr_mode_info[i].fdd.ul_num_sul_frequency_bands; + LOG_D(F1AP, "num_available_supported_SULBands = %d \n", num_available_supported_SULBands); + int fdd_ul_k; + for (fdd_ul_k=0; + fdd_ul_k<num_available_supported_SULBands; + fdd_ul_k++) { + F1AP_SupportedSULFreqBandItem_t nr_supportedSULFreqBandItem; + memset((void *)&nr_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t)); + /* FDD.1.3.2.1 freqBandIndicatorNr */ + nr_supportedSULFreqBandItem.freqBandIndicatorNr = f1ap_du_data->nr_mode_info[i].fdd.ul_nr_sul_band[fdd_ul_k]; // + ASN_SEQUENCE_ADD(&nr_freqBandNrItem.supportedSULBandList.list, &nr_supportedSULFreqBandItem); + } // for FDD : UL supported_SULBands + ASN_SEQUENCE_ADD(&fDD_Info->uL_NRFreqInfo.freqBandListNr.list, &nr_freqBandNrItem); + } // for FDD : UL freq_Bands + + /* FDD.2 DL NRFreqInfo */ + /* FDD.2.1 DL NRFreqInfo ARFCN */ + fDD_Info->dL_NRFreqInfo.nRARFCN = f1ap_du_data->nr_mode_info[i].fdd.dl_nr_arfcn; // Integer + + /* FDD.2.2 F1AP_SUL_Information */ + if(0) { // Optional + F1AP_SUL_Information_t *fdd_sul_info = (F1AP_SUL_Information_t *)calloc(1, sizeof(F1AP_SUL_Information_t)); + fdd_sul_info->sUL_NRARFCN = 0; + fdd_sul_info->sUL_transmission_Bandwidth.nRSCS = 0; + fdd_sul_info->sUL_transmission_Bandwidth.nRNRB = 0; + fDD_Info->dL_NRFreqInfo.sul_Information = fdd_sul_info; + } + + /* FDD.2.3 freqBandListNr */ + int fdd_dl_num_available_freq_Bands = f1ap_du_data->nr_mode_info[i].fdd.dl_num_frequency_bands; + LOG_D(F1AP, "fdd_dl_num_available_freq_Bands = %d \n", fdd_dl_num_available_freq_Bands); + int fdd_dl_j; + for (fdd_dl_j=0; + fdd_dl_j<fdd_dl_num_available_freq_Bands; + fdd_dl_j++) { + + F1AP_FreqBandNrItem_t nr_freqBandNrItem; + memset((void *)&nr_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t)); + /* FDD.2.3.1 freqBandIndicatorNr*/ + nr_freqBandNrItem.freqBandIndicatorNr = f1ap_du_data->nr_mode_info[i].fdd.dl_nr_band[fdd_dl_j]; // + + /* FDD.2.3.2 supportedSULBandList*/ + int num_available_supported_SULBands = f1ap_du_data->nr_mode_info[i].fdd.dl_num_sul_frequency_bands; + LOG_D(F1AP, "num_available_supported_SULBands = %d \n", num_available_supported_SULBands); + int fdd_dl_k; + for (fdd_dl_k=0; + fdd_dl_k<num_available_supported_SULBands; + fdd_dl_k++) { + F1AP_SupportedSULFreqBandItem_t nr_supportedSULFreqBandItem; + memset((void *)&nr_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t)); + /* FDD.2.3.2.1 freqBandIndicatorNr */ + nr_supportedSULFreqBandItem.freqBandIndicatorNr = f1ap_du_data->nr_mode_info[i].fdd.dl_nr_sul_band[fdd_dl_k]; // + ASN_SEQUENCE_ADD(&nr_freqBandNrItem.supportedSULBandList.list, &nr_supportedSULFreqBandItem); + } // for FDD : DL supported_SULBands + ASN_SEQUENCE_ADD(&fDD_Info->dL_NRFreqInfo.freqBandListNr.list, &nr_freqBandNrItem); + } // for FDD : DL freq_Bands + + /* FDD.3 UL Transmission Bandwidth */ + fDD_Info->uL_Transmission_Bandwidth.nRSCS = f1ap_du_data->nr_mode_info[i].fdd.ul_scs; + fDD_Info->uL_Transmission_Bandwidth.nRNRB = f1ap_du_data->nr_mode_info[i].fdd.ul_nrb; + /* FDD.4 DL Transmission Bandwidth */ + fDD_Info->dL_Transmission_Bandwidth.nRSCS = f1ap_du_data->nr_mode_info[i].fdd.dl_scs; + fDD_Info->dL_Transmission_Bandwidth.nRNRB = f1ap_du_data->nr_mode_info[i].fdd.dl_nrb; + + nR_Mode_Info.choice.fDD = fDD_Info; + } else { // TDD + nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_tDD; + F1AP_TDD_Info_t *tDD_Info = (F1AP_TDD_Info_t *)calloc(1, sizeof(F1AP_TDD_Info_t)); + + /* TDD.1 nRFreqInfo */ + /* TDD.1.1 nRFreqInfo ARFCN */ + tDD_Info->nRFreqInfo.nRARFCN = f1ap_du_data->nr_mode_info[i].tdd.nr_arfcn; // Integer + + /* TDD.1.2 F1AP_SUL_Information */ + if(0) { // Optional + F1AP_SUL_Information_t *tdd_sul_info = (F1AP_SUL_Information_t *)calloc(1, sizeof(F1AP_SUL_Information_t)); + tdd_sul_info->sUL_NRARFCN = 0; + tdd_sul_info->sUL_transmission_Bandwidth.nRSCS = 0; + tdd_sul_info->sUL_transmission_Bandwidth.nRNRB = 0; + tDD_Info->nRFreqInfo.sul_Information = tdd_sul_info; + } + + /* TDD.1.3 freqBandListNr */ + int tdd_num_available_freq_Bands = f1ap_du_data->nr_mode_info[i].tdd.num_frequency_bands; + LOG_D(F1AP, "tdd_num_available_freq_Bands = %d \n", tdd_num_available_freq_Bands); + int j; + for (j=0; + j<tdd_num_available_freq_Bands; + j++) { + + F1AP_FreqBandNrItem_t nr_freqBandNrItem; + memset((void *)&nr_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t)); + /* TDD.1.3.1 freqBandIndicatorNr*/ + nr_freqBandNrItem.freqBandIndicatorNr = *f1ap_du_data->nr_mode_info[i].tdd.nr_band; // + + /* TDD.1.3.2 supportedSULBandList*/ + int num_available_supported_SULBands = f1ap_du_data->nr_mode_info[i].tdd.num_sul_frequency_bands; + LOG_D(F1AP, "num_available_supported_SULBands = %d \n", num_available_supported_SULBands); + int k; + for (k=0; + k<num_available_supported_SULBands; + k++) { + F1AP_SupportedSULFreqBandItem_t nr_supportedSULFreqBandItem; + memset((void *)&nr_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t)); + /* TDD.1.3.2.1 freqBandIndicatorNr */ + nr_supportedSULFreqBandItem.freqBandIndicatorNr = *f1ap_du_data->nr_mode_info[i].tdd.nr_sul_band; // + ASN_SEQUENCE_ADD(&nr_freqBandNrItem.supportedSULBandList.list, &nr_supportedSULFreqBandItem); + } // for TDD : supported_SULBands + ASN_SEQUENCE_ADD(&tDD_Info->nRFreqInfo.freqBandListNr.list, &nr_freqBandNrItem); + } // for TDD : freq_Bands + + /* TDD.2 transmission_Bandwidth */ + tDD_Info->transmission_Bandwidth.nRSCS = f1ap_du_data->nr_mode_info[i].tdd.scs; + tDD_Info->transmission_Bandwidth.nRNRB = f1ap_du_data->nr_mode_info[i].tdd.nrb; + + nR_Mode_Info.choice.tDD = tDD_Info; + } // if nR_Mode_Info + + served_cell_information.nR_Mode_Info = nR_Mode_Info; + + /* - measurementTimingConfiguration */ + char *measurementTimingConfiguration = f1ap_du_data->measurement_timing_information[i]; // sept. 2018 + + OCTET_STRING_fromBuf(&served_cell_information.measurementTimingConfiguration, + measurementTimingConfiguration, + strlen(measurementTimingConfiguration)); + gnb_du_served_cells_item.served_Cell_Information = served_cell_information; // + + /* 4.1.2 gNB-DU System Information */ + F1AP_GNB_DU_System_Information_t *gNB_DU_System_Information = (F1AP_GNB_DU_System_Information_t *)calloc(1, sizeof(F1AP_GNB_DU_System_Information_t)); + + OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message, // sept. 2018 + (const char*)f1ap_du_data->mib[i],//f1ap_du_data->mib, + f1ap_du_data->mib_length[i]); + + OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message, // sept. 2018 + (const char*)f1ap_du_data->sib1[i], + f1ap_du_data->sib1_length[i]); + + gnb_du_served_cells_item.gNB_DU_System_Information = gNB_DU_System_Information; // + + /* ADD */ + gnb_du_served_cell_list_item_ies->value.choice.GNB_DU_Served_Cells_Item = gnb_du_served_cells_item; + + ASN_SEQUENCE_ADD(&ie->value.choice.GNB_DU_Served_Cells_List.list, + gnb_du_served_cell_list_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_F1AP_DU, + MSC_F1AP_CU, + (const char *)buffer, + len, + MSC_AS_TIME_FMT" F1_SETUP_REQUEST initiatingMessage gNB_DU_name %s", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + f1ap_du_data->gNB_DU_name); + + du_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data->assoc_id, buffer, len, 0); + + return 0; +} + +int DU_handle_F1_SETUP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) +{ + + LOG_D(F1AP, "DU_handle_F1_SETUP_RESPONSE\n"); + + AssertFatal(pdu->present == F1AP_F1AP_PDU_PR_successfulOutcome, + "pdu->present != F1AP_F1AP_PDU_PR_successfulOutcome\n"); + AssertFatal(pdu->choice.successfulOutcome->procedureCode == F1AP_ProcedureCode_id_F1Setup, + "pdu->choice.successfulOutcome->procedureCode != F1AP_ProcedureCode_id_F1Setup\n"); + AssertFatal(pdu->choice.successfulOutcome->criticality == F1AP_Criticality_reject, + "pdu->choice.successfulOutcome->criticality != F1AP_Criticality_reject\n"); + AssertFatal(pdu->choice.successfulOutcome->value.present == F1AP_SuccessfulOutcome__value_PR_F1SetupResponse, + "pdu->choice.successfulOutcome->value.present != F1AP_SuccessfulOutcome__value_PR_F1SetupResponse\n"); + + F1AP_F1SetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.F1SetupResponse; + + + F1AP_F1SetupResponseIEs_t *ie; + int TransactionId = -1; + int num_cells_to_activate = 0; + F1AP_Cells_to_be_Activated_List_Item_t *cell; + + MessageDef *msg_p = itti_alloc_new_message (TASK_DU_F1, F1AP_SETUP_RESP); + + LOG_D(F1AP, "F1AP: F1Setup-Resp: protocolIEs.list.count %d\n", + in->protocolIEs.list.count); + for (int i=0;i < in->protocolIEs.list.count; i++) { + ie = in->protocolIEs.list.array[i]; + switch (ie->id) { + case F1AP_ProtocolIE_ID_id_TransactionID: + AssertFatal(ie->criticality == F1AP_Criticality_reject, + "ie->criticality != F1AP_Criticality_reject\n"); + AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_TransactionID, + "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n"); + TransactionId=ie->value.choice.TransactionID; + LOG_D(F1AP, "F1AP: F1Setup-Resp: TransactionId %d\n", + TransactionId); + break; + case F1AP_ProtocolIE_ID_id_gNB_CU_Name: + AssertFatal(ie->criticality == F1AP_Criticality_ignore, + "ie->criticality != F1AP_Criticality_ignore\n"); + AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_GNB_CU_Name, + "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_TransactionID\n"); + F1AP_SETUP_RESP (msg_p).gNB_CU_name = malloc(ie->value.choice.GNB_CU_Name.size+1); + memcpy(F1AP_SETUP_RESP (msg_p).gNB_CU_name,ie->value.choice.GNB_CU_Name.buf,ie->value.choice.GNB_CU_Name.size); + F1AP_SETUP_RESP (msg_p).gNB_CU_name[ie->value.choice.GNB_CU_Name.size]='\0'; + LOG_D(F1AP, "F1AP: F1Setup-Resp: gNB_CU_name %s\n", + F1AP_SETUP_RESP (msg_p).gNB_CU_name); + break; + case F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List: + AssertFatal(ie->criticality == F1AP_Criticality_reject, + "ie->criticality != F1AP_Criticality_reject\n"); + AssertFatal(ie->value.present == F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List, + "ie->value.present != F1AP_F1SetupResponseIEs__value_PR_Cells_to_be_Activated_List\n"); + num_cells_to_activate = ie->value.choice.Cells_to_be_Activated_List.list.count; + LOG_D(F1AP, "F1AP: Activating %d cells\n",num_cells_to_activate); + for (int i=0;i<num_cells_to_activate;i++) { + + F1AP_Cells_to_be_Activated_List_ItemIEs_t *cells_to_be_activated_list_item_ies = (F1AP_Cells_to_be_Activated_List_ItemIEs_t *) ie->value.choice.Cells_to_be_Activated_List.list.array[i]; + + AssertFatal(cells_to_be_activated_list_item_ies->id == F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item, + "cells_to_be_activated_list_item_ies->id != F1AP_ProtocolIE_ID_id_Cells_to_be_Activated_List_Item"); + AssertFatal(cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject, + "cells_to_be_activated_list_item_ies->criticality == F1AP_Criticality_reject"); + AssertFatal(cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item, + "cells_to_be_activated_list_item_ies->value.present == F1AP_Cells_to_be_Activated_List_ItemIEs__value_PR_Cells_to_be_Activated_List_Item"); + + cell = &cells_to_be_activated_list_item_ies->value.choice.Cells_to_be_Activated_List_Item; + + TBCD_TO_MCC_MNC(&cell->nRCGI.pLMN_Identity, F1AP_SETUP_RESP (msg_p).mcc[i], F1AP_SETUP_RESP (msg_p).mnc[i], F1AP_SETUP_RESP (msg_p).mnc_digit_length[i]); + AssertFatal(cell->nRPCI != NULL, "nRPCI is null\n"); + LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n", + cell->nRCGI.nRCellIdentity.buf[0], + cell->nRCGI.nRCellIdentity.buf[1], + cell->nRCGI.nRCellIdentity.buf[2], + cell->nRCGI.nRCellIdentity.buf[3], + cell->nRCGI.nRCellIdentity.buf[4]); + BIT_STRING_TO_NR_CELL_IDENTITY(&cell->nRCGI.nRCellIdentity, + F1AP_SETUP_RESP (msg_p).nr_cellid[i]); + F1AP_SETUP_RESP (msg_p).nrpci[i] = *cell->nRPCI; + + F1AP_ProtocolExtensionContainer_160P9_t *ext = (F1AP_ProtocolExtensionContainer_160P9_t *)cell->iE_Extensions; + AssertFatal(ext!=NULL,"Extension for SI is null\n"); + F1AP_SETUP_RESP (msg_p).num_SI[i] = ext->list.count; + AssertFatal(ext->list.count==1,"At least one SI message should be there, and only 1 for now!\n"); + LOG_D(F1AP, "F1AP: F1Setup-Resp Cell %d MCC %d MNC %d NRCellid %lx num_si %d\n", + i, F1AP_SETUP_RESP (msg_p).mcc[i], F1AP_SETUP_RESP (msg_p).mnc[i], + F1AP_SETUP_RESP (msg_p).nr_cellid[i], F1AP_SETUP_RESP (msg_p).num_SI[i]); + for (int si =0;si < ext->list.count;si++) { + size_t size = ext->list.array[si]->extensionValue.choice.GNB_CUSystemInformation.sImessage.size; + F1AP_SETUP_RESP (msg_p).SI_container_length[i][si] = size; + LOG_D(F1AP, "F1AP: F1Setup-Resp SI_container_length[%d][%d] %ld bytes\n", i, si, size); + F1AP_SETUP_RESP (msg_p).SI_container[i][si] = malloc(F1AP_SETUP_RESP (msg_p).SI_container_length[i][si]); + + memcpy((void*)F1AP_SETUP_RESP (msg_p).SI_container[i][si], + (void*)ext->list.array[si]->extensionValue.choice.GNB_CUSystemInformation.sImessage.buf, + F1AP_SETUP_RESP (msg_p).SI_container_length[i][si]); + } + } + break; + } + } + AssertFatal(TransactionId!=-1,"TransactionId was not sent\n"); + AssertFatal(num_cells_to_activate>0,"No cells activated\n"); + F1AP_SETUP_RESP (msg_p).num_cells_to_activate = num_cells_to_activate; + + for (int i=0;i<num_cells_to_activate;i++) + AssertFatal(F1AP_SETUP_RESP (msg_p).num_SI[i] > 0, "System Information %d is missing",i); + + MSC_LOG_RX_MESSAGE( + MSC_F1AP_DU, + MSC_F1AP_CU, + 0, + 0, + MSC_AS_TIME_FMT" DU_handle_F1_SETUP_RESPONSE successfulOutcome assoc_id %d", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + assoc_id); + + LOG_D(F1AP, "Sending F1AP_SETUP_RESP ITTI message to ENB_APP with assoc_id (%d->%d)\n", + assoc_id,ENB_MODULE_ID_TO_INSTANCE(assoc_id)); + itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(assoc_id), msg_p); + + return 0; +} + +// SETUP FAILURE +int DU_handle_F1_SETUP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + LOG_E(F1AP, "DU_handle_F1_SETUP_FAILURE\n"); + return 0; +} + + +/* + gNB-DU Configuration Update +*/ + +//void DU_send_gNB_DU_CONFIGURATION_UPDATE(F1AP_GNBDUConfigurationUpdate_t *GNBDUConfigurationUpdate) { +int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, + instance_t du_mod_idP, + f1ap_setup_req_t *f1ap_setup_req) { + F1AP_F1AP_PDU_t pdu; + F1AP_GNBDUConfigurationUpdate_t *out; + F1AP_GNBDUConfigurationUpdateIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0; + int j = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_gNBDUConfigurationUpdate; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_reject; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_GNBDUConfigurationUpdate; + out = &pdu.choice.initiatingMessage->value.choice.GNBDUConfigurationUpdate; + + /* mandatory */ + /* c1. Transaction ID (integer value) */ + ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_TransactionID; + ie->value.choice.TransactionID = F1AP_get_next_transaction_identifier(instance, du_mod_idP); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c2. Served_Cells_To_Add */ + ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Add_List; + + for (j=0; + j<1; + j++) { + // + F1AP_Served_Cells_To_Add_ItemIEs_t *served_cells_to_add_item_ies; + served_cells_to_add_item_ies = (F1AP_Served_Cells_To_Add_ItemIEs_t *)calloc(1, sizeof(F1AP_Served_Cells_To_Add_ItemIEs_t)); + served_cells_to_add_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_Item; + served_cells_to_add_item_ies->criticality = F1AP_Criticality_reject; + served_cells_to_add_item_ies->value.present = F1AP_Served_Cells_To_Add_ItemIEs__value_PR_Served_Cells_To_Add_Item; + + F1AP_Served_Cells_To_Add_Item_t served_cells_to_add_item; + memset((void *)&served_cells_to_add_item, 0, sizeof(F1AP_Served_Cells_To_Add_Item_t)); + + /* 2.1.1 serverd cell Information */ + F1AP_Served_Cell_Information_t served_cell_information; + + memset((void *)&served_cell_information, 0, sizeof(F1AP_Served_Cell_Information_t)); + /* - nRCGI */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], &nRCGI.pLMN_Identity); + LOG_D(F1AP, "nr_cellId : %x %x %x %x %x\n", + nRCGI.nRCellIdentity.buf[0], + nRCGI.nRCellIdentity.buf[1], + nRCGI.nRCellIdentity.buf[2], + nRCGI.nRCellIdentity.buf[3], + nRCGI.nRCellIdentity.buf[4]); + NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &nRCGI.nRCellIdentity); + served_cell_information.nRCGI = nRCGI; + + /* - nRPCI */ + served_cell_information.nRPCI = f1ap_setup_req->nr_pci[i]; // int 0..1007 + + /* - fiveGS_TAC */ + OCTET_STRING_fromBuf(&served_cell_information.fiveGS_TAC, + (const char *) &f1ap_setup_req->tac[i], + 3); + + /* - Configured_EPS_TAC */ + if(1){ + served_cell_information.configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t)); + OCTET_STRING_fromBuf(served_cell_information.configured_EPS_TAC, + "2", + 2); + } + + /* - broadcast PLMNs */ + int maxnoofBPLMNS = 1; + for (i=0; + i<maxnoofBPLMNS; + i++) { + /* > PLMN BroadcastPLMNs Item */ + F1AP_BroadcastPLMNs_Item_t *broadcastPLMNs_Item = (F1AP_BroadcastPLMNs_Item_t *)calloc(1, sizeof(F1AP_BroadcastPLMNs_Item_t)); + //memset((void *)&broadcastPLMNs_Item, 0, sizeof(F1AP_BroadcastPLMNs_Item_t)); + MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], &broadcastPLMNs_Item->pLMN_Identity); + ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, broadcastPLMNs_Item); + } + + // // /* - CHOICE NR-MODE-Info */ + F1AP_NR_Mode_Info_t nR_Mode_Info; + + if (f1ap_setup_req->fdd_flag) { + nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_fDD; + /* > FDD >> FDD Info */ + F1AP_FDD_Info_t *fDD_Info = (F1AP_FDD_Info_t *)calloc(1, sizeof(F1AP_FDD_Info_t)); + /* >>> UL NRFreqInfo */ + fDD_Info->uL_NRFreqInfo.nRARFCN = 999L; + + F1AP_FreqBandNrItem_t ul_freqBandNrItem; + memset((void *)&ul_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t)); + ul_freqBandNrItem.freqBandIndicatorNr = 888L; + + F1AP_SupportedSULFreqBandItem_t ul_supportedSULFreqBandItem; + memset((void *)&ul_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t)); + ul_supportedSULFreqBandItem.freqBandIndicatorNr = 777L; + ASN_SEQUENCE_ADD(&ul_freqBandNrItem.supportedSULBandList.list, &ul_supportedSULFreqBandItem); + + ASN_SEQUENCE_ADD(&fDD_Info->uL_NRFreqInfo.freqBandListNr.list, &ul_freqBandNrItem); + + /* >>> DL NRFreqInfo */ + fDD_Info->dL_NRFreqInfo.nRARFCN = 666L; + + F1AP_FreqBandNrItem_t dl_freqBandNrItem; + memset((void *)&dl_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t)); + dl_freqBandNrItem.freqBandIndicatorNr = 555L; + + F1AP_SupportedSULFreqBandItem_t dl_supportedSULFreqBandItem; + memset((void *)&dl_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t)); + dl_supportedSULFreqBandItem.freqBandIndicatorNr = 444L; + ASN_SEQUENCE_ADD(&dl_freqBandNrItem.supportedSULBandList.list, &dl_supportedSULFreqBandItem); + + ASN_SEQUENCE_ADD(&fDD_Info->dL_NRFreqInfo.freqBandListNr.list, &dl_freqBandNrItem); + + /* >>> UL Transmission Bandwidth */ + fDD_Info->uL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15; + fDD_Info->uL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11; + /* >>> DL Transmission Bandwidth */ + fDD_Info->dL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15; + fDD_Info->dL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11; + + nR_Mode_Info.choice.fDD = fDD_Info; + } else { // TDD + nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_tDD; + + /* > TDD >> TDD Info */ + F1AP_TDD_Info_t *tDD_Info = (F1AP_TDD_Info_t *)calloc(1, sizeof(F1AP_TDD_Info_t)); + /* >>> ARFCN */ + tDD_Info->nRFreqInfo.nRARFCN = 999L; // Integer + F1AP_FreqBandNrItem_t nr_freqBandNrItem; + memset((void *)&nr_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t)); + nr_freqBandNrItem.freqBandIndicatorNr = 555L; + + F1AP_SupportedSULFreqBandItem_t nr_supportedSULFreqBandItem; + memset((void *)&nr_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t)); + nr_supportedSULFreqBandItem.freqBandIndicatorNr = 444L; + ASN_SEQUENCE_ADD(&nr_freqBandNrItem.supportedSULBandList.list, &nr_supportedSULFreqBandItem); + + ASN_SEQUENCE_ADD(&tDD_Info->nRFreqInfo.freqBandListNr.list, &nr_freqBandNrItem); + + tDD_Info->transmission_Bandwidth.nRSCS= F1AP_NRSCS_scs15; + tDD_Info->transmission_Bandwidth.nRNRB= F1AP_NRNRB_nrb11; + + nR_Mode_Info.choice.tDD = tDD_Info; + } + + served_cell_information.nR_Mode_Info = nR_Mode_Info; + + /* - measurementTimingConfiguration */ + char *measurementTimingConfiguration = "0"; // sept. 2018 + + OCTET_STRING_fromBuf(&served_cell_information.measurementTimingConfiguration, + measurementTimingConfiguration, + strlen(measurementTimingConfiguration)); + served_cells_to_add_item.served_Cell_Information = served_cell_information; // + + /* 2.1.2 gNB-DU System Information */ + F1AP_GNB_DU_System_Information_t *gNB_DU_System_Information = (F1AP_GNB_DU_System_Information_t *)calloc(1, sizeof(F1AP_GNB_DU_System_Information_t)); + + OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message, // sept. 2018 + "1", + sizeof("1")); + + OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message, // sept. 2018 + "1", + sizeof("1")); + served_cells_to_add_item.gNB_DU_System_Information = gNB_DU_System_Information; // + + /* ADD */ + served_cells_to_add_item_ies->value.choice.Served_Cells_To_Add_Item = served_cells_to_add_item; + + ASN_SEQUENCE_ADD(&ie->value.choice.Served_Cells_To_Add_List.list, + served_cells_to_add_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c3. Served_Cells_To_Modify */ + ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Modify_List; + + for (i=0; + i<1; + i++) { + // + F1AP_Served_Cells_To_Modify_ItemIEs_t *served_cells_to_modify_item_ies; + served_cells_to_modify_item_ies = (F1AP_Served_Cells_To_Modify_ItemIEs_t *)calloc(1, sizeof(F1AP_Served_Cells_To_Modify_ItemIEs_t)); + served_cells_to_modify_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_Item; + served_cells_to_modify_item_ies->criticality = F1AP_Criticality_reject; + served_cells_to_modify_item_ies->value.present = F1AP_Served_Cells_To_Modify_ItemIEs__value_PR_Served_Cells_To_Modify_Item; + + F1AP_Served_Cells_To_Modify_Item_t served_cells_to_modify_item; + memset((void *)&served_cells_to_modify_item, 0, sizeof(F1AP_Served_Cells_To_Modify_Item_t)); + + /* 3.1 oldNRCGI */ + F1AP_NRCGI_t oldNRCGI; + MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], + &oldNRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &oldNRCGI.nRCellIdentity); + served_cells_to_modify_item.oldNRCGI = oldNRCGI; + + + /* 3.2.1 serverd cell Information */ + F1AP_Served_Cell_Information_t served_cell_information; + memset((void *)&served_cell_information, 0, sizeof(F1AP_Served_Cell_Information_t)); + + /* - nRCGI */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &nRCGI.nRCellIdentity); + served_cell_information.nRCGI = nRCGI; + + /* - nRPCI */ + served_cell_information.nRPCI = f1ap_setup_req->nr_pci[i]; // int 0..1007 + + /* - fiveGS_TAC */ + OCTET_STRING_fromBuf(&served_cell_information.fiveGS_TAC, + (const char *) &f1ap_setup_req->tac[i], + 3); + + /* - Configured_EPS_TAC */ + if(1){ + served_cell_information.configured_EPS_TAC = (F1AP_Configured_EPS_TAC_t *)calloc(1, sizeof(F1AP_Configured_EPS_TAC_t)); + OCTET_STRING_fromBuf(served_cell_information.configured_EPS_TAC, + "2", + 2); + } + + /* - broadcast PLMNs */ + int maxnoofBPLMNS = 1; + for (i=0; + i<maxnoofBPLMNS; + i++) { + /* > PLMN BroadcastPLMNs Item */ + F1AP_BroadcastPLMNs_Item_t *broadcastPLMNs_Item = (F1AP_BroadcastPLMNs_Item_t *)calloc(1, sizeof(F1AP_BroadcastPLMNs_Item_t)); + //memset((void *)&broadcastPLMNs_Item, 0, sizeof(F1AP_BroadcastPLMNs_Item_t)); + MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], &broadcastPLMNs_Item->pLMN_Identity); + ASN_SEQUENCE_ADD(&served_cell_information.servedPLMNs.list, broadcastPLMNs_Item); + } + + // // /* - CHOICE NR-MODE-Info */ + F1AP_NR_Mode_Info_t nR_Mode_Info; + + if (f1ap_setup_req->fdd_flag) { + nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_fDD; + /* > FDD >> FDD Info */ + F1AP_FDD_Info_t *fDD_Info = (F1AP_FDD_Info_t *)calloc(1, sizeof(F1AP_FDD_Info_t)); + /* >>> UL NRFreqInfo */ + fDD_Info->uL_NRFreqInfo.nRARFCN = 999L; + + F1AP_FreqBandNrItem_t ul_freqBandNrItem; + memset((void *)&ul_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t)); + ul_freqBandNrItem.freqBandIndicatorNr = 888L; + + F1AP_SupportedSULFreqBandItem_t ul_supportedSULFreqBandItem; + memset((void *)&ul_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t)); + ul_supportedSULFreqBandItem.freqBandIndicatorNr = 777L; + ASN_SEQUENCE_ADD(&ul_freqBandNrItem.supportedSULBandList.list, &ul_supportedSULFreqBandItem); + + ASN_SEQUENCE_ADD(&fDD_Info->uL_NRFreqInfo.freqBandListNr.list, &ul_freqBandNrItem); + + /* >>> DL NRFreqInfo */ + fDD_Info->dL_NRFreqInfo.nRARFCN = 666L; + + F1AP_FreqBandNrItem_t dl_freqBandNrItem; + memset((void *)&dl_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t)); + dl_freqBandNrItem.freqBandIndicatorNr = 555L; + + F1AP_SupportedSULFreqBandItem_t dl_supportedSULFreqBandItem; + memset((void *)&dl_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t)); + dl_supportedSULFreqBandItem.freqBandIndicatorNr = 444L; + ASN_SEQUENCE_ADD(&dl_freqBandNrItem.supportedSULBandList.list, &dl_supportedSULFreqBandItem); + + ASN_SEQUENCE_ADD(&fDD_Info->dL_NRFreqInfo.freqBandListNr.list, &dl_freqBandNrItem); + + /* >>> UL Transmission Bandwidth */ + fDD_Info->uL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15; + fDD_Info->uL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11; + /* >>> DL Transmission Bandwidth */ + fDD_Info->dL_Transmission_Bandwidth.nRSCS = F1AP_NRSCS_scs15; + fDD_Info->dL_Transmission_Bandwidth.nRNRB = F1AP_NRNRB_nrb11; + + nR_Mode_Info.choice.fDD = fDD_Info; + } else { // TDD + nR_Mode_Info.present = F1AP_NR_Mode_Info_PR_tDD; + + /* > TDD >> TDD Info */ + F1AP_TDD_Info_t *tDD_Info = (F1AP_TDD_Info_t *)calloc(1, sizeof(F1AP_TDD_Info_t)); + /* >>> ARFCN */ + tDD_Info->nRFreqInfo.nRARFCN = 999L; // Integer + F1AP_FreqBandNrItem_t nr_freqBandNrItem; + memset((void *)&nr_freqBandNrItem, 0, sizeof(F1AP_FreqBandNrItem_t)); + nr_freqBandNrItem.freqBandIndicatorNr = 555L; + + F1AP_SupportedSULFreqBandItem_t nr_supportedSULFreqBandItem; + memset((void *)&nr_supportedSULFreqBandItem, 0, sizeof(F1AP_SupportedSULFreqBandItem_t)); + nr_supportedSULFreqBandItem.freqBandIndicatorNr = 444L; + ASN_SEQUENCE_ADD(&nr_freqBandNrItem.supportedSULBandList.list, &nr_supportedSULFreqBandItem); + + ASN_SEQUENCE_ADD(&tDD_Info->nRFreqInfo.freqBandListNr.list, &nr_freqBandNrItem); + + tDD_Info->transmission_Bandwidth.nRSCS= F1AP_NRSCS_scs15; + tDD_Info->transmission_Bandwidth.nRNRB= F1AP_NRNRB_nrb11; + + nR_Mode_Info.choice.tDD = tDD_Info; + } + + served_cell_information.nR_Mode_Info = nR_Mode_Info; + + /* - measurementTimingConfiguration */ + char *measurementTimingConfiguration = "0"; // sept. 2018 + + OCTET_STRING_fromBuf(&served_cell_information.measurementTimingConfiguration, + measurementTimingConfiguration, + strlen(measurementTimingConfiguration)); + served_cells_to_modify_item.served_Cell_Information = served_cell_information; // + + /* 3.2.2 gNB-DU System Information */ + F1AP_GNB_DU_System_Information_t *gNB_DU_System_Information = (F1AP_GNB_DU_System_Information_t *)calloc(1, sizeof(F1AP_GNB_DU_System_Information_t)); + + OCTET_STRING_fromBuf(&gNB_DU_System_Information->mIB_message, // sept. 2018 + "1", + sizeof("1")); + + OCTET_STRING_fromBuf(&gNB_DU_System_Information->sIB1_message, // sept. 2018 + "1", + sizeof("1")); + served_cells_to_modify_item.gNB_DU_System_Information = gNB_DU_System_Information; // + + /* ADD */ + served_cells_to_modify_item_ies->value.choice.Served_Cells_To_Modify_Item = served_cells_to_modify_item; + + ASN_SEQUENCE_ADD(&ie->value.choice.Served_Cells_To_Modify_List.list, + served_cells_to_modify_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c4. Served_Cells_To_Delete */ + ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Delete_List; + + for (i=0; + i<1; + i++) { + // + F1AP_Served_Cells_To_Delete_ItemIEs_t *served_cells_to_delete_item_ies; + served_cells_to_delete_item_ies = (F1AP_Served_Cells_To_Delete_ItemIEs_t *)calloc(1, sizeof(F1AP_Served_Cells_To_Delete_ItemIEs_t)); + served_cells_to_delete_item_ies->id = F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_Item; + served_cells_to_delete_item_ies->criticality = F1AP_Criticality_reject; + served_cells_to_delete_item_ies->value.present = F1AP_Served_Cells_To_Delete_ItemIEs__value_PR_Served_Cells_To_Delete_Item; + + F1AP_Served_Cells_To_Delete_Item_t served_cells_to_delete_item; + memset((void *)&served_cells_to_delete_item, 0, sizeof(F1AP_Served_Cells_To_Delete_Item_t)); + + /* 3.1 oldNRCGI */ + F1AP_NRCGI_t oldNRCGI; + MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], + &oldNRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &oldNRCGI.nRCellIdentity); + served_cells_to_delete_item.oldNRCGI = oldNRCGI; + + /* ADD */ + served_cells_to_delete_item_ies->value.choice.Served_Cells_To_Delete_Item = served_cells_to_delete_item; + + ASN_SEQUENCE_ADD(&ie->value.choice.Served_Cells_To_Delete_List.list, + served_cells_to_delete_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c5. Active_Cells_List */ + ie = (F1AP_GNBDUConfigurationUpdateIEs_t *)calloc(1, sizeof(F1AP_GNBDUConfigurationUpdateIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Active_Cells_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_GNBDUConfigurationUpdateIEs__value_PR_Active_Cells_List; + + for (i=0; + i<1; + i++) { + // + F1AP_Active_Cells_ItemIEs_t *active_cells_item_ies; + active_cells_item_ies = (F1AP_Active_Cells_ItemIEs_t *)calloc(1, sizeof(F1AP_Active_Cells_ItemIEs_t)); + active_cells_item_ies->id = F1AP_ProtocolIE_ID_id_Active_Cells_Item; + active_cells_item_ies->criticality = F1AP_Criticality_reject; + active_cells_item_ies->value.present = F1AP_Active_Cells_ItemIEs__value_PR_Active_Cells_Item; + + F1AP_Active_Cells_Item_t active_cells_item; + memset((void *)&active_cells_item, 0, sizeof(F1AP_Active_Cells_Item_t)); + + /* 3.1 oldNRCGI */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(f1ap_setup_req->mcc[i], f1ap_setup_req->mnc[i], f1ap_setup_req->mnc_digit_length[i], + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(f1ap_setup_req->nr_cellid[i], &nRCGI.nRCellIdentity); + active_cells_item.nRCGI = nRCGI; + + /* ADD */ + active_cells_item_ies->value.choice.Active_Cells_Item = active_cells_item; + + ASN_SEQUENCE_ADD(&ie->value.choice.Active_Cells_List.list, + active_cells_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + return 0; +} + + + +int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + +int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + F1AP_GNBCUConfigurationUpdateFailure_t *GNBCUConfigurationUpdateFailure) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + F1AP_GNBCUConfigurationUpdateAcknowledge_t *GNBCUConfigurationUpdateAcknowledge) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + +int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, + F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest) { + AssertFatal(0, "Not implemented yet\n"); +} + +int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(0, "Not implemented yet\n"); +} diff --git a/openair2/F1AP/f1ap_du_interface_management.h b/openair2/F1AP/f1ap_du_interface_management.h new file mode 100644 index 0000000000000000000000000000000000000000..941b86a6d4228d7e61539c5de198178de363471e --- /dev/null +++ b/openair2/F1AP/f1ap_du_interface_management.h @@ -0,0 +1,118 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#ifndef F1AP_DU_INTERFACE_MANAGEMENT_H_ +#define F1AP_DU_INTERFACE_MANAGEMENT_H_ + +/* + * Reset + */ +int DU_handle_RESET(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); +int DU_send_RESET_ACKKNOWLEDGE(instance_t instance, F1AP_ResetAcknowledge_t *ResetAcknowledge); +int DU_send_RESET(instance_t instance, F1AP_Reset_t *Reset); +int DU_handle_RESET_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +/* + * Error Indication + */ +int DU_send_ERROR_INDICATION(instance_t instance, F1AP_F1AP_PDU_t *pdu_p); +int DU_handle_ERROR_INDICATION(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + + +/* + * F1 Setup + */ +int DU_send_F1_SETUP_REQUEST(instance_t instance); + +int DU_handle_F1_SETUP_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +int DU_handle_F1_SETUP_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +/* + * gNB-DU Configuration Update + */ +int DU_send_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, + instance_t du_mod_idP, + f1ap_setup_req_t *f1ap_du_data); + +int DU_handle_gNB_DU_CONFIGURATION_FAILURE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +int DU_handle_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +/* + * gNB-CU Configuration Update + */ +int DU_handle_gNB_CU_CONFIGURATION_UPDATE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +int DU_send_gNB_CU_CONFIGURATION_UPDATE_FAILURE(instance_t instance, + F1AP_GNBCUConfigurationUpdateFailure_t *GNBCUConfigurationUpdateFailure); + +int DU_send_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, + F1AP_GNBCUConfigurationUpdateAcknowledge_t *GNBCUConfigurationUpdateAcknowledge); + + +/* + * gNB-DU Resource Coordination + */ +int DU_send_gNB_DU_RESOURCE_COORDINATION_REQUEST(instance_t instance, + F1AP_GNBDUResourceCoordinationRequest_t *GNBDUResourceCoordinationRequest); + +int DU_handle_gNB_DU_RESOURCE_COORDINATION_RESPONSE(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +#endif /* F1AP_DU_INTERFACE_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/f1ap_du_paging.c b/openair2/F1AP/f1ap_du_paging.c new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_du_paging.c @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_du_paging.h b/openair2/F1AP/f1ap_du_paging.h new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_du_paging.h @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c new file mode 100644 index 0000000000000000000000000000000000000000..902cebcb3dd92262fc36ecbc28f0fa1facbe4497 --- /dev/null +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -0,0 +1,881 @@ +/* + * 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 f1ap_du_rrc_message_transfer.c + * \brief f1ap rrc message transfer for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#include "f1ap_common.h" +#include "f1ap_encoder.h" +#include "f1ap_decoder.h" +#include "f1ap_itti_messaging.h" + +#include "f1ap_du_rrc_message_transfer.h" + + +#include "LTE_DL-CCCH-Message.h" +#include "LTE_DL-DCCH-Message.h" +#include "LTE_UL-DCCH-Message.h" + +// for SRB1_logicalChannelConfig_defaultValue +#include "rrc_extern.h" +#include "common/ran_context.h" + +#include "rrc_eNB_UE_context.h" + +// undefine C_RNTI from +// openair1/PHY/LTE_TRANSPORT/transport_common.h which +// replaces in ie->value.choice.C_RNTI, causing +// a compile error + +#undef C_RNTI + +extern f1ap_setup_req_t *f1ap_du_data; +extern RAN_CONTEXT_t RC; +extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB]; + + + +/* DL RRC Message Transfer */ +int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + LOG_D(F1AP, "DU_handle_DL_RRC_MESSAGE_TRANSFER \n"); + + F1AP_DLRRCMessageTransfer_t *container; + F1AP_DLRRCMessageTransferIEs_t *ie; + + uint64_t cu_ue_f1ap_id; + uint64_t du_ue_f1ap_id; + uint64_t srb_id; + int executeDuplication; + sdu_size_t rrc_dl_sdu_len; + //uint64_t subscriberProfileIDforRFP; + //uint64_t rAT_FrequencySelectionPriority; + + DevAssert(pdu != NULL); + + if (stream != 0) { + LOG_E(F1AP, "[SCTP %d] Received F1 on stream != 0 (%d)\n", + assoc_id, stream); + return -1; + } + + container = &pdu->choice.initiatingMessage->value.choice.DLRRCMessageTransfer; + + + /* GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + cu_ue_f1ap_id = ie->value.choice.GNB_CU_UE_F1AP_ID; + LOG_D(F1AP, "cu_ue_f1ap_id %lu \n", cu_ue_f1ap_id); + + + /* GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + du_ue_f1ap_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + LOG_D(F1AP, "du_ue_f1ap_id %lu associated with UE RNTI %x \n", + du_ue_f1ap_id, + f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id)); // this should be the one transmitted via initial ul rrc message transfer + + if (f1ap_du_add_cu_ue_id(&f1ap_du_inst[instance],du_ue_f1ap_id, cu_ue_f1ap_id) < 0 ) { + LOG_E(F1AP, "Failed to find the F1AP UID \n"); + //return -1; + } + + /* optional */ + /* oldgNB_DU_UE_F1AP_ID */ + if (0) { + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, true); + } + + /* mandatory */ + /* SRBID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_SRBID, true); + srb_id = ie->value.choice.SRBID; + LOG_D(F1AP, "srb_id %lu \n", srb_id); + + /* optional */ + /* ExecuteDuplication */ + if (0) { + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_ExecuteDuplication, true); + executeDuplication = ie->value.choice.ExecuteDuplication; + LOG_D(F1AP, "ExecuteDuplication %d \n", executeDuplication); + } + + // issue in here + /* mandatory */ + /* RRC Container */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_RRCContainer, true); + // BK: need check + // create an ITTI message and copy SDU + + // message_p = itti_alloc_new_message (TASK_CU_F1, RRC_MAC_CCCH_DATA_IND); + // memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + rrc_dl_sdu_len = ie->value.choice.RRCContainer.size; + // memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf, + // ccch_sdu_len); + + //LOG_I(F1AP, "%s() RRCContainer size %lu: ", __func__, ie->value.choice.RRCContainer.size); + //for (int i = 0;i < ie->value.choice.RRCContainer.size; i++) + // printf("%02x ", ie->value.choice.RRCContainer.buf[i]); + //printf("\n"); + + /* optional */ + /* RAT_FrequencyPriorityInformation */ + if (0) { + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation, true); + + switch(ie->value.choice.RAT_FrequencyPriorityInformation.present) { + case F1AP_RAT_FrequencyPriorityInformation_PR_subscriberProfileIDforRFP: + //subscriberProfileIDforRFP = ie->value.choice.RAT_FrequencyPriorityInformation.choice.subscriberProfileIDforRFP; + break; + case F1AP_RAT_FrequencyPriorityInformation_PR_rAT_FrequencySelectionPriority: + //rAT_FrequencySelectionPriority = ie->value.choice.RAT_FrequencyPriorityInformation.choice.rAT_FrequencySelectionPriority; + break; + default: + LOG_W(F1AP, "unhandled IE RAT_FrequencyPriorityInformation.present\n"); + break; + } + } + + // decode RRC Container and act on the message type + AssertFatal(srb_id<3,"illegal srb_id\n"); + + protocol_ctxt_t ctxt; + ctxt.rnti = f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id); + ctxt.module_id = instance; + ctxt.instance = instance; + ctxt.enb_flag = 1; + + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context( + RC.rrc[ctxt.module_id], + ctxt.rnti); + + if (srb_id == 0) { + LTE_DL_CCCH_Message_t* dl_ccch_msg=NULL; + asn_dec_rval_t dec_rval; + dec_rval = uper_decode(NULL, + &asn_DEF_LTE_DL_CCCH_Message, + (void**)&dl_ccch_msg, + ie->value.choice.RRCContainer.buf, + rrc_dl_sdu_len,0,0); + AssertFatal(dec_rval.code == RC_OK, "could not decode F1AP message\n"); + switch (dl_ccch_msg->message.choice.c1.present) { + + case LTE_DL_CCCH_MessageType__c1_PR_NOTHING: + LOG_I(F1AP, "Received PR_NOTHING on DL-CCCH-Message\n"); + break; + + case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment: + LOG_I(F1AP, + "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishment\n"); + break; + + case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject: + LOG_I(F1AP, + "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishmentReject\n"); + break; + + case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReject: + LOG_I(F1AP, + "Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n"); + break; + + case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup: + { + LOG_I(F1AP, + "Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup DU_ID %lx/RNTI %x\n", + du_ue_f1ap_id, + f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id)); + // Get configuration + + LTE_RRCConnectionSetup_t* rrcConnectionSetup = &dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup; + AssertFatal(rrcConnectionSetup!=NULL,"rrcConnectionSetup is null\n"); + LTE_RadioResourceConfigDedicated_t* radioResourceConfigDedicated = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated; + + // get SRB logical channel information + LTE_SRB_ToAddModList_t *SRB_configList; + LTE_SRB_ToAddMod_t *SRB1_config; + LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL; + SRB_configList = radioResourceConfigDedicated->srb_ToAddModList; + + AssertFatal(SRB_configList!=NULL,"SRB_configList is null\n"); + for (int cnt = 0; cnt < (SRB_configList)->list.count; cnt++) { + if ((SRB_configList)->list.array[cnt]->srb_Identity == 1) { + SRB1_config = (SRB_configList)->list.array[cnt]; + + if (SRB1_config->logicalChannelConfig) { + if (SRB1_config->logicalChannelConfig->present == + LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; + } else { + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + } + } else { + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + } + } + } // for + rrc_rlc_config_asn1_req(&ctxt, + SRB_configList, + (LTE_DRB_ToAddModList_t*) NULL, + (LTE_DRB_ToReleaseList_t*) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL, + 0,0 +# endif + ); + + // This should be somewhere in the f1ap_cudu_ue_inst_t + /*int macrlc_instance = 0; + + rnti_t rnti = f1ap_get_rnti_by_du_id(&f1ap_du_inst[0], du_ue_f1ap_id); + struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[macrlc_instance],rnti); + */ + eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; + AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n"); + + memcpy((void*)ue_p->Srb0.Tx_buffer.Payload, + (void*)ie->value.choice.RRCContainer.buf, + rrc_dl_sdu_len); // ie->value.choice.RRCContainer.size + + ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len; + + LTE_MAC_MainConfig_t *mac_MainConfig = NULL; + if (radioResourceConfigDedicated->mac_MainConfig) + mac_MainConfig = &radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; + + rrc_mac_config_req_eNB( + ctxt.module_id, + 0, //primaryCC_id, + 0,0,0,0,0, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + 0, +#endif + ctxt.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#endif + radioResourceConfigDedicated->physicalConfigDedicated, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, +#endif + (LTE_MeasObjectToAddMod_t **) NULL, + mac_MainConfig, + 1, + SRB1_logicalChannelConfig, + NULL, // measGapConfig, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL +#endif + ); + break; + } // case + + default: + AssertFatal(1==0, + "Unknown message\n"); + break; + }// switch case + return(0); + } else if (srb_id == 1) { + + LTE_DL_DCCH_Message_t* dl_dcch_msg=NULL; + asn_dec_rval_t dec_rval; + dec_rval = uper_decode(NULL, + &asn_DEF_LTE_DL_DCCH_Message, + (void**)&dl_dcch_msg, + &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header + rrc_dl_sdu_len,0,0); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) + LOG_E(F1AP," Failed to decode DL-DCCH (%zu bytes)\n",dec_rval.consumed); + else + LOG_D(F1AP, "Received message: present %d and c1 present %d\n", + dl_dcch_msg->message.present, dl_dcch_msg->message.choice.c1.present); + + if (dl_dcch_msg->message.present == LTE_DL_DCCH_MessageType_PR_c1) { + + switch (dl_dcch_msg->message.choice.c1.present) { + + case LTE_DL_DCCH_MessageType__c1_PR_NOTHING: + LOG_I(F1AP, "Received PR_NOTHING on DL-DCCH-Message\n"); + return 0; + case LTE_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: + LOG_I(F1AP,"Received NAS DL Information Transfer\n"); + break; + case LTE_DL_DCCH_MessageType__c1_PR_csfbParametersResponseCDMA2000: + LOG_I(F1AP,"Received NAS sfbParametersResponseCDMA2000\n"); + break; + case LTE_DL_DCCH_MessageType__c1_PR_handoverFromEUTRAPreparationRequest: + LOG_I(F1AP,"Received NAS andoverFromEUTRAPreparationRequest\n"); + break; + case LTE_DL_DCCH_MessageType__c1_PR_mobilityFromEUTRACommand: + LOG_I(F1AP,"Received NAS mobilityFromEUTRACommand\n"); + break; + case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration: + // handle RRCConnectionReconfiguration + LOG_I(F1AP, + "Logical Channel DL-DCCH (SRB1), Received RRCConnectionReconfiguration DU_ID %lx/RNTI %x\n", + du_ue_f1ap_id, + f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], du_ue_f1ap_id)); + + LTE_RRCConnectionReconfiguration_t* rrcConnectionReconfiguration = &dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration; + + if (rrcConnectionReconfiguration->criticalExtensions.present == LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1) { + if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present == + LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) { + LTE_RRCConnectionReconfiguration_r8_IEs_t* rrcConnectionReconfiguration_r8 = + &rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8; + + if (rrcConnectionReconfiguration_r8->mobilityControlInfo) { + LOG_I(F1AP, "Mobility Control Information is present\n"); + AssertFatal(1==0,"Can't handle this yet in DU\n"); + } + if (rrcConnectionReconfiguration_r8->measConfig != NULL) { + LOG_I(F1AP, "Measurement Configuration is present\n"); + } + + if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated) { + LOG_I(F1AP, "Radio Resource Configuration is present\n"); + uint8_t DRB2LCHAN[8]; + long drb_id; + int i; + LTE_DRB_ToAddModList_t *DRB_configList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->drb_ToAddModList; + LTE_SRB_ToAddModList_t *SRB_configList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->srb_ToAddModList; + LTE_DRB_ToReleaseList_t *DRB_ReleaseList = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->drb_ToReleaseList; + LTE_MAC_MainConfig_t *mac_MainConfig = NULL; + if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig) + mac_MainConfig = &rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; + LTE_MeasGapConfig_t *measGapConfig = NULL; + struct LTE_PhysicalConfigDedicated* physicalConfigDedicated = rrcConnectionReconfiguration_r8->radioResourceConfigDedicated->physicalConfigDedicated; + rrc_rlc_config_asn1_req( + &ctxt, + SRB_configList, // NULL, //LG-RK 14/05/2014 SRB_configList, + DRB_configList, + DRB_ReleaseList + #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL + , 0, 0 + #endif + ); + + if (SRB_configList != NULL) { + for (i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { + if (SRB_configList->list.array[i]->srb_Identity == 1 ){ + ue_context_p->ue_context.Srb1.Active=1; + } + else if (SRB_configList->list.array[i]->srb_Identity == 2 ) { + ue_context_p->ue_context.Srb2.Active=1; + ue_context_p->ue_context.Srb2.Srb_info.Srb_id=2; + LOG_I(F1AP, "[DU %d] SRB2 is now active\n",ctxt.module_id); + } else { + LOG_W(F1AP, "[DU %d] invalide SRB identity %ld\n",ctxt.module_id, + SRB_configList->list.array[i]->srb_Identity); + } + } + } + + if (DRB_configList != NULL) { + for (i = 0; i < DRB_configList->list.count; i++) { // num max DRB (11-3-8) + if (DRB_configList->list.array[i]) { + drb_id = (int)DRB_configList->list.array[i]->drb_Identity; + LOG_I(F1AP, + "[DU %d] Logical Channel UL-DCCH, Received RRCConnectionReconfiguration for UE rnti %x, reconfiguring DRB %d/LCID %d\n", + ctxt.module_id, + ctxt.rnti, + (int)DRB_configList->list.array[i]->drb_Identity, + (int)*DRB_configList->list.array[i]->logicalChannelIdentity); + + if (ue_context_p->ue_context.DRB_active[drb_id] == 0) { + ue_context_p->ue_context.DRB_active[drb_id] = 1; + + if (DRB_configList->list.array[i]->logicalChannelIdentity) { + DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity; + } + + rrc_mac_config_req_eNB( + ctxt.module_id, + 0,0,0,0,0,0, + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + 0, + #endif + ue_context_p->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, + #endif + physicalConfigDedicated, + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, + #endif + (LTE_MeasObjectToAddMod_t **) NULL, + mac_MainConfig, + DRB2LCHAN[i], + DRB_configList->list.array[i]->logicalChannelConfig, + measGapConfig, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + #endif + #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + #endif + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0, + (LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, + (LTE_SchedulingInfo_MBMS_r14_t *) NULL, + (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL + #endif + ); + } + + } else { // remove LCHAN from MAC/PHY + AssertFatal(1==0,"Can't handle this yet in DU\n"); + } + } + } + } + } + } + break; + case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: + // handle RRCConnectionRelease + LOG_I(F1AP, "Received RRCConnectionRelease\n"); + break; + case LTE_DL_DCCH_MessageType__c1_PR_securityModeCommand: + LOG_I(F1AP, "Received securityModeCommand\n"); + break; + case LTE_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: + LOG_I(F1AP, "Received ueCapabilityEnquiry\n"); + break; + case LTE_DL_DCCH_MessageType__c1_PR_counterCheck: + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + case LTE_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r10: + case LTE_DL_DCCH_MessageType__c1_PR_rnReconfiguration_r10: + #endif + case LTE_DL_DCCH_MessageType__c1_PR_spare1: + case LTE_DL_DCCH_MessageType__c1_PR_spare2: + case LTE_DL_DCCH_MessageType__c1_PR_spare3: + #if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) + case LTE_DL_DCCH_MessageType__c1_PR_spare4: + #endif + break; + case LTE_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9: + LOG_I(F1AP, "Received ueInformationRequest_r9\n"); + break; + case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionResume_r13: + LOG_I(F1AP, "Received rrcConnectionResume_r13\n"); + } + } + } + else if (srb_id == 2) { + + } + + LOG_I(F1AP, "Received DL RRC Transfer on srb_id %ld\n", srb_id); + rlc_op_status_t rlc_status; + boolean_t ret = TRUE; + mem_block_t *pdcp_pdu_p = NULL; + pdcp_pdu_p = get_free_mem_block(rrc_dl_sdu_len, __func__); + + //LOG_I(F1AP, "PRRCContainer size %lu:", ie->value.choice.RRCContainer.size); + //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++) + // printf("%02x ", ie->value.choice.RRCContainer.buf[i]); + + //printf (", PDCP PDU size %d:", rrc_dl_sdu_len); + //for (int i=0;i<rrc_dl_sdu_len;i++) printf("%2x ",pdcp_pdu_p->data[i]); + //printf("\n"); + + + if (pdcp_pdu_p != NULL) { + memset(pdcp_pdu_p->data, 0, rrc_dl_sdu_len); + memcpy(&pdcp_pdu_p->data[0], ie->value.choice.RRCContainer.buf, rrc_dl_sdu_len); + rlc_status = rlc_data_req(&ctxt + , 1 + , MBMS_FLAG_NO + , srb_id + , 0 + , 0 + , rrc_dl_sdu_len + , pdcp_pdu_p +#ifdef Rel14 + ,NULL + ,NULL +#endif + ); + switch (rlc_status) { + case RLC_OP_STATUS_OK: + //LOG_I(F1AP, "Data sending request over RLC succeeded!\n"); + ret=TRUE; + break; + + case RLC_OP_STATUS_BAD_PARAMETER: + LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); + ret= FALSE; + break; + + case RLC_OP_STATUS_INTERNAL_ERROR: + LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); + ret= FALSE; + break; + + case RLC_OP_STATUS_OUT_OF_RESSOURCES: + LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); + ret= FALSE; + break; + + default: + LOG_W(F1AP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); + ret= FALSE; + break; + } // switch case + return ret; + } // if pdcp_pdu_p + + return 0; + +} + +int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg) { + const rnti_t rnti = msg->rnti; + + F1AP_F1AP_PDU_t pdu; + F1AP_ULRRCMessageTransfer_t *out; + F1AP_ULRRCMessageTransferIEs_t *ie; + + uint8_t *buffer = NULL; + uint32_t len; + + + LOG_I(F1AP, "[DU %d] %s: size %d UE RNTI %x in SRB %d\n", + instance, __func__, msg->rrc_container_length, rnti, msg->srb_id); + + //LOG_I(F1AP, "%s() RRCContainer size %d: ", __func__, msg->rrc_container_length); + //for (int i = 0;i < msg->rrc_container_length; i++) + // printf("%02x ", msg->rrc_container[i]); + //printf("\n"); + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_ULRRCMessageTransfer; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_ULRRCMessageTransfer; + out = &pdu.choice.initiatingMessage->value.choice.ULRRCMessageTransfer; + + /* mandatory */ + /* c1. GNB_CU_UE_F1AP_ID */ + ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; + + ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_du_inst[instance], rnti); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. GNB_DU_UE_F1AP_ID */ + ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_du_inst[instance], rnti); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c3. SRBID */ + ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SRBID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_SRBID; + ie->value.choice.SRBID = msg->srb_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + // issue in here + /* mandatory */ + /* c4. RRCContainer */ + ie = (F1AP_ULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_ULRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_ULRRCMessageTransferIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, + (const char *) msg->rrc_container, + msg->rrc_container_length); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (msg->srb_id == 1 || msg->srb_id == 2) { + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], rnti); + + + LTE_UL_DCCH_Message_t* ul_dcch_msg=NULL; + asn_dec_rval_t dec_rval; + dec_rval = uper_decode(NULL, + &asn_DEF_LTE_UL_DCCH_Message, + (void**)&ul_dcch_msg, + &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header + msg->rrc_container_length, 0, 0); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) + LOG_E(F1AP, " Failed to decode UL-DCCH (%zu bytes)\n",dec_rval.consumed); + else + LOG_I(F1AP, "Received message: present %d and c1 present %d\n", + ul_dcch_msg->message.present, ul_dcch_msg->message.choice.c1.present); + + if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_c1) { + + switch (ul_dcch_msg->message.choice.c1.present) { + case LTE_UL_DCCH_MessageType__c1_PR_NOTHING: /* No components present */ + break; + + case LTE_UL_DCCH_MessageType__c1_PR_csfbParametersRequestCDMA2000: + break; + + case LTE_UL_DCCH_MessageType__c1_PR_measurementReport: + break; + + case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: + break; + + case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: + break; + + case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete: + LOG_I(F1AP, "[MSG] RRC UL rrcConnectionSetupComplete \n"); + if(!ue_context_p){ + LOG_E(F1AP, "Did not find the UE context associated with UE RNTOI %x, ue_context_p is NULL\n", rnti); + }else { + LOG_I(F1AP, "Processing RRCConnectionSetupComplete UE %x\n", rnti); + ue_context_p->ue_context.Status = RRC_CONNECTED; + } + + break; + case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete: + LOG_I(F1AP, "[MSG] RRC securityModeComplete \n"); + break; + + case LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure: + break; + + case LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: + LOG_I(F1AP, "[MSG] RRC ueCapabilityInformation \n"); + break; + + case LTE_UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer: + break; + + case LTE_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: + LOG_I(F1AP,"[MSG] RRC UL Information Transfer \n"); + break; + + case LTE_UL_DCCH_MessageType__c1_PR_counterCheckResponse: + break; + +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + + case LTE_UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9: + break; + case LTE_UL_DCCH_MessageType__c1_PR_proximityIndication_r9: + break; +#endif + +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + case LTE_UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10: + break; + + case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10: + break; + + case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10: + break; +#endif + + } + } + } + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + du_f1ap_itti_send_sctp_data_req(instance, f1ap_du_data->assoc_id, buffer, len, f1ap_du_data->default_sctp_stream_id); + return 0; +} + + +/* UL RRC Message Transfer */ +int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP, + int CC_idP, + int UE_id, + rnti_t rntiP, + const uint8_t *sduP, + sdu_size_t sdu_lenP) { + F1AP_F1AP_PDU_t pdu; + F1AP_InitialULRRCMessageTransfer_t *out; + F1AP_InitialULRRCMessageTransferIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int f1ap_uid = f1ap_add_ue (&f1ap_du_inst[module_idP], module_idP, CC_idP,UE_id, rntiP); + + if (f1ap_uid < 0 ) { + LOG_E(F1AP, "Failed to add UE \n"); + return -1; + } + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_InitialULRRCMessageTransfer; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_InitialULRRCMessageTransfer; + out = &pdu.choice.initiatingMessage->value.choice.InitialULRRCMessageTransfer; + + + /* mandatory */ + /* c1. GNB_DU_UE_F1AP_ID */ + ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_du_inst[module_idP].f1ap_ue[f1ap_uid].du_ue_f1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. NRCGI */ + ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_NRCGI; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_NRCGI; + + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[0], f1ap_du_data->mnc[0], f1ap_du_data->mnc_digit_length[0], + &nRCGI.pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(f1ap_du_data->nr_cellid[0], &nRCGI.nRCellIdentity); + ie->value.choice.NRCGI = nRCGI; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c3. C_RNTI */ // 16 + ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_C_RNTI; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_C_RNTI; + C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c4. RRCContainer */ + ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie->value.choice.RRCContainer, (const char *)sduP, sdu_lenP); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c5. DUtoCURRCContainer */ + if (0) { + ie = (F1AP_InitialULRRCMessageTransferIEs_t *)calloc(1, sizeof(F1AP_InitialULRRCMessageTransferIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DUtoCURRCContainer; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer; + OCTET_STRING_fromBuf(&ie->value.choice.DUtoCURRCContainer, "dummy_val", + strlen("dummy_val")); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + + struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[module_idP]); + ue_context_p->ue_id_rnti = rntiP; + ue_context_p->ue_context.rnti = rntiP; + ue_context_p->ue_context.random_ue_identity = rntiP; + ue_context_p->ue_context.Srb0.Active = 1; + RB_INSERT(rrc_ue_tree_s, &RC.rrc[module_idP]->rrc_ue_head, ue_context_p); + du_f1ap_itti_send_sctp_data_req(module_idP, f1ap_du_data->assoc_id, buffer, len, f1ap_du_data->default_sctp_stream_id); + + return 0; +} + + +void init_f1ap_du_ue_inst (void) { + + memset(f1ap_du_inst, 0, sizeof(f1ap_du_inst)); +} + + diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.h b/openair2/F1AP/f1ap_du_rrc_message_transfer.h new file mode 100644 index 0000000000000000000000000000000000000000..1406e48f3d3a76320a2d4ca99b7fc1b5cbdd6bd6 --- /dev/null +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.h @@ -0,0 +1,53 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_du_rrc_message_transfer.h + * \brief f1ap rrc message transfer for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + + +#ifndef F1AP_DU_RRC_MESSAGE_TRANSFER_H_ +#define F1AP_DU_RRC_MESSAGE_TRANSFER_H_ + +#include "f1ap_common.h" + +int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, const f1ap_ul_rrc_message_t *msg); + +int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP, + int CC_idP, + int UE_id, + rnti_t rntiP, + const uint8_t *sduP, + sdu_size_t sdu_lenP); + +#endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */ diff --git a/openair2/F1AP/f1ap_du_system_information.c b/openair2/F1AP/f1ap_du_system_information.c new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_du_system_information.c @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_du_system_information.h b/openair2/F1AP/f1ap_du_system_information.h new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_du_system_information.h @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c new file mode 100644 index 0000000000000000000000000000000000000000..d287e1e5bf7d5f4cadab48b590225f106ca75aea --- /dev/null +++ b/openair2/F1AP/f1ap_du_task.c @@ -0,0 +1,207 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/F1AP/f1ap_du_task.c +* \brief data structures for F1 interface modules +* \author EURECOM/NTUST +* \date 2018 +* \version 0.1 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr, bing-kai.hong@eurecom.fr +* \note +* \warning +*/ + +#include "f1ap_common.h" +#include "f1ap_handlers.h" +#include "f1ap_du_interface_management.h" +#include "f1ap_du_ue_context_management.h" +#include "f1ap_du_rrc_message_transfer.h" +#include "f1ap_du_task.h" +#include "proto_agent.h" + +extern RAN_CONTEXT_t RC; + +f1ap_setup_req_t *f1ap_du_data; +f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB]; + +void du_task_send_sctp_association_req(instance_t instance, f1ap_setup_req_t *f1ap_setup_req) { + + DevAssert(f1ap_setup_req != NULL); + + MessageDef *message_p = NULL; + sctp_new_association_req_t *sctp_new_association_req_p = NULL; + + message_p = itti_alloc_new_message(TASK_DU_F1, SCTP_NEW_ASSOCIATION_REQ); + + sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; + sctp_new_association_req_p->ulp_cnx_id = instance; + sctp_new_association_req_p->port = F1AP_PORT_NUMBER; + sctp_new_association_req_p->ppid = F1AP_SCTP_PPID; + + sctp_new_association_req_p->in_streams = f1ap_setup_req->sctp_in_streams; + sctp_new_association_req_p->out_streams = f1ap_setup_req->sctp_out_streams; + + // remote + memcpy(&sctp_new_association_req_p->remote_address, + &f1ap_setup_req->CU_f1_ip_address, + sizeof(f1ap_setup_req->CU_f1_ip_address)); + + // local + memcpy(&sctp_new_association_req_p->local_address, + &f1ap_setup_req->DU_f1_ip_address, + sizeof(f1ap_setup_req->DU_f1_ip_address)); + + // store data + f1ap_du_data = (f1ap_setup_req_t *)calloc(1, sizeof(f1ap_setup_req_t)); + *f1ap_du_data = *f1ap_setup_req; + //printf("sib itti message %s\n", f1ap_setup_req_t->sib1[0]); + + //printf("nr_cellid : %llx (%lld)",f1ap_setup_req->nr_cellid[0],f1ap_setup_req->nr_cellid[0]); + + //du_f1ap_register_to_sctp + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + +void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { + + DevAssert(sctp_new_association_resp != NULL); + + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + + //f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + return; // exit -1 for debugging + } + + // save the assoc id + f1ap_du_data->assoc_id = sctp_new_association_resp->assoc_id; + f1ap_du_data->sctp_in_streams = sctp_new_association_resp->in_streams; + f1ap_du_data->sctp_out_streams = sctp_new_association_resp->out_streams; + f1ap_du_data->default_sctp_stream_id = 0; + + /* setup parameters for F1U and start the server */ + const cudu_params_t params = { + .local_ipv4_address = RC.mac[instance]->eth_params_n.my_addr, + .local_port = RC.mac[instance]->eth_params_n.my_portd, + .remote_ipv4_address = RC.mac[instance]->eth_params_n.remote_addr, + .remote_port = RC.mac[instance]->eth_params_n.remote_portd + }; + AssertFatal(proto_agent_start(instance, ¶ms) == 0, + "could not start PROTO_AGENT for F1U on instance %d!\n", instance); + + DU_send_F1_SETUP_REQUEST(instance); +} + +void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) +{ + int result; + + DevAssert(sctp_data_ind != NULL); + + f1ap_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length); + + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); +} + + +void *F1AP_DU_task(void *arg) { + + //sctp_cu_init(); + MessageDef *received_msg = NULL; + int result; + + LOG_I(F1AP, "Starting F1AP at DU\n"); + + //f1ap_eNB_prepare_internal_data(); + + itti_mark_task_ready(TASK_DU_F1); + + // SCTP + while (1) { + itti_receive_msg(TASK_DU_F1, &received_msg); + + switch (ITTI_MSG_ID(received_msg)) { + + // case TERMINATE_MESSAGE: + // //F1AP_WARN(" *** Exiting F1AP DU thread\n"); + // itti_exit_task(); + // break; + + case F1AP_SETUP_REQ: // this is not a true F1 message, but rather an ITTI message sent by enb_app + // 1. save the itti msg so that you can use it to sen f1ap_setup_req, fill the f1ap_setup_req message, + // 2. store the message in f1ap context, that is also stored in RC + // 2. send a sctp_association req + LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n"); + du_task_send_sctp_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &F1AP_SETUP_REQ(received_msg)); + break; + + case SCTP_NEW_ASSOCIATION_RESP: + // 1. store the respon + // 2. send the f1setup_req + LOG_I(F1AP, "DU Task Received SCTP_NEW_ASSOCIATION_RESP\n"); + du_task_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_resp); + break; + + case SCTP_DATA_IND: + // ex: any F1 incoming message for DU ends here + LOG_I(F1AP, "DU Task Received SCTP_DATA_IND\n"); + du_task_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_data_ind); + break; + + case F1AP_UL_RRC_MESSAGE: // from rrc + LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); + DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &F1AP_UL_RRC_MESSAGE(received_msg)); + break; + + case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC + LOG_I(F1AP, "DU Task Received F1AP_UE_CONTEXT_RELEASE_REQ\n"); + DU_send_UE_CONTEXT_RELEASE_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &F1AP_UE_CONTEXT_RELEASE_REQ(received_msg)); + break; + + case TERMINATE_MESSAGE: + LOG_W(F1AP, " *** Exiting F1AP thread\n"); + itti_exit_task(); + break; + + default: + LOG_E(F1AP, "DU Received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } // switch + result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + + received_msg = NULL; + } // while + + return NULL; +} diff --git a/openair2/F1AP/f1ap_du_task.h b/openair2/F1AP/f1ap_du_task.h new file mode 100644 index 0000000000000000000000000000000000000000..2d5195baedea362bef3a1a68150860f5d2a27560 --- /dev/null +++ b/openair2/F1AP/f1ap_du_task.h @@ -0,0 +1,30 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef F1AP_DU_TASK_H_ +#define F1AP_DU_TASK_H_ + +void du_task_send_sctp_association_req(instance_t instance, f1ap_setup_req_t *f1ap_setup_req); +void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); +void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind); +void *F1AP_DU_task(void *arg); + +#endif /* F1AP_DU_TASK_H_ */ diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c new file mode 100644 index 0000000000000000000000000000000000000000..1a80132ea83d35fa47770c4e111cd1863b94d00f --- /dev/null +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -0,0 +1,1292 @@ +/* + * 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 f1ap_du_ue_context_management.c + * \brief F1AP UE Context Management, DU side + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#include "f1ap_common.h" +#include "f1ap_encoder.h" +#include "f1ap_decoder.h" +#include "f1ap_itti_messaging.h" +#include "f1ap_du_ue_context_management.h" + +#include "rrc_extern.h" +#include "rrc_eNB_UE_context.h" + +// undefine C_RNTI from +// openair1/PHY/LTE_TRANSPORT/transport_common.h which +// replaces in ie->value.choice.C_RNTI, causing +// a compile error + +#undef C_RNTI + +extern f1ap_setup_req_t *f1ap_du_data; +extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB]; +extern RAN_CONTEXT_t RC; + +int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) +{ + MessageDef *msg_p; // message to RRC + F1AP_UEContextSetupRequest_t *container; + F1AP_UEContextSetupRequestIEs_t *ie; + int i; + + DevAssert(pdu); + + msg_p = itti_alloc_new_message(TASK_DU_F1, F1AP_UE_CONTEXT_SETUP_REQ); + f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req; + f1ap_ue_context_setup_req = &F1AP_UE_CONTEXT_SETUP_REQ(msg_p); + + container = &pdu->choice.initiatingMessage->value.choice.UEContextSetupRequest; + + /* GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + f1ap_ue_context_setup_req->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; + + /* optional */ + /* GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, false); + if (ie) { + f1ap_ue_context_setup_req->gNB_DU_ue_id = malloc(sizeof(uint32_t)); + if (f1ap_ue_context_setup_req->gNB_DU_ue_id) + *f1ap_ue_context_setup_req->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + } else { + f1ap_ue_context_setup_req->gNB_DU_ue_id = NULL; + } + + /* SpCell_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_SpCell_ID, true); + PLMNID_TO_MCC_MNC(&ie->value.choice.NRCGI.pLMN_Identity, + f1ap_ue_context_setup_req->mcc, + f1ap_ue_context_setup_req->mnc, + f1ap_ue_context_setup_req->mnc_digit_length); + BIT_STRING_TO_NR_CELL_IDENTITY(&ie->value.choice.NRCGI.nRCellIdentity, f1ap_ue_context_setup_req->nr_cellid); + + + /* ServCellIndex */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_ServCellndex, true); + f1ap_ue_context_setup_req->servCellIndex = ie->value.choice.ServCellIndex; + + /* optional */ + /* CellULConfigured */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_SpCellULConfigured, false); // SpCellULConfigured + if (ie) { + /* correct here */ + f1ap_ue_context_setup_req->cellULConfigured = malloc(sizeof(uint32_t)); + if (f1ap_ue_context_setup_req->cellULConfigured) + *f1ap_ue_context_setup_req->cellULConfigured = ie->value.choice.CellULConfigured; + } else { + f1ap_ue_context_setup_req->cellULConfigured = NULL; + } + + /* CUtoDURRCInformation */ + + + /* Candidate_SpCell_List */ + + + /* optional */ + /* DRXCycle */ + + /* optional */ + /* ResourceCoordinationTransferContainer */ + + + /* SCell_ToBeSetup_List */ + + /* SRBs_ToBeSetup_List */ + + /* DRBs_ToBeSetup_List */ + + /* Decode DRBs_ToBeSetup_List */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List, true); + f1ap_ue_context_setup_req->drbs_to_be_setup_length = ie->value.choice.DRBs_ToBeSetup_List.list.count; + f1ap_ue_context_setup_req->drbs_to_be_setup = calloc(f1ap_ue_context_setup_req->drbs_to_be_setup_length, + sizeof(f1ap_drb_to_be_setup_t)); + AssertFatal(f1ap_ue_context_setup_req->drbs_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_req->drbs_to_be_setup\n"); + for (i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; ++i) { + f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_setup_req->drbs_to_be_setup[i]; + F1AP_DRBs_ToBeSetup_Item_t *drbs_tobesetup_item_p; + drbs_tobesetup_item_p = &((F1AP_DRBs_ToBeSetup_ItemIEs_t *)ie->value.choice.DRBs_ToBeSetup_List.list.array[i])->value.choice.DRBs_ToBeSetup_Item; + + drb_p->drb_id = drbs_tobesetup_item_p->dRBID; + + /* TODO in the following, assume only one UP UL TNL is present. + * this matches/assumes OAI CU implementation, can be up to 2! */ + drb_p->up_ul_tnl_length = 1; + AssertFatal(drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.count > 0, + "no UL UP TNL Information in DRBs to be Setup list\n"); + F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0]; + F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel; + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address); + OCTET_STRING_TO_INT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].gtp_teid); + + switch (drbs_tobesetup_item_p->rLCMode) { + case F1AP_RLCMode_rlc_am: + drb_p->rlc_mode = RLC_MODE_AM; + break; + default: + drb_p->rlc_mode = RLC_MODE_TM; + break; + } + } + + AssertFatal(0, "check configuration, send to appropriate handler\n"); + + return 0; +} + +//void DU_send_UE_CONTEXT_SETUP_RESPONSE(F1AP_UEContextSetupResponse_t *UEContextSetupResponse) { +int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance) { + F1AP_F1AP_PDU_t pdu; + F1AP_UEContextSetupResponse_t *out; + F1AP_UEContextSetupResponseIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0, j = 0; + + rnti_t rntiP; // note: need get value + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome = (F1AP_SuccessfulOutcome_t *)calloc(1, sizeof(F1AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome->procedureCode = F1AP_ProcedureCode_id_UEContextSetup; + pdu.choice.successfulOutcome->criticality = F1AP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextSetupResponse; + out = &pdu.choice.successfulOutcome->value.choice.UEContextSetupResponse; + + /* mandatory */ + /* c1. GNB_CU_UE_F1AP_ID */ + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie->value.choice.GNB_CU_UE_F1AP_ID = 126L; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. GNB_DU_UE_F1AP_ID */ + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie->value.choice.GNB_DU_UE_F1AP_ID = 651L; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c3. DUtoCURRCInformation */ + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DUtoCURRCInformation; + { + /* cellGroupConfig */ + OCTET_STRING_fromBuf(&ie->value.choice.DUtoCURRCInformation.cellGroupConfig, "asdsa", + strlen("asdsa")); + /* OPTIONAL */ + /* measGapConfig */ + if (0) { + ie->value.choice.DUtoCURRCInformation.measGapConfig = (F1AP_MeasGapConfig_t *)calloc(1, sizeof(F1AP_MeasGapConfig_t)); + OCTET_STRING_fromBuf( ie->value.choice.DUtoCURRCInformation.measGapConfig, "asdsa", + strlen("asdsa")); + } + + /* OPTIONAL */ + /* requestedP_MaxFR1 */ + if (0) { + ie->value.choice.DUtoCURRCInformation.requestedP_MaxFR1 = (OCTET_STRING_t *)calloc(1, sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf( ie->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, "asdsa", + strlen("asdsa")); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c4. C_RNTI */ + if (0) { + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_C_RNTI; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI; + C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c5. ResourceCoordinationTransferContainer */ + if (0) { + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_ResourceCoordinationTransferContainer; + OCTET_STRING_fromBuf(&ie->value.choice.ResourceCoordinationTransferContainer, "asdsa", + strlen("asdsa")); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c6. FullConfiguration */ + if (0) { + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_FullConfiguration; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_FullConfiguration; + ie->value.choice.FullConfiguration = F1AP_FullConfiguration_full; //enum + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + /* c7. DRBs_Setup_List */ + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_List; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List; + + for (i=0; + i<1; + i++) { + // + F1AP_DRBs_Setup_ItemIEs_t *drbs_setup_item_ies; + drbs_setup_item_ies = (F1AP_DRBs_Setup_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_Setup_ItemIEs_t)); + drbs_setup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_Item; + drbs_setup_item_ies->criticality = F1AP_Criticality_ignore; + drbs_setup_item_ies->value.present = F1AP_SRBs_FailedToBeSetup_ItemIEs__value_PR_SRBs_FailedToBeSetup_Item; + + /* 7.1 DRBs_Setup_Item */ + F1AP_DRBs_Setup_Item_t drbs_setup_item; + memset((void *)&drbs_setup_item, 0, sizeof(F1AP_DRBs_Setup_Item_t)); + + /* dRBID */ + drbs_setup_item.dRBID = 12; + + /* OPTIONAL */ + /* lCID */ + //drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t)); + //drbs_setup_item.lCID = 1L; + + for (j=0; + j<1; + j++) { + + F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dLUPTNLInformation_ToBeSetup_Item; + dLUPTNLInformation_ToBeSetup_Item = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_DLUPTNLInformation_ToBeSetup_Item_t)); + dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + + /* gTPTunnel */ + F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t)); + { + /* transportLayerAddress */ + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); + + /* gTP_TEID */ + OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", + strlen("1204")); + dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel = gTPTunnel; + } + /* ADD */ + ASN_SEQUENCE_ADD(&drbs_setup_item.dLUPTNLInformation_ToBeSetup_List.list, + dLUPTNLInformation_ToBeSetup_Item); + } // for j + + /* ADD */ + drbs_setup_item_ies->value.choice.DRBs_Setup_Item = drbs_setup_item; + ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_Setup_List.list, + drbs_setup_item_ies); + } // for i + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c8. SRBs_FailedToBeSetup_List */ + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetup_List; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_SRBs_FailedToBeSetup_List; + + for (i=0; + i<1; + i++) { + // + F1AP_SRBs_FailedToBeSetup_ItemIEs_t *srbs_failedToBeSetup_item_ies; + srbs_failedToBeSetup_item_ies = (F1AP_SRBs_FailedToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_SRBs_FailedToBeSetup_ItemIEs_t)); + srbs_failedToBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetup_Item; + srbs_failedToBeSetup_item_ies->criticality = F1AP_Criticality_ignore; + srbs_failedToBeSetup_item_ies->value.present = F1AP_SRBs_FailedToBeSetup_ItemIEs__value_PR_SRBs_FailedToBeSetup_Item; + + /* 8.1 SRBs_Setup_Item */ + F1AP_SRBs_FailedToBeSetup_Item_t srbs_failedToBeSetup_item; + memset((void *)&srbs_failedToBeSetup_item, 0, sizeof(F1AP_SRBs_FailedToBeSetup_Item_t)); + + /* sRBID */ + srbs_failedToBeSetup_item.sRBID = 13L; + + /* cause */ + srbs_failedToBeSetup_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); + + // dummy value + srbs_failedToBeSetup_item.cause->present = F1AP_Cause_PR_radioNetwork; + + switch(srbs_failedToBeSetup_item.cause->present) + { + case F1AP_Cause_PR_radioNetwork: + srbs_failedToBeSetup_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified; + break; + case F1AP_Cause_PR_transport: + srbs_failedToBeSetup_item.cause->choice.transport = F1AP_CauseTransport_unspecified; + break; + case F1AP_Cause_PR_protocol: + srbs_failedToBeSetup_item.cause->choice.protocol = F1AP_CauseProtocol_unspecified; + break; + case F1AP_Cause_PR_misc: + srbs_failedToBeSetup_item.cause->choice.misc = F1AP_CauseMisc_unspecified; + break; + case F1AP_Cause_PR_NOTHING: + default: + break; + } // switch + + /* ADD */ + srbs_failedToBeSetup_item_ies->value.choice.SRBs_FailedToBeSetup_Item = srbs_failedToBeSetup_item; + ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_FailedToBeSetup_List.list, + srbs_failedToBeSetup_item_ies); + } // for i + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* */ + /* c9. DRBs_FailedToBeSetup_List */ + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetup_List; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_FailedToBeSetup_List; + + for (i=0; + i<1; + i++) { + // + F1AP_DRBs_FailedToBeSetup_ItemIEs_t *drbs_failedToBeSetup_item_ies; + drbs_failedToBeSetup_item_ies = (F1AP_DRBs_FailedToBeSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_FailedToBeSetup_ItemIEs_t)); + drbs_failedToBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetup_Item; + drbs_failedToBeSetup_item_ies->criticality = F1AP_Criticality_ignore; + drbs_failedToBeSetup_item_ies->value.present = F1AP_DRBs_FailedToBeSetup_ItemIEs__value_PR_DRBs_FailedToBeSetup_Item; + + /* 9.1 DRBs_Setup_Item */ + F1AP_DRBs_FailedToBeSetup_Item_t drbs_failedToBeSetup_item; + memset((void *)&drbs_failedToBeSetup_item, 0, sizeof(F1AP_DRBs_FailedToBeSetup_Item_t)); + + /* dRBID */ + drbs_failedToBeSetup_item.dRBID = 14; + + /* cause */ + drbs_failedToBeSetup_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); + + // dummy value + drbs_failedToBeSetup_item.cause->present = F1AP_Cause_PR_radioNetwork; + + switch(drbs_failedToBeSetup_item.cause->present) + { + case F1AP_Cause_PR_radioNetwork: + drbs_failedToBeSetup_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified; + break; + case F1AP_Cause_PR_transport: + drbs_failedToBeSetup_item.cause->choice.transport = F1AP_CauseTransport_unspecified; + break; + case F1AP_Cause_PR_protocol: + drbs_failedToBeSetup_item.cause->choice.protocol = F1AP_CauseProtocol_unspecified; + break; + case F1AP_Cause_PR_misc: + drbs_failedToBeSetup_item.cause->choice.misc = F1AP_CauseMisc_unspecified; + break; + case F1AP_Cause_PR_NOTHING: + default: + break; + } // switch + + /* ADD */ + drbs_failedToBeSetup_item_ies->value.choice.DRBs_FailedToBeSetup_Item = drbs_failedToBeSetup_item; + ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_FailedToBeSetup_List.list, + drbs_failedToBeSetup_item_ies); + } // for i + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + // /* */ + /* c10. SCell_FailedtoSetup_List */ + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetup_List; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_SCell_FailedtoSetup_List; + + for (i=0; + i<1; + i++) { + // + F1AP_SCell_FailedtoSetup_ItemIEs_t *sCell_FailedtoSetup_item_ies; + sCell_FailedtoSetup_item_ies = (F1AP_SCell_FailedtoSetup_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_FailedtoSetup_ItemIEs_t)); + sCell_FailedtoSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetup_Item; + sCell_FailedtoSetup_item_ies->criticality = F1AP_Criticality_ignore; + sCell_FailedtoSetup_item_ies->value.present = F1AP_SCell_FailedtoSetup_ItemIEs__value_PR_SCell_FailedtoSetup_Item; + + /* 10.1 DRBs_Setup_Item */ + F1AP_SCell_FailedtoSetup_Item_t sCell_FailedtoSetup_item; + memset((void *)&sCell_FailedtoSetup_item, 0, sizeof(F1AP_SCell_FailedtoSetup_Item_t)); + + /* sCell_ID */ + F1AP_NRCGI_t nRCGI; // issue here + MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], &nRCGI.pLMN_Identity); + + NR_CELL_ID_TO_BIT_STRING(f1ap_du_data->nr_cellid[0], &nRCGI.nRCellIdentity); + + sCell_FailedtoSetup_item.sCell_ID = nRCGI; + + /* cause */ + sCell_FailedtoSetup_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); + + // dummy value + sCell_FailedtoSetup_item.cause->present = F1AP_Cause_PR_radioNetwork; + + switch(sCell_FailedtoSetup_item.cause->present) + { + case F1AP_Cause_PR_radioNetwork: + sCell_FailedtoSetup_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified; + break; + case F1AP_Cause_PR_transport: + sCell_FailedtoSetup_item.cause->choice.transport = F1AP_CauseTransport_unspecified; + break; + case F1AP_Cause_PR_protocol: + sCell_FailedtoSetup_item.cause->choice.protocol = F1AP_CauseProtocol_unspecified; + break; + case F1AP_Cause_PR_misc: + sCell_FailedtoSetup_item.cause->choice.misc = F1AP_CauseMisc_unspecified; + break; + case F1AP_Cause_PR_NOTHING: + default: + break; + } // switch + + /* ADD */ + sCell_FailedtoSetup_item_ies->value.choice.SCell_FailedtoSetup_Item = sCell_FailedtoSetup_item; + ASN_SEQUENCE_ADD(&ie->value.choice.SCell_FailedtoSetup_List.list, + sCell_FailedtoSetup_item_ies); + } // for i + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* Optional */ + /* c11. InactivityMonitoringResponse */ + if (0) { + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_InactivityMonitoringResponse; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_InactivityMonitoringResponse; + ie->value.choice.InactivityMonitoringResponse = F1AP_InactivityMonitoringResponse_not_supported; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + + /* Optional */ + /* c12. CriticalityDiagnostics */ + if (0) { + ie = (F1AP_UEContextSetupResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextSetupResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextSetupResponseIEs__value_PR_CriticalityDiagnostics; + + ie->value.choice.CriticalityDiagnostics.procedureCode = (F1AP_ProcedureCode_t *)calloc(1, sizeof(F1AP_ProcedureCode_t)); + *ie->value.choice.CriticalityDiagnostics.procedureCode = F1AP_ProcedureCode_id_UEContextSetup; + + ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)calloc(1, sizeof(F1AP_TriggeringMessage_t)); + *ie->value.choice.CriticalityDiagnostics.triggeringMessage = F1AP_TriggeringMessage_initiating_message; + + ie->value.choice.CriticalityDiagnostics.procedureCriticality = (F1AP_Criticality_t *)calloc(1, sizeof(F1AP_Criticality_t)); + *ie->value.choice.CriticalityDiagnostics.procedureCriticality = F1AP_Criticality_reject; + + ie->value.choice.CriticalityDiagnostics.transactionID = (F1AP_TransactionID_t *)calloc(1, sizeof(F1AP_TransactionID_t)); + *ie->value.choice.CriticalityDiagnostics.transactionID = 0; + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + return 0; +} + +int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance) { + AssertFatal(1==0,"Not implemented yet\n"); +} + + +int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, + f1ap_ue_context_release_req_t *req) { + F1AP_F1AP_PDU_t pdu; + F1AP_UEContextReleaseRequest_t *out; + F1AP_UEContextReleaseRequestIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + //int i = 0, j = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (F1AP_InitiatingMessage_t *)calloc(1, sizeof(F1AP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = F1AP_ProcedureCode_id_UEContextReleaseRequest; + pdu.choice.initiatingMessage->criticality = F1AP_Criticality_reject; + pdu.choice.initiatingMessage->value.present = F1AP_InitiatingMessage__value_PR_UEContextReleaseRequest; + out = &pdu.choice.initiatingMessage->value.choice.UEContextReleaseRequest; + + /* mandatory */ + /* c1. GNB_CU_UE_F1AP_ID */ + ie = (F1AP_UEContextReleaseRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_du_inst[instance], req->rnti); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. GNB_DU_UE_F1AP_ID */ + ie = (F1AP_UEContextReleaseRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_du_inst[instance], req->rnti); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c3. Cause */ + ie = (F1AP_UEContextReleaseRequestIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseRequestIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_Cause; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_Cause; + + switch (req->cause) + { + case F1AP_CAUSE_RADIO_NETWORK: + ie->value.choice.Cause.present = F1AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = req->cause_value; + break; + case F1AP_CAUSE_TRANSPORT: + ie->value.choice.Cause.present = F1AP_Cause_PR_transport; + ie->value.choice.Cause.choice.transport = req->cause_value; + break; + case F1AP_CAUSE_PROTOCOL: + ie->value.choice.Cause.present = F1AP_Cause_PR_protocol; + ie->value.choice.Cause.choice.protocol = req->cause_value; + break; + case F1AP_CAUSE_MISC: + ie->value.choice.Cause.present = F1AP_Cause_PR_misc; + ie->value.choice.Cause.choice.misc = req->cause_value; + break; + case F1AP_CAUSE_NOTHING: + default: + ie->value.choice.Cause.present = F1AP_Cause_PR_NOTHING; + break; + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 context release request\n"); + return -1; + } + + du_f1ap_itti_send_sctp_data_req(instance, + f1ap_du_data->assoc_id, + buffer, + len, + f1ap_du_data->default_sctp_stream_id); + + return 0; +} + + +int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + + F1AP_UEContextReleaseCommand_t *container; + F1AP_UEContextReleaseCommandIEs_t *ie; + protocol_ctxt_t ctxt; + + DevAssert(pdu); + + container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand; + + /* GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + ctxt.rnti = f1ap_get_rnti_by_cu_id(&f1ap_du_inst[instance], ie->value.choice.GNB_CU_UE_F1AP_ID); + ctxt.module_id = instance; + ctxt.instance = instance; + ctxt.enb_flag = 1; + + /* GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + const rnti_t rnti = f1ap_get_rnti_by_du_id(&f1ap_du_inst[instance], + ie->value.choice.GNB_DU_UE_F1AP_ID); + AssertFatal(ctxt.rnti == rnti, + "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", + rnti, ctxt.rnti); + + int UE_out_of_sync = 0; + for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) { + if (RC.mac[instance]->UE_list.active[n] == TRUE + && rnti == UE_RNTI(instance, n)) { + UE_out_of_sync = RC.mac[instance]->UE_list.UE_sched_ctrl[n].ul_out_of_sync; + break; + } + } + + /* We don't need the Cause */ + + /* Optional RRC Container: if present, send to UE */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_RRCContainer, false); + if (ie && !UE_out_of_sync) { + /* RRC message and UE is reachable, send message */ + const sdu_size_t sdu_len = ie->value.choice.RRCContainer.size; + mem_block_t *pdu_p = NULL; + pdu_p = get_free_mem_block(sdu_len, __func__); + memcpy(&pdu_p->data[0], ie->value.choice.RRCContainer.buf, sdu_len); + rlc_op_status_t rlc_status = rlc_data_req(&ctxt + , 1 + , MBMS_FLAG_NO + , 1 // SRB 1 correct? + , 0 + , 0 + , sdu_len + , pdu_p +#ifdef Rel14 + ,NULL + ,NULL +#endif + ); + switch (rlc_status) { + case RLC_OP_STATUS_OK: + break; + case RLC_OP_STATUS_BAD_PARAMETER: + LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); + break; + case RLC_OP_STATUS_INTERNAL_ERROR: + LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); + break; + case RLC_OP_STATUS_OUT_OF_RESSOURCES: + LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); + break; + default: + LOG_W(F1AP, "RLC returned an unknown status code after F1AP placed " + "the order to send some data (Status Code:%d)\n", rlc_status); + break; + } + } + + struct rrc_eNB_ue_context_s* ue_context_p; + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id], ctxt.rnti); + if (ue_context_p && !UE_out_of_sync) { + /* UE exists and is in sync so we start a timer before releasing the + * connection */ + pthread_mutex_lock(&rrc_release_freelist); + for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) { + if (ue_context_p->ue_context.ue_release_timer_s1 > 0) + rrc_release_info.RRC_release_ctrl[release_num].flag = 1; + else + rrc_release_info.RRC_release_ctrl[release_num].flag = 2; + rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt.rnti; + LOG_D(F1AP, "add rrc_release_info RNTI %x\n", ctxt.rnti); + // TODO: how to provide the correct MUI? + rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = 0; + rrc_release_info.num_UEs++; + LOG_D(RRC,"Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n",release_num, + ctxt.rnti, 0, rrc_release_info.RRC_release_ctrl[release_num].flag); + break; + } + } + pthread_mutex_unlock(&rrc_release_freelist); + ue_context_p->ue_context.ue_release_timer_s1 = 0; + } else if (ue_context_p && UE_out_of_sync) { + /* UE exists and is out of sync, drop the connection */ + mac_eNB_rrc_ul_failure(instance, 0, 0, 0, rnti); + } else { + LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", rnti); + } + + /* TODO send this once the connection has really been released */ + f1ap_ue_context_release_cplt_t cplt; + cplt.rnti = ctxt.rnti; + DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt); + + return 0; +} + + +int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, + f1ap_ue_context_release_cplt_t *cplt) { + F1AP_F1AP_PDU_t pdu; + F1AP_UEContextReleaseComplete_t *out; + F1AP_UEContextReleaseCompleteIEs_t *ie; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome = (F1AP_SuccessfulOutcome_t *)calloc(1, sizeof(F1AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome->procedureCode = F1AP_ProcedureCode_id_UEContextRelease; + pdu.choice.successfulOutcome->criticality = F1AP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextReleaseComplete; + out = &pdu.choice.successfulOutcome->value.choice.UEContextReleaseComplete; + + /* mandatory */ + /* c1. GNB_CU_UE_F1AP_ID */ + ie = (F1AP_UEContextReleaseCompleteIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCompleteIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_du_inst[instance], cplt->rnti); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. GNB_DU_UE_F1AP_ID */ + ie = (F1AP_UEContextReleaseCompleteIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCompleteIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(&f1ap_du_inst[instance], cplt->rnti); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional -> currently not used */ + /* c3. CriticalityDiagnostics */ + //if (0) { + // ie = (F1AP_UEContextReleaseCompleteIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCompleteIEs_t)); + // ie->id = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + // ie->criticality = F1AP_Criticality_ignore; + // ie->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_CriticalityDiagnostics; + + // // dummy value + // /* optional */ + // /* procedureCode */ + // if (0) { + // ie->value.choice.CriticalityDiagnostics.procedureCode = (F1AP_ProcedureCode_t *)calloc(1, sizeof(F1AP_ProcedureCode_t)); + // ie->value.choice.CriticalityDiagnostics.procedureCode = 0L; + // } + + // /* optional */ + // /* triggeringMessage */ + // if (0) { + // ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)calloc(1, sizeof(F1AP_TriggeringMessage_t)); + // ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)F1AP_TriggeringMessage_successful_outcome; + // } + + // /* optional */ + // /* procedureCriticality */ + // if (0) { + // ie->value.choice.CriticalityDiagnostics.procedureCriticality = (F1AP_Criticality_t *)calloc(1, sizeof(F1AP_Criticality_t)); + // ie->value.choice.CriticalityDiagnostics.procedureCriticality = F1AP_Criticality_reject; + // } + + // /* optional */ + // /* transactionID */ + // if (0) { + // ie->value.choice.CriticalityDiagnostics.transactionID = (F1AP_TransactionID_t *)calloc(1, sizeof(F1AP_TransactionID_t)); + // ie->value.choice.CriticalityDiagnostics.transactionID = 0L; + // } + + // /* optional */ + // /* F1AP_CriticalityDiagnostics_IE_List */ + // if (0) { + // for (i=0; + // i<0; + // i++) { + + // F1AP_CriticalityDiagnostics_IE_Item_t *criticalityDiagnostics_ie_item = (F1AP_CriticalityDiagnostics_IE_Item_t *)calloc(1, sizeof(F1AP_CriticalityDiagnostics_IE_Item_t));; + // criticalityDiagnostics_ie_item->iECriticality = F1AP_Criticality_reject; + // criticalityDiagnostics_ie_item->iE_ID = 0L; + // criticalityDiagnostics_ie_item->typeOfError = F1AP_TypeOfError_not_understood; + + // ASN_SEQUENCE_ADD(&ie->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics->list, + // criticalityDiagnostics_ie_item); + // } + // } + // ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + //} + + /* encode */ + uint8_t *buffer; + uint32_t len; + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 context release complete\n"); + return -1; + } + + du_f1ap_itti_send_sctp_data_req(instance, + f1ap_du_data->assoc_id, + buffer, + len, + f1ap_du_data->default_sctp_stream_id); + + f1ap_remove_ue(&f1ap_du_inst[instance], cplt->rnti); + return 0; +} + + +int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +//void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) { +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { + F1AP_F1AP_PDU_t pdu; + F1AP_UEContextModificationResponse_t *out; + F1AP_UEContextModificationResponseIEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int i = 0; + + /* Create */ + /* 0. Message Type */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome = (F1AP_SuccessfulOutcome_t *)calloc(1, sizeof(F1AP_SuccessfulOutcome_t)); + pdu.choice.successfulOutcome->procedureCode = F1AP_ProcedureCode_id_UEContextModification; + pdu.choice.successfulOutcome->criticality = F1AP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextModificationResponse; + out = &pdu.choice.successfulOutcome->value.choice.UEContextModificationResponse; + + /* mandatory */ + /* c1. GNB_CU_UE_F1AP_ID */ + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID; + ie->value.choice.GNB_CU_UE_F1AP_ID = 126L; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c2. GNB_DU_UE_F1AP_ID */ + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID; + ie->value.choice.GNB_DU_UE_F1AP_ID = 651L; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + /* c3. ResourceCoordinationTransferContainer */ + if (0) { + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_ResourceCoordinationTransferContainer; + OCTET_STRING_fromBuf(&ie->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + /* c4. DUtoCURRCInformation */ + if (0) { + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DUtoCURRCInformation; + + OCTET_STRING_fromBuf(&ie->value.choice.DUtoCURRCInformation.cellGroupConfig, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + /* OPTIONAL */ + if (1) { + ie->value.choice.DUtoCURRCInformation.measGapConfig = (F1AP_MeasGapConfig_t *)calloc(1, sizeof(F1AP_MeasGapConfig_t)); + OCTET_STRING_fromBuf( ie->value.choice.DUtoCURRCInformation.measGapConfig, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + } + + + /* mandatory */ + /* c5. DRBs_SetupMod_List */ + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_SetupMod_List; + + for (i=0; + i<1; + i++) { + // + F1AP_DRBs_SetupMod_ItemIEs_t *drbs_setupMod_item_ies; + drbs_setupMod_item_ies = (F1AP_DRBs_SetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_SetupMod_ItemIEs_t)); + drbs_setupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_Item; + drbs_setupMod_item_ies->criticality = F1AP_Criticality_reject; + drbs_setupMod_item_ies->value.present = F1AP_DRBs_SetupMod_ItemIEs__value_PR_DRBs_SetupMod_Item; + + /* 10.1 DRBs_SetupMod_Item */ + F1AP_DRBs_SetupMod_Item_t drbs_setupMod_item; + memset((void *)&drbs_setupMod_item, 0, sizeof(F1AP_DRBs_SetupMod_Item_t)); + + /* dRBID */ + drbs_setupMod_item.dRBID = 30L; + + /* DLTunnels_SetupMod_List */ + int j = 0; + int maxnoofDLUPTNLInformation = 1; // 2; + for (j=0; + j<maxnoofDLUPTNLInformation; + j++) { + /* DLTunnels_ToBeSetup_Item */ + F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dLUPTNLInformation_ToBeSetup_Item; + dLUPTNLInformation_ToBeSetup_Item = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_DLUPTNLInformation_ToBeSetup_Item_t)); + dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t)); + + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); + + OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", + strlen("1204")); + + dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel = gTPTunnel; + + ASN_SEQUENCE_ADD(&drbs_setupMod_item.dLUPTNLInformation_ToBeSetup_List.list, dLUPTNLInformation_ToBeSetup_Item); + } + + /* ADD */ + drbs_setupMod_item_ies->value.choice.DRBs_SetupMod_Item = drbs_setupMod_item; + ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_SetupMod_List.list, + drbs_setupMod_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c6. DRBs_Modified_List */ + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_Modified_List; + + for (i=0; + i<1; + i++) { + // + F1AP_DRBs_Modified_ItemIEs_t *drbs_modified_item_ies; + drbs_modified_item_ies = (F1AP_DRBs_Modified_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_Modified_ItemIEs_t)); + drbs_modified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_Item; + drbs_modified_item_ies->criticality = F1AP_Criticality_reject; + drbs_modified_item_ies->value.present = F1AP_DRBs_Modified_ItemIEs__value_PR_DRBs_Modified_Item; + + /* 13.1 SRBs_modified_Item */ + F1AP_DRBs_Modified_Item_t drbs_modified_item; + memset((void *)&drbs_modified_item, 0, sizeof(F1AP_DRBs_Modified_Item_t)); + + /* dRBID */ + drbs_modified_item.dRBID = 25L; + + /* ULTunnels_Modified_List */ + int maxnoofULTunnels = 1; // 2; + int j = 0; + for (j=0; + j<maxnoofULTunnels; + j++) { + /* DLTunnels_Modified_Item */ + F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dLUPTNLInformation_ToBeSetup_Item; + dLUPTNLInformation_ToBeSetup_Item = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)calloc(1, sizeof(F1AP_DLUPTNLInformation_ToBeSetup_Item_t)); + dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + F1AP_GTPTunnel_t *gTPTunnel = (F1AP_GTPTunnel_t *)calloc(1, sizeof(F1AP_GTPTunnel_t)); + + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); + + OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", + strlen("1204")); + + dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel = gTPTunnel; + + ASN_SEQUENCE_ADD(&drbs_modified_item.dLUPTNLInformation_ToBeSetup_List.list, dLUPTNLInformation_ToBeSetup_Item); + } + + /* ADD */ + drbs_modified_item_ies->value.choice.DRBs_Modified_Item = drbs_modified_item; + ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_Modified_List.list, + drbs_modified_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c7. SRBs_FailedToBeSetupMod_List */ + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SRBs_FailedToBeSetupMod_List; + + for (i=0; + i<1; + i++) { + // + F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t *srbs_failedToBeSetupMod_item_ies; + srbs_failedToBeSetupMod_item_ies = (F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t)); + srbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_Item; + srbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; + srbs_failedToBeSetupMod_item_ies->value.present = F1AP_SRBs_FailedToBeSetupMod_ItemIEs__value_PR_SRBs_FailedToBeSetupMod_Item; + + /* 9.1 SRBs_FailedToBeSetupMod_Item */ + F1AP_SRBs_FailedToBeSetupMod_Item_t srbs_failedToBeSetupMod_item; + memset((void *)&srbs_failedToBeSetupMod_item, 0, sizeof(F1AP_SRBs_FailedToBeSetupMod_Item_t)); + + /* - sRBID */ + srbs_failedToBeSetupMod_item.sRBID = 50L; + + srbs_failedToBeSetupMod_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); + srbs_failedToBeSetupMod_item.cause->present = F1AP_Cause_PR_radioNetwork; + srbs_failedToBeSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id; + + /* ADD */ + srbs_failedToBeSetupMod_item_ies->value.choice.SRBs_FailedToBeSetupMod_Item = srbs_failedToBeSetupMod_item; + ASN_SEQUENCE_ADD(&ie->value.choice.SRBs_FailedToBeSetupMod_List.list, + srbs_failedToBeSetupMod_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c8. DRBs_FailedToBeSetupMod_List */ + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeSetupMod_List; + + for (i=0; + i<1; + i++) { + // + F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t *drbs_failedToBeSetupMod_item_ies; + drbs_failedToBeSetupMod_item_ies = (F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t)); + drbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_Item; + drbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; + drbs_failedToBeSetupMod_item_ies->value.present = F1AP_DRBs_FailedToBeSetupMod_ItemIEs__value_PR_DRBs_FailedToBeSetupMod_Item; + + /* 10.1 DRBs_ToBeSetupMod_Item */ + F1AP_DRBs_FailedToBeSetupMod_Item_t drbs_failedToBeSetupMod_item; + memset((void *)&drbs_failedToBeSetupMod_item, 0, sizeof(F1AP_DRBs_FailedToBeSetupMod_Item_t)); + + /* dRBID */ + drbs_failedToBeSetupMod_item.dRBID = 30L; + + drbs_failedToBeSetupMod_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); + drbs_failedToBeSetupMod_item.cause->present = F1AP_Cause_PR_radioNetwork; + drbs_failedToBeSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id; + + /* ADD */ + drbs_failedToBeSetupMod_item_ies->value.choice.DRBs_FailedToBeSetupMod_Item = drbs_failedToBeSetupMod_item; + ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_FailedToBeSetupMod_List.list, + drbs_failedToBeSetupMod_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* mandatory */ + /* c9. SCell_FailedtoSetupMod_List */ + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SCell_FailedtoSetupMod_List; + + for (i=0; + i<1; + i++) { + // + F1AP_SCell_FailedtoSetupMod_ItemIEs_t *scell_failedtoSetupMod_item_ies; + scell_failedtoSetupMod_item_ies = (F1AP_SCell_FailedtoSetupMod_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_FailedtoSetupMod_ItemIEs_t)); + scell_failedtoSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_Item; + scell_failedtoSetupMod_item_ies->criticality = F1AP_Criticality_ignore; + scell_failedtoSetupMod_item_ies->value.present = F1AP_SCell_FailedtoSetupMod_ItemIEs__value_PR_SCell_FailedtoSetupMod_Item; + + /* 8.1 SCell_ToBeSetup_Item */ + F1AP_SCell_FailedtoSetupMod_Item_t scell_failedtoSetupMod_item; + memset((void *)&scell_failedtoSetupMod_item, 0, sizeof(F1AP_SCell_FailedtoSetupMod_Item_t)); + + /* - sCell_ID */ + F1AP_NRCGI_t nRCGI; + MCC_MNC_TO_PLMNID(f1ap_du_data->mcc[i], f1ap_du_data->mnc[i], f1ap_du_data->mnc_digit_length[i], + &nRCGI.pLMN_Identity); + + NR_CELL_ID_TO_BIT_STRING(f1ap_du_data->nr_cellid[0], &nRCGI.nRCellIdentity); + + scell_failedtoSetupMod_item.sCell_ID = nRCGI; + + scell_failedtoSetupMod_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); + scell_failedtoSetupMod_item.cause->present = F1AP_Cause_PR_radioNetwork; + scell_failedtoSetupMod_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id; + + /* ADD */ + scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item = scell_failedtoSetupMod_item; + ASN_SEQUENCE_ADD(&ie->value.choice.SCell_FailedtoSetupMod_List.list, + scell_failedtoSetupMod_item_ies); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + /* c10. DRBs_FailedToBeModified_List */ + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeModified_List; + + for (i=0; + i<1; + i++) { + // + F1AP_DRBs_FailedToBeModified_ItemIEs_t *drbs_failedToBeModified_item_ies; + drbs_failedToBeModified_item_ies = (F1AP_DRBs_FailedToBeModified_ItemIEs_t *)calloc(1, sizeof(F1AP_DRBs_FailedToBeModified_ItemIEs_t)); + drbs_failedToBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_Item; + drbs_failedToBeModified_item_ies->criticality = F1AP_Criticality_reject; + drbs_failedToBeModified_item_ies->value.present = F1AP_DRBs_FailedToBeModified_ItemIEs__value_PR_DRBs_FailedToBeModified_Item; + + /* 13.1 DRBs_FailedToBeModified_Item */ + F1AP_DRBs_FailedToBeModified_Item_t drbs_failedToBeModified_item; + memset((void *)&drbs_failedToBeModified_item, 0, sizeof(F1AP_DRBs_FailedToBeModified_Item_t)); + + /* dRBID */ + drbs_failedToBeModified_item.dRBID = 30L; + + drbs_failedToBeModified_item.cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); + drbs_failedToBeModified_item.cause->present = F1AP_Cause_PR_radioNetwork; + drbs_failedToBeModified_item.cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnd_du_ue_f1ap_id; + + /* ADD */ + drbs_failedToBeModified_item_ies->value.choice.DRBs_FailedToBeModified_Item = drbs_failedToBeModified_item; + ASN_SEQUENCE_ADD(&ie->value.choice.DRBs_FailedToBeModified_List.list, + drbs_failedToBeModified_item_ies); + + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + // /* */ + /* c11. CriticalityDiagnostics */ + if (0) { + ie = (F1AP_UEContextModificationResponseIEs_t *)calloc(1, sizeof(F1AP_UEContextModificationResponseIEs_t)); + ie->id = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_UEContextModificationResponseIEs__value_PR_CriticalityDiagnostics; + + // dummy value + /* optional */ + /* procedureCode */ + if (0) { + ie->value.choice.CriticalityDiagnostics.procedureCode = (F1AP_ProcedureCode_t *)calloc(1, sizeof(F1AP_ProcedureCode_t)); + ie->value.choice.CriticalityDiagnostics.procedureCode = 0L; + } + + /* optional */ + /* triggeringMessage */ + if (0) { + ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)calloc(1, sizeof(F1AP_TriggeringMessage_t)); + ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)F1AP_TriggeringMessage_successful_outcome; + } + + /* optional */ + /* procedureCriticality */ + if (0) { + ie->value.choice.CriticalityDiagnostics.procedureCriticality = (F1AP_Criticality_t *)calloc(1, sizeof(F1AP_Criticality_t)); + ie->value.choice.CriticalityDiagnostics.procedureCriticality = F1AP_Criticality_reject; + } + + /* optional */ + /* transactionID */ + if (0) { + ie->value.choice.CriticalityDiagnostics.transactionID = (F1AP_TransactionID_t *)calloc(1, sizeof(F1AP_TransactionID_t)); + ie->value.choice.CriticalityDiagnostics.transactionID = 0L; + } + + /* optional */ + /* F1AP_CriticalityDiagnostics_IE_List */ + if (0) { + for (i=0; + i<0; + i++) { + + F1AP_CriticalityDiagnostics_IE_Item_t *criticalityDiagnostics_ie_item = (F1AP_CriticalityDiagnostics_IE_Item_t *)calloc(1, sizeof(F1AP_CriticalityDiagnostics_IE_Item_t));; + criticalityDiagnostics_ie_item->iECriticality = F1AP_Criticality_reject; + criticalityDiagnostics_ie_item->iE_ID = 0L; + criticalityDiagnostics_ie_item->typeOfError = F1AP_TypeOfError_not_understood; + + ASN_SEQUENCE_ADD(&ie->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics->list, + criticalityDiagnostics_ie_item); + } + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 setup request\n"); + return -1; + } + + //du_f1ap_itti_send_sctp_data_req(instance, f1ap_setup_req->assoc_id, buffer, len, 0); + return 0; + +} + +int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance) { + AssertFatal(1==0,"Not implemented yet\n"); +} + +int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + AssertFatal(1==0,"Not implemented yet\n"); +} diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h new file mode 100644 index 0000000000000000000000000000000000000000..2bb3ca95b9600cc552d616d9788e78bb79eccee4 --- /dev/null +++ b/openair2/F1AP/f1ap_du_ue_context_management.h @@ -0,0 +1,97 @@ +/* + * 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 f1ap_du_ue_context_management.h + * \brief f1ap ue context management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#ifndef F1AP_DU_UE_CONTEXT_MANAGEMENT_H_ +#define F1AP_DU_UE_CONTEXT_MANAGEMENT_H_ + +/* + * UE Context Setup + */ +int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); +int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance); +int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance); + + +/* + * UE Context Release Request (gNB-DU initiated) + */ +int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, + f1ap_ue_context_release_req_t *req); + + +/* + * UE Context Release Command (gNB-CU initiated) + */ +int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +/* + * UE Context Release Complete (gNB-DU initiated) + */ +int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, + f1ap_ue_context_release_cplt_t *cplt); + + +/* + * UE Context Modification (gNB-CU initiated) + */ +int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance); +int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance); + + +/* + * UE Context Modification Required (gNB-DU initiated) + */ +int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(instance_t instance); +int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +/* + * UE Inactivity Notification + */ + +/* + * Notify + */ + +#endif /* F1AP_DU_UE_CONTEXT_MANAGEMENT_H_ */ diff --git a/openair2/F1AP/f1ap_du_warning_message_transmission.c b/openair2/F1AP/f1ap_du_warning_message_transmission.c new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_du_warning_message_transmission.c @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_du_warning_message_transmission.h b/openair2/F1AP/f1ap_du_warning_message_transmission.h new file mode 100644 index 0000000000000000000000000000000000000000..b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60 --- /dev/null +++ b/openair2/F1AP/f1ap_du_warning_message_transmission.h @@ -0,0 +1,31 @@ +/* + * 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 f1ap_du_interface_management.h + * \brief f1ap interface management for DU + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ \ No newline at end of file diff --git a/openair2/F1AP/f1ap_encoder.c b/openair2/F1AP/f1ap_encoder.c new file mode 100644 index 0000000000000000000000000000000000000000..e448690139f64ebb62a4a34394ffa29bf35d0683 --- /dev/null +++ b/openair2/F1AP/f1ap_encoder.c @@ -0,0 +1,376 @@ +/* + * 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 f1ap_encoder.c + * \brief f1ap pdu encode procedures + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#include "f1ap_common.h" +#include "f1ap_encoder.h" + +int asn1_encoder_xer_print = 0; + +/* +static inline int f1ap_encode_initiating(f1ap_message *message, + uint8_t **buffer, + uint32_t *len); + +static inline int f1ap_encode_successfull_outcome(f1ap_message *message, + uint8_t **buffer, uint32_t *len); + +static inline int f1ap_encode_unsuccessfull_outcome(f1ap_message *message, + uint8_t **buffer, uint32_t *len); + +static inline int f1ap_encode_f1_setup_request( + F1ap_F1SetupRequestIEs_t *f1SetupRequestIEs, uint8_t **buffer, uint32_t *length); + +static inline int f1ap_encode_trace_failure(F1ap_TraceFailureIndicationIEs_t + *trace_failure_ies_p, uint8_t **buffer, + uint32_t *length); + +static inline int f1ap_encode_initial_context_setup_response( + F1ap_InitialContextSetupResponseIEs_t *initialContextSetupResponseIEs, + uint8_t **buffer, + uint32_t *length); + +static inline +int f1ap_encode_ue_context_release_complete( + F1ap_UEContextReleaseCompleteIEs_t *f1ap_UEContextReleaseCompleteIEs, + uint8_t **buffer, + uint32_t *length); + +static inline +int f1ap_encode_ue_context_release_request( + F1ap_UEContextReleaseRequestIEs_t *f1ap_UEContextReleaseRequestIEs, + uint8_t **buffer, + uint32_t *length); + */ + +int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length) +{ + ssize_t encoded; + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + DevAssert(length != NULL); + + if (asn1_encoder_xer_print) { + LOG_E(F1AP, "----------------- ASN1 ENCODER PRINT START ----------------- \n"); + xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, pdu); + LOG_E(F1AP, "----------------- ASN1 ENCODER PRINT END----------------- \n"); + } + + encoded = aper_encode_to_new_buffer(&asn_DEF_F1AP_F1AP_PDU, 0, pdu, (void **)buffer); + + if (encoded < 0) { + LOG_E(F1AP, "Failed to encode F1AP message\n"); + return -1; + } + + *length = encoded; + + return encoded; +} + +/* +static inline +int f1ap_encode_initiating(f1ap_message *f1ap_message_p, + uint8_t **buffer, uint32_t *len) +{ + int ret = -1; + MessageDef *message_p; + char *message_string = NULL; + size_t message_string_size; + MessagesIds message_id; + + DevAssert(f1ap_message_p != NULL); + + message_string = calloc(10000, sizeof(char)); + + f1ap_string_total_size = 0; + + switch(f1ap_message_p->procedureCode) { + case F1ap_ProcedureCode_id_F1Setup: + ret = f1ap_encode_f1_setup_request( + &f1ap_message_p->msg.f1ap_F1SetupRequestIEs, buffer, len); + //f1ap_xer_print_f1ap_f1setuprequest(f1ap_xer__print2sp, message_string, f1ap_message_p); + message_id = F1AP_F1_SETUP_LOG; + break; + + case F1ap_ProcedureCode_id_UEContextReleaseRequest: + ret = f1ap_encode_ue_context_release_request( + &f1ap_message_p->msg.f1ap_UEContextReleaseRequestIEs, buffer, len); + //f1ap_xer_print_f1ap_uecontextreleaserequest(f1ap_xer__print2sp, + // message_string, f1ap_message_p); + message_id = F1AP_UE_CONTEXT_RELEASE_REQ_LOG; + break; + + + default: + F1AP_DEBUG("Unknown procedure ID (%d) for initiating message\n", + (int)f1ap_message_p->procedureCode); + return ret; + break; + } + + message_string_size = strlen(message_string); + + message_p = itti_alloc_new_message_sized(TASK_F1AP, message_id, message_string_size + sizeof (IttiMsgText)); + message_p->ittiMsg.f1ap_f1_setup_log.size = message_string_size; + memcpy(&message_p->ittiMsg.f1ap_f1_setup_log.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + + free(message_string); + + return ret; +} + +static inline +int f1ap_encode_successfull_outcome(f1ap_message *f1ap_message_p, + uint8_t **buffer, uint32_t *len) +{ + int ret = -1; + MessageDef *message_p; + char *message_string = NULL; + size_t message_string_size; + MessagesIds message_id; + + DevAssert(f1ap_message_p != NULL); + + message_string = calloc(10000, sizeof(char)); + + f1ap_string_total_size = 0; + message_string_size = strlen(message_string); + + + switch(f1ap_message_p->procedureCode) { + case F1ap_ProcedureCode_id_InitialContextSetup: + ret = f1ap_encode_initial_context_setup_response( + &f1ap_message_p->msg.f1ap_InitialContextSetupResponseIEs, buffer, len); + + f1ap_xer_print_f1ap_initialcontextsetupresponse(f1ap_xer__print2sp, message_string, f1ap_message_p); + message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG; + message_p = itti_alloc_new_message_sized(TASK_F1AP, message_id, message_string_size + sizeof (IttiMsgText)); + message_p->ittiMsg.f1ap_initial_context_setup_log.size = message_string_size; + memcpy(&message_p->ittiMsg.f1ap_initial_context_setup_log.text, message_string, message_string_size); + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + free(message_string); + break; + + case F1ap_ProcedureCode_id_UEContextRelease: + ret = f1ap_encode_ue_context_release_complete( + &f1ap_message_p->msg.f1ap_UEContextReleaseCompleteIEs, buffer, len); + f1ap_xer_print_f1ap_uecontextreleasecomplete(f1ap_xer__print2sp, message_string, f1ap_message_p); + message_id = F1AP_UE_CONTEXT_RELEASE_COMPLETE_LOG; + message_p = itti_alloc_new_message_sized(TASK_F1AP, message_id, message_string_size + sizeof (IttiMsgText)); + message_p->ittiMsg.f1ap_ue_context_release_complete_log.size = message_string_size; + memcpy(&message_p->ittiMsg.f1ap_ue_context_release_complete_log.text, message_string, message_string_size); + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + free(message_string); + break; + + default: + F1AP_WARN("Unknown procedure ID (%d) for successfull outcome message\n", + (int)f1ap_message_p->procedureCode); + return ret; + break; + } + + + return ret; +} + +static inline +int f1ap_encode_unsuccessfull_outcome(f1ap_message *f1ap_message_p, + uint8_t **buffer, uint32_t *len) +{ + int ret = -1; + MessageDef *message_p; + char *message_string = NULL; + size_t message_string_size; + MessagesIds message_id; + + DevAssert(f1ap_message_p != NULL); + + message_string = calloc(10000, sizeof(char)); + + f1ap_string_total_size = 0; + + switch(f1ap_message_p->procedureCode) { + case F1ap_ProcedureCode_id_InitialContextSetup: + // ret = f1ap_encode_f1ap_initialcontextsetupfailureies( + // &f1ap_message_p->ittiMsg.f1ap_InitialContextSetupFailureIEs, buffer, len); + f1ap_xer_print_f1ap_initialcontextsetupfailure(f1ap_xer__print2sp, message_string, f1ap_message_p); + message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG; + break; + + default: + F1AP_DEBUG("Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)f1ap_message_p->procedureCode); + return ret; + break; + } + + message_string_size = strlen(message_string); + + message_p = itti_alloc_new_message_sized(TASK_F1AP, message_id, message_string_size + sizeof (IttiMsgText)); + message_p->ittiMsg.f1ap_initial_context_setup_log.size = message_string_size; + memcpy(&message_p->ittiMsg.f1ap_initial_context_setup_log.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + + free(message_string); + + return ret; +} + +static inline +int f1ap_encode_f1_setup_request( + F1ap_F1SetupRequestIEs_t *f1SetupRequestIEs, + uint8_t **buffer, + uint32_t *length) +{ + F1ap_F1SetupRequest_t f1SetupRequest; + F1ap_F1SetupRequest_t *f1SetupRequest_p = &f1SetupRequest; + + memset((void *)f1SetupRequest_p, 0, sizeof(f1SetupRequest)); + + if (f1ap_encode_f1ap_f1setuprequesties(f1SetupRequest_p, f1SetupRequestIEs) < 0) { + return -1; + } + + return f1ap_generate_initiating_message(buffer, + length, + F1ap_ProcedureCode_id_F1Setup, + F1ap_Criticality_reject, + &asn_DEF_F1ap_F1SetupRequest, + f1SetupRequest_p); +} + +static inline +int f1ap_encode_trace_failure( + F1ap_TraceFailureIndicationIEs_t *trace_failure_ies_p, + uint8_t **buffer, + uint32_t *length) +{ + F1ap_TraceFailureIndication_t trace_failure; + F1ap_TraceFailureIndication_t *trace_failure_p = &trace_failure; + + memset((void *)trace_failure_p, 0, sizeof(trace_failure)); + + if (f1ap_encode_f1ap_tracefailureindicationies( + trace_failure_p, trace_failure_ies_p) < 0) { + return -1; + } + + return f1ap_generate_initiating_message(buffer, + length, + F1ap_ProcedureCode_id_TraceFailureIndication, + F1ap_Criticality_reject, + &asn_DEF_F1ap_TraceFailureIndication, + trace_failure_p); +} + +static inline +int f1ap_encode_initial_context_setup_response( + F1ap_InitialContextSetupResponseIEs_t *initialContextSetupResponseIEs, + uint8_t **buffer, + uint32_t *length) +{ + F1ap_InitialContextSetupResponse_t initial_context_setup_response; + F1ap_InitialContextSetupResponse_t *initial_context_setup_response_p = + &initial_context_setup_response; + + memset((void *)initial_context_setup_response_p, 0, + sizeof(initial_context_setup_response)); + + if (f1ap_encode_f1ap_initialcontextsetupresponseies( + initial_context_setup_response_p, initialContextSetupResponseIEs) < 0) { + return -1; + } + + return f1ap_generate_successfull_outcome(buffer, + length, + F1ap_ProcedureCode_id_InitialContextSetup, + F1ap_Criticality_reject, + &asn_DEF_F1ap_InitialContextSetupResponse, + initial_context_setup_response_p); +} + +static inline +int f1ap_encode_ue_context_release_complete( + F1ap_UEContextReleaseCompleteIEs_t *f1ap_UEContextReleaseCompleteIEs, + uint8_t **buffer, + uint32_t *length) +{ + F1ap_UEContextReleaseComplete_t ue_context_release_complete; + F1ap_UEContextReleaseComplete_t *ue_context_release_complete_p = + &ue_context_release_complete; + + memset((void *)ue_context_release_complete_p, 0, + sizeof(ue_context_release_complete)); + + if (f1ap_encode_f1ap_uecontextreleasecompleteies( + ue_context_release_complete_p, f1ap_UEContextReleaseCompleteIEs) < 0) { + return -1; + } + + return f1ap_generate_successfull_outcome(buffer, + length, + F1ap_ProcedureCode_id_UEContextRelease, + F1ap_Criticality_reject, + &asn_DEF_F1ap_UEContextReleaseComplete, + ue_context_release_complete_p); +} + +static inline +int f1ap_encode_ue_context_release_request( + F1ap_UEContextReleaseRequestIEs_t *f1ap_UEContextReleaseRequestIEs, + uint8_t **buffer, + uint32_t *length) +{ + F1ap_UEContextReleaseRequest_t ue_context_release_request; + F1ap_UEContextReleaseRequest_t *ue_context_release_request_p = + &ue_context_release_request; + + memset((void *)ue_context_release_request_p, 0, + sizeof(ue_context_release_request)); + + if (f1ap_encode_f1ap_uecontextreleaserequesties( + ue_context_release_request_p, f1ap_UEContextReleaseRequestIEs) < 0) { + return -1; + } + + return f1ap_generate_initiating_message(buffer, + length, + F1ap_ProcedureCode_id_UEContextReleaseRequest, + F1ap_Criticality_reject, + &asn_DEF_F1ap_UEContextReleaseRequest, + ue_context_release_request_p); +} +*/ diff --git a/openair2/F1AP/f1ap_encoder.h b/openair2/F1AP/f1ap_encoder.h new file mode 100644 index 0000000000000000000000000000000000000000..695245d39b82a95febea987484f42cc7dfd61550 --- /dev/null +++ b/openair2/F1AP/f1ap_encoder.h @@ -0,0 +1,39 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_encoder.h + * \brief f1ap pdu encode procedures + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#ifndef F1AP_ENCODER_H_ +#define F1AP_ENCODER_H_ + +int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length) +__attribute__ ((warn_unused_result)); + +#endif /* F1AP_ENCODER_H_ */ diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c new file mode 100644 index 0000000000000000000000000000000000000000..a5b6a0996303da9c8b05e1beedf9cc7287fa2c92 --- /dev/null +++ b/openair2/F1AP/f1ap_handlers.c @@ -0,0 +1,127 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_handlers.c + * \brief f1ap messages handlers + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#include "f1ap_common.h" +#include "f1ap_handlers.h" +#include "f1ap_decoder.h" +#include "f1ap_cu_interface_management.h" +#include "f1ap_du_interface_management.h" +#include "f1ap_cu_rrc_message_transfer.h" +#include "f1ap_du_rrc_message_transfer.h" +#include "f1ap_cu_ue_context_management.h" +#include "f1ap_du_ue_context_management.h" + +extern f1ap_setup_req_t *f1ap_du_data_from_du; + +/* Handlers matrix. Only f1 related procedure present here */ +f1ap_message_decoded_callback f1ap_messages_callback[][3] = { + + + { 0, 0, 0 }, /* Reset */ + { CU_handle_F1_SETUP_REQUEST, DU_handle_F1_SETUP_RESPONSE, DU_handle_F1_SETUP_FAILURE }, /* F1Setup */ + { 0, 0, 0 }, /* ErrorIndication */ + { 0, 0, 0 }, /* gNBDUConfigurationUpdate */ + { 0, 0, 0 }, /* gNBCUConfigurationUpdate */ + { DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0 }, /* UEContextSetup */ + { DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0 }, /* UEContextRelease */ + { 0, 0, 0 }, /* UEContextModification */ + { 0, 0, 0 }, /* UEContextModificationRequired */ + { 0, 0, 0 }, /* UEMobilityCommand */ + { CU_handle_UE_CONTEXT_RELEASE_REQUEST, 0, 0 }, /* UEContextReleaseRequest */ + { CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER, 0, 0 }, /* InitialULRRCMessageTransfer */ + { DU_handle_DL_RRC_MESSAGE_TRANSFER, 0, 0 }, /* DLRRCMessageTransfer */ + { CU_handle_UL_RRC_MESSAGE_TRANSFER, 0, 0 }, /* ULRRCMessageTransfer */ + { 0, 0, 0 }, /* privateMessage */ + { 0, 0, 0 }, /* UEInactivityNotification */ + { 0, 0, 0 }, /* GNBDUResourceCoordination */ + { 0, 0, 0 }, /* SystemInformationDeliveryCommand */ + { 0, 0, 0 }, /* Paging */ + { 0, 0, 0 }, /* Notify */ + { 0, 0, 0 }, /* WriteReplaceWarning */ + { 0, 0, 0 }, /* PWSCancel */ + { 0, 0, 0 }, /* PWSRestartIndication */ + { 0, 0, 0 }, /* PWSFailureIndication */ +}; + +const char *f1ap_direction2String(int f1ap_dir) { +static const char *f1ap_direction_String[] = { + "", /* Nothing */ + "Initiating message", /* initiating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ +}; +return(f1ap_direction_String[f1ap_dir]); +} + +int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length) +{ + F1AP_F1AP_PDU_t pdu; + int ret; + + DevAssert(data != NULL); + + memset(&pdu, 0, sizeof(pdu)); + + if (f1ap_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(F1AP, "Failed to decode PDU\n"); + return -1; + } + + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage->procedureCode > sizeof(f1ap_messages_callback) / (3 * sizeof( + f1ap_message_decoded_callback)) + || (pdu.present > F1AP_F1AP_PDU_PR_unsuccessfulOutcome)) { + LOG_E(F1AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", + assoc_id, pdu.choice.initiatingMessage->procedureCode, pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (f1ap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) { + LOG_E(F1AP, "[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage->procedureCode, + f1ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu); + return -1; + } + + /* Calling the right handler */ + LOG_I(F1AP, "Calling handler with instance %d\n",instance); + ret = (*f1ap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu); + return ret; +} diff --git a/openair2/F1AP/f1ap_handlers.h b/openair2/F1AP/f1ap_handlers.h new file mode 100644 index 0000000000000000000000000000000000000000..631249a324287607d7c2c3ea539f6aea85913a9d --- /dev/null +++ b/openair2/F1AP/f1ap_handlers.h @@ -0,0 +1,39 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_handlers.h + * \brief f1ap messages handlers + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + +#ifndef F1AP_HANDLERS_H_ +#define F1AP_HANDLERS_H_ + +int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); + +#endif /* F1AP_HANDLERS_H_ */ diff --git a/openair2/F1AP/f1ap_itti_messaging.c b/openair2/F1AP/f1ap_itti_messaging.c new file mode 100644 index 0000000000000000000000000000000000000000..fa8951536a913259553209491e3b137f6c50eb71 --- /dev/null +++ b/openair2/F1AP/f1ap_itti_messaging.c @@ -0,0 +1,73 @@ +/* + * 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 "f1ap_common.h" +#include "f1ap_itti_messaging.h" + +void cu_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream) +{ + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; + + message_p = itti_alloc_new_message(TASK_CU_F1, SCTP_DATA_REQ); + + sctp_data_req = &message_p->ittiMsg.sctp_data_req; + + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + +void du_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream) +{ + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; + + message_p = itti_alloc_new_message(TASK_DU_F1, SCTP_DATA_REQ); + + sctp_data_req = &message_p->ittiMsg.sctp_data_req; + + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; + + LOG_I(F1AP, "Sending ITTI message to SCTP Task\n"); + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + +void f1ap_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id) +{ + MessageDef *message_p = NULL; + sctp_close_association_t *sctp_close_association_p = NULL; + + message_p = itti_alloc_new_message(TASK_S1AP, SCTP_CLOSE_ASSOCIATION); + sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; + sctp_close_association_p->assoc_id = assoc_id; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + diff --git a/openair2/F1AP/f1ap_itti_messaging.h b/openair2/F1AP/f1ap_itti_messaging.h new file mode 100644 index 0000000000000000000000000000000000000000..66c59a72e72ee1f721aa7bd41b4b07e6c961073a --- /dev/null +++ b/openair2/F1AP/f1ap_itti_messaging.h @@ -0,0 +1,35 @@ +/* + * 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 F1AP_ITTI_MESSAGING_H_ +#define F1AP_ITTI_MESSAGING_H_ + +void cu_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); + +void du_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); + +void f1ap_eNB_itti_send_sctp_close_association(instance_t instance, + int32_t assoc_id); + + +#endif /* F1AP_ITTI_MESSAGING_H_ */ diff --git a/openair2/F1AP/f1ap_messaging.c b/openair2/F1AP/f1ap_messaging.c new file mode 100644 index 0000000000000000000000000000000000000000..fb189eaed3d28c9cc6c22c6bb7c8dd0110ab4814 --- /dev/null +++ b/openair2/F1AP/f1ap_messaging.c @@ -0,0 +1,66 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file f1ap_messaging.c + * \brief f1ap procedures + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + + +#include "f1ap_common.h" +#include "f1ap_messaging.h" + +// void f1ap_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, +// uint32_t buffer_length, uint16_t stream) +// { +// MessageDef *message_p; +// sctp_data_req_t *sctp_data_req; + +// message_p = itti_alloc_new_message(TASK_F1AP, SCTP_DATA_REQ); + +// sctp_data_req = &message_p->ittiMsg.sctp_data_req; + +// sctp_data_req->assoc_id = assoc_id; +// sctp_data_req->buffer = buffer; +// sctp_data_req->buffer_length = buffer_length; +// sctp_data_req->stream = stream; + +// itti_send_msg_to_task(TASK_SCTP, instance, message_p); +// } + +// void f1ap_send_sctp_close_association(instance_t instance, int32_t assoc_id) +// { +// MessageDef *message_p = NULL; +// sctp_close_association_t *sctp_close_association_p = NULL; + +// message_p = itti_alloc_new_message(TASK_F1AP, SCTP_CLOSE_ASSOCIATION); +// sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; +// sctp_close_association_p->assoc_id = assoc_id; + +// itti_send_msg_to_task(TASK_SCTP, instance, message_p); +// } + diff --git a/openair2/F1AP/f1ap_messaging.h b/openair2/F1AP/f1ap_messaging.h new file mode 100644 index 0000000000000000000000000000000000000000..9ad0388d0198179d164e0176b246aa98f154522d --- /dev/null +++ b/openair2/F1AP/f1ap_messaging.h @@ -0,0 +1,44 @@ +/* + * 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 f1ap_messaging.h + * \brief f1ap procedures + * \author EURECOM/NTUST + * \date 2018 + * \version 0.1 + * \company Eurecom + * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr + * \note + * \warning + */ + + +#ifndef F1AP_MESSAGING_H_ +#define F1AP_MESSAGING_H_ + +void f1ap_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); + +void f1ap_send_sctp_close_association(instance_t instance, + int32_t assoc_id); + + +#endif /* F1AP_MESSAGING_H_ */ diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 826b1445fd6aff1f2d0c418fbc036b6957004e64..1ef04e204c7978707cdca7d0d061773c296c24c5 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -36,7 +36,7 @@ //#include "RadioResourceConfigCommonSIB.h" #include "LTE_RadioResourceConfigDedicated.h" #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) -#include "LTE_PRACH-ConfigSIB-v1310.h" + #include "LTE_PRACH-ConfigSIB-v1310.h" #endif #include "LTE_MeasGapConfig.h" #include "LTE_MeasObjectToAddModList.h" @@ -46,22 +46,21 @@ #include "mac_proto.h" #include "mac_extern.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/ran_context.h" -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) #include "LTE_MBSFN-AreaInfoList-r9.h" #include "LTE_MBSFN-AreaInfo-r9.h" #include "LTE_MBSFN-SubframeConfigList.h" #include "LTE_PMCH-InfoList-r9.h" -#endif + extern RAN_CONTEXT_t RC; extern int l2_init_eNB(void); extern void mac_top_init_eNB(void); extern void mac_init_cell_params(int Mod_idP,int CC_idP); -extern uint8_t nfapi_mode; int32_t **rxdata; int32_t **txdata; @@ -134,42 +133,37 @@ static const eutra_bandentry_t eutra_bandtable[] = { {68, 6980, 7280, 7530, 7830, 67536} }; -uint32_t to_earfcn(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw) -{ +#define BANDTABLE_SIZE (sizeof(eutra_bandtable)/sizeof(eutra_bandentry_t)) + +uint32_t to_earfcn(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw) { uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq / 100000; int bw_by_100 = bw / 100; - int i; - AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP); - for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); + + for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++); AssertFatal(dl_CarrierFreq_by_100k >= eutra_bandtable[i].dl_min, - "Band %d, bw %u : DL carrier frequency %u Hz < %u\n", - eutra_bandP, bw, dl_CarrierFreq, - eutra_bandtable[i].dl_min); + "Band %d, bw %u : DL carrier frequency %u Hz < %u\n", + eutra_bandP, bw, dl_CarrierFreq, + eutra_bandtable[i].dl_min); AssertFatal(dl_CarrierFreq_by_100k <= - (eutra_bandtable[i].dl_max - bw_by_100), - "Band %d, bw %u: DL carrier frequency %u Hz > %d\n", - eutra_bandP, bw, dl_CarrierFreq, - eutra_bandtable[i].dl_max - bw_by_100); - - + (eutra_bandtable[i].dl_max - bw_by_100), + "Band %d, bw %u: DL carrier frequency %u Hz > %d\n", + eutra_bandP, bw, dl_CarrierFreq, + eutra_bandtable[i].dl_max - bw_by_100); return (dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min + - (eutra_bandtable[i].N_OFFs_DL / 10)); + (eutra_bandtable[i].N_OFFs_DL / 10)); } -uint32_t to_earfcn_DL(int eutra_bandP, long long int dl_CarrierFreq, uint32_t bw) -{ - +uint32_t to_earfcn_DL(int eutra_bandP, long long int dl_CarrierFreq, uint32_t bw) { uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq / 100000; int bw_by_100 = bw / 100; - int i; - AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP); - for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); + + for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++); AssertFatal(dl_CarrierFreq_by_100k >= eutra_bandtable[i].dl_min, "Band %d, bw %u : DL carrier frequency %lld Hz < %u\n", @@ -180,22 +174,17 @@ uint32_t to_earfcn_DL(int eutra_bandP, long long int dl_CarrierFreq, uint32_t bw "Band %d, bw %u : DL carrier frequency %lld Hz > %d\n", eutra_bandP, bw, dl_CarrierFreq, eutra_bandtable[i].dl_max - bw_by_100); - - return (dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min + (eutra_bandtable[i].N_OFFs_DL / 10)); } -uint32_t to_earfcn_UL(int eutra_bandP, long long int ul_CarrierFreq, uint32_t bw) -{ - +uint32_t to_earfcn_UL(int eutra_bandP, long long int ul_CarrierFreq, uint32_t bw) { uint32_t ul_CarrierFreq_by_100k = ul_CarrierFreq / 100000; int bw_by_100 = bw / 100; - int i; - AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP); - for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); + + for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++); AssertFatal(ul_CarrierFreq_by_100k >= eutra_bandtable[i].ul_min, "Band %d, bw %u : UL carrier frequency %lld Hz < %u\n", @@ -206,168 +195,139 @@ uint32_t to_earfcn_UL(int eutra_bandP, long long int ul_CarrierFreq, uint32_t bw "Band %d, bw %u : UL carrier frequency %lld Hz > %d\n", eutra_bandP, bw, ul_CarrierFreq, eutra_bandtable[i].ul_max - bw_by_100); - - return (ul_CarrierFreq_by_100k - eutra_bandtable[i].ul_min + ((eutra_bandtable[i].N_OFFs_DL + 180000) / 10)); } -uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) -{ - +uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) { int i; - AssertFatal(eutra_bandP < 69, "eutra_band %d > 68\n", eutra_bandP); - for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); + + for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++); return (eutra_bandtable[i].dl_min + - (dl_earfcn - (eutra_bandtable[i].N_OFFs_DL / 10))) * 100000; + (dl_earfcn - (eutra_bandtable[i].N_OFFs_DL / 10))) * 100000; } -int32_t get_uldl_offset(int eutra_bandP) -{ +int32_t get_uldl_offset(int eutra_bandP) { int i; - for (i = 0; i < 69 && eutra_bandtable[i].band != eutra_bandP; i++); + for (i = 0; i < BANDTABLE_SIZE && eutra_bandtable[i].band != eutra_bandP; i++); + return (eutra_bandtable[i].dl_min - eutra_bandtable[i].ul_min); } uint32_t bw_table[6] = {6*180,15*180,25*180,50*180,75*180,100*180}; void config_mib(int Mod_idP, - int CC_idP, - int eutra_bandP, - int dl_BandwidthP, - LTE_PHICH_Config_t *phich_configP, - int Nid_cellP, - int NcpP, - int p_eNBP, - uint32_t dl_CarrierFreqP, - uint32_t ul_CarrierFreqP + int CC_idP, + int eutra_bandP, + int dl_BandwidthP, + LTE_PHICH_Config_t *phich_configP, + int Nid_cellP, + int NcpP, + int p_eNBP, + uint32_t dl_CarrierFreqP, + uint32_t ul_CarrierFreqP #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - uint32_t pbch_repetitionP + , + uint32_t pbch_repetitionP #endif - ) { - + ) { nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; - cfg->num_tlv=0; - cfg->subframe_config.pcfich_power_offset.value = 6000; // 0dB cfg->subframe_config.pcfich_power_offset.tl.tag = NFAPI_SUBFRAME_CONFIG_PCFICH_POWER_OFFSET_TAG; cfg->num_tlv++; - cfg->subframe_config.dl_cyclic_prefix_type.value = NcpP; cfg->subframe_config.dl_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_DL_CYCLIC_PREFIX_TYPE_TAG; cfg->num_tlv++; - cfg->subframe_config.ul_cyclic_prefix_type.value = NcpP; cfg->subframe_config.ul_cyclic_prefix_type.tl.tag = NFAPI_SUBFRAME_CONFIG_UL_CYCLIC_PREFIX_TYPE_TAG; cfg->num_tlv++; - cfg->rf_config.dl_channel_bandwidth.value = to_prb(dl_BandwidthP); cfg->rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG; cfg->num_tlv++; LOG_D(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP); - cfg->rf_config.ul_channel_bandwidth.value = to_prb(dl_BandwidthP); cfg->rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG; cfg->num_tlv++; - cfg->rf_config.tx_antenna_ports.value = p_eNBP; cfg->rf_config.tx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_TX_ANTENNA_PORTS_TAG; cfg->num_tlv++; - cfg->rf_config.rx_antenna_ports.value = 2; cfg->rf_config.rx_antenna_ports.tl.tag = NFAPI_RF_CONFIG_RX_ANTENNA_PORTS_TAG; cfg->num_tlv++; - cfg->nfapi_config.earfcn.value = to_earfcn(eutra_bandP,dl_CarrierFreqP,bw_table[dl_BandwidthP]/100); cfg->nfapi_config.earfcn.tl.tag = NFAPI_NFAPI_EARFCN_TAG; cfg->num_tlv++; - cfg->nfapi_config.rf_bands.number_rf_bands = 1; - cfg->nfapi_config.rf_bands.rf_band[0] = eutra_bandP; + cfg->nfapi_config.rf_bands.rf_band[0] = eutra_bandP; cfg->nfapi_config.rf_bands.tl.tag = NFAPI_PHY_RF_BANDS_TAG; cfg->num_tlv++; - cfg->phich_config.phich_resource.value = phich_configP->phich_Resource; cfg->phich_config.phich_resource.tl.tag = NFAPI_PHICH_CONFIG_PHICH_RESOURCE_TAG; cfg->num_tlv++; - cfg->phich_config.phich_duration.value = phich_configP->phich_Duration; cfg->phich_config.phich_duration.tl.tag = NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG; cfg->num_tlv++; - cfg->phich_config.phich_power_offset.value = 6000; // 0dB cfg->phich_config.phich_power_offset.tl.tag = NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG; cfg->num_tlv++; - cfg->sch_config.primary_synchronization_signal_epre_eprers.value = 6000; // 0dB cfg->sch_config.primary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_PRIMARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; cfg->num_tlv++; - cfg->sch_config.secondary_synchronization_signal_epre_eprers.value = 6000; // 0dB cfg->sch_config.secondary_synchronization_signal_epre_eprers.tl.tag = NFAPI_SCH_CONFIG_SECONDARY_SYNCHRONIZATION_SIGNAL_EPRE_EPRERS_TAG; cfg->num_tlv++; - cfg->sch_config.physical_cell_id.value = Nid_cellP; cfg->sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG; cfg->num_tlv++; - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) cfg->emtc_config.pbch_repetitions_enable_r13.value = pbch_repetitionP; cfg->emtc_config.pbch_repetitions_enable_r13.tl.tag = NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG; cfg->num_tlv++; -#endif +#endif LOG_I(MAC, - "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" + "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - - " PBCH repetition %d" -#endif - "\n" - ,__FUNCTION__ - ,cfg->num_tlv - ,cfg->rf_config.dl_channel_bandwidth.value - ,cfg->rf_config.ul_channel_bandwidth.value - ,NcpP,p_eNBP - ,cfg->nfapi_config.earfcn.value - ,cfg->nfapi_config.rf_bands.rf_band[0] - ,cfg->phich_config.phich_resource.value - ,cfg->phich_config.phich_duration.value - ,cfg->phich_config.phich_power_offset.value - ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value - ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value - ,cfg->sch_config.physical_cell_id.value + " PBCH repetition %d" +#endif + "\n" + ,__FUNCTION__ + ,cfg->num_tlv + ,cfg->rf_config.dl_channel_bandwidth.value + ,cfg->rf_config.ul_channel_bandwidth.value + ,NcpP,p_eNBP + ,cfg->nfapi_config.earfcn.value + ,cfg->nfapi_config.rf_bands.rf_band[0] + ,cfg->phich_config.phich_resource.value + ,cfg->phich_config.phich_duration.value + ,cfg->phich_config.phich_power_offset.value + ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value + ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value + ,cfg->sch_config.physical_cell_id.value #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,cfg->emtc_config.pbch_repetitions_enable_r13.value -#endif - ); + ,cfg->emtc_config.pbch_repetitions_enable_r13.value +#endif + ); } -void config_sib1(int Mod_idP, int CC_idP, LTE_TDD_Config_t * tdd_ConfigP) -{ - - +void config_sib1(int Mod_idP, int CC_idP, LTE_TDD_Config_t *tdd_ConfigP) { nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; if (tdd_ConfigP) { //TDD cfg->subframe_config.duplex_mode.value = 0; cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; cfg->num_tlv++; - cfg->tdd_frame_structure_config.subframe_assignment.value = tdd_ConfigP->subframeAssignment; cfg->tdd_frame_structure_config.subframe_assignment.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SUBFRAME_ASSIGNMENT_TAG; cfg->num_tlv++; - cfg->tdd_frame_structure_config.special_subframe_patterns.value = tdd_ConfigP->specialSubframePatterns; cfg->tdd_frame_structure_config.special_subframe_patterns.tl.tag = NFAPI_TDD_FRAME_STRUCTURE_SPECIAL_SUBFRAME_PATTERNS_TAG; cfg->num_tlv++; - } - else { // FDD + } else { // FDD cfg->subframe_config.duplex_mode.value = 1; cfg->subframe_config.duplex_mode.tl.tag = NFAPI_SUBFRAME_CONFIG_DUPLEX_MODE_TAG; cfg->num_tlv++; @@ -379,399 +339,351 @@ int power_off_dB[6] = { 78, 118, 140, 170, 188, 200 }; void config_sib2(int Mod_idP, - int CC_idP, - LTE_RadioResourceConfigCommonSIB_t * radioResourceConfigCommonP, + int CC_idP, + LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommonP, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - LTE_RadioResourceConfigCommonSIB_t * radioResourceConfigCommon_BRP, + LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BRP, #endif LTE_ARFCN_ValueEUTRA_t *ul_CArrierFreqP, long *ul_BandwidthP, LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmissionP, struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) { - nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; - cfg->subframe_config.pb.value = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b; cfg->subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG; cfg->num_tlv++; - cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower; cfg->rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG; cfg->num_tlv++; - cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value + power_off_dB[cfg->rf_config.dl_channel_bandwidth.value]; cfg->nfapi_config.max_transmit_power.tl.tag = NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG; cfg->num_tlv++; - cfg->prach_config.configuration_index.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex; cfg->prach_config.configuration_index.tl.tag = NFAPI_PRACH_CONFIG_CONFIGURATION_INDEX_TAG; cfg->num_tlv++; - cfg->prach_config.root_sequence_index.value = radioResourceConfigCommonP->prach_Config.rootSequenceIndex; cfg->prach_config.root_sequence_index.tl.tag = NFAPI_PRACH_CONFIG_ROOT_SEQUENCE_INDEX_TAG; cfg->num_tlv++; - cfg->prach_config.zero_correlation_zone_configuration.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; cfg->prach_config.zero_correlation_zone_configuration.tl.tag = NFAPI_PRACH_CONFIG_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; cfg->num_tlv++; - cfg->prach_config.high_speed_flag.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.highSpeedFlag; cfg->prach_config.high_speed_flag.tl.tag = NFAPI_PRACH_CONFIG_HIGH_SPEED_FLAG_TAG; cfg->num_tlv++; - cfg->prach_config.frequency_offset.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_FreqOffset; cfg->prach_config.frequency_offset.tl.tag = NFAPI_PRACH_CONFIG_FREQUENCY_OFFSET_TAG; cfg->num_tlv++; - - cfg->pusch_config.hopping_mode.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; cfg->pusch_config.hopping_mode.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_MODE_TAG; cfg->num_tlv++; - cfg->pusch_config.number_of_subbands.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; cfg->pusch_config.number_of_subbands.tl.tag = NFAPI_PUSCH_CONFIG_NUMBER_OF_SUBBANDS_TAG; cfg->num_tlv++; - cfg->pusch_config.hopping_offset.value = radioResourceConfigCommonP->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; cfg->pusch_config.hopping_offset.tl.tag = NFAPI_PUSCH_CONFIG_HOPPING_OFFSET_TAG; cfg->num_tlv++; - cfg->pucch_config.delta_pucch_shift.value = radioResourceConfigCommonP->pucch_ConfigCommon.deltaPUCCH_Shift; cfg->pucch_config.delta_pucch_shift.tl.tag = NFAPI_PUCCH_CONFIG_DELTA_PUCCH_SHIFT_TAG; cfg->num_tlv++; - cfg->pucch_config.n_cqi_rb.value = radioResourceConfigCommonP->pucch_ConfigCommon.nRB_CQI; cfg->pucch_config.n_cqi_rb.tl.tag = NFAPI_PUCCH_CONFIG_N_CQI_RB_TAG; cfg->num_tlv++; - cfg->pucch_config.n_an_cs.value = radioResourceConfigCommonP->pucch_ConfigCommon.nCS_AN; cfg->pucch_config.n_an_cs.tl.tag = NFAPI_PUCCH_CONFIG_N_AN_CS_TAG; cfg->num_tlv++; - cfg->pucch_config.n1_pucch_an.value = radioResourceConfigCommonP->pucch_ConfigCommon.n1PUCCH_AN; cfg->pucch_config.n1_pucch_an.tl.tag = NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG; cfg->num_tlv++; if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled == true) { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1; - } - else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) { + } else if (radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled == true) { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 2; - } - else { + } else { cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0; } + cfg->uplink_reference_signal_config.uplink_rs_hopping.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_UPLINK_RS_HOPPING_TAG; cfg->num_tlv++; - cfg->uplink_reference_signal_config.group_assignment.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; cfg->uplink_reference_signal_config.group_assignment.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_GROUP_ASSIGNMENT_TAG; cfg->num_tlv++; - cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.value = radioResourceConfigCommonP->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; cfg->uplink_reference_signal_config.cyclic_shift_1_for_drms.tl.tag = NFAPI_UPLINK_REFERENCE_SIGNAL_CONFIG_CYCLIC_SHIFT_1_FOR_DRMS_TAG; cfg->num_tlv++; - // how to enable/disable SRS? if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present== LTE_SoundingRS_UL_ConfigCommon_PR_setup) { cfg->srs_config.bandwidth_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; cfg->srs_config.bandwidth_configuration.tl.tag = NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG; cfg->num_tlv++; - cfg->srs_config.srs_subframe_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; cfg->srs_config.srs_subframe_configuration.tl.tag = NFAPI_SRS_CONFIG_SRS_SUBFRAME_CONFIGURATION_TAG; cfg->num_tlv++; - cfg->srs_config.srs_acknack_srs_simultaneous_transmission.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; cfg->srs_config.srs_acknack_srs_simultaneous_transmission.tl.tag = NFAPI_SRS_CONFIG_SRS_ACKNACK_SRS_SIMULTANEOUS_TRANSMISSION_TAG; cfg->num_tlv++; - + if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) { - cfg->srs_config.max_up_pts.value = 1; - } - else { - cfg->srs_config.max_up_pts.value = 0; + cfg->srs_config.max_up_pts.value = 1; + } else { + cfg->srs_config.max_up_pts.value = 0; } + cfg->srs_config.max_up_pts.tl.tag = NFAPI_SRS_CONFIG_MAX_UP_PTS_TAG; cfg->num_tlv++; } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0) { AssertFatal(radioResourceConfigCommon_BRP != NULL, "radioResource rou is missing\n"); AssertFatal(radioResourceConfigCommon_BRP->ext4 != NULL, "ext4 is missing\n"); cfg->emtc_config.prach_catm_root_sequence_index.value = radioResourceConfigCommon_BRP->prach_Config.rootSequenceIndex; cfg->emtc_config.prach_catm_root_sequence_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ROOT_SEQUENCE_INDEX_TAG; cfg->num_tlv++; - cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; cfg->emtc_config.prach_catm_zero_correlation_zone_configuration.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_ZERO_CORRELATION_ZONE_CONFIGURATION_TAG; cfg->num_tlv++; - cfg->emtc_config.prach_catm_high_speed_flag.value = radioResourceConfigCommon_BRP->prach_Config.prach_ConfigInfo.highSpeedFlag; cfg->emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG; cfg->num_tlv++; - struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; - LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; - LTE_PRACH_ParametersCE_r13_t *p; cfg->emtc_config.prach_ce_level_0_enable.value = 0; cfg->emtc_config.prach_ce_level_0_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; cfg->num_tlv++; - cfg->emtc_config.prach_ce_level_1_enable.value = 0; cfg->emtc_config.prach_ce_level_1_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; cfg->num_tlv++; - cfg->emtc_config.prach_ce_level_2_enable.value = 0; cfg->emtc_config.prach_ce_level_2_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; cfg->num_tlv++; - cfg->emtc_config.prach_ce_level_3_enable.value = 0; cfg->emtc_config.prach_ce_level_3_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; cfg->num_tlv++; - switch (prach_ParametersListCE_r13->list.count) { - case 4: - p = prach_ParametersListCE_r13->list.array[3]; - cfg->emtc_config.prach_ce_level_3_enable.value = 1; - cfg->emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_3_configuration_index.value = p->prach_ConfigIndex_r13; - cfg->emtc_config.prach_ce_level_3_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_3_frequency_offset.value = p->prach_FreqOffset_r13; - cfg->emtc_config.prach_ce_level_3_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value = 1<<p->numRepetitionPerPreambleAttempt_r13; - cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; - cfg->num_tlv++; - - if (p->prach_StartingSubframe_r13) { - cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG; + case 4: + p = prach_ParametersListCE_r13->list.array[3]; + cfg->emtc_config.prach_ce_level_3_enable.value = 1; + cfg->emtc_config.prach_ce_level_3_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_3_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_3_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.value = 1<<p->numRepetitionPerPreambleAttempt_r13; + cfg->emtc_config.prach_ce_level_3_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; cfg->num_tlv++; - } - - cfg->emtc_config.prach_ce_level_3_hopping_enable.value = p->prach_HoppingConfig_r13; - cfg->emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG; - cfg->num_tlv++; + if (p->prach_StartingSubframe_r13) { + cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_3_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } - cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; - cfg->emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG; - cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_3_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_3_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; + cfg->emtc_config.prach_ce_level_3_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_3_HOPPING_OFFSET_TAG; + cfg->num_tlv++; - case 3: - p = prach_ParametersListCE_r13->list.array[2]; - cfg->emtc_config.prach_ce_level_2_enable.value = 1; - cfg->emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_2_configuration_index.value = p->prach_ConfigIndex_r13; - cfg->emtc_config.prach_ce_level_2_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_2_frequency_offset.value = p->prach_FreqOffset_r13; - cfg->emtc_config.prach_ce_level_2_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value = 1<<p->numRepetitionPerPreambleAttempt_r13; - cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; - cfg->num_tlv++; - - if (p->prach_StartingSubframe_r13) { - cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG; + case 3: + p = prach_ParametersListCE_r13->list.array[2]; + cfg->emtc_config.prach_ce_level_2_enable.value = 1; + cfg->emtc_config.prach_ce_level_2_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_2_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_2_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.value = 1<<p->numRepetitionPerPreambleAttempt_r13; + cfg->emtc_config.prach_ce_level_2_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; cfg->num_tlv++; - } - cfg->emtc_config.prach_ce_level_2_hopping_enable.value = p->prach_HoppingConfig_r13; - cfg->emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG; - cfg->num_tlv++; + if (p->prach_StartingSubframe_r13) { + cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_2_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } - cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; - cfg->emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG; - cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_2_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_2_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; + cfg->emtc_config.prach_ce_level_2_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_2_HOPPING_OFFSET_TAG; + cfg->num_tlv++; - case 2: - p = prach_ParametersListCE_r13->list.array[1]; - cfg->emtc_config.prach_ce_level_1_enable.value = 1; - cfg->emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_1_configuration_index.value = p->prach_ConfigIndex_r13; - cfg->emtc_config.prach_ce_level_1_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_1_frequency_offset.value = p->prach_FreqOffset_r13; - cfg->emtc_config.prach_ce_level_1_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value = 1<<p->numRepetitionPerPreambleAttempt_r13; - cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; - cfg->num_tlv++; - - if (p->prach_StartingSubframe_r13) { - cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG; + case 2: + p = prach_ParametersListCE_r13->list.array[1]; + cfg->emtc_config.prach_ce_level_1_enable.value = 1; + cfg->emtc_config.prach_ce_level_1_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_1_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_1_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.value = 1<<p->numRepetitionPerPreambleAttempt_r13; + cfg->emtc_config.prach_ce_level_1_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; cfg->num_tlv++; - } - cfg->emtc_config.prach_ce_level_1_hopping_enable.value = p->prach_HoppingConfig_r13; - cfg->emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG; - cfg->num_tlv++; + if (p->prach_StartingSubframe_r13) { + cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_1_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } - cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; - cfg->emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG; - cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_1_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_1_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; + cfg->emtc_config.prach_ce_level_1_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_1_HOPPING_OFFSET_TAG; + cfg->num_tlv++; - case 1: - p = prach_ParametersListCE_r13->list.array[0]; - cfg->emtc_config.prach_ce_level_0_enable.value = 1; - cfg->emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_0_configuration_index.value = p->prach_ConfigIndex_r13; - cfg->emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_0_frequency_offset.value = p->prach_FreqOffset_r13; - cfg->emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG; - cfg->num_tlv++; - - cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value = 1<<p->numRepetitionPerPreambleAttempt_r13; - cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; - cfg->num_tlv++; - - if (p->prach_StartingSubframe_r13) { - cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; - cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG; + case 1: + p = prach_ParametersListCE_r13->list.array[0]; + cfg->emtc_config.prach_ce_level_0_enable.value = 1; + cfg->emtc_config.prach_ce_level_0_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_configuration_index.value = p->prach_ConfigIndex_r13; + cfg->emtc_config.prach_ce_level_0_configuration_index.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_CONFIGURATION_INDEX_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_frequency_offset.value = p->prach_FreqOffset_r13; + cfg->emtc_config.prach_ce_level_0_frequency_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_FREQUENCY_OFFSET_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.value = 1<<p->numRepetitionPerPreambleAttempt_r13; + cfg->emtc_config.prach_ce_level_0_number_of_repetitions_per_attempt.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_NUMBER_OF_REPETITIONS_PER_ATTEMPT_TAG; cfg->num_tlv++; - } - cfg->emtc_config.prach_ce_level_0_hopping_enable.value = p->prach_HoppingConfig_r13; - cfg->emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG; - cfg->num_tlv++; + if (p->prach_StartingSubframe_r13) { + cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.value = 2<<*p->prach_StartingSubframe_r13; + cfg->emtc_config.prach_ce_level_0_starting_subframe_periodicity.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_STARTING_SUBFRAME_PERIODICITY_TAG; + cfg->num_tlv++; + } - cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; - cfg->emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG; - cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_hopping_enable.value = p->prach_HoppingConfig_r13; + cfg->emtc_config.prach_ce_level_0_hopping_enable.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_ENABLE_TAG; + cfg->num_tlv++; + cfg->emtc_config.prach_ce_level_0_hopping_offset.value = cfg->rf_config.ul_channel_bandwidth.value - 6; + cfg->emtc_config.prach_ce_level_0_hopping_offset.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_HOPPING_OFFSET_TAG; + cfg->num_tlv++; } - AssertFatal(cfg->emtc_config.prach_ce_level_0_enable.value>0,"CE_level0 is not enabled\n"); - struct LTE_FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13; + if ((ext4_freqHoppingParameters) && - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)){ + (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)) { switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) { - case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ - break; - case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; - cfg->num_tlv++; - break; - case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13; - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; - cfg->num_tlv++; - break; + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ + break; + + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + cfg->num_tlv++; + break; + + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; + cfg->num_tlv++; + break; } } + if ((ext4_freqHoppingParameters) && - (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)){ + (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)) { switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->present) { - case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ - break; - case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; - cfg->num_tlv++; - break; - case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; - cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; - cfg->num_tlv++; - break; + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ + break; + + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + cfg->num_tlv++; + break; + + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; + cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; + cfg->num_tlv++; + break; } } } -#endif +#endif } void config_dedicated(int Mod_idP, - int CC_idP, - uint16_t rnti, - struct LTE_PhysicalConfigDedicated *physicalConfigDedicated) -{ - + int CC_idP, + uint16_t rnti, + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated) { } void config_dedicated_scell(int Mod_idP, - uint16_t rnti, - LTE_SCellToAddMod_r10_t * sCellToAddMod_r10) -{ - + uint16_t rnti, + LTE_SCellToAddMod_r10_t *sCellToAddMod_r10) { } int rrc_mac_config_req_eNB(module_id_t Mod_idP, - int CC_idP, - int physCellId, - int p_eNB, - int Ncp, int eutra_band, uint32_t dl_CarrierFreq, + int CC_idP, + int physCellId, + int p_eNB, + int Ncp, int eutra_band, uint32_t dl_CarrierFreq, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - int pbch_repetition, + int pbch_repetition, #endif - rnti_t rntiP, - LTE_BCCH_BCH_Message_t * mib, - LTE_RadioResourceConfigCommonSIB_t * - radioResourceConfigCommon, + rnti_t rntiP, + LTE_BCCH_BCH_Message_t *mib, + LTE_RadioResourceConfigCommonSIB_t * + radioResourceConfigCommon, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - LTE_RadioResourceConfigCommonSIB_t * - radioResourceConfigCommon_BR, + LTE_RadioResourceConfigCommonSIB_t * + radioResourceConfigCommon_BR, #endif - struct LTE_PhysicalConfigDedicated - *physicalConfigDedicated, + struct LTE_PhysicalConfigDedicated + *physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - LTE_SCellToAddMod_r10_t * sCellToAddMod_r10, - //struct LTE_PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, + LTE_SCellToAddMod_r10_t *sCellToAddMod_r10, + //struct LTE_PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - LTE_MeasObjectToAddMod_t ** measObj, - LTE_MAC_MainConfig_t * mac_MainConfig, - long logicalChannelIdentity, - LTE_LogicalChannelConfig_t * logicalChannelConfig, - LTE_MeasGapConfig_t * measGapConfig, - LTE_TDD_Config_t * tdd_Config, - LTE_MobilityControlInfo_t * mobilityControlInfo, - LTE_SchedulingInfoList_t * schedulingInfoList, - uint32_t ul_CarrierFreq, - long *ul_Bandwidth, - LTE_AdditionalSpectrumEmission_t * - additionalSpectrumEmission, - struct LTE_MBSFN_SubframeConfigList - *mbsfn_SubframeConfigList + LTE_MeasObjectToAddMod_t **measObj, + LTE_MAC_MainConfig_t *mac_MainConfig, + long logicalChannelIdentity, + LTE_LogicalChannelConfig_t *logicalChannelConfig, + LTE_MeasGapConfig_t *measGapConfig, + LTE_TDD_Config_t *tdd_Config, + LTE_MobilityControlInfo_t *mobilityControlInfo, + LTE_SchedulingInfoList_t *schedulingInfoList, + uint32_t ul_CarrierFreq, + long *ul_Bandwidth, + LTE_AdditionalSpectrumEmission_t * + additionalSpectrumEmission, + struct LTE_MBSFN_SubframeConfigList + *mbsfn_SubframeConfigList #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , uint8_t MBMS_Flag, - LTE_MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, - LTE_PMCH_InfoList_r9_t * pmch_InfoList + , uint8_t MBMS_Flag, + LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, + LTE_PMCH_InfoList_r9_t *pmch_InfoList #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - LTE_SystemInformationBlockType1_v1310_IEs_t * - sib1_v13ext + , + LTE_SystemInformationBlockType1_v1310_IEs_t * + sib1_v13ext #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , @@ -785,13 +697,10 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, ) { int i; - int UE_id = -1; eNB_MAC_INST *eNB = RC.mac[Mod_idP]; UE_list_t *UE_list= &eNB->UE_list; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); - LOG_D(MAC, "RC.mac:%p mib:%p\n", RC.mac, mib); if (mib != NULL) { @@ -799,45 +708,41 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, l2_init_eNB(); //mac_top_init_eNB(); - RC.mac[Mod_idP]->common_channels[CC_idP].mib = mib; RC.mac[Mod_idP]->common_channels[CC_idP].physCellId = physCellId; RC.mac[Mod_idP]->common_channels[CC_idP].p_eNB = p_eNB; RC.mac[Mod_idP]->common_channels[CC_idP].Ncp = Ncp; RC.mac[Mod_idP]->common_channels[CC_idP].eutra_band = eutra_band; RC.mac[Mod_idP]->common_channels[CC_idP].dl_CarrierFreq = dl_CarrierFreq; - LOG_I(MAC, - "Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", - Mod_idP, - CC_idP, - eutra_band, - to_prb((int)mib->message.dl_Bandwidth), - physCellId, - p_eNB, - dl_CarrierFreq, - (int)mib->message.phich_Config.phich_Resource, - (int)mib->message.phich_Config.phich_Duration); - + "Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", + Mod_idP, + CC_idP, + eutra_band, + to_prb((int)mib->message.dl_Bandwidth), + physCellId, + p_eNB, + dl_CarrierFreq, + (int)mib->message.phich_Config.phich_Resource, + (int)mib->message.phich_Config.phich_Duration); config_mib(Mod_idP,CC_idP, - eutra_band, - mib->message.dl_Bandwidth, - &mib->message.phich_Config, - physCellId, - Ncp, - p_eNB, - dl_CarrierFreq, - ul_CarrierFreq + eutra_band, + mib->message.dl_Bandwidth, + &mib->message.phich_Config, + physCellId, + Ncp, + p_eNB, + dl_CarrierFreq, + ul_CarrierFreq #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , pbch_repetition + , pbch_repetition #endif - ); - + ); mac_init_cell_params(Mod_idP,CC_idP); if (schedulingInfoList!=NULL) { - RC.mac[Mod_idP]->common_channels[CC_idP].tdd_Config = tdd_Config; - RC.mac[Mod_idP]->common_channels[CC_idP].schedulingInfoList = schedulingInfoList; + RC.mac[Mod_idP]->common_channels[CC_idP].tdd_Config = tdd_Config; + RC.mac[Mod_idP]->common_channels[CC_idP].schedulingInfoList = schedulingInfoList; config_sib1(Mod_idP,CC_idP,tdd_Config); } @@ -849,118 +754,117 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + if (sib1_v13ext != NULL) { RC.mac[Mod_idP]->common_channels[CC_idP].sib1_v13ext = sib1_v13ext; } + #endif - if (radioResourceConfigCommon != NULL) { - LOG_I(MAC, "[CONFIG]SIB2/3 Contents (partial)\n"); - LOG_I(MAC, "[CONFIG]pusch_config_common.n_SB = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.n_SB); - LOG_I(MAC, "[CONFIG]pusch_config_common.hoppingMode = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); - LOG_I(MAC, - "[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); - LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); - LOG_I(MAC, - "[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. - groupHoppingEnabled); - LOG_I(MAC, - "[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. - groupAssignmentPUSCH); - LOG_I(MAC, - "[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH. - sequenceHoppingEnabled); - LOG_I(MAC, "[CONFIG]pusch_config_common.cyclicShift = %ld\n", - radioResourceConfigCommon-> - pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); - - AssertFatal(radioResourceConfigCommon-> - rach_ConfigCommon.maxHARQ_Msg3Tx > 0, - "radioResourceconfigCommon %d == 0\n", - (int) radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); - - RC.mac[Mod_idP]->common_channels[CC_idP].radioResourceConfigCommon = radioResourceConfigCommon; - RC.mac[Mod_idP]->common_channels[CC_idP].radioResourceConfigCommon_BR = radioResourceConfigCommon_BR; - if (ul_CarrierFreq > 0) RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq = ul_CarrierFreq; - if (ul_Bandwidth) RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = *ul_Bandwidth; - else RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.dl_Bandwidth; - - config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon, + AssertFatal(radioResourceConfigCommon != NULL, "radioResourceConfigCommon is null\n"); + LOG_I(MAC, "[CONFIG]SIB2/3 Contents (partial)\n"); + LOG_I(MAC, "[CONFIG]pusch_config_common.n_SB = %ld\n", + radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB); + LOG_I(MAC, "[CONFIG]pusch_config_common.hoppingMode = %ld\n", + radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); + LOG_I(MAC, "[CONFIG]pusch_config_common.pusch_HoppingOffset = %ld\n", + radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); + LOG_I(MAC, "[CONFIG]pusch_config_common.enable64QAM = %d\n", + radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); + LOG_I(MAC, "[CONFIG]pusch_config_common.groupHoppingEnabled = %d\n", + radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled); + LOG_I(MAC, "[CONFIG]pusch_config_common.groupAssignmentPUSCH = %ld\n", + radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); + LOG_I(MAC, "[CONFIG]pusch_config_common.sequenceHoppingEnabled = %d\n", + radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled); + LOG_I(MAC, "[CONFIG]pusch_config_common.cyclicShift = %ld\n", + radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); + AssertFatal(radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx > 0, + "radioResourceconfigCommon %d == 0\n", + (int) radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); + RC.mac[Mod_idP]->common_channels[CC_idP].radioResourceConfigCommon = radioResourceConfigCommon; + RC.mac[Mod_idP]->common_channels[CC_idP].radioResourceConfigCommon_BR = radioResourceConfigCommon_BR; + + if (ul_CarrierFreq > 0) RC.mac[Mod_idP]->common_channels[CC_idP].ul_CarrierFreq = ul_CarrierFreq; + + if (ul_Bandwidth) RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = *ul_Bandwidth; + else RC.mac[Mod_idP]->common_channels[CC_idP].ul_Bandwidth = RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.dl_Bandwidth; + + config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - radioResourceConfigCommon_BR, + radioResourceConfigCommon_BR, #endif - NULL, ul_Bandwidth, additionalSpectrumEmission, - mbsfn_SubframeConfigList); - - - } + NULL, ul_Bandwidth, additionalSpectrumEmission, + mbsfn_SubframeConfigList); } // mib != NULL + if (mobilityControlInfo !=NULL) { + if ((UE_id = add_new_ue(Mod_idP, CC_idP, + rntiP, -1 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + 0 +#endif + )) == -1) { + LOG_E(MAC, "%s:%d: fatal\n", __FILE__, __LINE__); + abort(); + } + } // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup - if (logicalChannelConfig != NULL) { // check for eMTC specific things + if (logicalChannelConfig != NULL) { // check for eMTC specific things UE_id = find_UE_id(Mod_idP, rntiP); - if (UE_id<0) { + if (UE_id<0) { LOG_E(MAC,"Configuration received for unknown UE (%x), shouldn't happen\n",rntiP); return(-1); } + if (logicalChannelConfig) { - UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = *logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup; - UE_list->UE_template[CC_idP][UE_id].lcgidpriority[logicalChannelIdentity] = logicalChannelConfig->ul_SpecificParameters->priority; + UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = *logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup; + UE_list->UE_template[CC_idP][UE_id].lcgidpriority[logicalChannelIdentity] = logicalChannelConfig->ul_SpecificParameters->priority; } else UE_list->UE_template[CC_idP][UE_id].lcgidmap[logicalChannelIdentity] = 0; } - + if (physicalConfigDedicated != NULL) { UE_id = find_UE_id(Mod_idP, rntiP); - if (UE_id<0) { + + if (UE_id<0) { LOG_E(MAC,"Configuration received for unknown UE (%x), shouldn't happen\n",rntiP); return(-1); } + UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated = physicalConfigDedicated; LOG_I(MAC,"Added physicalConfigDedicated %p for %d.%d\n",physicalConfigDedicated,CC_idP,UE_id); } - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (sCellToAddMod_r10 != NULL) { - if (UE_id<0) { + if (UE_id<0) { LOG_E(MAC,"Configuration received for unknown UE (%x), shouldn't happen\n",rntiP); return(-1); } + AssertFatal(UE_id>=0,"Configuration received for unknown UE (%x), shouldn't happen\n",rntiP); config_dedicated_scell(Mod_idP, rntiP, sCellToAddMod_r10); } + #endif if (mbsfn_SubframeConfigList != NULL) { LOG_I(MAC, - "[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", - Mod_idP, mbsfn_SubframeConfigList->list.count); + "[eNB %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", + Mod_idP, mbsfn_SubframeConfigList->list.count); RC.mac[Mod_idP]->common_channels[0].num_sf_allocation_pattern = mbsfn_SubframeConfigList->list.count; for (i = 0; i < mbsfn_SubframeConfigList->list.count; i++) { RC.mac[Mod_idP]->common_channels[0].mbsfn_SubframeConfig[i] = mbsfn_SubframeConfigList->list.array[i]; LOG_I(MAC, - "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", - Mod_idP, i, - RC.mac[Mod_idP]-> - common_channels[0].mbsfn_SubframeConfig[i]-> - subframeAllocation.choice.oneFrame.buf[0]); + "[eNB %d][CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", + Mod_idP, i, + RC.mac[Mod_idP]-> + common_channels[0].mbsfn_SubframeConfig[i]-> + subframeAllocation.choice.oneFrame.buf[0]); } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -1006,75 +910,426 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time LOG_I(MAC,"[eNB %d][CONFIG] Received %d MBSFN Area Info\n", Mod_idP, mbsfn_AreaInfoList->list.count); RC.mac[Mod_idP]->common_channels[0].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; - + for (i =0; i< mbsfn_AreaInfoList->list.count; i++) { RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i] = mbsfn_AreaInfoList->list.array[i]; LOG_I(MAC,"[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_idP,i, - RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); // config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); } - } + } if (pmch_InfoList != NULL) { - // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); - LOG_I(MAC, "[CONFIG] Number of PMCH in this MBSFN Area %d\n", - pmch_InfoList->list.count); - + pmch_InfoList->list.count); + for (i = 0; i < pmch_InfoList->list.count; i++) { RC.mac[Mod_idP]->common_channels[0].pmch_Config[i] = - &pmch_InfoList->list.array[i]->pmch_Config_r9; - + &pmch_InfoList->list.array[i]->pmch_Config_r9; LOG_I(MAC, - "[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n", - i, - RC.mac[Mod_idP]->common_channels[0]. - pmch_Config[i]->sf_AllocEnd_r9); + "[CONFIG] PMCH[%d]: This PMCH stop (sf_AllocEnd_r9) at subframe %ldth\n", + i, + RC.mac[Mod_idP]->common_channels[0]. + pmch_Config[i]->sf_AllocEnd_r9); LOG_I(MAC, "[CONFIG] PMCH[%d]: mch_Scheduling_Period = %ld\n", - i, - RC.mac[Mod_idP]->common_channels[0]. - pmch_Config[i]->mch_SchedulingPeriod_r9); + i, + RC.mac[Mod_idP]->common_channels[0]. + pmch_Config[i]->mch_SchedulingPeriod_r9); LOG_I(MAC, "[CONFIG] PMCH[%d]: dataMCS = %ld\n", i, - RC.mac[Mod_idP]->common_channels[0]. - pmch_Config[i]->dataMCS_r9); - + RC.mac[Mod_idP]->common_channels[0]. + pmch_Config[i]->dataMCS_r9); // MBMS session info list in each MCH RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i] = - &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9; + &pmch_InfoList->list.array[i]->mbms_SessionInfoList_r9; LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n", i, - RC.mac[Mod_idP]->common_channels[0]. - mbms_SessionList[i]->list.count); + RC.mac[Mod_idP]->common_channels[0]. + mbms_SessionList[i]->list.count); } } - -#endif - LOG_D(MAC, "%s() %s:%d RC.mac[Mod_idP]->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.mac[Mod_idP]->if_inst->PHY_config_req); - - // if in nFAPI mode - if ( - (nfapi_mode == 1 || nfapi_mode == 2) && - (RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) - ) { - while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) { - // DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); - usleep(100 * 1000); - printf("Waiting for PHY_config_req\n"); - } +#endif + LOG_D(MAC, "%s() %s:%d RC.mac[Mod_idP]->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.mac[Mod_idP]->if_inst->PHY_config_req); + + // if in nFAPI mode + if ( + (NFAPI_MODE == NFAPI_MODE_PNF ||NFAPI_MODE == NFAPI_MODE_VNF) && + (RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) + ) { + while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) { + // DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); + usleep(100 * 1000); + printf("Waiting for PHY_config_req\n"); } + } + + if (radioResourceConfigCommon != NULL) { + PHY_Config_t phycfg; + phycfg.Mod_id = Mod_idP; + phycfg.CC_id = CC_idP; + phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; + + if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); + } + + RC.mac[Mod_idP]->scheduler_mode = global_scheduler_mode; + return(0); +} + + +//----------------------------------------------------------------------------- +/* +* Configure local DRX timers and thresholds following the drx_configuration input +*/ +void eNB_Config_Local_DRX( + module_id_t Mod_id, + rnti_t rnti, + LTE_DRX_Config_t *const drx_Configuration +) +//----------------------------------------------------------------------------- +{ + UE_list_t *UE_list_mac = NULL; + int UE_id = -1; + UE_sched_ctrl *UE_scheduling_control = NULL; + + UE_list_mac = &(RC.mac[Mod_id]->UE_list); + + UE_id = find_UE_id(Mod_id, rnti); + + /* Check UE_id */ + if (UE_id == -1) { + LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n", + __FILE__, + __LINE__, + __FUNCTION__); + return; + } + + /* Get struct to modify */ + UE_scheduling_control = &(UE_list_mac->UE_sched_ctrl[UE_id]); + + /* Check drx_Configuration */ + if (drx_Configuration == NULL) { + LOG_I(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n"); + + UE_scheduling_control->cdrx_configured = FALSE; + return; + } + + /* Check if drx config present */ + if (drx_Configuration->present != LTE_DRX_Config_PR_setup) { + LOG_I(MAC, "No drx_Configuration present, don't configure local UE parameters\n"); + + UE_scheduling_control->cdrx_configured = FALSE; + return; + } + + /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ + UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when ACK is received + UE_scheduling_control->cdrx_waiting_ack = TRUE; // set to true first, waiting for the UE to configure CDRX on its side + UE_scheduling_control->in_active_time = FALSE; + UE_scheduling_control->dci0_ongoing_timer = 0; + + UE_scheduling_control->on_duration_timer = 0; + switch (drx_Configuration->choice.setup.onDurationTimer) { + case 0: + UE_scheduling_control->on_duration_timer_thres = 1; + break; + case 1: + UE_scheduling_control->on_duration_timer_thres = 2; + break; + case 2: + UE_scheduling_control->on_duration_timer_thres = 3; + break; + case 3: + UE_scheduling_control->on_duration_timer_thres = 4; + break; + case 4: + UE_scheduling_control->on_duration_timer_thres = 5; + break; + case 5: + UE_scheduling_control->on_duration_timer_thres = 6; + break; + case 6: + UE_scheduling_control->on_duration_timer_thres = 8; + break; + case 7: + UE_scheduling_control->on_duration_timer_thres = 10; + break; + case 8: + UE_scheduling_control->on_duration_timer_thres = 20; + break; + case 9: + UE_scheduling_control->on_duration_timer_thres = 30; + break; + case 10: + UE_scheduling_control->on_duration_timer_thres = 40; + break; + case 11: + UE_scheduling_control->on_duration_timer_thres = 50; + break; + case 12: + UE_scheduling_control->on_duration_timer_thres = 60; + break; + case 13: + UE_scheduling_control->on_duration_timer_thres = 80; + break; + case 14: + UE_scheduling_control->on_duration_timer_thres = 100; + break; + case 15: + UE_scheduling_control->on_duration_timer_thres = 200; + break; + default: + LOG_E(MAC, "Error in local DRX configuration, the on duration timer value specified is unknown\n"); + break; + } + + UE_scheduling_control->drx_inactivity_timer = 0; + switch (drx_Configuration->choice.setup.drx_InactivityTimer) { + case 0: + UE_scheduling_control->drx_inactivity_timer_thres = 1; + break; + case 1: + UE_scheduling_control->drx_inactivity_timer_thres = 2; + break; + case 2: + UE_scheduling_control->drx_inactivity_timer_thres = 3; + break; + case 3: + UE_scheduling_control->drx_inactivity_timer_thres = 4; + break; + case 4: + UE_scheduling_control->drx_inactivity_timer_thres = 5; + break; + case 5: + UE_scheduling_control->drx_inactivity_timer_thres = 6; + break; + case 6: + UE_scheduling_control->drx_inactivity_timer_thres = 8; + break; + case 7: + UE_scheduling_control->drx_inactivity_timer_thres = 10; + break; + case 8: + UE_scheduling_control->drx_inactivity_timer_thres = 20; + break; + case 9: + UE_scheduling_control->drx_inactivity_timer_thres = 30; + break; + case 10: + UE_scheduling_control->drx_inactivity_timer_thres = 40; + break; + case 11: + UE_scheduling_control->drx_inactivity_timer_thres = 50; + break; + case 12: + UE_scheduling_control->drx_inactivity_timer_thres = 60; + break; + case 13: + UE_scheduling_control->drx_inactivity_timer_thres = 80; + break; + case 14: + UE_scheduling_control->drx_inactivity_timer_thres = 100; + break; + case 15: + UE_scheduling_control->drx_inactivity_timer_thres = 200; + break; + case 16: + UE_scheduling_control->drx_inactivity_timer_thres = 300; + break; + case 17: + UE_scheduling_control->drx_inactivity_timer_thres = 500; + break; + case 18: + UE_scheduling_control->drx_inactivity_timer_thres = 750; + break; + case 19: + UE_scheduling_control->drx_inactivity_timer_thres = 1280; + break; + case 20: + UE_scheduling_control->drx_inactivity_timer_thres = 1920; + break; + case 21: + UE_scheduling_control->drx_inactivity_timer_thres = 2560; + break; + case 22: + UE_scheduling_control->drx_inactivity_timer_thres = 0; + break; + default: + LOG_E(MAC, "Error in local DRX configuration, the drx inactivity timer value specified is unknown\n"); + break; + } - if (radioResourceConfigCommon != NULL) { - PHY_Config_t phycfg; - phycfg.Mod_id = Mod_idP; - phycfg.CC_id = CC_idP; - phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP]; - - if (RC.mac[Mod_idP]->if_inst->PHY_config_req) RC.mac[Mod_idP]->if_inst->PHY_config_req(&phycfg); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); + if (drx_Configuration->choice.setup.shortDRX == NULL) { + UE_scheduling_control->in_short_drx_cycle = FALSE; + UE_scheduling_control->drx_shortCycle_timer_value = 0; + UE_scheduling_control->short_drx_cycle_duration = 0; + UE_scheduling_control->drx_shortCycle_timer = 0; + UE_scheduling_control->drx_shortCycle_timer_thres = -1; + } else { + UE_scheduling_control->in_short_drx_cycle = FALSE; + UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) drx_Configuration->choice.setup.shortDRX->drxShortCycleTimer; + switch (drx_Configuration->choice.setup.shortDRX->shortDRX_Cycle) { + case 0: + UE_scheduling_control->short_drx_cycle_duration = 2; + break; + case 1: + UE_scheduling_control->short_drx_cycle_duration = 5; + break; + case 2: + UE_scheduling_control->short_drx_cycle_duration = 8; + break; + case 3: + UE_scheduling_control->short_drx_cycle_duration = 10; + break; + case 4: + UE_scheduling_control->short_drx_cycle_duration = 16; + break; + case 5: + UE_scheduling_control->short_drx_cycle_duration = 20; + break; + case 6: + UE_scheduling_control->short_drx_cycle_duration = 32; + break; + case 7: + UE_scheduling_control->short_drx_cycle_duration = 40; + break; + case 8: + UE_scheduling_control->short_drx_cycle_duration = 64; + break; + case 9: + UE_scheduling_control->short_drx_cycle_duration = 80; + break; + case 10: + UE_scheduling_control->short_drx_cycle_duration = 128; + break; + case 11: + UE_scheduling_control->short_drx_cycle_duration = 160; + break; + case 12: + UE_scheduling_control->short_drx_cycle_duration = 256; + break; + case 13: + UE_scheduling_control->short_drx_cycle_duration = 320; + break; + case 14: + UE_scheduling_control->short_drx_cycle_duration = 512; + break; + case 15: + UE_scheduling_control->short_drx_cycle_duration = 640; + break; + default: + LOG_E(MAC, "Error in local DRX configuration, the short drx timer value specified is unknown\n"); + break; } - RC.mac[Mod_idP]->scheduler_mode = global_scheduler_mode; - return(0); + UE_scheduling_control->drx_shortCycle_timer = 0; + UE_scheduling_control->drx_shortCycle_timer_thres = UE_scheduling_control->drx_shortCycle_timer_value * UE_scheduling_control->short_drx_cycle_duration; + } + + UE_scheduling_control->in_long_drx_cycle = FALSE; + UE_scheduling_control->drx_longCycle_timer = 0; + switch (drx_Configuration->choice.setup.longDRX_CycleStartOffset.present) { + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: + UE_scheduling_control->drx_longCycle_timer_thres = 10; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf10; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: + UE_scheduling_control->drx_longCycle_timer_thres = 20; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf20; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: + UE_scheduling_control->drx_longCycle_timer_thres = 32; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf32; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: + UE_scheduling_control->drx_longCycle_timer_thres = 40; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf40; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: + UE_scheduling_control->drx_longCycle_timer_thres = 64; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf64; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: + UE_scheduling_control->drx_longCycle_timer_thres = 80; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf80; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: + UE_scheduling_control->drx_longCycle_timer_thres = 128; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf128; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: + UE_scheduling_control->drx_longCycle_timer_thres = 160; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf160; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: + UE_scheduling_control->drx_longCycle_timer_thres = 256; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf256; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: + UE_scheduling_control->drx_longCycle_timer_thres = 320; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf320; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: + UE_scheduling_control->drx_longCycle_timer_thres = 512; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf512; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: + UE_scheduling_control->drx_longCycle_timer_thres = 640; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf640; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: + UE_scheduling_control->drx_longCycle_timer_thres = 1024; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1024; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: + UE_scheduling_control->drx_longCycle_timer_thres = 1280; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1280; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: + UE_scheduling_control->drx_longCycle_timer_thres = 2048; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2048; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: + UE_scheduling_control->drx_longCycle_timer_thres = 2560; + UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2560; + break; + default: + LOG_E(MAC, "Invalid long_DRX value in DRX local configuration\n"); + break; + } + + memset(UE_scheduling_control->drx_retransmission_timer, 0, sizeof(UE_scheduling_control->drx_retransmission_timer)); + switch (drx_Configuration->choice.setup.drx_RetransmissionTimer) { + case 0: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 1, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 1: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 2, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 2: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 4, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 3: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 6, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 4: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 8, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 5: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 16, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 6: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 24, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + case 7: + memset(UE_scheduling_control->drx_retransmission_timer_thres, 33, sizeof(UE_scheduling_control->drx_retransmission_timer_thres)); + break; + default: + LOG_E(MAC, "Error in local DRX configuration, the drx retransmission timer value specified is unknown\n"); + break; + } } diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c index a211d593102d68cb858ab1f24ad89fac88a38daf..c196933d4d3645f8c2bb218e640509596531ba51 100644 --- a/openair2/LAYER2/MAC/config_ue.c +++ b/openair2/LAYER2/MAC/config_ue.c @@ -34,12 +34,12 @@ #include "COMMON/platform_types.h" #include "COMMON/platform_constants.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "SCHED_UE/sched_UE.h" #include "LTE_SystemInformationBlockType2.h" -//#include "RadioResourceConfigCommonSIB.h" #include "LTE_RadioResourceConfigDedicated.h" #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) -#include "LTE_PRACH-ConfigSIB-v1310.h" + #include "LTE_PRACH-ConfigSIB-v1310.h" #endif #include "LTE_MeasGapConfig.h" #include "LTE_MeasObjectToAddModList.h" @@ -54,51 +54,38 @@ #include "common/ran_context.h" #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "LTE_MBSFN-AreaInfoList-r9.h" -#include "LTE_MBSFN-AreaInfo-r9.h" -#include "LTE_MBSFN-SubframeConfigList.h" -#include "LTE_PMCH-InfoList-r9.h" + #include "LTE_MBSFN-AreaInfoList-r9.h" + #include "LTE_MBSFN-AreaInfo-r9.h" + #include "LTE_MBSFN-SubframeConfigList.h" + #include "LTE_PMCH-InfoList-r9.h" #endif extern void mac_init_cell_params(int Mod_idP,int CC_idP); extern void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index); -extern uint8_t nfapi_mode; /* sec 5.9, 36.321: MAC Reset Procedure */ -void ue_mac_reset(module_id_t module_idP, uint8_t eNB_index) -{ - +void ue_mac_reset(module_id_t module_idP, uint8_t eNB_index) { //Resetting Bj UE_mac_inst[module_idP].scheduling_info.Bj[0] = 0; UE_mac_inst[module_idP].scheduling_info.Bj[1] = 0; UE_mac_inst[module_idP].scheduling_info.Bj[2] = 0; - //Stopping all timers - //timeAlignmentTimer expires - // PHY changes for UE MAC reset phy_reset_ue(module_idP, 0, eNB_index); - // notify RRC to relase PUCCH/SRS // cancel all pending SRs UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0; - //Set BSR Trigger Bmp and remove timer flags UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE; - // stop ongoing RACH procedure - // discard explicitly signaled ra_PreambleIndex and ra_RACH_MaskIndex, if any - UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = 0; // check! + UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = 0; // check! UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = 0; - - - ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure - + ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure } int32_t **rxdata; @@ -107,43 +94,43 @@ int32_t **txdata; int rrc_mac_config_req_ue(module_id_t Mod_idP, - int CC_idP, - uint8_t eNB_index, - LTE_RadioResourceConfigCommonSIB_t * - radioResourceConfigCommon, - struct LTE_PhysicalConfigDedicated - *physicalConfigDedicated, + int CC_idP, + uint8_t eNB_index, + LTE_RadioResourceConfigCommonSIB_t * + radioResourceConfigCommon, + struct LTE_PhysicalConfigDedicated + *physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - LTE_SCellToAddMod_r10_t * sCellToAddMod_r10, - //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, + LTE_SCellToAddMod_r10_t *sCellToAddMod_r10, + //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - LTE_MeasObjectToAddMod_t ** measObj, - LTE_MAC_MainConfig_t * mac_MainConfig, - long logicalChannelIdentity, - LTE_LogicalChannelConfig_t * logicalChannelConfig, - LTE_MeasGapConfig_t * measGapConfig, - LTE_TDD_Config_t * tdd_Config, - LTE_MobilityControlInfo_t * mobilityControlInfo, - uint8_t * SIwindowsize, - uint16_t * SIperiod, - LTE_ARFCN_ValueEUTRA_t * ul_CarrierFreq, - long *ul_Bandwidth, - LTE_AdditionalSpectrumEmission_t * - additionalSpectrumEmission, - struct LTE_MBSFN_SubframeConfigList - *mbsfn_SubframeConfigList + LTE_MeasObjectToAddMod_t **measObj, + LTE_MAC_MainConfig_t *mac_MainConfig, + long logicalChannelIdentity, + LTE_LogicalChannelConfig_t *logicalChannelConfig, + LTE_MeasGapConfig_t *measGapConfig, + LTE_TDD_Config_t *tdd_Config, + LTE_MobilityControlInfo_t *mobilityControlInfo, + uint8_t *SIwindowsize, + uint16_t *SIperiod, + LTE_ARFCN_ValueEUTRA_t *ul_CarrierFreq, + long *ul_Bandwidth, + LTE_AdditionalSpectrumEmission_t * + additionalSpectrumEmission, + struct LTE_MBSFN_SubframeConfigList + *mbsfn_SubframeConfigList #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , uint8_t MBMS_Flag, - LTE_MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, - LTE_PMCH_InfoList_r9_t * pmch_InfoList + , uint8_t MBMS_Flag, + LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, + LTE_PMCH_InfoList_r9_t *pmch_InfoList #endif #ifdef CBA - , uint8_t num_active_cba_groups, uint16_t cba_rnti + , uint8_t num_active_cba_groups, uint16_t cba_rnti #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,config_action_t config_action - ,const uint32_t * const sourceL2Id - ,const uint32_t * const destinationL2Id + ,const uint32_t *const sourceL2Id + ,const uint32_t *const destinationL2Id #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , @@ -155,167 +142,167 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, { int i; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); - + (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN); LOG_I(MAC, "[CONFIG][UE %d] Configuring MAC/PHY from eNB %d\n", - Mod_idP, eNB_index); + Mod_idP, eNB_index); if (tdd_Config != NULL) { UE_mac_inst[Mod_idP].tdd_Config = tdd_Config; } - if (tdd_Config && SIwindowsize && SIperiod) { phy_config_sib1_ue(Mod_idP, 0, eNB_index, tdd_Config, - *SIwindowsize, *SIperiod); + *SIwindowsize, *SIperiod); } if (radioResourceConfigCommon != NULL) { UE_mac_inst[Mod_idP].radioResourceConfigCommon = radioResourceConfigCommon; phy_config_sib2_ue(Mod_idP, 0, eNB_index, - radioResourceConfigCommon, ul_CarrierFreq, - ul_Bandwidth, additionalSpectrumEmission, - mbsfn_SubframeConfigList); + radioResourceConfigCommon, ul_CarrierFreq, + ul_Bandwidth, additionalSpectrumEmission, + mbsfn_SubframeConfigList); } + // SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup if (logicalChannelConfig != NULL) { LOG_I(MAC, - "[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n", - Mod_idP, eNB_index); + "[CONFIG][UE %d] Applying RRC logicalChannelConfig from eNB%d\n", + Mod_idP, eNB_index); UE_mac_inst[Mod_idP].logicalChannelConfig[logicalChannelIdentity] = logicalChannelConfig; - UE_mac_inst[Mod_idP].scheduling_info.Bj[logicalChannelIdentity] = 0; // initilize the bucket for this lcid - + UE_mac_inst[Mod_idP].scheduling_info.Bj[logicalChannelIdentity] = 0; // initilize the bucket for this lcid AssertFatal(logicalChannelConfig->ul_SpecificParameters != NULL, - "[UE %d] LCID %ld NULL ul_SpecificParameters\n", - Mod_idP, logicalChannelIdentity); - UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity] = logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size + "[UE %d] LCID %ld NULL ul_SpecificParameters\n", + Mod_idP, logicalChannelIdentity); + UE_mac_inst[Mod_idP].scheduling_info.bucket_size[logicalChannelIdentity] = logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate * + logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration; // set the max bucket size + if (logicalChannelConfig->ul_SpecificParameters-> - logicalChannelGroup != NULL) { + logicalChannelGroup != NULL) { UE_mac_inst[Mod_idP].scheduling_info. - LCGID[logicalChannelIdentity] = - *logicalChannelConfig->ul_SpecificParameters-> - logicalChannelGroup; + LCGID[logicalChannelIdentity] = + *logicalChannelConfig->ul_SpecificParameters-> + logicalChannelGroup; LOG_D(MAC, - "[CONFIG][UE %d] LCID %ld is attached to the LCGID %ld\n", - Mod_idP, logicalChannelIdentity, - *logicalChannelConfig-> - ul_SpecificParameters->logicalChannelGroup); + "[CONFIG][UE %d] LCID %ld is attached to the LCGID %ld\n", + Mod_idP, logicalChannelIdentity, + *logicalChannelConfig-> + ul_SpecificParameters->logicalChannelGroup); } else { UE_mac_inst[Mod_idP].scheduling_info. - LCGID[logicalChannelIdentity] = MAX_NUM_LCGID; + LCGID[logicalChannelIdentity] = MAX_NUM_LCGID; } + UE_mac_inst[Mod_idP]. - scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0; + scheduling_info.LCID_buffer_remain[logicalChannelIdentity] = 0; } if (mac_MainConfig != NULL) { LOG_I(MAC, - "[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n", - Mod_idP, eNB_index); + "[CONFIG][UE%d] Applying RRC macMainConfig from eNB%d\n", + Mod_idP, eNB_index); UE_mac_inst[Mod_idP].macConfig = mac_MainConfig; UE_mac_inst[Mod_idP].measGapConfig = measGapConfig; if (mac_MainConfig->ul_SCH_Config) { - if (mac_MainConfig->ul_SCH_Config->periodicBSR_Timer) { - UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = - (uint16_t) * - mac_MainConfig->ul_SCH_Config->periodicBSR_Timer; + UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = + (uint16_t) * + mac_MainConfig->ul_SCH_Config->periodicBSR_Timer; } else { - UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = + UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = #if (LTE_RRC_VERSION < MAKE_VERSION(12, 0, 0)) - (uint16_t) - LTE_MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity + (uint16_t) + LTE_MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity #else - (uint16_t) LTE_PeriodicBSR_Timer_r12_infinity; + (uint16_t) LTE_PeriodicBSR_Timer_r12_infinity; #endif - ; + ; } if (mac_MainConfig->ul_SCH_Config->maxHARQ_Tx) { - UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = - (uint16_t) * mac_MainConfig->ul_SCH_Config->maxHARQ_Tx; + UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = + (uint16_t) * mac_MainConfig->ul_SCH_Config->maxHARQ_Tx; } else { - UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = - (uint16_t) - LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = + (uint16_t) + LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; } - if(nfapi_mode!=3) + + if(NFAPI_MODE != NFAPI_UE_STUB_PNF) phy_config_harq_ue(Mod_idP, 0, eNB_index, - UE_mac_inst[Mod_idP]. - scheduling_info.maxHARQ_Tx); + UE_mac_inst[Mod_idP]. + scheduling_info.maxHARQ_Tx); if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) { - UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = - (uint16_t) mac_MainConfig->ul_SCH_Config-> - retxBSR_Timer; + UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = + (uint16_t) mac_MainConfig->ul_SCH_Config-> + retxBSR_Timer; } else { #if (LTE_RRC_VERSION < MAKE_VERSION(12, 0, 0)) - UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = - (uint16_t) - LTE_MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; + UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = + (uint16_t) + LTE_MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; #else - UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = - (uint16_t) LTE_RetxBSR_Timer_r12_sf2560; + UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = + (uint16_t) LTE_RetxBSR_Timer_r12_sf2560; #endif } } + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mac_MainConfig->ext1 - && mac_MainConfig->ext1->sr_ProhibitTimer_r9) { + && mac_MainConfig->ext1->sr_ProhibitTimer_r9) { UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = - (uint16_t) * mac_MainConfig->ext1->sr_ProhibitTimer_r9; + (uint16_t) * mac_MainConfig->ext1->sr_ProhibitTimer_r9; } else { UE_mac_inst[Mod_idP].scheduling_info.sr_ProhibitTimer = 0; } if (mac_MainConfig->ext2 - && mac_MainConfig->ext2->mac_MainConfig_v1020) { + && mac_MainConfig->ext2->mac_MainConfig_v1020) { if (mac_MainConfig->ext2-> - mac_MainConfig_v1020->extendedBSR_Sizes_r10) { - UE_mac_inst[Mod_idP].scheduling_info. - extendedBSR_Sizes_r10 = - (uint16_t) * - mac_MainConfig->ext2-> - mac_MainConfig_v1020->extendedBSR_Sizes_r10; + mac_MainConfig_v1020->extendedBSR_Sizes_r10) { + UE_mac_inst[Mod_idP].scheduling_info. + extendedBSR_Sizes_r10 = + (uint16_t) * + mac_MainConfig->ext2-> + mac_MainConfig_v1020->extendedBSR_Sizes_r10; } else { - UE_mac_inst[Mod_idP].scheduling_info. - extendedBSR_Sizes_r10 = (uint16_t) 0; + UE_mac_inst[Mod_idP].scheduling_info. + extendedBSR_Sizes_r10 = (uint16_t) 0; } + if (mac_MainConfig->ext2->mac_MainConfig_v1020-> - extendedPHR_r10) { - UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = - (uint16_t) * - mac_MainConfig->ext2->mac_MainConfig_v1020-> - extendedPHR_r10; + extendedPHR_r10) { + UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = + (uint16_t) * + mac_MainConfig->ext2->mac_MainConfig_v1020-> + extendedPHR_r10; } else { - UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = - (uint16_t) 0; + UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = + (uint16_t) 0; } } else { UE_mac_inst[Mod_idP].scheduling_info.extendedBSR_Sizes_r10 = - (uint16_t) 0; + (uint16_t) 0; UE_mac_inst[Mod_idP].scheduling_info.extendedPHR_r10 = - (uint16_t) 0; + (uint16_t) 0; } + #endif UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; - UE_mac_inst[Mod_idP].BSR_reporting_active = BSR_TRIGGER_NONE; - LOG_D(MAC, "[UE %d]: periodic BSR %d (SF), retx BSR %d (SF)\n", - Mod_idP, - UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF, - UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF); - + Mod_idP, + UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_SF, + UE_mac_inst[Mod_idP].scheduling_info.retxBSR_SF); UE_mac_inst[Mod_idP].scheduling_info.drx_config = mac_MainConfig->drx_Config; UE_mac_inst[Mod_idP].scheduling_info.phr_config = @@ -323,165 +310,167 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, if (mac_MainConfig->phr_Config) { UE_mac_inst[Mod_idP].PHR_state = - mac_MainConfig->phr_Config->present; + mac_MainConfig->phr_Config->present; UE_mac_inst[Mod_idP].PHR_reconfigured = 1; UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = - mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer; UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = - mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer; + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer; UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = - mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange; + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange; } else { UE_mac_inst[Mod_idP].PHR_reconfigured = 0; UE_mac_inst[Mod_idP].PHR_state = - LTE_MAC_MainConfig__phr_Config_PR_setup; + LTE_MAC_MainConfig__phr_Config_PR_setup; UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = - LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; + LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = - LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; + LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = - LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; + LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; } UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF = get_sf_perioidicPHR_Timer(UE_mac_inst[Mod_idP]. - scheduling_info.periodicPHR_Timer); + scheduling_info.periodicPHR_Timer); UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF = get_sf_prohibitPHR_Timer(UE_mac_inst[Mod_idP]. - scheduling_info.prohibitPHR_Timer); + scheduling_info.prohibitPHR_Timer); UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db = get_db_dl_PathlossChange(UE_mac_inst[Mod_idP]. - scheduling_info.PathlossChange); + scheduling_info.PathlossChange); UE_mac_inst[Mod_idP].PHR_reporting_active = 0; LOG_D(MAC, - "[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n", - Mod_idP, - (mac_MainConfig->phr_Config) ? mac_MainConfig-> - phr_Config->present : -1, - UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF, - UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF, - UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db); + "[UE %d] config PHR (%d): periodic %d (SF) prohibit %d (SF) pathlosschange %d (db) \n", + Mod_idP, + (mac_MainConfig->phr_Config) ? mac_MainConfig-> + phr_Config->present : -1, + UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF, + UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_SF, + UE_mac_inst[Mod_idP].scheduling_info.PathlossChange_db); } - if (physicalConfigDedicated != NULL) { - if(nfapi_mode!=3) + if(NFAPI_MODE != NFAPI_UE_STUB_PNF) phy_config_dedicated_ue(Mod_idP, 0, eNB_index, - physicalConfigDedicated); - UE_mac_inst[Mod_idP].physicalConfigDedicated = physicalConfigDedicated; // for SR proc + physicalConfigDedicated); + + UE_mac_inst[Mod_idP].physicalConfigDedicated = physicalConfigDedicated; // for SR proc } + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (sCellToAddMod_r10 != NULL) { - - phy_config_dedicated_scell_ue(Mod_idP, eNB_index, - sCellToAddMod_r10, 1); - UE_mac_inst[Mod_idP].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0 + sCellToAddMod_r10, 1); + UE_mac_inst[Mod_idP].physicalConfigDedicatedSCell_r10 = sCellToAddMod_r10->radioResourceConfigDedicatedSCell_r10->physicalConfigDedicatedSCell_r10; // using SCell index 0 } + #endif if (measObj != NULL) { - if (measObj[0] != NULL) { + if (measObj[0] != NULL && + measObj[0]->measObject.present == LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA && + measObj[0]->measObject.choice.measObjectEUTRA.cellsToAddModList != NULL) { UE_mac_inst[Mod_idP].n_adj_cells = - measObj[0]->measObject.choice. - measObjectEUTRA.cellsToAddModList->list.count; + measObj[0]->measObject.choice. + measObjectEUTRA.cellsToAddModList->list.count; LOG_I(MAC, "Number of adjacent cells %d\n", - UE_mac_inst[Mod_idP].n_adj_cells); + UE_mac_inst[Mod_idP].n_adj_cells); for (i = 0; i < UE_mac_inst[Mod_idP].n_adj_cells; i++) { - UE_mac_inst[Mod_idP].adj_cell_id[i] = - measObj[0]->measObject.choice. - measObjectEUTRA.cellsToAddModList->list.array[i]-> - physCellId; - LOG_I(MAC, "Cell %d : Nid_cell %d\n", i, - UE_mac_inst[Mod_idP].adj_cell_id[i]); + UE_mac_inst[Mod_idP].adj_cell_id[i] = + measObj[0]->measObject.choice. + measObjectEUTRA.cellsToAddModList->list.array[i]-> + physCellId; + LOG_I(MAC, "Cell %d : Nid_cell %d\n", i, + UE_mac_inst[Mod_idP].adj_cell_id[i]); } phy_config_meas_ue(Mod_idP, 0, eNB_index, - UE_mac_inst[Mod_idP].n_adj_cells, - UE_mac_inst[Mod_idP].adj_cell_id); + UE_mac_inst[Mod_idP].n_adj_cells, + UE_mac_inst[Mod_idP].adj_cell_id); } } - if (mobilityControlInfo != NULL) { - LOG_D(MAC, "[UE%d] MAC Reset procedure triggered by RRC eNB %d \n", - Mod_idP, eNB_index); + Mod_idP, eNB_index); ue_mac_reset(Mod_idP, eNB_index); if (mobilityControlInfo->radioResourceConfigCommon. - rach_ConfigCommon) { + rach_ConfigCommon) { memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - rach_ConfigCommon, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.rach_ConfigCommon, - sizeof(LTE_RACH_ConfigCommon_t)); + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + rach_ConfigCommon, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.rach_ConfigCommon, + sizeof(LTE_RACH_ConfigCommon_t)); } memcpy((void *) &UE_mac_inst[Mod_idP]. - radioResourceConfigCommon->prach_Config.prach_ConfigInfo, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.prach_Config.prach_ConfigInfo, - sizeof(LTE_PRACH_ConfigInfo_t)); + radioResourceConfigCommon->prach_Config.prach_ConfigInfo, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.prach_Config.prach_ConfigInfo, + sizeof(LTE_PRACH_ConfigInfo_t)); UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - prach_Config.rootSequenceIndex = + prach_Config.rootSequenceIndex = mobilityControlInfo->radioResourceConfigCommon. prach_Config.rootSequenceIndex; if (mobilityControlInfo->radioResourceConfigCommon. - pdsch_ConfigCommon) { + pdsch_ConfigCommon) { memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - pdsch_ConfigCommon, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.pdsch_ConfigCommon, - sizeof(LTE_PDSCH_ConfigCommon_t)); + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + pdsch_ConfigCommon, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.pdsch_ConfigCommon, + sizeof(LTE_PDSCH_ConfigCommon_t)); } + // not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon memcpy((void *) &UE_mac_inst[Mod_idP]. - radioResourceConfigCommon->pusch_ConfigCommon, - (void *) &mobilityControlInfo-> - radioResourceConfigCommon.pusch_ConfigCommon, - sizeof(LTE_PUSCH_ConfigCommon_t)); + radioResourceConfigCommon->pusch_ConfigCommon, + (void *) &mobilityControlInfo-> + radioResourceConfigCommon.pusch_ConfigCommon, + sizeof(LTE_PUSCH_ConfigCommon_t)); if (mobilityControlInfo->radioResourceConfigCommon.phich_Config) { /* memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->phich_Config, - (void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config, - sizeof(LTE_PHICH_Config_t)); */ + (void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config, + sizeof(LTE_PHICH_Config_t)); */ } if (mobilityControlInfo->radioResourceConfigCommon. - pucch_ConfigCommon) { + pucch_ConfigCommon) { memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - pucch_ConfigCommon, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.pucch_ConfigCommon, - sizeof(LTE_PUCCH_ConfigCommon_t)); + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + pucch_ConfigCommon, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.pucch_ConfigCommon, + sizeof(LTE_PUCCH_ConfigCommon_t)); } if (mobilityControlInfo-> - radioResourceConfigCommon.soundingRS_UL_ConfigCommon) { + radioResourceConfigCommon.soundingRS_UL_ConfigCommon) { memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - soundingRS_UL_ConfigCommon, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.soundingRS_UL_ConfigCommon, - sizeof(LTE_SoundingRS_UL_ConfigCommon_t)); + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + soundingRS_UL_ConfigCommon, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.soundingRS_UL_ConfigCommon, + sizeof(LTE_SoundingRS_UL_ConfigCommon_t)); } if (mobilityControlInfo-> - radioResourceConfigCommon.uplinkPowerControlCommon) { + radioResourceConfigCommon.uplinkPowerControlCommon) { memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - uplinkPowerControlCommon, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.uplinkPowerControlCommon, - sizeof(LTE_UplinkPowerControlCommon_t)); + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + uplinkPowerControlCommon, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.uplinkPowerControlCommon, + sizeof(LTE_UplinkPowerControlCommon_t)); } + //configure antennaInfoCommon somewhere here.. if (mobilityControlInfo->radioResourceConfigCommon.p_Max) { //to be configured @@ -489,97 +478,97 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, if (mobilityControlInfo->radioResourceConfigCommon.tdd_Config) { UE_mac_inst[Mod_idP].tdd_Config = - mobilityControlInfo->radioResourceConfigCommon.tdd_Config; + mobilityControlInfo->radioResourceConfigCommon.tdd_Config; } if (mobilityControlInfo-> - radioResourceConfigCommon.ul_CyclicPrefixLength) { + radioResourceConfigCommon.ul_CyclicPrefixLength) { memcpy((void *) - &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> - ul_CyclicPrefixLength, - (void *) mobilityControlInfo-> - radioResourceConfigCommon.ul_CyclicPrefixLength, - sizeof(LTE_UL_CyclicPrefixLength_t)); + &UE_mac_inst[Mod_idP].radioResourceConfigCommon-> + ul_CyclicPrefixLength, + (void *) mobilityControlInfo-> + radioResourceConfigCommon.ul_CyclicPrefixLength, + sizeof(LTE_UL_CyclicPrefixLength_t)); } + // store the previous rnti in case of failure, and set thenew rnti UE_mac_inst[Mod_idP].crnti_before_ho = UE_mac_inst[Mod_idP].crnti; UE_mac_inst[Mod_idP].crnti = ((mobilityControlInfo-> - newUE_Identity.buf[0]) | (mobilityControlInfo-> - newUE_Identity.buf[1] << 8)); + newUE_Identity.buf[0]) | (mobilityControlInfo-> + newUE_Identity.buf[1] << 8)); LOG_I(MAC, "[UE %d] Received new identity %x from %d\n", Mod_idP, - UE_mac_inst[Mod_idP].crnti, eNB_index); + UE_mac_inst[Mod_idP].crnti, eNB_index); UE_mac_inst[Mod_idP].rach_ConfigDedicated = malloc(sizeof(*mobilityControlInfo->rach_ConfigDedicated)); if (mobilityControlInfo->rach_ConfigDedicated) { memcpy((void *) UE_mac_inst[Mod_idP].rach_ConfigDedicated, - (void *) mobilityControlInfo->rach_ConfigDedicated, - sizeof(*mobilityControlInfo->rach_ConfigDedicated)); + (void *) mobilityControlInfo->rach_ConfigDedicated, + sizeof(*mobilityControlInfo->rach_ConfigDedicated)); } phy_config_afterHO_ue(Mod_idP, 0, eNB_index, mobilityControlInfo, - 0); + 0); } - if (mbsfn_SubframeConfigList != NULL) { LOG_I(MAC, - "[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", - Mod_idP, mbsfn_SubframeConfigList->list.count); + "[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n", + Mod_idP, mbsfn_SubframeConfigList->list.count); UE_mac_inst[Mod_idP].num_sf_allocation_pattern = mbsfn_SubframeConfigList->list.count; for (i = 0; i < mbsfn_SubframeConfigList->list.count; i++) { LOG_I(MAC, - "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n", - Mod_idP, i); + "[UE %d] Configuring MBSFN_SubframeConfig %d from received SIB2 \n", + Mod_idP, i); UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i] = - mbsfn_SubframeConfigList->list.array[i]; + mbsfn_SubframeConfigList->list.array[i]; // LOG_I("[UE %d] MBSFN_SubframeConfig[%d] pattern is %ld\n", Mod_idP, // UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); } } + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mbsfn_AreaInfoList != NULL) { LOG_I(MAC, "[UE %d][CONFIG] Received %d MBSFN Area Info\n", - Mod_idP, mbsfn_AreaInfoList->list.count); + Mod_idP, mbsfn_AreaInfoList->list.count); UE_mac_inst[Mod_idP].num_active_mbsfn_area = mbsfn_AreaInfoList->list.count; for (i = 0; i < mbsfn_AreaInfoList->list.count; i++) { UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i] = - mbsfn_AreaInfoList->list.array[i]; + mbsfn_AreaInfoList->list.array[i]; LOG_I(MAC, - "[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", - Mod_idP, i, - UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i]-> - mcch_Config_r9.mcch_RepetitionPeriod_r9); + "[UE %d] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", + Mod_idP, i, + UE_mac_inst[Mod_idP].mbsfn_AreaInfo[i]-> + mcch_Config_r9.mcch_RepetitionPeriod_r9); phy_config_sib13_ue(Mod_idP, 0, eNB_index, i, - UE_mac_inst[Mod_idP]. - mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); + UE_mac_inst[Mod_idP]. + mbsfn_AreaInfo[i]->mbsfn_AreaId_r9); } } if (pmch_InfoList != NULL) { - // LOG_I(MAC,"DUY: lcid when entering rrc_mac config_req is %02d\n",(pmch_InfoList->list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9)); - LOG_I(MAC, "[UE %d] Configuring PMCH_config from MCCH MESSAGE \n", - Mod_idP); + Mod_idP); for (i = 0; i < pmch_InfoList->list.count; i++) { UE_mac_inst[Mod_idP].pmch_Config[i] = - &pmch_InfoList->list.array[i]->pmch_Config_r9; + &pmch_InfoList->list.array[i]->pmch_Config_r9; LOG_I(MAC, "[UE %d] PMCH[%d]: MCH_Scheduling_Period = %ld\n", - Mod_idP, i, - UE_mac_inst[Mod_idP]. - pmch_Config[i]->mch_SchedulingPeriod_r9); + Mod_idP, i, + UE_mac_inst[Mod_idP]. + pmch_Config[i]->mch_SchedulingPeriod_r9); } UE_mac_inst[Mod_idP].mcch_status = 1; } + #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -597,44 +586,53 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, UE_mac_inst[Mod_idP].cba_rnti[num_active_cba_groups - 1] = cba_rnti; LOG_D(MAC, - "[UE %d] configure CBA group %d RNTI %x for eNB %d (total active cba group %d)\n", - Mod_idP, Mod_idP % num_active_cba_groups, cba_rnti, - eNB_index, num_active_cba_groups); + "[UE %d] configure CBA group %d RNTI %x for eNB %d (total active cba group %d)\n", + Mod_idP, Mod_idP % num_active_cba_groups, cba_rnti, + eNB_index, num_active_cba_groups); phy_config_cba_rnti(Mod_idP, CC_idP, eNB_flagP, eNB_index, - cba_rnti, num_active_cba_groups - 1, - num_active_cba_groups); + cba_rnti, num_active_cba_groups - 1, + num_active_cba_groups); } + #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); + (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); //for D2D - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - switch (config_action) { +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + + switch (config_action) { case CONFIG_ACTION_ADD: - if (sourceL2Id){ - UE_mac_inst[Mod_idP].sourceL2Id = *sourceL2Id; - LOG_I(MAC,"[UE %d] Configure source L2Id 0x%08x \n", Mod_idP, *sourceL2Id ); - } - if (destinationL2Id) { - LOG_I(MAC,"[UE %d] Configure destination L2Id 0x%08x\n", Mod_idP, *destinationL2Id ); - int j = 0; - int i = 0; - for (i=0; i< MAX_NUM_DEST; i++) { - if ((UE_mac_inst[Mod_idP].destinationList[i] == 0) && (j == 0)) j = i+1; - if (UE_mac_inst[Mod_idP].destinationList[i] == *destinationL2Id) break; //destination already exists! - } - if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[Mod_idP].destinationList[j-1] = *destinationL2Id; - UE_mac_inst[Mod_idP].numCommFlows++; - } - break; + if (sourceL2Id) { + UE_mac_inst[Mod_idP].sourceL2Id = *sourceL2Id; + LOG_I(MAC,"[UE %d] Configure source L2Id 0x%08x \n", Mod_idP, *sourceL2Id ); + } + + if (destinationL2Id) { + LOG_I(MAC,"[UE %d] Configure destination L2Id 0x%08x\n", Mod_idP, *destinationL2Id ); + int j = 0; + int i = 0; + + for (i=0; i< MAX_NUM_DEST; i++) { + if ((UE_mac_inst[Mod_idP].destinationList[i] == 0) && (j == 0)) j = i+1; + + if (UE_mac_inst[Mod_idP].destinationList[i] == *destinationL2Id) break; //destination already exists! + } + + if ((i == MAX_NUM_DEST) && (j > 0)) UE_mac_inst[Mod_idP].destinationList[j-1] = *destinationL2Id; + + UE_mac_inst[Mod_idP].numCommFlows++; + } + + break; + case CONFIG_ACTION_REMOVE: - //TODO - break; - default: - break; - } + //TODO + break; - #endif + default: + break; + } +#endif return (0); } diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 6af0fd66ca9ed25f74c950970e7557a72ba6a18b..4e781e5b3f33f6873ee159b163aa8dd62dc6844f 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -61,13 +61,13 @@ #include "RACH-ConfigCommon.h" #include "MeasObjectToAddModList.h" #include "MobilityControlInfo.h" -#if defined(Rel10) || defined(Rel14) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #include "MBSFN-AreaInfoList-r9.h" #include "MBSFN-SubframeConfigList.h" #include "PMCH-InfoList-r9.h" #include "SCellToAddMod-r10.h" #endif -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #include "SystemInformationBlockType1-v1310-IEs.h" #endif @@ -87,7 +87,7 @@ #define SCH_PAYLOAD_SIZE_MAX 4096 /// Logical channel ids from 36-311 (Note BCCH is not specified in 36-311, uses the same as first DRB) -#if defined(Rel10) || defined(Rel14) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // Mask for identifying subframe for MBMS #define MBSFN_TDD_SF3 0x80// for TDD @@ -132,7 +132,7 @@ /*!\brief size of buffer status report table */ #define BSR_TABLE_SIZE 64 /*!\brief The power headroom reporting range is from -23 ...+40 dB and beyond, with step 1 */ -#define PHR_MAPPING_OFFSET 23 // if ( x>= -23 ) val = floor (x + 23) +#define PHR_MAPPING_OFFSET 23 // if ( x>= -23 ) val = floor (x + 23) /*!\brief maximum number of resource block groups */ #define N_RBG_MAX 25 // for 20MHz channel BW /*!\brief minimum value for channel quality indicator */ @@ -140,9 +140,9 @@ /*!\brief maximum value for channel quality indicator */ #define MAX_CQI_VALUE 15 /*!\briefmaximum number of supported bandwidth (1.4, 5, 10, 20 MHz) */ -#define MAX_SUPPORTED_BW 4 +#define MAX_SUPPORTED_BW 4 /*!\brief CQI values range from 1 to 15 (4 bits) */ -#define CQI_VALUE_RANGE 16 +#define CQI_VALUE_RANGE 16 /*!\brief value for indicating BSR Timer is not running */ #define MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF) @@ -157,16 +157,16 @@ #define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE) /*!\brief maximum number of slices / groups */ -#define MAX_NUM_SLICES 4 +#define MAX_NUM_SLICES 4 -/* - * eNB part - */ +/* + * eNB part + */ -/* - * UE/ENB common part - */ +/* + * UE/ENB common part + */ /*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */ typedef struct { uint8_t RAPID:6; @@ -283,7 +283,7 @@ typedef struct { uint8_t payload[PCCH_PAYLOAD_SIZE_MAX] ; } __attribute__((__packed__))PCCH_PDU; -#if defined(Rel10) || defined(Rel14) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /*! \brief MCCH payload */ typedef struct { uint8_t payload[MCCH_PAYLOAD_SIZE_MAX] ; @@ -306,18 +306,18 @@ typedef struct { uint8_t stop_sf_LSB:8; } __attribute__((__packed__))MSI_ELEMENT; #endif -/*! \brief Values of CCCH LCID for DLSCH */ +/*! \brief Values of CCCH LCID for DLSCH */ #define CCCH_LCHANID 0 /*!\brief Values of BCCH logical channel (fake)*/ -#define BCCH 3 // SI +#define BCCH 3 // SI /*!\brief Values of PCCH logical channel (fake)*/ -#define PCCH 4 // Paging +#define PCCH 4 // Paging /*!\brief Values of PCCH logical channel (fake) */ -#define MIBCH 5 // MIB +#define MIBCH 5 // MIB /*!\brief Values of BCCH SIB1_BR logical channel (fake) */ -#define BCCH_SIB1_BR 6 // SIB1_BR +#define BCCH_SIB1_BR 6 // SIB1_BR /*!\brief Values of BCCH SIB_BR logical channel (fake) */ -#define BCCH_SI_BR 7 // SI-BR +#define BCCH_SI_BR 7 // SI-BR /*!\brief Value of CCCH / SRB0 logical channel */ #define CCCH 0 // srb0 /*!\brief DCCH / SRB1 logical channel */ @@ -327,9 +327,9 @@ typedef struct { /*!\brief DTCH DRB1 logical channel */ #define DTCH 3 // LCID /*!\brief MCCH logical channel */ -#define MCCH 4 +#define MCCH 4 /*!\brief MTCH logical channel */ -#define MTCH 1 +#define MTCH 1 // DLSCH LCHAN ID /*!\brief LCID of UE contention resolution identity for DLSCH*/ #define UE_CONT_RES 28 @@ -340,7 +340,7 @@ typedef struct { /*!\brief LCID of padding LCID for DLSCH */ #define SHORT_PADDING 31 -#if defined(Rel10) || defined(Rel14) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // MCH LCHAN IDs (table6.2.1-4 TS36.321) /*!\brief LCID of MCCH for DL */ #define MCCH_LCHANID 0 @@ -441,20 +441,20 @@ typedef struct { } eNB_DLSCH_INFO; /*! \brief eNB overall statistics */ typedef struct { - /// num BCCH PDU per CC + /// num BCCH PDU per CC uint32_t total_num_bcch_pdu; - /// BCCH buffer size + /// BCCH buffer size uint32_t bcch_buffer; - /// total BCCH buffer size + /// total BCCH buffer size uint32_t total_bcch_buffer; /// BCCH MCS uint32_t bcch_mcs; - /// num CCCH PDU per CC + /// num CCCH PDU per CC uint32_t total_num_ccch_pdu; - /// BCCH buffer size + /// BCCH buffer size uint32_t ccch_buffer; - /// total BCCH buffer size + /// total BCCH buffer size uint32_t total_ccch_buffer; /// BCCH MCS uint32_t ccch_mcs; @@ -481,22 +481,22 @@ typedef struct { uint32_t total_dlsch_bytes_tx; // uint32_t total_dlsch_pdus_tx; - + // here for RX // uint32_t ulsch_bitrate; // uint32_t ulsch_bytes_rx; // - uint64_t ulsch_pdus_rx; + uint64_t ulsch_pdus_rx; uint32_t total_ulsch_bitrate; // uint32_t total_ulsch_bytes_rx; // uint32_t total_ulsch_pdus_rx; - - + + /// MAC agent-related stats /// total number of scheduling decisions int sched_decisions; @@ -600,9 +600,9 @@ typedef struct { uint32_t rbs_used_retx_rx; /// total rb used for a new uplink transmission uint32_t total_rbs_used_rx; - /// normalized rx power + /// normalized rx power int32_t normalized_rx_power; - /// target rx power + /// target rx power int32_t target_rx_power; /// num rx pdu @@ -613,7 +613,7 @@ typedef struct { // uint32_t tti_goodput[NB_RB_MAX]; /// errors uint32_t num_errors_rx; - + uint64_t overhead_bytes_rx; /// headers+ CE + padding bytes for a MAC PDU uint64_t total_overhead_bytes_rx; @@ -676,6 +676,9 @@ typedef struct { /// Number of Allocated RBs for UL after scheduling uint16_t first_rb_ul[8]; // num_max_harq + /// Is CQI requested for UL after scheduling 1st transmission + uint8_t cqi_req[8]; // num_max_harq + /// Cyclic shift for DMRS after scheduling uint16_t cshift[8]; // num_max_harq @@ -732,12 +735,12 @@ typedef struct { uint32_t dl_buffer_head_sdu_creation_time[MAX_NUM_LCID]; /// maximum creation time of the downlink buffer head across all LCID uint32_t dl_buffer_head_sdu_creation_time_max; - /// a flag indicating that the downlink head SDU is segmented + /// a flag indicating that the downlink head SDU is segmented uint8_t dl_buffer_head_sdu_is_segmented[MAX_NUM_LCID]; /// size of remaining size to send for the downlink head SDU uint32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID]; - /// total uplink buffer size + /// total uplink buffer size uint32_t ul_total_buffer; /// uplink buffer creation time for each LCID uint32_t ul_buffer_creation_time[MAX_NUM_LCGID]; @@ -759,7 +762,7 @@ typedef struct { eNB_UE_estimated_distances distance; #endif -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint8_t rach_resource_type; uint16_t mpdcch_repetition_cnt; @@ -797,7 +800,7 @@ typedef struct { uint16_t priority[MAX_NUM_LCID]; // resource scheduling information - + /// Current DL harq round per harq_pid on each CC uint8_t round[MAX_NUM_CCs][10]; /// Current Active TBs per harq_pid on each CC @@ -813,7 +816,7 @@ typedef struct { int32_t context_active_timer; int32_t cqi_req_timer; int32_t ul_inactivity_timer; - int32_t ul_failure_timer; + int32_t ul_failure_timer; int32_t ul_scheduled; int32_t ra_pdcch_order_sent; int32_t ul_out_of_sync; @@ -923,7 +926,7 @@ typedef struct { uint8_t msg4_rrc_sdu_length; uint32_t msg4_delay; -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint8_t rach_resource_type; uint8_t msg2_mpdcch_repetition_cnt; uint8_t msg2_mpdcch_done; @@ -943,25 +946,25 @@ typedef struct { uint8_t sb_size; uint8_t nb_active_sb; } SBMAP_CONF; -/*! \brief UE list used by eNB to order UEs/CC for scheduling*/ +/*! \brief UE list used by eNB to order UEs/CC for scheduling*/ typedef struct { /// Dedicated information for UEs struct PhysicalConfigDedicated *physicalConfigDedicated[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// DLSCH pdu + /// DLSCH pdu DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX]; /// DCI template and MAC connection parameters for UEs UE_TEMPLATE UE_template[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; /// DCI template and MAC connection for RA processes int pCC_id[NUMBER_OF_UE_MAX]; - /// sorted downlink component carrier for the scheduler + /// sorted downlink component carrier for the scheduler int ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// number of downlink active component carrier + /// number of downlink active component carrier int numactiveCCs[NUMBER_OF_UE_MAX]; - /// sorted uplink component carrier for the scheduler + /// sorted uplink component carrier for the scheduler int ordered_ULCCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// number of uplink active component carrier + /// number of uplink active component carrier int numactiveULCCs[NUMBER_OF_UE_MAX]; - /// number of downlink active component carrier + /// number of downlink active component carrier uint8_t dl_CC_bitmap[NUMBER_OF_UE_MAX]; /// eNB to UE statistics eNB_UE_STATS eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; @@ -976,7 +979,7 @@ typedef struct { boolean_t active[NUMBER_OF_UE_MAX]; } UE_list_t; -/*! \brief eNB common channels */ +/*! \brief eNB common channels */ typedef struct { int physCellId; int p_eNB; @@ -985,8 +988,8 @@ typedef struct { uint32_t dl_CarrierFreq; BCCH_BCH_Message_t *mib; RadioResourceConfigCommonSIB_t *radioResourceConfigCommon; -#ifdef Rel14 - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR; #endif TDD_Config_t *tdd_Config; SchedulingInfoList_t *schedulingInfoList; @@ -1012,7 +1015,7 @@ typedef struct { struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; -#if defined(Rel10) || defined(Rel14) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /// MBMS Flag uint8_t MBMS_flag; /// Outgoing MCCH pdu for PHY @@ -1034,7 +1037,7 @@ typedef struct { /// Outgoing MCH pdu for PHY MCH_PDU MCH_pdu; #endif -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// Rel13 parameters from SIB1 SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext; /// Counter for SIB1-BR scheduling @@ -1043,7 +1046,7 @@ typedef struct { BCCH_PDU BCCH_BR_pdu[20]; #endif } COMMON_channels_t; -/*! \brief top level eNB MAC structure */ +/*! \brief top level eNB MAC structure */ typedef struct eNB_MAC_INST_s { /// Ethernet parameters for northbound midhaul interface eth_params_t eth_params_n; @@ -1076,7 +1079,7 @@ typedef struct eNB_MAC_INST_s { nfapi_ul_config_request_t UL_req[MAX_NUM_CCs]; /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10]; - /// Preallocated HI_DCI0 pdu list + /// Preallocated HI_DCI0 pdu list nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU]; /// NFAPI HI/DCI0 Config Request Structure nfapi_hi_dci0_request_t HI_DCI0_req[MAX_NUM_CCs]; @@ -1097,29 +1100,29 @@ typedef struct eNB_MAC_INST_s { /// eNB stats eNB_STATS eNB_stats[MAX_NUM_CCs]; // MAC function execution peformance profiler - /// processing time of eNB scheduler + /// processing time of eNB scheduler time_stats_t eNB_scheduler; - /// processing time of eNB scheduler for SI + /// processing time of eNB scheduler for SI time_stats_t schedule_si; /// processing time of eNB scheduler for Random access time_stats_t schedule_ra; - /// processing time of eNB ULSCH scheduler + /// processing time of eNB ULSCH scheduler time_stats_t schedule_ulsch; /// processing time of eNB DCI generation time_stats_t fill_DLSCH_dci; /// processing time of eNB MAC preprocessor time_stats_t schedule_dlsch_preprocessor; - /// processing time of eNB DLSCH scheduler + /// processing time of eNB DLSCH scheduler time_stats_t schedule_dlsch; // include rlc_data_req + MAC header + preprocessor - /// processing time of eNB MCH scheduler + /// processing time of eNB MCH scheduler time_stats_t schedule_mch; /// processing time of eNB ULSCH reception time_stats_t rx_ulsch_sdu; // include rlc_data_ind } eNB_MAC_INST; -/* - * UE part - */ +/* + * UE part + */ typedef enum { TYPE0, @@ -1222,7 +1225,7 @@ typedef struct { struct RACH_ConfigDedicated *rach_ConfigDedicated; /// pointer to RRC PHY configuration struct PhysicalConfigDedicated *physicalConfigDedicated; -#if defined(Rel10) || defined(Rel14) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /// pointer to RRC PHY configuration SCEll struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10; #endif @@ -1298,7 +1301,7 @@ typedef struct { struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; -#if defined(Rel10) || defined(Rel14) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /// number of active MBSFN area uint8_t num_active_mbsfn_area; /// MBSFN Area Info @@ -1311,25 +1314,25 @@ typedef struct { uint8_t msi_status;// could be an array if there are >1 MCH in one MBSFN area #endif //#ifdef CBA - /// CBA RNTI for each group + /// CBA RNTI for each group uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; - /// last SFN for CBA channel access + /// last SFN for CBA channel access uint8_t cba_last_access[NUM_MAX_CBA_GROUP]; //#endif - /// total UE scheduler processing time + /// total UE scheduler processing time time_stats_t ue_scheduler; // total - /// UE ULSCH tx processing time inlcuding RLC interface (rlc_data_req) and mac header generation - time_stats_t tx_ulsch_sdu; + /// UE ULSCH tx processing time inlcuding RLC interface (rlc_data_req) and mac header generation + time_stats_t tx_ulsch_sdu; /// UE DLSCH rx processing time inlcuding RLC interface (mac_rrc_data_ind or mac_rlc_status_ind+mac_rlc_data_ind) and mac header parser - time_stats_t rx_dlsch_sdu ; - /// UE query for MCH subframe processing time + time_stats_t rx_dlsch_sdu ; + /// UE query for MCH subframe processing time time_stats_t ue_query_mch; - /// UE MCH rx processing time + /// UE MCH rx processing time time_stats_t rx_mch_sdu; - /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind) - time_stats_t rx_si; - /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind) - time_stats_t rx_p; + /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind) + time_stats_t rx_si; + /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind) + time_stats_t rx_p; } UE_MAC_INST; /*! \brief ID of the neighboring cells used for HO*/ typedef struct { @@ -1340,6 +1343,3 @@ typedef struct { #include "proto.h" /*@}*/ #endif /*__LAYER2_MAC_DEFS_H__ */ - - - diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index a9036f61c5a229204834d6744f3bb6c990432a11..8736d9aa6abcc3bef58cefbcb2f558395eca0999 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -36,6 +36,7 @@ #include "LAYER2/MAC/mac_proto.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" @@ -55,7 +56,7 @@ #include "eNB_scheduler_fairRR.h" #if defined(ENABLE_ITTI) -#include "intertask_interface.h" + #include "intertask_interface.h" #endif #include "assertions.h" @@ -68,292 +69,365 @@ extern RAN_CONTEXT_t RC; uint16_t pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; - -void -schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) +//----------------------------------------------------------------------------- +/* + * Schedule periodic SRS + */ +void schedule_SRS(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) +//----------------------------------------------------------------------------- { - - - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - nfapi_ul_config_request_body_t *ul_req; - int CC_id, UE_id; - COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; - LTE_SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon; - struct LTE_SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated; - uint8_t TSFC; - uint16_t deltaTSFC; // bitmap - uint8_t srs_SubframeConfig; - + int CC_id = 0; + int UE_id = -1; + uint8_t TSFC = 0; + uint8_t srs_SubframeConfig = 0; + uint16_t srsPeriodicity = 0; + uint16_t srsOffset = 0; + uint16_t deltaTSFC = 0; // bitmap // table for TSFC (Period) and deltaSFC (offset) - const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD - const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD - - uint16_t srsPeriodicity, srsOffset; - + const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD + const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &(eNB->UE_list); + nfapi_ul_config_request_body_t *ul_req = NULL; + UE_sched_ctrl *UE_scheduling_control = NULL; + COMMON_channels_t *cc = eNB->common_channels; + LTE_SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon = NULL; + struct LTE_SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated = NULL; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon; - // check if SRS is enabled in this frame/subframe + soundingRS_UL_ConfigCommon = &(cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon); + + /* Check if SRS is enabled in this frame/subframe */ if (soundingRS_UL_ConfigCommon) { srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; - if (cc[CC_id].tdd_Config == NULL) { // FDD - deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; - TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; - } else { // TDD - deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; - TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; + + if (cc[CC_id].tdd_Config == NULL) { // FDD + deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0]; + TSFC = deltaTSFCTabType1[srs_SubframeConfig][1]; + } else { // TDD + deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0]; + TSFC = deltaTSFCTabType2[srs_SubframeConfig][1]; } - // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC + + /* Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC) */ uint16_t tmp = (subframeP % TSFC); - + if ((1 << tmp) & deltaTSFC) { - // This is an SRS subframe, loop over UEs - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (!RC.mac[module_idP]->UE_list.active[UE_id]) continue; - ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; - - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, - "physicalConfigDedicated is null for UE %d\n", - UE_id); - - if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) { - if (soundingRS_UL_ConfigDedicated->present == LTE_SoundingRS_UL_ConfigDedicated_PR_setup) { - get_srs_pos(&cc[CC_id], - soundingRS_UL_ConfigDedicated->choice. - setup.srs_ConfigIndex, - &srsPeriodicity, &srsOffset); - if (((10 * frameP + subframeP) % srsPeriodicity) == srsOffset) { - // Program SRS - ul_req->srs_present = 1; - nfapi_ul_config_request_pdu_t * ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; - memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; - ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu)); - ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG; - ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu); - ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; - ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; - ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; - ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;; - ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; - ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; - ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; // ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;// - // ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;// - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; - RC.mac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req->number_of_pdus++; - } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) - } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) - } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) - } // for (UE_id ... - } // if((1<<tmp) & deltaTSFC) - - } // SRS config - } + /* This is an SRS subframe, loop over UEs */ + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (!UE_list->active[UE_id]) { + continue; + } + + /* Drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet */ + if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) { + continue; + } + + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated is null for UE %d\n", + UE_id); + + /* CDRX condition on Active Time and SRS type-0 report (36.321 5.7) */ + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + + /* Test if Active Time not running since 6+ subframes */ + if (UE_scheduling_control->cdrx_configured == TRUE && UE_scheduling_control->in_active_time == FALSE) { + /* + * TODO: 6+ subframes condition not checked here + */ + continue; + } + + ul_req = &(eNB->UL_req[CC_id].ul_config_request_body); + + if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) { + if (soundingRS_UL_ConfigDedicated->present == LTE_SoundingRS_UL_ConfigDedicated_PR_setup) { + get_srs_pos(&cc[CC_id], + soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, + &srsPeriodicity, + &srsOffset); + + if (((10 * frameP + subframeP) % srsPeriodicity) == srsOffset) { + // Program SRS + ul_req->srs_present = 1; + nfapi_ul_config_request_pdu_t *ul_config_pdu = &(ul_req->ul_config_pdu_list[ul_req->number_of_pdus]); + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu)); + ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG; + ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu); + ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; + ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; + ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;; + ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; + ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; + ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; + + eNB->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + eNB->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req->number_of_pdus++; + } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) + } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) + } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) + } // end for loop on UE_id + } // if((1<<tmp) & deltaTSFC) + } // SRS config not NULL + } // end for loop on CC_id } -void -schedule_CSI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) +//----------------------------------------------------------------------------- +/* +* Schedule the CSI (CQI/PMI/RI/PTI/CRI) periodic reception +*/ +void schedule_CSI(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) +//----------------------------------------------------------------------------- { + int CC_id = 0; + int UE_id = 0; + int H = 0; + uint16_t Npd = 0; + uint16_t N_OFFSET_CQI = 0; + struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic = NULL; eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list = &eNB->UE_list; - COMMON_channels_t *cc; - nfapi_ul_config_request_body_t *ul_req; - int CC_id, UE_id; - struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic; - uint16_t Npd, N_OFFSET_CQI; - int H; + COMMON_channels_t *cc = NULL; + nfapi_ul_config_request_body_t *ul_req = NULL; + UE_sched_ctrl *UE_scheduling_control = NULL; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - cc = &eNB->common_channels[CC_id]; + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (!UE_list->active[UE_id]) continue; - - ul_req = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body; - - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; - - AssertFatal(UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated - != NULL, - "physicalConfigDedicated is null for UE %d\n", - UE_id); - - if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) { - if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) != NULL - && (cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_release)) { - //Rel8 Periodic CQI/PMI/RI reporting - - get_csi_params(cc, cqi_ReportPeriodic, &Npd, - &N_OFFSET_CQI, &H); - - if ((((frameP * 10) + subframeP) % Npd) == N_OFFSET_CQI) { // CQI opportunity - UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id] = (((frameP * 10) + subframeP) / Npd) % H; - // Program CQI - nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; - ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id], CC_id, cc, - get_tmode(module_idP, CC_id, UE_id), - cqi_ReportPeriodic); - ul_req->number_of_pdus++; - ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + if (UE_list->active[UE_id] == FALSE) { + continue; + } + + /* Drop the allocation if the UE hasn't sent RRCConnectionSetupComplete yet */ + if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) { + continue; + } + + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated is null for UE %d\n", + UE_id); + /* + * CDRX condition on Active Time and CSI report on PUCCH (36.321 5.7). + * Here we consider classic periodic reports on PUCCH without PUSCH simultaneous transmission condition. + * TODO: add the handling or test on simultaneous PUCCH/PUSCH transmission + */ + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + + if (UE_scheduling_control->cdrx_configured == TRUE) { + /* Test if CQI masking activated */ + if (UE_scheduling_control->cqi_mask_boolean == TRUE) { + // CQI masking => test if onDurationTime not running since 6+ subframe + if (UE_scheduling_control->on_duration_timer == 0) { + /* + * TODO: 6+ subframes condition not checked here + */ + continue; + } + } else { // No CQI masking => test if Active Time not running since 6+ subframe + if (UE_scheduling_control->in_active_time == FALSE) { + /* + * TODO: 6+ subframes condition not checked here + */ + continue; + } + } + } + + ul_req = &(eNB->UL_req[CC_id].ul_config_request_body); + + if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL) { + cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic; + + if (cqi_ReportPeriodic != NULL) { + /* Rel8 Periodic CSI (CQI/PMI/RI) reporting */ + if (cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_release) { + get_csi_params(cc, cqi_ReportPeriodic, &Npd, &N_OFFSET_CQI, &H); + + if ((((frameP * 10) + subframeP) % Npd) == N_OFFSET_CQI) { // CQI periodic opportunity + UE_scheduling_control->feedback_cnt[CC_id] = (((frameP * 10) + subframeP) / Npd) % H; + + // Program CQI + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id], CC_id, cc, get_tmode(module_idP, CC_id, UE_id), cqi_ReportPeriodic); + ul_req->number_of_pdus++; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - // PUT rel10-13 UCI options here + // PUT rel10-13 UCI options here #endif - } else - if ((cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) - && ((((frameP * 10) + subframeP) % ((H * Npd) << (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex / 161))) == N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex % 161))) { // RI opportunity - // Program RI - nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; - memset((void *) ul_config_pdu, 0, - sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; - ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; - ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = (cc->p_eNB == 2) ? 1 : 2; - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; - ul_req->number_of_pdus++; - ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - } - } // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) { - } // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) - } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { - } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + } else if (cqi_ReportPeriodic->choice.setup.ri_ConfigIndex != NULL) { + if ((((frameP * 10) + subframeP) % ((H * Npd) << (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex / 161))) == + N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex % 161)) { // RI opportunity + + // Program RI + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE; + ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_uci_cqi_pdu)); + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_INFORMATION_REL8_TAG; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; + ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size = (cc->p_eNB == 2) ? 1 : 2; + RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + ul_req->number_of_pdus++; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + } + } + } // if CSI Periodic is not release state + } // if (cqi_ReportPeriodic != NULL) + } // if cqi_ReportConfig != NULL + } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { } +//----------------------------------------------------------------------------- +/* +* Schedule a possible Scheduling Request reception +*/ void -schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) +schedule_SR (module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) +//----------------------------------------------------------------------------- { - eNB_MAC_INST *eNB = RC.mac[module_idP]; - UE_list_t *UE_list = &eNB->UE_list; - nfapi_ul_config_request_t *ul_req; - nfapi_ul_config_request_body_t *ul_req_body; - int CC_id; - int UE_id; - LTE_SchedulingRequestConfig_t *SRconfig; - int skip_ue; - int is_harq; + int skip_ue = 0; + int is_harq = 0; + int pdu_list_index = 0; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + nfapi_ul_config_request_t *ul_req = NULL; + nfapi_ul_config_request_body_t *ul_req_body = NULL; + LTE_SchedulingRequestConfig_t *SRconfig = NULL; nfapi_ul_config_sr_information sr; - int i; - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; - - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (!RC.mac[module_idP]->UE_list.active[UE_id]) continue; - ul_req = &RC.mac[module_idP]->UL_req[CC_id]; - ul_req_body = &ul_req->ul_config_request_body; + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + eNB->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; - // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet - if (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; + for (int UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (!UE_list->active[UE_id]) { + continue; + } - AssertFatal(UE_list-> - UE_template[CC_id][UE_id].physicalConfigDedicated!= NULL, - "physicalConfigDedicated is null for UE %d\n", - UE_id); + if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated == NULL) continue; if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig) != NULL) { - if (SRconfig->present == LTE_SchedulingRequestConfig_PR_setup) { - if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period - if ((subframeP % 5) != SRconfig->choice.setup.sr_ConfigIndex) continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period - if (subframeP != (SRconfig->choice.setup.sr_ConfigIndex - 5)) continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period - if ((10 * (frameP & 1) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 15)) continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period - if ((10 * (frameP & 3) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 35)) continue; - } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period - if ((10 * (frameP & 7) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 75)) continue; - } - } // SRconfig->present == SchedulingRequestConfig_PR_setup) - } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) - - // if we get here there is some PUCCH1 reception to schedule for SR + if (SRconfig->present == LTE_SchedulingRequestConfig_PR_setup) { + if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period + if ((subframeP % 5) != SRconfig->choice.setup.sr_ConfigIndex) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period + if (subframeP != (SRconfig->choice.setup.sr_ConfigIndex - 5)) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period + if ((10 * (frameP & 1) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 15)) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period + if ((10 * (frameP & 3) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 35)) continue; + } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period + if ((10 * (frameP & 7) + subframeP) != (SRconfig->choice.setup.sr_ConfigIndex - 75)) continue; + } + } // SRconfig->present == SchedulingRequestConfig_PR_setup) + } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) + /* If we get here there is some PUCCH1 reception to schedule for SR */ + ul_req = &(eNB->UL_req[CC_id]); + ul_req_body = &(ul_req->ul_config_request_body); skip_ue = 0; is_harq = 0; - // check that there is no existing UL grant for ULSCH which overrides the SR - for (i = 0; i < ul_req_body->number_of_pdus; i++) { - if (((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) || - (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) || - (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) || - (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)) && - (ul_req_body->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { - skip_ue = 1; - break; - } - /* if there is already an HARQ pdu, convert to SR_HARQ */ - else if ((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && - (ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { - is_harq = 1; - break; - } + pdu_list_index = 0; + + /* Check that there is no existing UL grant for ULSCH which overrides the SR */ + for (int i = 0; i < ul_req_body->number_of_pdus; i++) { + if (((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) || + (ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)) && + (ul_req_body->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { + skip_ue = 1; + pdu_list_index = i; + break; + } + /* If there is already an HARQ pdu, convert to SR_HARQ */ + else if ((ul_req_body->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && + (ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) { + is_harq = 1; + pdu_list_index = i; + break; + } } - // drop the allocation because ULSCH with handle it with BSR + /* Drop the allocation because ULSCH will handle it with BSR */ if (skip_ue == 1) continue; - LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x is_harq:%d\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti, is_harq); + LOG_D(MAC, "Frame %d, Subframe %d : Scheduling SR for UE %d/%x is_harq:%d \n", + frameP, + subframeP, + UE_id, + UE_list->UE_template[CC_id][UE_id].rnti, + is_harq); - // check Rel10 or Rel8 SR + /* Check Rel10 or Rel8 SR */ #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - if ((UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) - && (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020) - && (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) { - sr.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; - sr.sr_information_rel10.number_of_pucch_resources = 1; - sr.sr_information_rel10.pucch_index_p1 = *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; - LOG_D(MAC,"REL10 PUCCH INDEX P1:%d\n", sr.sr_information_rel10.pucch_index_p1); + if ((UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) && + (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020) && + (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) { + sr.sr_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL10_TAG; + sr.sr_information_rel10.number_of_pucch_resources = 1; + sr.sr_information_rel10.pucch_index_p1 = *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10; + + LOG_D(MAC, "REL10 PUCCH INDEX P1:%d \n", sr.sr_information_rel10.pucch_index_p1); + } else #endif - { - sr.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; - sr.sr_information_rel8.pucch_index = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; - LOG_D(MAC,"REL8 PUCCH INDEX:%d\n", sr.sr_information_rel8.pucch_index); - } + { + sr.sr_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SR_INFORMATION_REL8_TAG; + sr.sr_information_rel8.pucch_index = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; + + LOG_D(MAC, "REL8 PUCCH INDEX:%d\n", sr.sr_information_rel8.pucch_index); + } - /* if there is already an HARQ pdu, convert to SR_HARQ */ + /* If there is already an HARQ pdu, convert to SR_HARQ */ if (is_harq) { - nfapi_ul_config_harq_information h = ul_req_body->ul_config_pdu_list[i].uci_harq_pdu.harq_information; - ul_req_body->ul_config_pdu_list[i].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; - ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.sr_information = sr; - ul_req_body->ul_config_pdu_list[i].uci_sr_harq_pdu.harq_information = h; + nfapi_ul_config_harq_information harq = ul_req_body->ul_config_pdu_list[pdu_list_index].uci_harq_pdu.harq_information; + ul_req_body->ul_config_pdu_list[pdu_list_index].pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + ul_req_body->ul_config_pdu_list[pdu_list_index].uci_sr_harq_pdu.sr_information = sr; + ul_req_body->ul_config_pdu_list[pdu_list_index].uci_sr_harq_pdu.harq_information = harq; } else { - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel11.tl.tag = 0; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel13.tl.tag = 0; - ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.sr_information = sr; - ul_req_body->number_of_pdus++; - } /* if (is_harq) */ - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) - } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].pdu_type = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel11.tl.tag = 0; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel13.tl.tag = 0; + ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus].uci_sr_pdu.sr_information = sr; + ul_req_body->number_of_pdus++; + } // if (is_harq) + + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + + } // for (int UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) + } // for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) } -extern uint8_t nfapi_mode; - void check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, - frame_t frameP, sub_frame_t subframeP) -{ + frame_t frameP, sub_frame_t subframeP) { UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; uint16_t rnti = UE_RNTI(module_idP, UE_id); @@ -365,9 +439,9 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 1) LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti, UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); + if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) { UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1; - // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe) nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[DL_req[CC_id].dl_config_request_body.number_pdu]; memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_config_request_pdu_t)); @@ -376,259 +450,480 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), - UE_list->UE_sched_ctrl[UE_id]. - dl_cqi[CC_id], format1A); + UE_list->UE_sched_ctrl[UE_id]. + dl_cqi[CC_id], format1A); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >= 0) && (cc[CC_id].mib->message.dl_Bandwidth < 6), - "illegal dl_Bandwidth %d\n", - (int) cc[CC_id].mib->message.dl_Bandwidth); + "illegal dl_Bandwidth %d\n", + (int) cc[CC_id].mib->message.dl_Bandwidth); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth]; DL_req[CC_id].dl_config_request_body.number_dci++; DL_req[CC_id].dl_config_request_body.number_pdu++; DL_req[CC_id].dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; LOG_D(MAC, - "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n", - UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_block_coding); - } else { // ra_pdcch_sent==1 + "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n", + UE_id, rnti, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer, + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.resource_block_coding); + } else { // ra_pdcch_sent==1 LOG_D(MAC, - "UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n", - UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 80) == 0) UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 8 frames + "UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n", + UE_id, rnti, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); + + if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 80) == 0) UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 8 frames } UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++; + // check threshold if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 4000) { // note: probably ul_failure_timer should be less than UE radio link failure time(see T310/N310/N311) - // inform RRC of failure and clear timer - LOG_I(MAC, - "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n", - UE_id, rnti); - mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti); + if (NODE_IS_DU(RC.rrc[module_idP]->node_type)) { + MessageDef *m = itti_alloc_new_message(TASK_MAC_ENB, F1AP_UE_CONTEXT_RELEASE_REQ); + F1AP_UE_CONTEXT_RELEASE_REQ(m).rnti = rnti; + F1AP_UE_CONTEXT_RELEASE_REQ(m).cause = F1AP_CAUSE_RADIO_NETWORK; + F1AP_UE_CONTEXT_RELEASE_REQ(m).cause_value = 1; // 1 = F1AP_CauseRadioNetwork_rl_failure + F1AP_UE_CONTEXT_RELEASE_REQ(m).rrc_container = NULL; + F1AP_UE_CONTEXT_RELEASE_REQ(m).rrc_container_length = 0; + itti_send_msg_to_task(TASK_DU_F1, module_idP, m); + } else { + // inform RRC of failure and clear timer + LOG_I(MAC, "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n", + UE_id, + rnti); + mac_eNB_rrc_ul_failure(module_idP, + CC_id, + frameP, + subframeP, + rnti); + } + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; - - //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future - if (rrc_agent_registered[module_idP]) { - LOG_W(MAC, "notify flexran Agent of UE state change\n"); - agent_rrc_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP, - rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); - } } - } // ul_failure_timer>0 + } // ul_failure_timer>0 } void -clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP, - frame_t frameP, sub_frame_t subframeP) -{ +clear_nfapi_information(eNB_MAC_INST *eNB, int CC_idP, + frame_t frameP, sub_frame_t subframeP) { nfapi_dl_config_request_t *DL_req = &eNB->DL_req[0]; nfapi_ul_config_request_t *UL_req = &eNB->UL_req[0]; nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[CC_idP][subframeP]; nfapi_tx_request_t *TX_req = &eNB->TX_req[0]; - eNB->pdu_index[CC_idP] = 0; - if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF - + if (NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MONOLITHIC) { // monolithic or PNF DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols = 1; DL_req[CC_idP].dl_config_request_body.number_dci = 0; DL_req[CC_idP].dl_config_request_body.number_pdu = 0; DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti = 0; DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich = 6000; DL_req[CC_idP].sfn_sf = subframeP + (frameP<<4); - HI_DCI0_req->hi_dci0_request_body.sfnsf = subframeP + (frameP<<4); HI_DCI0_req->hi_dci0_request_body.number_of_dci = 0; - - UL_req[CC_idP].ul_config_request_body.number_of_pdus = 0; UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources = 0; // ignored, handled by PHY for now UL_req[CC_idP].ul_config_request_body.srs_present = 0; // ignored, handled by PHY for now - TX_req[CC_idP].tx_request_body.number_of_pdus = 0; - } } void -copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) -{ +copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { int CC_id; eNB_MAC_INST *mac = RC.mac[module_idP]; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][subframeP]; nfapi_ul_config_request_t *ul_req = &mac->UL_req[CC_id]; nfapi_ul_config_request_pdu_t *ul_req_pdu = ul_req->ul_config_request_body.ul_config_pdu_list; - *ul_req = *ul_req_tmp; - // Restore the pointer ul_req->ul_config_request_body.ul_config_pdu_list = ul_req_pdu; ul_req->sfn_sf = (frameP<<4) + subframeP; ul_req_tmp->ul_config_request_body.number_of_pdus = 0; - if (ul_req->ul_config_request_body.number_of_pdus>0) - { - LOG_D(PHY, "%s() active NOW (frameP:%d subframeP:%d) pdus:%d\n", __FUNCTION__, frameP, subframeP, ul_req->ul_config_request_body.number_of_pdus); - } + if (ul_req->ul_config_request_body.number_of_pdus>0) { + LOG_D(PHY, "%s() active NOW (frameP:%d subframeP:%d) pdus:%d\n", __FUNCTION__, frameP, subframeP, ul_req->ul_config_request_body.number_of_pdus); + } - memcpy((void*)ul_req->ul_config_request_body.ul_config_pdu_list, - (void*)ul_req_tmp->ul_config_request_body.ul_config_pdu_list, - ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); + memcpy((void *)ul_req->ul_config_request_body.ul_config_pdu_list, + (void *)ul_req_tmp->ul_config_request_body.ul_config_pdu_list, + ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); } } void -eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, - sub_frame_t subframeP) +eNB_dlsch_ulsch_scheduler(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) { - int mbsfn_status[MAX_NUM_CCs]; protocol_ctxt_t ctxt; + rnti_t rnti = 0; + int CC_id = 0; + int UE_id = -1; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &(eNB->UE_list); + COMMON_channels_t *cc = eNB->common_channels; + UE_sched_ctrl *UE_scheduling_control = NULL; - int CC_id, i = -1; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - rnti_t rnti; - - COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; + start_meas(&(eNB->eNB_scheduler)); - start_meas(&RC.mac[module_idP]->eNB_scheduler); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, - VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, VCD_FUNCTION_IN); - RC.mac[module_idP]->frame = frameP; - RC.mac[module_idP]->subframe = subframeP; + eNB->frame = frameP; + eNB->subframe = subframeP; for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { mbsfn_status[CC_id] = 0; - // clear vrb_maps + /* Clear vrb_maps */ memset(cc[CC_id].vrb_map, 0, 100); memset(cc[CC_id].vrb_map_UL, 0, 100); - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - cc[CC_id].mcch_active = 0; + cc[CC_id].mcch_active = 0; #endif - clear_nfapi_information(RC.mac[module_idP], CC_id, frameP, subframeP); } - // refresh UE list based on UEs dropped by PHY in previous subframe - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (UE_list->active[i]) { - rnti = UE_RNTI(module_idP, i); - CC_id = UE_PCCID(module_idP, i); - - if (((frameP&127) == 0) && (subframeP == 0)) { - LOG_I(MAC, - "UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", - rnti, - UE_list->UE_sched_ctrl[i].ul_out_of_sync == - 0 ? "in synch" : "out of sync", - UE_list->UE_template[CC_id][i].phr_info, - UE_list->UE_sched_ctrl[i].dl_cqi[CC_id], - (5*UE_list->UE_sched_ctrl[i].pusch_snr[CC_id] - 640) / 10, - (5*UE_list->UE_sched_ctrl[i].pucch1_snr[CC_id] - 640) / 10); + /* Refresh UE list based on UEs dropped by PHY in previous subframe */ + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { + if (UE_list->active[UE_id]) { + rnti = UE_RNTI(module_idP, UE_id); + CC_id = UE_PCCID(module_idP, UE_id); + + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + + if (((frameP & 127) == 0) && (subframeP == 0)) { + LOG_I(MAC,"UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", + rnti, + UE_scheduling_control->ul_out_of_sync == 0 ? "in synch" : "out of sync", + UE_list->UE_template[CC_id][UE_id].phr_info, + UE_scheduling_control->dl_cqi[CC_id], + (5 * UE_scheduling_control->pusch_snr[CC_id] - 640) / 10, + (5 * UE_scheduling_control->pucch1_snr[CC_id] - 640) / 10); } + + RC.eNB[module_idP][CC_id]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = -63; + + if (UE_id == UE_list->head) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, RC.eNB[module_idP][CC_id]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP]); + } + + /* Set and increment CDRX related timers */ + if (UE_scheduling_control->cdrx_configured == TRUE) { + boolean_t harq_active_time_condition = FALSE; + UE_TEMPLATE *UE_template = NULL; + + unsigned long active_time_condition = 0; // variable used only for tracing purpose + + /* (UL and DL) HARQ RTT timers and DRX retransmission timers */ + for (int harq_process_id = 0; harq_process_id < 8; harq_process_id++) { + /* DL asynchronous HARQ process */ + if (UE_scheduling_control->drx_retransmission_timer[harq_process_id] > 0) { + UE_scheduling_control->drx_retransmission_timer[harq_process_id]++; + + if (UE_scheduling_control->drx_retransmission_timer[harq_process_id] > UE_scheduling_control->drx_retransmission_timer_thres[harq_process_id]) { + UE_scheduling_control->drx_retransmission_timer[harq_process_id] = 0; + } + } + + if (UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] > 0) { + UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id]++; + + if (UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] > 8) { + /* Note: here drx_retransmission_timer is restarted instead of started in the specification */ + UE_scheduling_control->drx_retransmission_timer[harq_process_id] = 1; // started when HARQ RTT timer expires + UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] = 0; + } + } + + /* UL asynchronous HARQ process: only UL HARQ RTT timer is implemented (hence not implemented) */ + if (UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] > 0) { + UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id]++; + + if (UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] > 4) { + /* + * TODO: implement the handling of UL asynchronous HARQ + * drx_ULRetransmissionTimer should be (re)started here + */ + UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] = 0; + } + } + + /* UL synchronous HARQ process */ + if (UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id] > 0) { + UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id]++; + + if (UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id] > 5) { + harq_active_time_condition = TRUE; + UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id] = 0; + active_time_condition = 5; // for tracing purpose + } + } + } + + /* On duration timer */ + if (UE_scheduling_control->on_duration_timer > 0) { + UE_scheduling_control->on_duration_timer++; + + if (UE_scheduling_control->on_duration_timer > UE_scheduling_control->on_duration_timer_thres) { + UE_scheduling_control->on_duration_timer = 0; + } + } + + /* DRX inactivity timer */ + if (UE_scheduling_control->drx_inactivity_timer > 0) { + UE_scheduling_control->drx_inactivity_timer++; + + if (UE_scheduling_control->drx_inactivity_timer > (UE_scheduling_control->drx_inactivity_timer_thres + 1)) { + /* Note: the +1 on the threshold is due to information in table C-1 of 36.321 */ + UE_scheduling_control->drx_inactivity_timer = 0; + + /* When timer expires switch into short or long DRX cycle */ + if (UE_scheduling_control->drx_shortCycle_timer_thres > 0) { + UE_scheduling_control->in_short_drx_cycle = TRUE; + UE_scheduling_control->drx_shortCycle_timer = 0; + UE_scheduling_control->in_long_drx_cycle = FALSE; + } else { + UE_scheduling_control->in_long_drx_cycle = TRUE; + } + } + } + + /* Short DRX Cycle */ + if (UE_scheduling_control->in_short_drx_cycle == TRUE) { + UE_scheduling_control->drx_shortCycle_timer++; + + /* When the Short DRX cycles are over, switch to long DRX cycle */ + if (UE_scheduling_control->drx_shortCycle_timer > UE_scheduling_control->drx_shortCycle_timer_thres) { + UE_scheduling_control->drx_shortCycle_timer = 0; + UE_scheduling_control->in_short_drx_cycle = FALSE; + UE_scheduling_control->in_long_drx_cycle = TRUE; + UE_scheduling_control->drx_longCycle_timer = 0; + } + } else { + UE_scheduling_control->drx_shortCycle_timer = 0; + } + + /* Long DRX Cycle */ + if (UE_scheduling_control->in_long_drx_cycle == TRUE) { + UE_scheduling_control->drx_longCycle_timer++; + + if (UE_scheduling_control->drx_longCycle_timer > UE_scheduling_control->drx_longCycle_timer_thres) { + UE_scheduling_control->drx_longCycle_timer = 1; + } + } else { + UE_scheduling_control->drx_longCycle_timer = 0; + } + + /* Check for error cases */ + if ((UE_scheduling_control->in_short_drx_cycle == TRUE) && (UE_scheduling_control->in_long_drx_cycle == TRUE)) { + LOG_E(MAC, "Error in C-DRX: UE id %d is in both short and long DRX cycle. Should not happen. Back it to long cycle only\n", UE_id); + UE_scheduling_control->in_short_drx_cycle = FALSE; + } + + /* Condition to start On Duration Timer */ + if (UE_scheduling_control->in_short_drx_cycle == TRUE && UE_scheduling_control->on_duration_timer == 0) { + if (((frameP * 10) + subframeP) % (UE_scheduling_control->short_drx_cycle_duration) == + (UE_scheduling_control->drx_start_offset) % (UE_scheduling_control->short_drx_cycle_duration)) { + + UE_scheduling_control->on_duration_timer = 1; + } + } else if (UE_scheduling_control->in_long_drx_cycle == TRUE && UE_scheduling_control->on_duration_timer == 0) { + if (((frameP * 10) + subframeP) % (UE_scheduling_control->drx_longCycle_timer_thres) == + (UE_scheduling_control->drx_start_offset)) { + + UE_scheduling_control->on_duration_timer = 1; + } + } + + /* Update Active Time status of UE + * Based on 36.321 5.7 the differents conditions for the UE to be in Acttive Should be check ONLY + * here for the current subframe. The variable 'UE_scheduling_control->in_active_time' should be updated + * ONLY here. The variable can then be used for testing the actual state of the UE for scheduling purpose. + */ + UE_template = &(UE_list->UE_template[CC_id][UE_id]); + /* (a)synchronous HARQ processes handling for Active Time */ + for (int harq_process_id = 0; harq_process_id < 8; harq_process_id++) { + if (UE_scheduling_control->drx_retransmission_timer[harq_process_id] > 0) { + harq_active_time_condition = TRUE; + active_time_condition = 2; // for tracing purpose + break; + } + } + + /* Active time conditions */ + if (UE_scheduling_control->on_duration_timer > 0 || + UE_scheduling_control->drx_inactivity_timer > 1 || + harq_active_time_condition || + UE_template->ul_SR > 0) { + + UE_scheduling_control->in_active_time = TRUE; + + } else { + UE_scheduling_control->in_active_time = FALSE; + } + + /* BEGIN VCD */ + if (UE_id == 0) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_ON_DURATION_TIMER, (unsigned long) UE_scheduling_control->on_duration_timer); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) UE_scheduling_control->drx_inactivity_timer); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_SHORT_CYCLE, (unsigned long) UE_scheduling_control->drx_shortCycle_timer); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_LONG_CYCLE, (unsigned long) UE_scheduling_control->drx_longCycle_timer); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) UE_scheduling_control->drx_retransmission_timer[0]); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_ACTIVE_TIME, (unsigned long) UE_scheduling_control->in_active_time); + + /* For tracing purpose */ + if (UE_template->ul_SR > 0) { + active_time_condition = 1; + } else if ((UE_scheduling_control->on_duration_timer > 0) && (active_time_condition == 0)) { + active_time_condition = 3; + } else if ((UE_scheduling_control->drx_inactivity_timer > 1) && (active_time_condition == 0)) { + active_time_condition = 4; + } + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_ACTIVE_TIME_CONDITION, (unsigned long) active_time_condition); + } + /* END VCD */ + + /* DCI0 ongoing timer */ + if (UE_scheduling_control->dci0_ongoing_timer > 0) { + if (UE_scheduling_control->dci0_ongoing_timer > 7) { + UE_scheduling_control->dci0_ongoing_timer = 0; + } else { + UE_scheduling_control->dci0_ongoing_timer++; + } + } + + } else { // else: CDRX not configured + /* Note: (UL) HARQ RTT timers processing is done here and can be used by other features than CDRX */ + /* HARQ RTT timers */ + for (int harq_process_id = 0; harq_process_id < 8; harq_process_id++) { + if (UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] > 0) { + UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id]++; + + if (UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] > 8) { + UE_scheduling_control->harq_rtt_timer[CC_id][harq_process_id] = 0; + } + } + + if (UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] > 0) { + UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id]++; + + if (UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] > 4) { + UE_scheduling_control->ul_harq_rtt_timer[CC_id][harq_process_id] = 0; + } + } + } // end loop harq process + } // end else CDRX not configured + + /* Increment these timers, they are cleared when we receive an sdu */ + UE_scheduling_control->ul_inactivity_timer++; + UE_scheduling_control->cqi_req_timer++; - RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP * 10) + - subframeP] = -63; - if (i == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME - (VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, - RC.eNB[module_idP][CC_id]-> - pusch_stats_bsr[i][(frameP * 10) + subframeP]); - // increment this, it is cleared when we receive an sdu - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++; - - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++; - LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", i, rnti, - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i]. - ul_inactivity_timer, - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer); - check_ul_failure(module_idP, CC_id, i, frameP, subframeP); - - if (RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0) { - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer++; - if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer >= - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres) { - RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer = 0; - //clear reestablish_rnti_map - if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres >20){ - for (int ue_id_l = 0; ue_id_l < MAX_MOBILES_PER_ENB; ue_id_l++) { - if (reestablish_rnti_map[ue_id_l][0] == rnti) { - // clear currentC-RNTI from map - reestablish_rnti_map[ue_id_l][0] = 0; - reestablish_rnti_map[ue_id_l][1] = 0; - break; - } - } + LOG_D(MAC, "UE %d/%x : ul_inactivity %d, cqi_req %d\n", + UE_id, + rnti, + UE_scheduling_control->ul_inactivity_timer, + UE_scheduling_control->cqi_req_timer); + + check_ul_failure(module_idP, CC_id, UE_id, frameP, subframeP); + + if (UE_scheduling_control->ue_reestablishment_reject_timer > 0) { + UE_scheduling_control->ue_reestablishment_reject_timer++; + + if (UE_scheduling_control->ue_reestablishment_reject_timer >= UE_scheduling_control->ue_reestablishment_reject_timer_thres) { + UE_scheduling_control->ue_reestablishment_reject_timer = 0; + + /* Clear reestablish_rnti_map */ + if (UE_scheduling_control->ue_reestablishment_reject_timer_thres > 20) { + for (int ue_id_l = 0; ue_id_l < MAX_MOBILES_PER_ENB; ue_id_l++) { + if (reestablish_rnti_map[ue_id_l][0] == rnti) { + /* Clear currentC-RNTI from map */ + reestablish_rnti_map[ue_id_l][0] = 0; + reestablish_rnti_map[ue_id_l][1] = 0; + break; + } + } PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rnti, 0, 0,module_idP); rrc_rlc_remove_ue(&ctxt); pdcp_remove_UE(&ctxt); } - // Note: This should not be done in the MAC! - for (int ii=0; ii<MAX_MOBILES_PER_ENB; ii++) { - LTE_eNB_ULSCH_t *ulsch = RC.eNB[module_idP][CC_id]->ulsch[ii]; - if((ulsch != NULL) && (ulsch->rnti == rnti)){ + + /* Note: This should not be done in the MAC! */ + for (int ii=0; ii<MAX_MOBILES_PER_ENB; ii++) { + LTE_eNB_ULSCH_t *ulsch = RC.eNB[module_idP][CC_id]->ulsch[ii]; + + if((ulsch != NULL) && (ulsch->rnti == rnti)) { void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - LOG_I(MAC, "clean_eNb_ulsch UE %x \n", rnti); - clean_eNb_ulsch(ulsch); - } - } - for (int ii=0; ii<MAX_MOBILES_PER_ENB; ii++) { - LTE_eNB_DLSCH_t *dlsch = RC.eNB[module_idP][CC_id]->dlsch[ii][0]; - if((dlsch != NULL) && (dlsch->rnti == rnti)){ + + LOG_I(MAC, "clean_eNb_ulsch UE %x \n", rnti); + + clean_eNb_ulsch(ulsch); + } + } + + for (int ii=0; ii<MAX_MOBILES_PER_ENB; ii++) { + LTE_eNB_DLSCH_t *dlsch = RC.eNB[module_idP][CC_id]->dlsch[ii][0]; + + if((dlsch != NULL) && (dlsch->rnti == rnti)) { void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); - LOG_I(MAC, "clean_eNb_dlsch UE %x \n", rnti); - clean_eNb_dlsch(dlsch); - } - } - - for(int j = 0; j < 10; j++){ - nfapi_ul_config_request_body_t *ul_req_tmp = NULL; - ul_req_tmp = &RC.mac[module_idP]->UL_req_tmp[CC_id][j].ul_config_request_body; - if(ul_req_tmp){ - int pdu_number = ul_req_tmp->number_of_pdus; - for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){ - if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti){ - LOG_I(MAC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number); - if(pdu_index < pdu_number -1){ - memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); - } - ul_req_tmp->number_of_pdus--; - } - } - } - } - rrc_mac_remove_ue(module_idP,rnti); - } - } - } - } + + LOG_I(MAC, "clean_eNb_dlsch UE %x \n", rnti); + + clean_eNb_dlsch(dlsch); + } + } + + for (int j = 0; j < 10; j++) { + nfapi_ul_config_request_body_t *ul_req_tmp = NULL; + ul_req_tmp = &(eNB->UL_req_tmp[CC_id][j].ul_config_request_body); + + if (ul_req_tmp) { + int pdu_number = ul_req_tmp->number_of_pdus; + + for (int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--) { + if (ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) { + LOG_I(MAC, "remove UE %x from ul_config_pdu_list %d/%d\n", + rnti, + pdu_index, + pdu_number); + + if (pdu_index < pdu_number -1) { + memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], + &ul_req_tmp->ul_config_pdu_list[pdu_index+1], + (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); + } + + ul_req_tmp->number_of_pdus--; + } + } // end for pdu_index + } // end if (ul_req_tmp) + } // end for j + + rrc_mac_remove_ue(module_idP,rnti); + + } // end if (UE_scheduling_control->ue_reestablishment_reject_timer >= UE_scheduling_control->ue_reestablishment_reject_timer_thres) + } // end if (UE_scheduling_control->ue_reestablishment_reject_timer > 0) + } // end if UE active + } // end for loop on UE_id #if (!defined(PRE_SCD_THREAD)) - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, - NOT_A_RNTI, frameP, subframeP, - module_idP); - pdcp_run(&ctxt); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP, module_idP); + pdcp_run(&ctxt); rrc_rx_tx(&ctxt, CC_id); -#endif +#endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { @@ -641,82 +936,86 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, #endif - static int debug_flag=0; - void (*schedule_ulsch_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe)=NULL; - void (*schedule_ue_spec_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag)=NULL; - if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_DEFAULT){ + static int debug_flag = 0; + void (*schedule_ulsch_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe) = NULL; + void (*schedule_ue_spec_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag) = NULL; + + if (eNB->scheduler_mode == SCHED_MODE_DEFAULT) { schedule_ulsch_p = schedule_ulsch; schedule_ue_spec_p = schedule_dlsch; - }else if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ + } else if (eNB->scheduler_mode == SCHED_MODE_FAIR_RR) { memset(dlsch_ue_select, 0, sizeof(dlsch_ue_select)); schedule_ulsch_p = schedule_ulsch_fairRR; schedule_ue_spec_p = schedule_ue_spec_fairRR; } - if(debug_flag==0){ - LOG_E(MAC,"SCHED_MODE=%d\n",RC.mac[module_idP]->scheduler_mode); - debug_flag=1; + + if(debug_flag == 0){ + LOG_E(MAC,"SCHED_MODE = %d\n", eNB->scheduler_mode); + debug_flag = 1; } - // This schedules MIB + /* This schedules MIB */ if ((subframeP == 0) && (frameP & 3) == 0) { - schedule_mib(module_idP, frameP, subframeP); - - //schedule_SI_MBMS(module_idP, frameP, subframeP); + schedule_mib(module_idP, frameP, subframeP); + + schedule_SI_MBMS(module_idP, frameP, subframeP); } - if (get_softmodem_params()->phy_test == 0){ - // This schedules SI for legacy LTE and eMTC starting in subframeP + + if (get_softmodem_params()->phy_test == 0) { + /* This schedules SI for legacy LTE and eMTC starting in subframeP */ schedule_SI(module_idP, frameP, subframeP); - // This schedules Paging in subframeP + /* This schedules Paging in subframeP */ schedule_PCH(module_idP,frameP,subframeP); - // This schedules Random-Access for legacy LTE and eMTC starting in subframeP + /* This schedules Random-Access for legacy LTE and eMTC starting in subframeP */ schedule_RA(module_idP, frameP, subframeP); - // copy previously scheduled UL resources (ULSCH + HARQ) + /* Copy previously scheduled UL resources (ULSCH + HARQ) */ copy_ulreq(module_idP, frameP, subframeP); - // This schedules SRS in subframeP + /* This schedules SRS in subframeP */ schedule_SRS(module_idP, frameP, subframeP); - // This schedules ULSCH in subframeP (dci0) + + /* This schedules ULSCH in subframeP (dci0) */ if (schedule_ulsch_p != NULL) { - schedule_ulsch_p(module_idP, frameP, subframeP); + schedule_ulsch_p(module_idP, frameP, subframeP); } else { - LOG_E(MAC," %s %d: schedule_ulsch_p is NULL, function not called\n",__FILE__,__LINE__); + LOG_E(MAC," %s %d: schedule_ulsch_p is NULL, function not called\n", + __FILE__, + __LINE__); } - // This schedules UCI_SR in subframeP + + /* This schedules UCI_SR in subframeP */ schedule_SR(module_idP, frameP, subframeP); - // This schedules UCI_CSI in subframeP + /* This schedules UCI_CSI in subframeP */ schedule_CSI(module_idP, frameP, subframeP); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - // This schedules DLSCH in subframeP - schedule_ue_spec_br(module_idP,frameP,subframeP); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + /* This schedules DLSCH in subframeP for BR UE*/ + schedule_ue_spec_br(module_idP, frameP, subframeP); #endif - // This schedules DLSCH in subframeP + /* This schedules DLSCH in subframeP */ if (schedule_ue_spec_p != NULL) { - schedule_ue_spec_p(module_idP, frameP, subframeP, mbsfn_status); + schedule_ue_spec_p(module_idP, frameP, subframeP, mbsfn_status); } else { - LOG_E(MAC," %s %d: schedule_ue_spec_p is NULL, function not called\n",__FILE__,__LINE__); + LOG_E(MAC," %s %d: schedule_ue_spec_p is NULL, function not called\n", + __FILE__, + __LINE__); } - } - else{ + } else { schedule_ulsch_phy_test(module_idP,frameP,subframeP); schedule_ue_spec_phy_test(module_idP,frameP,subframeP,mbsfn_status); } - if (RC.flexran[module_idP]->enabled) - flexran_agent_send_update_stats(module_idP); - - // Allocate CCEs for good after scheduling is done + /* Allocate CCEs for good after scheduling is done */ for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - if(cc[CC_id].tdd_Config == NULL || !(is_UL_sf(&cc[CC_id],subframeP))) + if (cc[CC_id].tdd_Config == NULL || !(is_UL_sf(&cc[CC_id],subframeP))) { allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2); + } } - if (mac_agent_registered[module_idP] && subframeP == 9) { + if (flexran_agent_get_mac_xface(module_idP) && subframeP == 9) { flexran_agent_slice_update(module_idP); } - stop_meas(&RC.mac[module_idP]->eNB_scheduler); + stop_meas(&(eNB->eNB_scheduler)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, - VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, VCD_FUNCTION_OUT); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 23b709f58e607df84b1880f916c82a94ac096a26..90afc0a00cd58c2a0667f64a0d4a96ad05910bc9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -41,6 +41,7 @@ #include "LAYER2/MAC/mac_proto.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" @@ -55,10 +56,10 @@ #include "pdcp.h" #if defined(ENABLE_ITTI) -#include "intertask_interface.h" + #include "intertask_interface.h" #endif -#include "SIMULATION/TOOLS/sim.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus #include "T.h" @@ -67,68 +68,58 @@ extern RAN_CONTEXT_t RC; -extern uint8_t nfapi_mode; -extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); -void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset) -{ - *frameP = (*frameP + ((*subframeP + offset) / 10)) % 1024; +extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); - *subframeP = ((*subframeP + offset) % 10); +void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset) { + *frameP = (*frameP + ((*subframeP + offset) / 10)) % 1024; + *subframeP = ((*subframeP + offset) % 10); } -uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset) -{ +uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset) { add_subframe(&frameP, &subframeP, offset); return frameP<<4|subframeP; } -void subtract_subframe(uint16_t *frameP, uint16_t *subframeP, int offset) -{ - if (*subframeP < offset) - { +void subtract_subframe(uint16_t *frameP, uint16_t *subframeP, int offset) { + if (*subframeP < offset) { *frameP = (*frameP+1024-1)%1024; } + *subframeP = (*subframeP+10-offset)%10; } -uint16_t sfnsf_subtract_subframe(uint16_t frameP, uint16_t subframeP, int offset) -{ +uint16_t sfnsf_subtract_subframe(uint16_t frameP, uint16_t subframeP, int offset) { subtract_subframe(&frameP, &subframeP, offset); return frameP<<4|subframeP; } void -add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, - sub_frame_t subframeP) -{ - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc = &mac->common_channels[CC_id]; - uint8_t j; - nfapi_ul_config_request_t *ul_req; - nfapi_ul_config_request_body_t *ul_req_body; - nfapi_ul_config_request_pdu_t *ul_config_pdu; - nfapi_hi_dci0_request_t *hi_dci0_req; - nfapi_hi_dci0_request_body_t *hi_dci0_req_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; - uint8_t sf_ahead_dl; - uint8_t rvseq[4] = { 0, 2, 3, 1 }; - - - ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe]; - ul_req_body = &ul_req->ul_config_request_body; - AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n", - ra->rnti); - +add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, + sub_frame_t subframeP) { + eNB_MAC_INST *mac = RC.mac[module_idP]; + COMMON_channels_t *cc = &mac->common_channels[CC_id]; + uint8_t j; + nfapi_ul_config_request_t *ul_req; + nfapi_ul_config_request_body_t *ul_req_body; + nfapi_ul_config_request_pdu_t *ul_config_pdu; + nfapi_hi_dci0_request_t *hi_dci0_req; + nfapi_hi_dci0_request_body_t *hi_dci0_req_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; + uint8_t sf_ahead_dl; + uint8_t rvseq[4] = {0, 2, 3, 1}; + ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe]; + ul_req_body = &ul_req->ul_config_request_body; + AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n", + ra->rnti); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (ra->rach_resource_type > 0) { - LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n", + LOG_D (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n", module_idP, frameP, subframeP, CC_id, ra->rach_resource_type - 1, ra->Msg3_frame, ra->Msg3_subframe); - LOG_I (MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d)\n", + LOG_D (MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d)\n", frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe, ra->msg3_nb_rb, ra->msg3_round); - ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - memset ((void *) ul_config_pdu, 0, sizeof (nfapi_ul_config_request_pdu_t)); ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_ulsch_pdu)); @@ -153,181 +144,181 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe; ul_req_body->number_of_pdus++; - } // if (ra->rach_resource_type>0) { + } // if (ra->rach_resource_type>0) { else #endif - { - LOG_D(MAC, - "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", - module_idP, frameP, subframeP, CC_id, ra->Msg3_frame, - ra->Msg3_subframe); - - LOG_D(MAC, - "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", - frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe, - ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round, ra->rnti); - - ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - - memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; - ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = ra->msg3_first_rb; - AssertFatal(ra->msg3_nb_rb > 0, "nb_rb = 0\n"); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round]; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = subframe2harqpid(cc, ra->Msg3_frame, ra->Msg3_subframe); - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(10, ra->msg3_nb_rb); - ul_req_body->number_of_pdus++; - ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; - ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; - // save UL scheduling information for preprocessor - for (j = 0; j < ra->msg3_nb_rb; j++) - cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; - - LOG_D(MAC, "MSG3: UL_CONFIG SFN/SF:%d number_of_pdus:%d ra->msg3_round:%d\n", NFAPI_SFNSF2DEC(ul_req->sfn_sf), ul_req_body->number_of_pdus, ra->msg3_round); - - if (ra->msg3_round != 0) { // program HI too - sf_ahead_dl = ul_subframe2_k_phich(cc, subframeP); - hi_dci0_req = &mac->HI_DCI0_req[CC_id][(subframeP+sf_ahead_dl)%10]; - hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; - hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; - memset((void *) hi_dci0_pdu, 0, - sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = ra->msg3_first_rb; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; - hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; - hi_dci0_req_body->number_of_hi++; - - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - - hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - - if (nfapi_mode) { - oai_nfapi_hi_dci0_req(hi_dci0_req); - hi_dci0_req_body->number_of_hi=0; - } - - LOG_D(MAC, "MSG3: HI_DCI0 SFN/SF:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req_body->number_of_dci, hi_dci0_req_body->number_of_hi); - - // save UL scheduling information for preprocessor - for (j = 0; j < ra->msg3_nb_rb; j++) - cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; - - LOG_D(MAC, - "[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA (mcs %d, first rb %d, nb_rb %d,round %d)\n", - module_idP, ra->rnti, CC_id, frameP, subframeP, 10, 1, 1, - ra->msg3_round - 1); - } // if (ra->msg3_round != 0) { // program HI too - } // non-BL/CE UE case -} + { + LOG_D(MAC, + "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", + module_idP, frameP, subframeP, CC_id, ra->Msg3_frame, + ra->Msg3_subframe); + LOG_D(MAC, + "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", + frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe, + ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round, ra->rnti); + ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = ra->msg3_first_rb; + AssertFatal(ra->msg3_nb_rb > 0, "nb_rb = 0\n"); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round]; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = subframe2harqpid(cc, ra->Msg3_frame, ra->Msg3_subframe); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(10, ra->msg3_nb_rb); + ul_req_body->number_of_pdus++; + ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + + // save UL scheduling information for preprocessor + for (j = 0; j < ra->msg3_nb_rb; j++) + cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; + + LOG_D(MAC, "MSG3: UL_CONFIG SFN/SF:%d number_of_pdus:%d ra->msg3_round:%d\n", NFAPI_SFNSF2DEC(ul_req->sfn_sf), ul_req_body->number_of_pdus, ra->msg3_round); + + if (ra->msg3_round != 0) { // program HI too + sf_ahead_dl = ul_subframe2_k_phich(cc, subframeP); + hi_dci0_req = &mac->HI_DCI0_req[CC_id][(subframeP+sf_ahead_dl)%10]; + hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; + hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + memset((void *) hi_dci0_pdu, 0, + sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = ra->msg3_first_rb; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; + hi_dci0_req_body->number_of_hi++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + + if (NFAPI_MODE != NFAPI_MONOLITHIC) { + oai_nfapi_hi_dci0_req(hi_dci0_req); + hi_dci0_req_body->number_of_hi=0; + } -void -generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, - sub_frame_t subframeP, RA_t * ra) -{ + LOG_D(MAC, "MSG3: HI_DCI0 SFN/SF:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req_body->number_of_dci, hi_dci0_req_body->number_of_hi); + // save UL scheduling information for preprocessor + for (j = 0; j < ra->msg3_nb_rb; j++) + cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; + LOG_D(MAC, + "[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA (mcs %d, first rb %d, nb_rb %d,round %d)\n", + module_idP, ra->rnti, CC_id, frameP, subframeP, 10, 1, 1, + ra->msg3_round - 1); + } // if (ra->msg3_round != 0) { // program HI too + } // non-BL/CE UE case +} + +//------------------------------------------------------------------------------ +/* + * Generate the RAR (message2) + */ +void generate_Msg2(module_id_t module_idP, + int CC_idP, + frame_t frameP, + sub_frame_t subframeP, + RA_t *ra) +//------------------------------------------------------------------------------ +{ eNB_MAC_INST *mac = RC.mac[module_idP]; COMMON_channels_t *cc = mac->common_channels; - - uint8_t *vrb_map; - int first_rb; - int N_RB_DL; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; - nfapi_dl_config_request_body_t *dl_req_body; - + uint8_t *vrb_map = NULL; + int first_rb = 0; + int N_RB_DL = 0; + nfapi_dl_config_request_pdu_t *dl_config_pdu = NULL; + nfapi_tx_request_pdu_t *TX_req = NULL; + nfapi_dl_config_request_body_t *dl_req_body = NULL; vrb_map = cc[CC_idP].vrb_map; dl_req_body = &mac->DL_req[CC_idP].dl_config_request_body; dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int rmax = 0; int rep = 0; int reps = 0; int num_nb = 0; - first_rb = 0; - struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach; - LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = NULL; + LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL; LTE_PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL }; - uint16_t absSF = (10 * frameP) + subframeP; uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe; - if (absSF > absSF_Msg2) - return; // we're not ready yet, need to be to start == - - if (cc[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0 && - cc[CC_idP].radioResourceConfigCommon_BR) { + if (absSF > absSF_Msg2) { + return; // we're not ready yet + } + if (cc[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0 && cc[CC_idP].radioResourceConfigCommon_BR) { ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; switch (prach_ParametersListCE_r13->list.count) { - case 4: - p[3] = prach_ParametersListCE_r13->list.array[3]; - case 3: - p[2] = prach_ParametersListCE_r13->list.array[2]; - case 2: - p[1] = prach_ParametersListCE_r13->list.array[1]; - case 1: - p[0] = prach_ParametersListCE_r13->list.array[0]; - break; - default: - AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", (int) prach_ParametersListCE_r13->list.count); - break; + case 4: + p[3] = prach_ParametersListCE_r13->list.array[3]; + + case 3: + p[2] = prach_ParametersListCE_r13->list.array[2]; + + case 2: + p[1] = prach_ParametersListCE_r13->list.array[1]; + + case 1: + p[0] = prach_ParametersListCE_r13->list.array[0]; + break; + default: + AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", (int) prach_ParametersListCE_r13->list.count); + break; } } if (ra->rach_resource_type > 0) { - - // This uses an MPDCCH Type 2 common allocation according to Section 9.1.5 36-213 - // Parameters: - // p=2+4 PRB set (number of PRB pairs 3) - // rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3 - // if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates - // if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates - // distributed transmission - - // rmax from SIB2 information - AssertFatal (rmax < 9, "rmax>8!\n"); + /* This uses an MPDCCH Type 2 common allocation according to Section 9.1.5 36-213 + * Parameters: + * p = 2 + 4 PRB set (number of PRB pairs 3) + * rmax = mpdcch-NumRepetition-RA-r13 => Table 9.1.5-3 + * if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates + * if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates + * distributed transmission + */ + /* rmax from SIB2 information */ + AssertFatal (rmax < 9, "rmax > 8!\n"); // not sure of this assertion rmax = 1 << p[ra->rach_resource_type - 1]->mpdcch_NumRepetition_RA_r13; - // choose r1 by default for RAR (Table 9.1.5-5) + /* Choose r1 by default for RAR (Table 9.1.5-5) */ rep = 0; - // get actual repetition count from Table 9.1.5-3 + /* Get actual repetition count from Table 9.1.5-3 */ reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep)); - // get narrowband according to higher-layer config + /* Get narrowband according to higher-layer config */ num_nb = p[ra->rach_resource_type - 1]->mpdcch_NarrowbandsToMonitor_r13.list.count; - ra->msg2_narrowband = *p[ra->rach_resource_type - 1]->mpdcch_NarrowbandsToMonitor_r13.list.array[ra->preamble_index % num_nb]-1; - first_rb = narrowband_to_first_rb (&cc[CC_idP], ra->msg2_narrowband); + ra->msg2_narrowband = *p[ra->rach_resource_type - 1]->mpdcch_NarrowbandsToMonitor_r13.list.array[ra->preamble_index % num_nb] - 1; + first_rb = narrowband_to_first_rb(&cc[CC_idP], ra->msg2_narrowband); - if ((ra->msg2_mpdcch_repetition_cnt == 0) && (mpdcch_sf_condition (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) { + if ((ra->msg2_mpdcch_repetition_cnt == 0) && (mpdcch_sf_condition(mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) { ra->msg2_mpdcch_done = 0; - // MPDCCH configuration for RAR - LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2 for CE Level %d, Programming MPDCCH %d repetitions\n", module_idP, frameP, subframeP, ra->rach_resource_type-1,reps); - - + /* MPDCCH configuration for RAR */ + LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2 for CE Level %d, Programming MPDCCH %d repetitions\n", + module_idP, + frameP, + subframeP, + ra->rach_resource_type - 1, + reps); memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); @@ -335,9 +326,12 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = ra->msg2_narrowband; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + + LOG_E(MAC, "start_symbol = %d \n", dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 2; // RA-RNTI @@ -346,7 +340,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_idP].physCellId; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | (ra->msg2_narrowband<<5); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6) | (ra->msg2_narrowband<<5); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 0; // adjust according to size of RAR, 208 bits with N1A_PRB=3 dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 0; // fix to 4 for now dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; @@ -376,36 +370,44 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, ra->msg2_mpdcch_repetition_cnt++; dl_req_body->number_pdu++; ra->Msg2_subframe = (ra->Msg2_subframe + 9) % 10; + } // repetition_count == 0 && SF condition met - } //repetition_count==0 && SF condition met if (ra->msg2_mpdcch_repetition_cnt > 0) { // we're in a stream of repetitions + if ((ra->msg2_mpdcch_repetition_cnt == reps) && (ra->msg2_mpdcch_done == 0)) { // this is the last mpdcch repetition + ra->msg2_mpdcch_done = 1; - - if ((ra->msg2_mpdcch_repetition_cnt == reps)&& - (ra->msg2_mpdcch_done == 0)){ // this is the last mpdcch repetition - ra->msg2_mpdcch_done = 1; if (cc[CC_idP].tdd_Config == NULL) { // FDD case // wait 2 subframes for PDSCH transmission if (subframeP > 7) ra->Msg2_frame = (frameP + 1) & 1023; else ra->Msg2_frame = frameP; + ra->Msg2_subframe = (subframeP + 2) % 10; // +2 is the "n+x" from Section 7.1.11 in 36.213 - LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, programmed Msg2 for %d.%d\n", module_idP, frameP, subframeP, ra->Msg2_frame,ra->Msg2_subframe); + LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, programmed Msg2 for %d.%d\n", + module_idP, + frameP, + subframeP, + ra->Msg2_frame, + ra->Msg2_subframe); } else { - AssertFatal (1 == 0, "TDD case not done yet\n"); + AssertFatal(1 == 0, "TDD case not done yet\n"); } - } // mpdcch_repetition_count == reps - else if (ra->msg2_mpdcch_done == 0) { - LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, MPDCCH repetition %d\n", module_idP, frameP, subframeP, ra->msg2_mpdcch_repetition_cnt); + } else if (ra->msg2_mpdcch_done == 0) { // mpdcch_repetition_count != reps + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, MPDCCH repetition %d\n", + module_idP, + frameP, + subframeP, + ra->msg2_mpdcch_repetition_cnt); ra->msg2_mpdcch_repetition_cnt++; } - - if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) { - // Program PDSCH - LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n", module_idP, frameP, subframeP); - + if((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) { + /* Program PDSCH */ + LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n", + module_idP, + frameP, + subframeP); dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; @@ -414,8 +416,8 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV (N_RB_DL, first_rb, 6); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; // QPSK dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; @@ -427,31 +429,32 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc[CC_idP].mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc[CC_idP].mib->message.dl_Bandwidth); // ignored dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_idP].p_eNB == 1) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - - // Rel10 fields + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + /* Rel10 fields */ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; - // Rel13 fields + /* Rel13 fields */ dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; dl_req_body->number_pdu++; - - fill_rar_br (mac, CC_idP, ra, frameP, subframeP, cc[CC_idP].RAR_pdu.payload, ra->rach_resource_type - 1) ; -// Program UL processing for Msg3, same as regular LTE + fill_rar_br(mac, CC_idP, ra, frameP, subframeP, cc[CC_idP].RAR_pdu.payload, ra->rach_resource_type - 1); + /* Program UL processing for Msg3, same as regular LTE */ get_Msg3alloc (&cc[CC_idP], subframeP, frameP, &ra->Msg3_frame, &ra->Msg3_subframe); add_msg3 (module_idP, CC_idP, ra, frameP, subframeP); - ra->state = WAITMSG3; - // DL request - LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming TX Req\n", module_idP, frameP, subframeP); + ra->state = WAITMSG3; + /* DL request */ + LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming TX Req\n", + module_idP, + frameP, + subframeP); mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus]; - TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble + TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble TX_req->pdu_index = mac->pdu_index[CC_idP]++; TX_req->num_segments = 1; TX_req->segments[0].segment_length = 7; @@ -459,243 +462,226 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, mac->TX_req[CC_idP].tx_request_body.number_of_pdus++; } } - } else - #endif - { + { + if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) { + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, state %d\n", + module_idP, CC_idP, frameP, subframeP, ra->state); + // Allocate 4 PRBS starting in RB 0 + first_rb = 0; + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = ra->RA_rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + + // This checks if the above DCI allocation is feasible in current subframe + if (!CCE_allocation_infeasible(module_idP, CC_idP, 0, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->RA_rnti)) { + LOG_D(MAC, + "Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n", + frameP, subframeP, ra->RA_rnti); + dl_req_body->number_dci++; + dl_req_body->number_pdu++; + dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req_body->number_pdu++; + mac->DL_req[CC_idP].sfn_sf = frameP<<4 | subframeP; + // Program UL processing for Msg3 + get_Msg3alloc(&cc[CC_idP], subframeP, frameP,&ra->Msg3_frame, &ra->Msg3_subframe); + LOG_D(MAC, + "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", + frameP, subframeP, ra->Msg3_frame, + ra->Msg3_subframe); + fill_rar(module_idP, CC_idP, ra, frameP, cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7); + add_msg3(module_idP, CC_idP, ra, frameP, subframeP); + ra->state = WAITMSG3; + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP); + T(T_ENB_MAC_UE_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), + T_INT(CC_idP), T_INT(ra->RA_rnti), T_INT(frameP), + T_INT(subframeP), T_INT(0 /*harq_pid always 0? */ ), + T_BUFFER(cc[CC_idP].RAR_pdu.payload, 7)); + // DL request + mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; + TX_req = + &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus]; + TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble + TX_req->pdu_index = mac->pdu_index[CC_idP]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = 7; + TX_req->segments[0].segment_data = + cc[CC_idP].RAR_pdu.payload; + mac->TX_req[CC_idP].tx_request_body.number_of_pdus++; - if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, state %d\n", - module_idP, CC_idP, frameP, subframeP, ra->state); - - // Allocate 4 PRBS starting in RB 0 - first_rb = 0; - vrb_map[first_rb] = 1; - vrb_map[first_rb + 1] = 1; - vrb_map[first_rb + 2] = 1; - vrb_map[first_rb + 3] = 1; - - memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = ra->RA_rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); - - // This checks if the above DCI allocation is feasible in current subframe - if (!CCE_allocation_infeasible(module_idP, CC_idP, 0, subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->RA_rnti)) { - LOG_D(MAC, - "Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n", - frameP, subframeP, ra->RA_rnti); - dl_req_body->number_dci++; - dl_req_body->number_pdu++; - - dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; - memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - dl_req_body->number_pdu++; - mac->DL_req[CC_idP].sfn_sf = frameP<<4 | subframeP; - - // Program UL processing for Msg3 - get_Msg3alloc(&cc[CC_idP], subframeP, frameP,&ra->Msg3_frame, &ra->Msg3_subframe); - - LOG_D(MAC, - "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", - frameP, subframeP, ra->Msg3_frame, - ra->Msg3_subframe); - - fill_rar(module_idP, CC_idP, ra, frameP, cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7); - add_msg3(module_idP, CC_idP, ra, frameP, subframeP); - ra->state = WAITMSG3; - LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP); - - T(T_ENB_MAC_UE_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), - T_INT(CC_idP), T_INT(ra->RA_rnti), T_INT(frameP), - T_INT(subframeP), T_INT(0 /*harq_pid always 0? */ ), - T_BUFFER(cc[CC_idP].RAR_pdu.payload, 7)); - - // DL request - mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; - TX_req = - &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus]; - TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble - TX_req->pdu_index = mac->pdu_index[CC_idP]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = 7; - TX_req->segments[0].segment_data = - cc[CC_idP].RAR_pdu.payload; - mac->TX_req[CC_idP].tx_request_body.number_of_pdus++; - if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ - set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti); - } - } // PDCCH CCE allocation is feasible - } // Msg2 frame/subframe condition - } // else BL/CE + if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR) { + set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti); + } + } // PDCCH CCE allocation is feasible + } // Msg2 frame/subframe condition + } // else BL/CE } + +//------------------------------------------------------------------------------ +/* + * Generate message 4 of RA procedure (RRC connection setup) + */ void -generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, - sub_frame_t subframeP, RA_t * ra) +generate_Msg4(module_id_t module_idP, + int CC_idP, + frame_t frameP, + sub_frame_t subframeP, + RA_t *ra) +//------------------------------------------------------------------------------ { - - eNB_MAC_INST *mac = RC.mac[module_idP]; COMMON_channels_t *cc = mac->common_channels; - int16_t rrc_sdu_length; + UE_list_t *UE_list = &(mac->UE_list); + int16_t rrc_sdu_length = 0; + uint16_t msg4_padding = 0; + uint16_t msg4_post_padding = 0; + uint16_t msg4_header = 0; int UE_id = -1; - uint16_t msg4_padding; - uint16_t msg4_post_padding; - uint16_t msg4_header; - - uint8_t *vrb_map; - int first_rb; - int N_RB_DL; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_ul_config_request_pdu_t *ul_config_pdu; - nfapi_tx_request_pdu_t *TX_req; - UE_list_t *UE_list=&mac->UE_list; - nfapi_dl_config_request_t *dl_req; - nfapi_dl_config_request_body_t *dl_req_body; - nfapi_ul_config_request_body_t *ul_req_body; - uint8_t lcid; - uint8_t offset; - - - + int first_rb = 0; + int N_RB_DL = 0; + uint8_t lcid = 0; + uint8_t offset = 0; + uint8_t *vrb_map = NULL; + nfapi_dl_config_request_pdu_t *dl_config_pdu = NULL; + nfapi_ul_config_request_pdu_t *ul_config_pdu = NULL; + nfapi_tx_request_pdu_t *TX_req = NULL; + nfapi_dl_config_request_t *dl_req = NULL; + nfapi_dl_config_request_body_t *dl_req_body = NULL; + nfapi_ul_config_request_body_t *ul_req_body = NULL; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int rmax = 0; int rep = 0; int reps = 0; - - first_rb = 0; - struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach; - struct LTE_PUCCH_ConfigCommon_v1310 *ext4_pucch; - LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; - struct LTE_N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13; + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = NULL; + struct LTE_PUCCH_ConfigCommon_v1310 *ext4_pucch = NULL; + LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL; + struct LTE_N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13 = NULL; LTE_PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL }; int pucchreps[4] = { 1, 1, 1, 1 }; int n1pucchan[4] = { 0, 0, 0, 0 }; - if (cc[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0 && - cc[CC_idP].radioResourceConfigCommon_BR) { - + if (cc[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0 && cc[CC_idP].radioResourceConfigCommon_BR) { ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; - ext4_pucch = cc[CC_idP].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310; prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; + ext4_pucch = cc[CC_idP].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310; pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13; AssertFatal (prach_ParametersListCE_r13 != NULL, "prach_ParametersListCE_r13 is null\n"); AssertFatal (pucch_N1PUCCH_AN_InfoList_r13 != NULL, "pucch_N1PUCCH_AN_InfoList_r13 is null\n"); - // check to verify CE-Level compatibility in SIB2_BR + /* Check to verify CE-Level compatibility in SIB2_BR */ AssertFatal (prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count, "prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n"); switch (prach_ParametersListCE_r13->list.count) { - case 4: - p[3] = prach_ParametersListCE_r13->list.array[3]; - n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3]; - AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n"); - pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13); - - case 3: - p[2] = prach_ParametersListCE_r13->list.array[2]; - n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2]; - AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n"); - pucchreps[2] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13); - case 2: - p[1] = prach_ParametersListCE_r13->list.array[1]; - n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1]; - AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n"); - pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13); - case 1: - p[0] = prach_ParametersListCE_r13->list.array[0]; - n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0]; - AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n"); - pucchreps[0] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13); - break; - default: - AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", prach_ParametersListCE_r13->list.count); - + case 4: + p[3] = prach_ParametersListCE_r13->list.array[3]; + n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3]; + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n"); + pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13); + + case 3: + p[2] = prach_ParametersListCE_r13->list.array[2]; + n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2]; + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n"); + pucchreps[2] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13); + + case 2: + p[1] = prach_ParametersListCE_r13->list.array[1]; + n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1]; + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n"); + pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13); + + case 1: + p[0] = prach_ParametersListCE_r13->list.array[0]; + n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0]; + AssertFatal(ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n"); + pucchreps[0] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13); + break; + + default: + AssertFatal(1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", prach_ParametersListCE_r13->list.count); } } #endif + vrb_map = cc[CC_idP].vrb_map; + dl_req = &mac->DL_req[CC_idP]; + dl_req_body = &dl_req->dl_config_request_body; + dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; + N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); + UE_id = find_UE_id(module_idP, ra->rnti); + if (UE_id < 0) { + LOG_E(MAC, "Can't find UE for t-crnti %x, kill RA procedure for this UE\n", + ra->rnti); + cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti); + return; + } - vrb_map = cc[CC_idP].vrb_map; - - dl_req = &mac->DL_req[CC_idP]; - dl_req_body = &dl_req->dl_config_request_body; - dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; - N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); - - UE_id = find_UE_id(module_idP, ra->rnti); - if (UE_id < 0) { - LOG_E(MAC,"Can't find UE for t-crnti %x, kill RA procedure for this UE\n",ra->rnti); - cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti); - return; - } - - // set HARQ process round to 0 for this UE - - ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - - /* // Get RRCConnectionSetup for Piggyback - rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block - &cc[CC_idP].CCCH_pdu.payload[0], 0); // not used in this case - if(rrc_sdu_length <= 0) { - LOG_D(MAC,"[MAC][eNB Scheduler] CCCH not allocated (%d)\n",rrc_sdu_length); - return; - } - //AssertFatal(rrc_sdu_length > 0, - //"[MAC][eNB Scheduler] CCCH not allocated\n"); - - - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n", - module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length);*/ - - + // set HARQ process round to 0 for this UE + ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); + /* // Get RRCConnectionSetup for Piggyback + rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block + &cc[CC_idP].CCCH_pdu.payload[0], 0); // not used in this case + if(rrc_sdu_length <= 0) { + LOG_D(MAC,"[MAC][eNB Scheduler] CCCH not allocated (%d)\n",rrc_sdu_length); + return; + } + //AssertFatal(rrc_sdu_length > 0, + //"[MAC][eNB Scheduler] CCCH not allocated\n"); + + + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n", + module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length);*/ #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (ra->rach_resource_type > 0) { + if (ra->rach_resource_type > 0) { ra->harq_pid = 0; // Generate DCI + repetitions first // This uses an MPDCCH Type 2 allocation according to Section 9.1.5 36-213, Type2 common allocation according to Table 7.1-8 (36-213) @@ -705,11 +691,8 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, // if CELevel = 0,1 => Table 9.1.5-1b for MPDCCH candidates // if CELevel = 2,3 => Table 9.1.5-2b for MPDCCH candidates // distributed transmission - // rmax from SIB2 information rmax = 1<<p[ra->rach_resource_type - 1]->mpdcch_NumRepetition_RA_r13; - - // choose r3 by default for Msg4 (this is ok from table 9.1.5-3 for rmax = >=4, if we choose rmax <4 it has to be less rep = 0; // get actual repetition count from Table 9.1.5-3 @@ -719,14 +702,12 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, if ((ra->msg4_mpdcch_repetition_cnt == 0) && (mpdcch_sf_condition (mac, CC_idP, frameP, subframeP, rmax, TYPE2, -1) > 0)) { // Get RRCConnectionSetup for Piggyback - ra->msg4_rrc_sdu_length = mac_rrc_data_req (module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block - &cc[CC_idP].CCCH_pdu.payload[0], 0); // not used in this case - + ra->msg4_rrc_sdu_length = mac_rrc_data_req (module_idP, CC_idP, frameP, CCCH, + UE_RNTI(module_idP, UE_id), 1, // 1 transport block + &cc[CC_idP].CCCH_pdu.payload[0], 0); // not used in this case AssertFatal (ra->msg4_rrc_sdu_length > 0, "[MAC][eNB Scheduler] CCCH not allocated\n"); - - - LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d, dl_req->num_pdu %d\n", module_idP, CC_idP, frameP, subframeP, UE_id, ra->msg4_rrc_sdu_length,dl_req_body->number_pdu); - + LOG_D (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d, dl_req->num_pdu %d\n", module_idP, CC_idP, frameP, subframeP, UE_id, ra->msg4_rrc_sdu_length, + dl_req_body->number_pdu); // MPDCCH configuration for Msg4 ra->msg4_mpdcch_done=0; memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); @@ -736,7 +717,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = ra->msg2_narrowband; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic @@ -774,44 +755,41 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; - ra->msg4_mpdcch_repetition_cnt++; dl_req_body->number_pdu++; ra->msg4_TBsize = get_TBS_DL(dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs, - 6); + 6); } //repetition_count==0 && SF condition met - + if ((ra->msg4_mpdcch_repetition_cnt > 0)&& - (ra->msg4_mpdcch_done==0)) { // we're in a stream of repetitions - LOG_I(MAC,"SFN.SF %d.%d : msg4 mpdcch repetition number %d/%d\n", - frameP,subframeP,ra->msg4_mpdcch_repetition_cnt,reps); + (ra->msg4_mpdcch_done==0)) { // we're in a stream of repetitions + LOG_D(MAC,"SFN.SF %d.%d : msg4 mpdcch repetition number %d/%d\n", + frameP,subframeP,ra->msg4_mpdcch_repetition_cnt,reps); + if (ra->msg4_mpdcch_repetition_cnt == reps) { // this is the last mpdcch repetition ra->msg4_mpdcch_done = 1; - if (cc[CC_idP].tdd_Config == NULL) { // FDD case + + if (cc[CC_idP].tdd_Config == NULL) { // FDD case // wait 2 subframes for PDSCH transmission if (subframeP > 7) ra->Msg4_frame = (frameP + 1) & 1023; else ra->Msg4_frame = frameP; + ra->Msg4_subframe = (subframeP + 2) % 10; - LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Set Msg4 PDSCH in %d.%d\n", - module_idP, CC_idP, frameP, subframeP, ra->Msg4_frame,ra->Msg4_subframe); + LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Set Msg4 PDSCH in %d.%d\n", + module_idP, CC_idP, frameP, subframeP, ra->Msg4_frame,ra->Msg4_subframe); } else { AssertFatal (1 == 0, "TDD case not done yet\n"); } - } - else if (ra->msg4_mpdcch_done==0) - ra->msg4_mpdcch_repetition_cnt++; + } else if (ra->msg4_mpdcch_done==0) + ra->msg4_mpdcch_repetition_cnt++; } -// mpdcch_repetition_count == reps + // mpdcch_repetition_count == reps else if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) { - // Program PDSCH - - LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (ce_level %d RNTI %x)\n", - module_idP, CC_idP, frameP, subframeP, ra->rach_resource_type - 1, ra->rnti); - - + LOG_D (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 BR with RRC Piggyback (ce_level %d RNTI %x)\n", + module_idP, CC_idP, frameP, subframeP, ra->rach_resource_type - 1, ra->rnti); dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; @@ -837,48 +815,41 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_idP].p_eNB == 1) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; dl_req_body->number_pdu++; - - ra->state = WAITMSG4ACK; - lcid = 0; - UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0; msg4_header = 1 + 6 + 1; // CR header, CR CE, SDU header AssertFatal((ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header)>=0, - "msg4_TBS %d is too small, change mcs to increase by %d bytes\n",ra->msg4_TBsize,ra->msg4_rrc_sdu_length+msg4_header-ra->msg4_TBsize); + "msg4_TBS %d is too small, change mcs to increase by %d bytes\n",ra->msg4_TBsize,ra->msg4_rrc_sdu_length+msg4_header-ra->msg4_TBsize); + if ((ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header; - msg4_post_padding = 0; + msg4_padding = ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header; + msg4_post_padding = 0; } else { - msg4_padding = 0; - msg4_post_padding = ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header - 1; + msg4_padding = 0; + msg4_post_padding = ra->msg4_TBsize - ra->msg4_rrc_sdu_length - msg4_header - 1; } - - LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", - module_idP, CC_idP, frameP, subframeP, ra->msg4_TBsize, ra->msg4_rrc_sdu_length, msg4_header, msg4_padding, msg4_post_padding); + + LOG_D (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", + module_idP, CC_idP, frameP, subframeP, ra->msg4_TBsize, ra->msg4_rrc_sdu_length, msg4_header, msg4_padding, msg4_post_padding); DevAssert (UE_id != UE_INDEX_INVALID); // FIXME not sure how to gracefully return // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0] offset = generate_dlsch_header ((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], 1, //num_sdus - (unsigned short *) &ra->msg4_rrc_sdu_length, // - &lcid, // sdu_lcid - 255, // no drx - 31, // no timing advance - ra->cont_res_id, // contention res id - msg4_padding, // no padding - msg4_post_padding); - + (unsigned short *) &ra->msg4_rrc_sdu_length, // + &lcid, // sdu_lcid + 255, // no drx + 31, // no timing advance + ra->cont_res_id, // contention res id + msg4_padding, // no padding + msg4_post_padding); memcpy ((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0][(unsigned char) offset], &cc[CC_idP].CCCH_pdu.payload[0], ra->msg4_rrc_sdu_length); - // DL request mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus]; @@ -888,7 +859,6 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, TX_req->segments[0].segment_length = ra->msg4_TBsize; TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0]; mac->TX_req[CC_idP].tx_request_body.number_of_pdus++; - // Program ACK/NAK for Msg4 PDSCH int absSF = (frameP * 10) + subframeP; // see Section 10.2 from 36.213 @@ -896,7 +866,6 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, AssertFatal (reps == 1, "Have to handle programming of ACK when PDSCH repetitions is > 1\n"); ul_req_body = &mac->UL_req_tmp[CC_idP][ackNAK_absSF % 10].ul_config_request_body; ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_uci_harq_pdu)); ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this @@ -905,650 +874,614 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[ra->rach_resource_type - 1]; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number = 0; + // Note need to keep sending this across reptitions!!!! Not really for PUCCH, to ask small-cell forum, we'll see for the other messages, maybe parameters change across repetitions and FAPI has to provide for that if (cc[CC_idP].tdd_Config == NULL) { // FDD case - ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = n1pucchan[ra->rach_resource_type - 1]; - // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case - // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level] - // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 => - // Delta_ARO = 0 from Table 10.1.2.1-1 - ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK - ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.number_of_pucch_resources = 1; + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = n1pucchan[ra->rach_resource_type - 1]; + // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case + // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level] + // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 => + // Delta_ARO = 0 from Table 10.1.2.1-1 + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.number_of_pucch_resources = 1; } else { - AssertFatal (1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n"); + AssertFatal (1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n"); } + ul_req_body->number_of_pdus++; T (T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT (module_idP), T_INT (CC_idP), T_INT (ra->rnti), T_INT (frameP), T_INT (subframeP), - T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], ra->msg4_TBsize)); - + T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id].payload[0], ra->msg4_TBsize)); + if (opt_enabled == 1) { - trace_pdu (1, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], ra->msg4_rrc_sdu_length, UE_id, 3, UE_RNTI (module_idP, UE_id), mac->frame, mac->subframe, 0, 0); - LOG_D (OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", module_idP, CC_idP, frameP, UE_RNTI (module_idP, UE_id), ra->msg4_rrc_sdu_length); + trace_pdu (1, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], ra->msg4_rrc_sdu_length, UE_id, 3, UE_RNTI (module_idP, UE_id), mac->frame, mac->subframe, 0, 0); + LOG_D (OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", module_idP, CC_idP, frameP, UE_RNTI (module_idP, UE_id), ra->msg4_rrc_sdu_length); } - } // Msg4 frame/subframe - } // rach_resource_type > 0 + } // Msg4 frame/subframe + } // rach_resource_type > 0 else #endif - { + { // This is normal LTE case - LOG_D(MAC, "generate_Msg4 1 ra->Msg4_frame SFN/SF: %d.%d, frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP); - if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) { - - // Get RRCConnectionSetup for Piggyback - /*rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block - &cc[CC_idP].CCCH_pdu.payload[0], ENB_FLAG_YES, module_idP, 0); // not used in this case*/ - - rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block - &cc[CC_idP].CCCH_pdu.payload[0], 0); // not used in this case - - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n", - module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length); - - AssertFatal(rrc_sdu_length > 0, - "[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length); - - - - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n", - module_idP, CC_idP, frameP, subframeP, ra->rnti); - - /// Choose first 4 RBs for Msg4, should really check that these are free! - first_rb = 0; - - vrb_map[first_rb] = 1; - vrb_map[first_rb + 1] = 1; - vrb_map[first_rb + 2] = 1; - vrb_map[first_rb + 3] = 1; - - - // Compute MCS/TBS for 3 PRB (coded on 4 vrb) - msg4_header = 1 + 6 + 1; // CR header, CR CE, SDU header - - if ((rrc_sdu_length + msg4_header) <= 22) { - ra->msg4_mcs = 4; - ra->msg4_TBsize = 22; - } else if ((rrc_sdu_length + msg4_header) <= 28) { - ra->msg4_mcs = 5; - ra->msg4_TBsize = 28; - } else if ((rrc_sdu_length + msg4_header) <= 32) { - ra->msg4_mcs = 6; - ra->msg4_TBsize = 32; - } else if ((rrc_sdu_length + msg4_header) <= 41) { - ra->msg4_mcs = 7; - ra->msg4_TBsize = 41; - } else if ((rrc_sdu_length + msg4_header) <= 49) { - ra->msg4_mcs = 8; - ra->msg4_TBsize = 49; - } else if ((rrc_sdu_length + msg4_header) <= 57) { - ra->msg4_mcs = 9; - ra->msg4_TBsize = 57; - } - - fill_nfapi_dl_dci_1A(dl_config_pdu, 4, // aggregation_level - ra->rnti, // rnti - 1, // rnti_type, CRNTI - ra->harq_pid, // harq_process - 1, // tpc, none - getRIV(N_RB_DL, first_rb, 4), // resource_block_coding - ra->msg4_mcs, // mcs - 1, // ndi - 0, // rv - 0); // vrb_flag - - LOG_D(MAC, - "Frame %d, subframe %d: Msg4 DCI pdu_num %d (rnti %x,rnti_type %d,harq_pid %d, resource_block_coding (%p) %d\n", - frameP, subframeP, dl_req_body->number_pdu, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process, - &dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding); - AssertFatal(dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_block_coding < 8192, - "resource_block_coding %u < 8192\n", - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.resource_block_coding); - if (!CCE_allocation_infeasible(module_idP, CC_idP, 1, subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->rnti)) { - dl_req_body->number_dci++; - dl_req_body->number_pdu++; - - ra->state = WAITMSG4ACK; - LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG4ACK\n", module_idP, frameP, subframeP); - - // increment Absolute subframe by 8 for Msg4 retransmission - LOG_D(MAC, - "Frame %d, Subframe %d: Preparing for Msg4 retransmission currently %d.%d\n", - frameP, subframeP, ra->Msg4_frame, - ra->Msg4_subframe); - get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe); - - LOG_D(MAC, - "Frame %d, Subframe %d: Msg4 retransmission in %d.%d\n", - frameP, subframeP, ra->Msg4_frame, - ra->Msg4_subframe); - lcid = 0; - - // put HARQ process round to 0 - ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0; - - if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { - msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header; - msg4_post_padding = 0; - } else { - msg4_padding = 0; - msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1; - } - - LOG_D(MAC, - "[eNB %d][RAPROC] CC_idP %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", - module_idP, CC_idP, frameP, subframeP, - ra->msg4_TBsize, rrc_sdu_length, msg4_header, - msg4_padding, msg4_post_padding); - DevAssert(UE_id != UE_INDEX_INVALID); // FIXME not sure how to gracefully return - // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0] - offset = generate_dlsch_header((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], 1, //num_sdus - (unsigned short *) &rrc_sdu_length, // - &lcid, // sdu_lcid - 255, // no drx - 31, // no timing advance - ra->cont_res_id, // contention res id - msg4_padding, // no padding - msg4_post_padding); - - memcpy((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], - &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length); - - // DLSCH Config - fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize, mac->pdu_index[CC_idP], ra->rnti, 2, // resource_allocation_type : format 1A/1B/1D - 0, // virtual_resource_block_assignment_flag : localized - getRIV(N_RB_DL, first_rb, 4), // resource_block_coding : RIV, 4 PRB - 2, // modulation: QPSK - 0, // redundancy version - 1, // transport_blocks - 0, // transport_block_to_codeword_swap_flag (0) - (cc->p_eNB == 1) ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - //0, // codebook index - 1, // ue_category_capacity - 4, // pa: 0 dB - 0, // delta_power_offset_index - 0, // ngap - 1, // NPRB = 3 like in DCI - (cc->p_eNB == 1) ? 1 : 2, // transmission mode - 1, // num_bf_prb_per_subband - 1); // num_bf_vector - LOG_D(MAC, - "Filled DLSCH config, pdu number %d, non-dci pdu_index %d\n", - dl_req_body->number_pdu, mac->pdu_index[CC_idP]); - - // Tx request - mac->TX_req[CC_idP].sfn_sf = - fill_nfapi_tx_req(&mac->TX_req[CC_idP].tx_request_body, - (frameP * 10) + subframeP, - rrc_sdu_length, - mac->pdu_index[CC_idP], - mac->UE_list. - DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); - mac->pdu_index[CC_idP]++; - - dl_req->sfn_sf = mac->TX_req[CC_idP].sfn_sf; - - LOG_D(MAC, "Filling UCI ACK/NAK information, cce_idx %d\n", - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); - // Program PUCCH1a for ACK/NAK - // Program ACK/NAK for Msg4 PDSCH - fill_nfapi_uci_acknak(module_idP, - CC_idP, - ra->rnti, - (frameP * 10) + subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); - - - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), - T_INT(CC_idP), T_INT(ra->rnti), T_INT(frameP), - T_INT(subframeP), T_INT(0 /*harq_pid always 0? */ ), - T_BUFFER(&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id]. - payload[0], ra->msg4_TBsize)); - - if (opt_enabled == 1) { - trace_pdu(DIRECTION_DOWNLINK, - (uint8_t *) mac-> - UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], - rrc_sdu_length, UE_id, WS_C_RNTI, - UE_RNTI(module_idP, UE_id), mac->frame, - mac->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", - module_idP, CC_idP, frameP, UE_RNTI(module_idP, - UE_id), - rrc_sdu_length); - } - if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ - set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); - } - } // CCE Allocation feasible - } // msg4 frame/subframe - } // else rach_resource_type + LOG_I(MAC, "generate_Msg4 ra->Msg4_frame SFN/SF: %d.%d, frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP); + + if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) { + // Get RRCConnectionSetup for Piggyback + /*rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block + &cc[CC_idP].CCCH_pdu.payload[0], ENB_FLAG_YES, module_idP, 0); // not used in this case*/ + // check if there's data on the CCCH to send with Msg4 + rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, + UE_RNTI(module_idP,UE_id),1, // 1 transport block + &cc[CC_idP].CCCH_pdu.payload[0], 0); // not used in this case + + if (rrc_sdu_length > 0) { + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: UE_id %d, rrc_sdu_length %d\n", + module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length); + // AssertFatal(rrc_sdu_length > 0, + // "[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length); + LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n", + module_idP, CC_idP, frameP, subframeP, ra->rnti); + /// Choose first 4 RBs for Msg4, should really check that these are free! + first_rb = 0; + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; + // Compute MCS/TBS for 3 PRB (coded on 4 vrb) + msg4_header = 1 + 6 + 1; // CR header, CR CE, SDU header + + if ((rrc_sdu_length + msg4_header) <= 22) { + ra->msg4_mcs = 4; + ra->msg4_TBsize = 22; + } else if ((rrc_sdu_length + msg4_header) <= 28) { + ra->msg4_mcs = 5; + ra->msg4_TBsize = 28; + } else if ((rrc_sdu_length + msg4_header) <= 32) { + ra->msg4_mcs = 6; + ra->msg4_TBsize = 32; + } else if ((rrc_sdu_length + msg4_header) <= 41) { + ra->msg4_mcs = 7; + ra->msg4_TBsize = 41; + } else if ((rrc_sdu_length + msg4_header) <= 49) { + ra->msg4_mcs = 8; + ra->msg4_TBsize = 49; + } else if ((rrc_sdu_length + msg4_header) <= 57) { + ra->msg4_mcs = 9; + ra->msg4_TBsize = 57; + } + + fill_nfapi_dl_dci_1A(dl_config_pdu, 4, // aggregation_level + ra->rnti, // rnti + 1, // rnti_type, CRNTI + ra->harq_pid, // harq_process + 1, // tpc, none + getRIV(N_RB_DL, first_rb, 4), // resource_block_coding + ra->msg4_mcs, // mcs + 1, // ndi + 0, // rv + 0); // vrb_flag + LOG_D(MAC, + "Frame %d, subframe %d: Msg4 DCI pdu_num %d (rnti %x,rnti_type %d,harq_pid %d, resource_block_coding (%p) %d\n", + frameP, subframeP, dl_req_body->number_pdu, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process, + &dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding); + AssertFatal(dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.resource_block_coding < 8192, + "resource_block_coding %u < 8192\n", + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.resource_block_coding); + + if (!CCE_allocation_infeasible(module_idP, CC_idP, 1, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->rnti)) { + dl_req_body->number_dci++; + dl_req_body->number_pdu++; + ra->state = WAITMSG4ACK; + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG4ACK\n", module_idP, frameP, subframeP); + // increment Absolute subframe by 8 for Msg4 retransmission + LOG_D(MAC, + "Frame %d, Subframe %d: Preparing for Msg4 retransmission currently %d.%d\n", + frameP, subframeP, ra->Msg4_frame, + ra->Msg4_subframe); + get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe); + LOG_D(MAC, + "Frame %d, Subframe %d: Msg4 retransmission in %d.%d\n", + frameP, subframeP, ra->Msg4_frame, + ra->Msg4_subframe); + lcid = 0; + // put HARQ process round to 0 + ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); + UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0; + + if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) { + msg4_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header; + msg4_post_padding = 0; + } else { + msg4_padding = 0; + msg4_post_padding = ra->msg4_TBsize - rrc_sdu_length - msg4_header - 1; + } + + LOG_D(MAC, + "[eNB %d][RAPROC] CC_idP %d Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", + module_idP, CC_idP, frameP, subframeP, + ra->msg4_TBsize, rrc_sdu_length, msg4_header, + msg4_padding, msg4_post_padding); + DevAssert(UE_id != UE_INDEX_INVALID); // FIXME not sure how to gracefully return + // CHECK THIS: &cc[CC_idP].CCCH_pdu.payload[0] + int num_sdus = rrc_sdu_length > 0 ? 1 : 0; + offset = generate_dlsch_header((unsigned char *) mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char) UE_id].payload[0], + num_sdus, //num_sdus + (unsigned short *) &rrc_sdu_length, // + &lcid, // sdu_lcid + 255, // no drx + 31, // no timing advance + ra->cont_res_id, // contention res id + msg4_padding, // no padding + msg4_post_padding); + memcpy((void *) &mac->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], + &cc[CC_idP].CCCH_pdu.payload[0], rrc_sdu_length); + // DLSCH Config + fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize, mac->pdu_index[CC_idP], ra->rnti, 2, // resource_allocation_type : format 1A/1B/1D + 0, // virtual_resource_block_assignment_flag : localized + getRIV(N_RB_DL, first_rb, 4), // resource_block_coding : RIV, 4 PRB + 2, // modulation: QPSK + 0, // redundancy version + 1, // transport_blocks + 0, // transport_block_to_codeword_swap_flag (0) + (cc->p_eNB == 1) ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + //0, // codebook index + 1, // ue_category_capacity + 4, // pa: 0 dB + 0, // delta_power_offset_index + 0, // ngap + 1, // NPRB = 3 like in DCI + (cc->p_eNB == 1) ? 1 : 2, // transmission mode + 1, // num_bf_prb_per_subband + 1); // num_bf_vector + LOG_D(MAC, + "Filled DLSCH config, pdu number %d, non-dci pdu_index %d\n", + dl_req_body->number_pdu, mac->pdu_index[CC_idP]); + // Tx request + mac->TX_req[CC_idP].sfn_sf = + fill_nfapi_tx_req(&mac->TX_req[CC_idP].tx_request_body, + (frameP * 10) + subframeP, + rrc_sdu_length, + mac->pdu_index[CC_idP], + mac->UE_list. + DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); + mac->pdu_index[CC_idP]++; + dl_req->sfn_sf = mac->TX_req[CC_idP].sfn_sf; + LOG_D(MAC, "Filling UCI ACK/NAK information, cce_idx %d\n", + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + // Program PUCCH1a for ACK/NAK + // Program ACK/NAK for Msg4 PDSCH + fill_nfapi_uci_acknak(module_idP, + CC_idP, + ra->rnti, + (frameP * 10) + subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), + T_INT(CC_idP), T_INT(ra->rnti), T_INT(frameP), + T_INT(subframeP), T_INT(0 /*harq_pid always 0? */ ), + T_BUFFER(&mac->UE_list.DLSCH_pdu[CC_idP][0][UE_id]. + payload[0], ra->msg4_TBsize)); + + if (opt_enabled == 1) { + trace_pdu(DIRECTION_DOWNLINK, + (uint8_t *) mac-> + UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0], + rrc_sdu_length, UE_id, WS_C_RNTI, + UE_RNTI(module_idP, UE_id), mac->frame, + mac->subframe, 0, 0); + LOG_D(OPT, + "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", + module_idP, CC_idP, frameP, UE_RNTI(module_idP, + UE_id), + rrc_sdu_length); + } + + if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR) { + set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); + } + } // CCE Allocation feasible + } else { + LOG_I(MAC, + "eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Delaying Msg4 for RRC Piggyback (RNTI %x)\n", + module_idP, CC_idP, frameP, subframeP, ra->rnti); + ra->Msg4_subframe ++; + ra->Msg4_delay_cnt++; + + if (ra->Msg4_delay_cnt==10) cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti); + + if (ra->Msg4_subframe == 10) { + ra->Msg4_frame++; + ra->Msg4_frame&=1023; + ra->Msg4_subframe = 0; + } + } + } // msg4 frame/subframe + } // else rach_resource_type } void check_Msg4_retransmission(module_id_t module_idP, int CC_idP, - frame_t frameP, sub_frame_t subframeP, RA_t * ra) -{ - - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc = mac->common_channels; - int UE_id = -1; - uint8_t *vrb_map; - int first_rb; - int N_RB_DL; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - UE_list_t *UE_list = &mac->UE_list; - nfapi_dl_config_request_t *dl_req; - nfapi_dl_config_request_body_t *dl_req_body; - - int round; - /* - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - COMMON_channels_t *cc = mac->common_channels; - - int rmax = 0; - int rep = 0; - int reps = 0; - - first_rb = 0; - struct PRACH_ConfigSIB_v1310 *ext4_prach; - PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; - PRACH_ParametersCE_r13_t *p[4]; - - if (cc[CC_idP].radioResourceConfigCommon_BR) { - - ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; - prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; - - switch (prach_ParametersListCE_r13->list.count) { - case 4: - p[3]=prach_ParametersListCE_r13->list.array[3]; - case 3: - p[2]=prach_ParametersListCE_r13->list.array[2]; - case 2: - p[1]=prach_ParametersListCE_r13->list.array[1]; - case 1: - p[0]=prach_ParametersListCE_r13->list.array[0]; - default: - AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",prach_ParametersListCE_r13->list.count); - } - } - #endif - */ - - // check HARQ status and retransmit if necessary - - - UE_id = find_UE_id(module_idP, ra->rnti); - AssertFatal(UE_id >= 0, "Can't find UE for t-crnti\n"); - - round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid]; - vrb_map = cc[CC_idP].vrb_map; - - dl_req = &mac->DL_req[CC_idP]; - dl_req_body = &dl_req->dl_config_request_body; - dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; - N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); - - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 for harq_pid %d was acknowledged (round %d), UE_id: %d \n", - module_idP, CC_idP, frameP, subframeP, ra->harq_pid, round, UE_id); - - if (round != 8) { + frame_t frameP, sub_frame_t subframeP, RA_t *ra) { + eNB_MAC_INST *mac = RC.mac[module_idP]; + COMMON_channels_t *cc = mac->common_channels; + int UE_id = -1; + uint8_t *vrb_map; + int first_rb; + int N_RB_DL; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + UE_list_t *UE_list = &mac->UE_list; + nfapi_dl_config_request_t *dl_req; + nfapi_dl_config_request_body_t *dl_req_body; + int round; + /* + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + COMMON_channels_t *cc = mac->common_channels; + + int rmax = 0; + int rep = 0; + int reps = 0; + + first_rb = 0; + struct PRACH_ConfigSIB_v1310 *ext4_prach; + PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; + PRACH_ParametersCE_r13_t *p[4]; + + if (cc[CC_idP].radioResourceConfigCommon_BR) { + + ext4_prach = cc[CC_idP].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; + + switch (prach_ParametersListCE_r13->list.count) { + case 4: + p[3]=prach_ParametersListCE_r13->list.array[3]; + case 3: + p[2]=prach_ParametersListCE_r13->list.array[2]; + case 2: + p[1]=prach_ParametersListCE_r13->list.array[1]; + case 1: + p[0]=prach_ParametersListCE_r13->list.array[0]; + default: + AssertFatal(1==0,"Illegal count for prach_ParametersListCE_r13 %d\n",prach_ParametersListCE_r13->list.count); + } + } + #endif + */ + // check HARQ status and retransmit if necessary + UE_id = find_UE_id(module_idP, ra->rnti); + AssertFatal(UE_id >= 0, "Can't find UE for t-crnti\n"); + round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid]; + vrb_map = cc[CC_idP].vrb_map; + dl_req = &mac->DL_req[CC_idP]; + dl_req_body = &dl_req->dl_config_request_body; + dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu]; + N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 for harq_pid %d was acknowledged (round %d), UE_id: %d \n", + module_idP, CC_idP, frameP, subframeP, ra->harq_pid, round, UE_id); + if (round != 8) { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (ra->rach_resource_type > 0) { - AssertFatal(1 == 0, - "Msg4 Retransmissions not handled yet for BL/CE UEs\n"); - } else + + if (ra->rach_resource_type > 0 && round > 0) { + AssertFatal(1 == 0, + "Msg4 Retransmissions not handled yet for BL/CE UEs, Frame %d, subframeP %d harq_pid %d round %d, UE_id: %d \n", + frameP, subframeP, ra->harq_pid, round, UE_id); + } else #endif - { - if ((ra->Msg4_frame == frameP) - && (ra->Msg4_subframe == subframeP)) { - - //ra->wait_ack_Msg4++; - // we have to schedule a retransmission - - dl_req->sfn_sf = frameP<<4 | subframeP; - - first_rb = 0; - vrb_map[first_rb] = 1; - vrb_map[first_rb + 1] = 1; - vrb_map[first_rb + 2] = 1; - vrb_map[first_rb + 3] = 1; - - fill_nfapi_dl_dci_1A(dl_config_pdu, 4, // aggregation_level - ra->rnti, // rnti - 1, // rnti_type, CRNTI - ra->harq_pid, // harq_process - 1, // tpc, none - getRIV(N_RB_DL, first_rb, 4), // resource_block_coding - ra->msg4_mcs, // mcs - 1, // ndi - round & 3, // rv - 0); // vrb_flag - - if (!CCE_allocation_infeasible - (module_idP, CC_idP, 1, subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, ra->rnti)) { - dl_req_body->number_dci++; - dl_req_body->number_pdu++; - dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - LOG_D(MAC, - "msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", - ra->rnti, round, frameP, subframeP); - // DLSCH Config - //DJP - fix this pdu_index = -1 - LOG_D(MAC, "check_Msg4_retransmission() before fill_nfapi_dlsch_config() with pdu_index = -1 \n"); - fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize, - -1 - /* retransmission, no pdu_index */ - , ra->rnti, 2, // resource_allocation_type : format 1A/1B/1D - 0, // virtual_resource_block_assignment_flag : localized - getRIV(N_RB_DL, first_rb, 4), // resource_block_coding : RIV, 4 PRB - 2, // modulation: QPSK - round & 3, // redundancy version - 1, // transport_blocks - 0, // transport_block_to_codeword_swap_flag (0) - (cc->p_eNB == 1) ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - //0, // codebook index - 1, // ue_category_capacity - 4, // pa: 0 dB - 0, // delta_power_offset_index - 0, // ngap - 1, // NPRB = 3 like in DCI - (cc->p_eNB == 1) ? 1 : 2, // transmission mode - 1, // num_bf_prb_per_subband - 1); // num_bf_vector - if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){ - set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); - } - } else - LOG_D(MAC, - "msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", - ra->rnti, round, frameP, subframeP); - - - // Program PUCCH1a for ACK/NAK - - - fill_nfapi_uci_acknak(module_idP, CC_idP, - ra->rnti, - (frameP * 10) + subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.cce_idx); - - // prepare frame for retransmission - get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe); - - LOG_W(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission round %d in %d.%d)\n", - module_idP, CC_idP, frameP, subframeP, ra->rnti, - round, ra->Msg4_frame, ra->Msg4_subframe); - - } // Msg4 frame/subframe - } // regular LTE case - } else { - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n", - module_idP, CC_idP, frameP, subframeP); - ra->state = IDLE; - LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP); - UE_id = find_UE_id(module_idP, ra->rnti); - DevAssert(UE_id != -1); - mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE; - cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti); - } + { + if ((ra->Msg4_frame == frameP) + && (ra->Msg4_subframe == subframeP)) { + //ra->wait_ack_Msg4++; + // we have to schedule a retransmission + dl_req->sfn_sf = frameP<<4 | subframeP; + first_rb = 0; + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 3] = 1; + fill_nfapi_dl_dci_1A(dl_config_pdu, 4, // aggregation_level + ra->rnti, // rnti + 1, // rnti_type, CRNTI + ra->harq_pid, // harq_process + 1, // tpc, none + getRIV(N_RB_DL, first_rb, 4), // resource_block_coding + ra->msg4_mcs, // mcs + 1, // ndi + round & 3, // rv + 0); // vrb_flag + + if (!CCE_allocation_infeasible + (module_idP, CC_idP, 1, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. + aggregation_level, ra->rnti)) { + dl_req_body->number_dci++; + dl_req_body->number_pdu++; + dl_req_body->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + LOG_D(MAC, + "msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", + ra->rnti, round, frameP, subframeP); + // DLSCH Config + //DJP - fix this pdu_index = -1 + LOG_D(MAC, "check_Msg4_retransmission() before fill_nfapi_dlsch_config() with pdu_index = -1 \n"); + fill_nfapi_dlsch_config(mac, dl_req_body, ra->msg4_TBsize, + -1 + /* retransmission, no pdu_index */ + , ra->rnti, 2, // resource_allocation_type : format 1A/1B/1D + 0, // virtual_resource_block_assignment_flag : localized + getRIV(N_RB_DL, first_rb, 4), // resource_block_coding : RIV, 4 PRB + 2, // modulation: QPSK + round & 3, // redundancy version + 1, // transport_blocks + 0, // transport_block_to_codeword_swap_flag (0) + (cc->p_eNB == 1) ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + //0, // codebook index + 1, // ue_category_capacity + 4, // pa: 0 dB + 0, // delta_power_offset_index + 0, // ngap + 1, // NPRB = 3 like in DCI + (cc->p_eNB == 1) ? 1 : 2, // transmission mode + 1, // num_bf_prb_per_subband + 1); // num_bf_vector + + if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR) { + set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti); + } + } else + LOG_D(MAC, + "msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", + ra->rnti, round, frameP, subframeP); + + // Program PUCCH1a for ACK/NAK + fill_nfapi_uci_acknak(module_idP, CC_idP, + ra->rnti, + (frameP * 10) + subframeP, + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.cce_idx); + // prepare frame for retransmission + get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe); + LOG_W(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission round %d in %d.%d)\n", + module_idP, CC_idP, frameP, subframeP, ra->rnti, + round, ra->Msg4_frame, ra->Msg4_subframe); + } // Msg4 frame/subframe + } // regular LTE case + } else { + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n", + module_idP, CC_idP, frameP, subframeP); + ra->state = IDLE; + LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP); + UE_id = find_UE_id(module_idP, ra->rnti); + DevAssert(UE_id != -1); + mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE; + cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti); + } } void -schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) -{ - - int CC_id; - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc = mac->common_channels; - RA_t *ra; - uint8_t i; - - - start_meas(&mac->schedule_ra); - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - // skip UL component carriers if TDD - if (is_UL_sf(&cc[CC_id], subframeP) == 1) - continue; - - for (i = 0; i < NB_RA_PROC_MAX; i++) { - - ra = (RA_t *) & cc[CC_id].ra[i]; +schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { + int CC_id; + eNB_MAC_INST *mac = RC.mac[module_idP]; + COMMON_channels_t *cc = mac->common_channels; + RA_t *ra; + uint8_t i; + start_meas(&mac->schedule_ra); - //LOG_D(MAC,"RA[state:%d]\n",ra->state); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + // skip UL component carriers if TDD + if (is_UL_sf(&cc[CC_id], subframeP) == 1) + continue; - if (ra->state == MSG2) - generate_Msg2(module_idP, CC_id, frameP, subframeP, ra); - else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP ) - generate_Msg4(module_idP, CC_id, frameP, subframeP, ra); - else if (ra->state == WAITMSG4ACK) - check_Msg4_retransmission(module_idP, CC_id, frameP, - subframeP, ra); + for (i = 0; i < NB_RA_PROC_MAX; i++) { + ra = (RA_t *) & cc[CC_id].ra[i]; - } // for i=0 .. N_RA_PROC-1 - } // CC_id + //LOG_D(MAC,"RA[state:%d]\n",ra->state); - stop_meas(&mac->schedule_ra); + if (ra->state == MSG2) + generate_Msg2(module_idP, CC_id, frameP, subframeP, ra); + else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP ) + generate_Msg4(module_idP, CC_id, frameP, subframeP, ra); + else if (ra->state == WAITMSG4ACK) + check_Msg4_retransmission(module_idP, CC_id, frameP, + subframeP, ra); + } // for i=0 .. N_RA_PROC-1 + } // CC_id + stop_meas(&mac->schedule_ra); } // handles the event of MSG1 reception void initiate_ra_proc(module_id_t module_idP, - int CC_id, - frame_t frameP, - sub_frame_t subframeP, - uint16_t preamble_index, - int16_t timing_offset, uint16_t ra_rnti + int CC_id, + frame_t frameP, + sub_frame_t subframeP, + uint16_t preamble_index, + int16_t timing_offset, uint16_t ra_rnti #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , uint8_t rach_resource_type + , uint8_t rach_resource_type #endif - ) -{ - - uint8_t i; - - COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; - RA_t *ra = &cc->ra[0]; + ) { + uint8_t i; + COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; + RA_t *ra = &cc->ra[0]; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - - - struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = NULL; - LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL; - - - - if (cc->mib->message.schedulingInfoSIB1_BR_r13>0) { - AssertFatal(cc->radioResourceConfigCommon_BR != NULL,"radioResourceConfigCommon_BR is null\n"); - AssertFatal(cc->radioResourceConfigCommon_BR->ext4 != NULL, "radioResourceConfigCommon_BR->ext4 is null\n"); - ext4_prach = cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; - AssertFatal(ext4_prach!=NULL,"ext4_prach is null\n"); - prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; - } + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = NULL; + LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL; + + if (cc->mib->message.schedulingInfoSIB1_BR_r13>0) { + AssertFatal(cc->radioResourceConfigCommon_BR != NULL,"radioResourceConfigCommon_BR is null\n"); + AssertFatal(cc->radioResourceConfigCommon_BR->ext4 != NULL, "radioResourceConfigCommon_BR->ext4 is null\n"); + ext4_prach = cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + AssertFatal(ext4_prach!=NULL,"ext4_prach is null\n"); + prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; + } #endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ - - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d\n", - module_idP, CC_id, frameP, subframeP, preamble_index); + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d\n", + module_idP, CC_id, frameP, subframeP, preamble_index); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d PRACH resource type %d\n", - module_idP, CC_id, frameP, subframeP, rach_resource_type); + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d PRACH resource type %d\n", + module_idP, CC_id, frameP, subframeP, rach_resource_type); #endif - - uint16_t msg2_frame = frameP; - uint16_t msg2_subframe = subframeP; - int offset; - - static uint8_t failure_cnt = 0 ; - + uint16_t msg2_frame = frameP; + uint16_t msg2_subframe = subframeP; + int offset; + static uint8_t failure_cnt = 0 ; #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - if (prach_ParametersListCE_r13 && - prach_ParametersListCE_r13->list.count < rach_resource_type) { - LOG_E(MAC, - "[eNB %d][RAPROC] CC_id %d Received impossible PRACH resource type %d, only %d CE levels configured\n", - module_idP, CC_id, rach_resource_type, - (int) prach_ParametersListCE_r13->list.count); - return; - } + if (prach_ParametersListCE_r13 && + prach_ParametersListCE_r13->list.count < rach_resource_type) { + LOG_E(MAC, + "[eNB %d][RAPROC] CC_id %d Received impossible PRACH resource type %d, only %d CE levels configured\n", + module_idP, CC_id, rach_resource_type, + (int) prach_ParametersListCE_r13->list.count); + return; + } #endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); - - for (i = 0; i < NB_RA_PROC_MAX; i++) { - if (ra[i].state == IDLE) { - int loop = 0; - LOG_D(MAC, "Frame %d, Subframe %d: Activating RA process %d\n", - frameP, subframeP, i); - ra[i].state = MSG2; - ra[i].timing_offset = timing_offset; - ra[i].preamble_subframe = subframeP; + for (i = 0; i < NB_RA_PROC_MAX; i++) { + if (ra[i].state == IDLE) { + int loop = 0; + LOG_D(MAC, "Frame %d, Subframe %d: Activating RA process %d\n", + frameP, subframeP, i); + ra[i].state = MSG2; + ra[i].Msg4_delay_cnt=0; + ra[i].timing_offset = timing_offset; + ra[i].preamble_subframe = subframeP; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ra[i].rach_resource_type = rach_resource_type; - ra[i].msg2_mpdcch_repetition_cnt = 0; - ra[i].msg4_mpdcch_repetition_cnt = 0; + ra[i].rach_resource_type = rach_resource_type; + ra[i].msg2_mpdcch_repetition_cnt = 0; + ra[i].msg4_mpdcch_repetition_cnt = 0; #endif + //TODO Fill in other TDD config. What about nfapi_mode? + if(cc->tdd_Config!=NULL) { + switch(cc->tdd_Config->subframeAssignment) { + default: + printf("%s:%d: TODO\n", __FILE__, __LINE__); + abort(); + case 1 : + offset = 6; + break; + } + } else { //FDD + // DJP - this is because VNF is 2 subframes ahead of PNF and TX needs 4 subframes + if (NFAPI_MODE != NFAPI_MONOLITHIC) + offset = 7; + else + offset = 5; + } - //TODO Fill in other TDD config. What about nfapi_mode? - if(cc->tdd_Config!=NULL){ - switch(cc->tdd_Config->subframeAssignment){ - default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort(); - case 1 : - offset = 6; - break; - } - }else{//FDD - // DJP - this is because VNF is 2 subframes ahead of PNF and TX needs 4 subframes - if (nfapi_mode) - offset = 7; - else - offset = 5; - } - - add_subframe(&msg2_frame, &msg2_subframe, offset); + add_subframe(&msg2_frame, &msg2_subframe, offset); + ra[i].Msg2_frame = msg2_frame; + ra[i].Msg2_subframe = msg2_subframe; + LOG_D(MAC,"%s() Msg2[%04d%d] SFN/SF:%04d%d offset:%d\n", __FUNCTION__,ra[i].Msg2_frame,ra[i].Msg2_subframe,frameP,subframeP,offset); + ra[i].Msg2_subframe = (subframeP + offset) % 10; - ra[i].Msg2_frame = msg2_frame; - ra[i].Msg2_subframe = msg2_subframe; + /* TODO: find better procedure to allocate RNTI */ + do { +#if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode + static int drnti[MAX_MOBILES_PER_ENB] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 }; + int j = 0; + int nb_ue = 0; + + for (j = 0; j < MAX_MOBILES_PER_ENB; j++) { + if (UE_RNTI(module_idP, j) > 0) { + nb_ue++; + } else { + break; + } + } - LOG_D(MAC,"%s() Msg2[%04d%d] SFN/SF:%04d%d offset:%d\n", __FUNCTION__,ra[i].Msg2_frame,ra[i].Msg2_subframe,frameP,subframeP,offset); + if (nb_ue >= MAX_MOBILES_PER_ENB) { + printf("No more free RNTI available, increase MAX_MOBILES_PER_ENB\n"); + abort(); + } - ra[i].Msg2_subframe = (subframeP + offset) % 10; - /* TODO: find better procedure to allocate RNTI */ - do { -#if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode - static int drnti[MAX_MOBILES_PER_ENB] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 }; - int j = 0; - int nb_ue = 0; - for (j = 0; j < MAX_MOBILES_PER_ENB; j++) { - if (UE_RNTI(module_idP, j) > 0) { - nb_ue++; - } else { - break; - } - } - if (nb_ue >= MAX_MOBILES_PER_ENB) { - printf("No more free RNTI available, increase MAX_MOBILES_PER_ENB\n"); - abort(); - } - ra[i].rnti = drnti[nb_ue]; -#else - ra[i].rnti = taus(); + ra[i].rnti = drnti[nb_ue]; +#else + ra[i].rnti = taus(); #endif - loop++; - } - while (loop != 100 && - /* TODO: this is not correct, the rnti may be in use without - * being in the MAC yet. To be refined. - */ - !(find_UE_id(module_idP, ra[i].rnti) == -1 && - /* 1024 and 60000 arbirarily chosen, not coming from standard */ - ra[i].rnti >= 1024 && ra[i].rnti < 60000)); - if (loop == 100) { - printf("%s:%d:%s: FATAL ERROR! contact the authors\n", - __FILE__, __LINE__, __FUNCTION__); - abort(); - } - ra[i].RA_rnti = ra_rnti; - ra[i].preamble_index = preamble_index; - failure_cnt = 0; - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, state %d\n", - module_idP, CC_id, frameP, ra[i].Msg2_frame, - ra[i].Msg2_subframe, i, ra[i].rnti, ra[i].state); - - return; - } - } + loop++; + } while (loop != 100 && + /* TODO: this is not correct, the rnti may be in use without + * being in the MAC yet. To be refined. + */ + !(find_UE_id(module_idP, ra[i].rnti) == -1 && + /* 1024 and 60000 arbirarily chosen, not coming from standard */ + ra[i].rnti >= 1024 && ra[i].rnti < 60000)); + + if (loop == 100) { + printf("%s:%d:%s: FATAL ERROR! contact the authors\n", + __FILE__, __LINE__, __FUNCTION__); + abort(); + } - LOG_E(MAC, - "[eNB %d][RAPROC] FAILURE: CC_id %d Frame %d Initiating RA procedure for preamble index %d\n", - module_idP, CC_id, frameP, preamble_index); - - failure_cnt++; - if(failure_cnt > 20) { - LOG_E(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Clear Random access information\n", module_idP, CC_id, frameP); - clear_ra_proc(module_idP, CC_id, frameP); + ra[i].RA_rnti = ra_rnti; + ra[i].preamble_index = preamble_index; + failure_cnt = 0; + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, state %d\n", + module_idP, CC_id, frameP, ra[i].Msg2_frame, + ra[i].Msg2_subframe, i, ra[i].rnti, ra[i].state); + return; } - + } + + LOG_E(MAC, + "[eNB %d][RAPROC] FAILURE: CC_id %d Frame %d Initiating RA procedure for preamble index %d\n", + module_idP, CC_id, frameP, preamble_index); + failure_cnt++; + + if(failure_cnt > 20) { + LOG_E(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Clear Random access information\n", module_idP, CC_id, frameP); + clear_ra_proc(module_idP, CC_id, frameP); + } } void cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, - rnti_t rnti) -{ - unsigned char i; - RA_t *ra = (RA_t *) & RC.mac[module_idP]->common_channels[CC_id].ra[0]; - - MSC_LOG_EVENT(MSC_PHY_ENB, "RA Cancelling procedure ue %" PRIx16 " ", - rnti); - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d Cancelling RA procedure for UE rnti %x\n", - module_idP, CC_id, frameP, rnti); + rnti_t rnti) { + unsigned char i; + RA_t *ra = (RA_t *) & RC.mac[module_idP]->common_channels[CC_id].ra[0]; + MSC_LOG_EVENT(MSC_PHY_ENB, "RA Cancelling procedure ue %" PRIx16 " ", + rnti); + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d Cancelling RA procedure for UE rnti %x\n", + module_idP, CC_id, frameP, rnti); - for (i = 0; i < NB_RA_PROC_MAX; i++) { - if (rnti == ra[i].rnti) { - ra[i].state = IDLE; - ra[i].timing_offset = 0; - ra[i].RRC_timer = 20; - ra[i].rnti = 0; - ra[i].msg3_round = 0; - LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Canceled RA procedure for UE rnti %x\n", module_idP, CC_id, frameP, rnti); - } + for (i = 0; i < NB_RA_PROC_MAX; i++) { + if (rnti == ra[i].rnti) { + ra[i].state = IDLE; + ra[i].timing_offset = 0; + ra[i].RRC_timer = 20; + ra[i].rnti = 0; + ra[i].msg3_round = 0; + LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Canceled RA procedure for UE rnti %x\n", module_idP, CC_id, frameP, rnti); } + } } -void clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP) -{ +void clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP) { unsigned char i; RA_t *ra = (RA_t *) & RC.mac[module_idP]->common_channels[CC_id].ra[0]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index 194a1af85c7e1a1245b38f08db51cbb2b7a1350d..fb80c9e1d6058a9c50b33c869063c4cb6da40929 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -422,7 +422,7 @@ schedule_SIB1_BR(module_id_t module_idP, n_NB = Sj[((cc->physCellId % N_S_NB) + (i * N_S_NB / m)) % N_S_NB]; - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SIB1_BR, 0xFFFF, 1, &cc->BCCH_BR_pdu[0].payload[0], 0); // not used in this case AssertFatal(cc->mib->message.schedulingInfoSIB1_BR_r13 < 19, "schedulingInfoSIB1_BR_r13 %d > 18\n", @@ -541,7 +541,6 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) //------------------------------------------------------------------------------ { - int8_t bcch_sdu_length; int CC_id; eNB_MAC_INST *eNB = RC.mac[module_idP]; @@ -579,7 +578,7 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, LTE_SchedulingInfoList_t *schedulingInfoList = cc->schedulingInfoList; AssertFatal(schedulingInfoList_BR_r13->list.count==schedulingInfoList->list.count, "schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n", - schedulingInfoList_BR_r13->list.count,schedulingInfoList->list.count); + schedulingInfoList_BR_r13->list.count,schedulingInfoList->list.count); AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<=LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, "si_WindowLength_BR_r13 %d > %d\n", @@ -599,130 +598,140 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, // cycle through SIB list for (i=0;i<schedulingInfoList_BR_r13->list.count;i++) { - long si_Periodicity = schedulingInfoList->list.array[i]->si_Periodicity; - long si_Narrowband_r13 = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13; - long si_TBS_r13 = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13]; - - // check if the SI is to be scheduled now - int period_in_sf = 80<<si_Periodicity; // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms - int sf_mod_period = absSF%period_in_sf; - int k = sf_mod_period&3; - // Note: definition of k and rvidx from 36.321 section 5.3.1 - rvidx = (((3*k)>>1) + (k&1))&3; - - if ((sf_mod_period < si_WindowLength_BR_r13) && - ((frameP&(((1<<si_RepetitionPattern_r13)-1)))==0)) { // this SIB is to be scheduled - - bcch_sdu_length = mac_rrc_data_req(module_idP, - CC_id, - frameP, - BCCH_SI_BR+i,1, - &cc->BCCH_BR_pdu[i+1].payload[0], - 0); // not used in this case - - AssertFatal(bcch_sdu_length>0,"RRC returned 0 bytes for SI-BR %d\n",i); - - if (bcch_sdu_length > 0) { - AssertFatal(bcch_sdu_length <= (si_TBS_r13>>3), - "RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n", - bcch_sdu_length,(int)(si_TBS_r13>>3),(int)schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13); - - // allocate all 6 PRBs in narrowband for SIB1_BR - - // check that SIB1 didn't take this narrowband - if (vrb_map[first_rb] > 0) continue; - - first_rb = narrowband_to_first_rb(cc,si_Narrowband_r13-1); - vrb_map[first_rb] = 1; - vrb_map[first_rb+1] = 1; - vrb_map[first_rb+2] = 1; - vrb_map[first_rb+4] = 1; - vrb_map[first_rb+5] = 1; - - if ((frameP&1023) < 200) - LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n", - module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx, - sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13, - bcch_sdu_length); - - - - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = si_TBS_r13>>3; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,6); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // Rel10 fields (for PDSCH starting symbol) - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; - // Rel13 fields - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = absSF - sf_mod_period; - - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - dl_req->number_pdu++; - - // Program TX Request - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = bcch_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = bcch_sdu_length; - TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[i+1].payload; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - - if (opt_enabled == 1) { - trace_pdu(1, - &cc->BCCH_BR_pdu[i+1].payload[0], - bcch_sdu_length, - 0xffff, - 4, - 0xffff, - eNB->frame, - eNB->subframe, - 0, - 0); - LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); - } - if (cc->tdd_Config!=NULL) { //TDD - LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (TDD) for CC_id %d SI-BR %d bytes\n", - frameP,i, - CC_id, - bcch_sdu_length); - } else { - LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (FDD) for CC_id %d SI-BR %d bytes\n", - frameP,i, - CC_id, - bcch_sdu_length); - } - } - } // scheduling in current frame/subframe - } //for SI List - } // eMTC is activated - } // CC_id + long si_Periodicity = schedulingInfoList->list.array[i]->si_Periodicity; + long si_Narrowband_r13 = schedulingInfoList_BR_r13->list.array[i]->si_Narrowband_r13; + long si_TBS_r13 = si_TBS_r13tab[schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13]; + + // check if the SI is to be scheduled now + int period_in_sf; + if ((si_Periodicity >= 0) && (si_Periodicity < 25)) { + // 2^i * 80 subframes, note: si_Periodicity is 2^i * 80ms + period_in_sf = 80 << ((int) si_Periodicity); + } else if (si_Periodicity < 0) { + period_in_sf = 80; + } else if (si_Periodicity > 24) { + period_in_sf = 80 << 24; + } + int sf_mod_period = absSF % period_in_sf; + int k = sf_mod_period & 3; + // Note: definition of k and rvidx from 36.321 section 5.3.1 + rvidx = (((3 * k) >> 1) + (k & 1)) & 3; + + if ((sf_mod_period < si_WindowLength_BR_r13) + && ((frameP & (((1 << si_RepetitionPattern_r13) - 1))) == 0)) { // this SIB is to be scheduled + + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_BR + i, 0xFFFF, 1, &cc->BCCH_BR_pdu[i + 1].payload[0], 0); // not used in this case + + + AssertFatal(bcch_sdu_length > 0, + "RRC returned 0 bytes for SI-BR %d\n", i); + + if (bcch_sdu_length > 0) { + AssertFatal(bcch_sdu_length <= (si_TBS_r13 >> 3), + "RRC provided bcch with length %d > %d (si_TBS_r13 %d)\n", + bcch_sdu_length, + (int) (si_TBS_r13 >> 3), + (int) schedulingInfoList_BR_r13->list.array[i]->si_TBS_r13); + + // allocate all 6 PRBs in narrowband for SIB1_BR + + // check that SIB1 didn't take this narrowband + if (vrb_map[first_rb] > 0) continue; + + first_rb = narrowband_to_first_rb(cc,si_Narrowband_r13 - 1); + vrb_map[first_rb] = 1; + vrb_map[first_rb + 1] = 1; + vrb_map[first_rb + 2] = 1; + vrb_map[first_rb + 4] = 1; + vrb_map[first_rb + 5] = 1; + + if ((frameP&1023) < 200) + LOG_D(MAC,"[eNB %d] Frame %d Subframe %d: SI_BR->DLSCH CC_id %d, Narrowband %d rvidx %d (sf_mod_period %d : si_WindowLength_BR_r13 %d : si_RepetitionPattern_r13 %d) bcch_sdu_length %d\n", + module_idP,frameP,subframeP,CC_id,(int)si_Narrowband_r13-1,rvidx, + sf_mod_period,(int)si_WindowLength_BR_r13,(int)si_RepetitionPattern_r13, + bcch_sdu_length); + + + //// Rel10 fields (for PDSCH starting symbol) + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + //// Rel13 fields + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL13_TAG; + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR + //dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = absSF - sf_mod_period; + + //// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + //dl_req->number_pdu++; + // dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = si_TBS_r13>>3; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL,first_rb,6); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = rvidx; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // Rel10 fields (for PDSCH starting symbol) + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; + // Rel13 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 1; // CEModeA UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 1; // SI-BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = absSF - sf_mod_period; + + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + dl_req->number_pdu++; + + // Program TX Request + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = bcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = bcch_sdu_length; + TX_req->segments[0].segment_data = cc->BCCH_BR_pdu[i+1].payload; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + + if (opt_enabled == 1) { + trace_pdu(DIRECTION_DOWNLINK, + &cc->BCCH_BR_pdu[i + 1].payload[0], + bcch_sdu_length, + 0xffff, + WS_SI_RNTI, + 0xffff, eNB->frame, eNB->subframe, 0, + 0); + LOG_D(OPT, "[eNB %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", + module_idP, frameP, CC_id, 0xffff, bcch_sdu_length); + } + if (cc->tdd_Config != NULL) { //TDD + LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (TDD) for CC_id %d SI-BR %d bytes\n", + frameP, i, CC_id, bcch_sdu_length); + } else { + LOG_D(MAC, "[eNB] Frame %d : Scheduling BCCH-BR %d->DLSCH (FDD) for CC_id %d SI-BR %d bytes\n", + frameP, i, CC_id, bcch_sdu_length); + } + } + } // scheduling in current frame/subframe + } //for SI List + } // eMTC is activated + } // CC_id return; } @@ -761,7 +770,7 @@ schedule_SI_MBMS(module_id_t module_idP, frame_t frameP, dl_req = &eNB->DL_req[CC_id].dl_config_request_body; - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_MBMS, 1, &cc->BCCH_MBMS_pdu.payload[0], 0); // not used in this case + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH_SI_MBMS,0xFFFF, 1, &cc->BCCH_MBMS_pdu.payload[0], 0); // not used in this case if (bcch_sdu_length > 0) { LOG_D(MAC, "[eNB %d] Frame %d : BCCH-MBMS->DLSCH CC_id %d, Received %d bytes \n", module_idP, frameP, CC_id, bcch_sdu_length); @@ -974,7 +983,7 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_req = &dl_config_request->dl_config_request_body; cc = &eNB->common_channels[CC_id]; - mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0], 0); // not used in this case + mib_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MIBCH, 0xFFFF, 1, &cc->MIB_pdu.payload[0], 0); // not used in this case LOG_D(MAC, "Frame %d, subframe %d: BCH PDU length %d\n", frameP, subframeP, mib_sdu_length); @@ -1061,7 +1070,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_req = &eNB->DL_req[CC_id].dl_config_request_body; - bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 1, &cc->BCCH_pdu.payload[0], 0); // not used in this case + bcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, BCCH, 0xFFFF,1, &cc->BCCH_pdu.payload[0], 0); // not used in this case if (bcch_sdu_length > 0) { LOG_D(MAC, "[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n", module_idP, frameP, CC_id, bcch_sdu_length); @@ -1119,8 +1128,10 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) mcs = 7; } else if (bcch_sdu_length <= 49) { mcs = 8; - } - + } else if (bcch_sdu_length <= 59) { + mcs = 9; + } + else AssertFatal(1==0,"Cannot Assign mcs for bcch_sdu_length %d (max mcs 9)\n",bcch_sdu_length); dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 737f4dfe749b7a5ce506b26c8a21e777db8a4c12..95e2bf59e8ee6e8173c5b52376df39591fb5641b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -35,6 +35,7 @@ #include "LAYER2/MAC/mac_proto.h" #include "LAYER2/MAC/mac_extern.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" @@ -64,43 +65,45 @@ #include "common/ran_context.h" extern RAN_CONTEXT_t RC; -extern uint8_t nfapi_mode; + //------------------------------------------------------------------------------ void add_ue_dlsch_info(module_id_t module_idP, int CC_id, - int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status) + int UE_id, + sub_frame_t subframeP, + UE_DLSCH_STATUS status, + rnti_t rnti) //------------------------------------------------------------------------------ { - //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id)); - eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); - // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; - eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; - eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; - eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++; + eNB_DLSCH_INFO *info = &eNB_dlsch_info[module_idP][CC_id][UE_id]; + // LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id)); + info->rnti = rnti; + // info->weight = weight; + info->subframe = subframeP; + info->status = status; + info->serving_num++; + return; } //------------------------------------------------------------------------------ int -schedule_next_dlue(module_id_t module_idP, int CC_id, +schedule_next_dlue(module_id_t module_idP, + int CC_id, sub_frame_t subframeP) //------------------------------------------------------------------------------ { int next_ue; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - for (next_ue = UE_list->head; next_ue >= 0; - next_ue = UE_list->next[next_ue]) { - if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == - S_DL_WAITING) { + for (next_ue = UE_list->head; next_ue >= 0; next_ue = UE_list->next[next_ue]) { + if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_WAITING) { return next_ue; } } - for (next_ue = UE_list->head; next_ue >= 0; - next_ue = UE_list->next[next_ue]) { + for (next_ue = UE_list->head; next_ue >= 0; next_ue = UE_list->next[next_ue]) { if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_BUFFERED) { eNB_dlsch_info[module_idP][CC_id][next_ue].status = S_DL_WAITING; } @@ -129,7 +132,7 @@ generate_dlsch_header(unsigned char *mac_header, // compute header components - if ((short_padding == 1) || (short_padding == 2)) { + if (short_padding == 1 || short_padding == 2) { mac_header_ptr->R = 0; mac_header_ptr->E = 0; mac_header_ptr->LCID = SHORT_PADDING; @@ -174,10 +177,11 @@ generate_dlsch_header(unsigned char *mac_header, last_size = 1; // msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0; - AssertFatal(timing_advance_cmd < 64, - "timing_advance_cmd %d > 63\n", timing_advance_cmd); + AssertFatal(timing_advance_cmd < 64, "timing_advance_cmd %d > 63\n", + timing_advance_cmd); ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; - LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd, + LOG_D(MAC, "timing advance =%d (%d)\n", + timing_advance_cmd, ((TIMING_ADVANCE_CMD *) ce_ptr)->TA); ce_ptr += sizeof(TIMING_ADVANCE_CMD); //msg("offset %d\n",ce_ptr-mac_header_control_elements); @@ -201,11 +205,16 @@ generate_dlsch_header(unsigned char *mac_header, mac_header_ptr->E = 0; mac_header_ptr->LCID = UE_CONT_RES; last_size = 1; - LOG_T(MAC, - "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", - ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], - ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); - memcpy(ce_ptr, ue_cont_res_id, 6); + LOG_T(MAC, "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", + ue_cont_res_id[0], + ue_cont_res_id[1], + ue_cont_res_id[2], + ue_cont_res_id[3], + ue_cont_res_id[4], + ue_cont_res_id[5]); + memcpy(ce_ptr, + ue_cont_res_id, + 6); ce_ptr += 6; // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); } @@ -214,7 +223,8 @@ generate_dlsch_header(unsigned char *mac_header, for (i = 0; i < num_sdus; i++) { LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n", - num_sdus, sdu_lengths[i]); + num_sdus, + sdu_lengths[i]); if (first_element > 0) { mac_header_ptr->E = 1; @@ -246,8 +256,7 @@ generate_dlsch_header(unsigned char *mac_header, ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; last_size = 3; #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, - "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", + LOG_D(MAC, "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", sdu_lengths[i], ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); @@ -289,10 +298,10 @@ generate_dlsch_header(unsigned char *mac_header, if ((ce_ptr - mac_header_control_elements) > 0) { // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements); - memcpy((void *) mac_header_ptr, mac_header_control_elements, + memcpy((void *) mac_header_ptr, + mac_header_control_elements, ce_ptr - mac_header_control_elements); - mac_header_ptr += - (unsigned char) (ce_ptr - mac_header_control_elements); + mac_header_ptr += (unsigned char) (ce_ptr - mac_header_control_elements); } //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); @@ -301,7 +310,10 @@ generate_dlsch_header(unsigned char *mac_header, //------------------------------------------------------------------------------ void -set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, +set_ul_DAI(int module_idP, + int UE_idP, + int CC_idP, + int frameP, int subframeP) //------------------------------------------------------------------------------ { @@ -312,9 +324,13 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, if (cc->tdd_Config != NULL) { //TDD DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", - module_idP, CC_idP, frameP, subframeP, DAI, UE_idP); + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n", + module_idP, + CC_idP, + frameP, + subframeP, + DAI, + UE_idP); // Save DAI for Format 0 DCI switch (cc->tdd_Config->subframeAssignment) { @@ -398,6 +414,8 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, break; } } + + return; } //------------------------------------------------------------------------------ @@ -409,1110 +427,38 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in for (i = 0; i < sli->n_dl; i++) { // Run each enabled slice-specific schedulers one by one - sli->dl[i].sched_cb(module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); + sli->dl[i].sched_cb(module_idP, + i, + frameP, + subframeP, + mbsfn_flag/*, dl_info*/); } } // changes to pre-processor for eMTC //------------------------------------------------------------------------------ -void getRepetition(UE_TEMPLATE * pue_template,unsigned int *maxRep , unsigned int *narrowBandindex){ - LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11; - - AssertFatal(pue_template->physicalConfigDedicated !=NULL, "no RRC physical configuration for this UE ") ; - AssertFatal(pue_template->physicalConfigDedicated->ext4 !=NULL, "no RRC physical configuration for this UE ") ; - - AssertFatal(pue_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.count > 0 ,"epdcch config list is empty") ; - - epdcch_setconfig_r11 = pue_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0] ; - - AssertFatal(epdcch_setconfig_r11->ext2 !=NULL && epdcch_setconfig_r11->ext2->mpdcch_config_r13 !=NULL," mpdcch config not found") ; - -*maxRep = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_NumRepetition_r13 ; - - *narrowBandindex = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 ; - - - - +void getRepetition(UE_TEMPLATE *pue_template,unsigned int *maxRep, unsigned int *narrowBandindex) { + LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11; + AssertFatal(pue_template->physicalConfigDedicated !=NULL, "no RRC physical configuration for this UE ") ; + AssertFatal(pue_template->physicalConfigDedicated->ext4 !=NULL, "no RRC physical configuration for this UE ") ; + AssertFatal(pue_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.count > 0,"epdcch config list is empty") ; + epdcch_setconfig_r11 = pue_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0] ; + AssertFatal(epdcch_setconfig_r11->ext2 !=NULL && epdcch_setconfig_r11->ext2->mpdcch_config_r13 !=NULL," mpdcch config not found") ; + *maxRep = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_NumRepetition_r13 ; + *narrowBandindex = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 ; } - - -/*void -schedule_ue_spec_br( - module_id_t module_idP, - frame_t frameP, - sub_frame_t subframeP, - int* mbsfn_flag -) //------------------------------------------------------------------------------ -{ - uint8_t CC_id; - int UE_id; - unsigned char aggregation; - mac_rlc_status_resp_t rlc_status; - unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; - unsigned char header_len_dtch = 0, header_len_dtch_tmp = 0, header_len_dtch_last = 0; - unsigned char ta_len = 0; - unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; - uint16_t nb_rb, nb_rb_temp, nb_available_rb; - uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = 0, post_padding = 0; - unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - unsigned char round = 0; - unsigned char harq_pid = 0; - eNB_UE_STATS *eNB_UE_stats = NULL; - uint16_t sdu_length_total = 0; - - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = eNB->common_channels; - UE_list_t *UE_list = &eNB->UE_list; - int continue_flag = 0; - int32_t normalized_rx_power, target_rx_power; - int32_t tpc = 1; - static int32_t tpc_accumulated = 0; - UE_sched_ctrl *ue_sched_ctl; - int mcs; - int i; - int min_rb_unit[MAX_NUM_CCs]; - int N_RB_DL[MAX_NUM_CCs]; - int total_nb_available_rb[MAX_NUM_CCs]; - int N_RBG[MAX_NUM_CCs]; - nfapi_dl_config_request_body_t *dl_req; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_tx_request_pdu_t *TX_req; - int tdd_sfa; - -#if 0 - if (UE_list->head == -1) { - return; - } -#endif - - uint8_t *vrb_map; - int first_rb; - start_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); - - - - aggregation = 2; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); - min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); - // get number of PRBs less those used by common channels - total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; - for (i = 0; i < N_RB_DL[CC_id]; i++) - if (cc[CC_id].vrb_map[i] != 0) - total_nb_available_rb[CC_id]--; - - N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); - - // store the global enb stats: - eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; - eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; - eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; - } - - /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); - //start_meas(&eNB->schedule_dlsch_preprocessor); - //dlsch_scheduler_pre_processor(module_idP, - // frameP, - // subframeP, - // N_RBG, - // mbsfn_flag); - //stop_meas(&eNB->schedule_dlsch_preprocessor); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) - { - vrb_map = cc[CC_id].vrb_map; - - LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); - - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; - - if (mbsfn_flag[CC_id] > 0) - continue; - - unsigned int rmax; - unsigned int narrowBandindex_index; - unsigned int first_rb, rep, reps; - - // rmax from RRC connection setup - getRepetition(&UE_list->UE_template[CC_id][UE_id], &rmax, &narrowBandindex_index); - - first_rb = narrowband_to_first_rb(cc,narrowBandindex_index); - - if (vrb_map[first_rb] == 1) // skip scheduling emtc UEs if first RB is taken - continue ; - - for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) - { - - if (UE_list->UE_template[CC_id][UE_id].rach_resource_type ==0 ) // do the following scheduling only if the UE is emtc - continue ; - - //[khalid] ******** allocate here the vrb_map - // 1st check on the vrb_map[] and allocate the one that is next to them - - // at the end of the scheduler make sure the right subbands coresponding to these RBs are allocated the UE in UE_template directely - // also check on the fill_DCI function - - - - vrb_map[first_rb] = 1; - vrb_map[first_rb + 1] = 1; - vrb_map[first_rb + 2] = 1; - vrb_map[first_rb + 3] = 1; - vrb_map[first_rb + 4] = 1; - vrb_map[first_rb + 5] = 1; - - - - - - continue_flag = 0; // reset the flag to allow allocation for the remaining UEs - rnti = UE_RNTI(module_idP, UE_id); - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - //[khalid] allocate the middle RB subbands in sf 1,5 for synch signals and PBCH - - - - - if (rnti == NOT_A_RNTI) { - LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", UE_id, UE_list->num_UEs); - continue_flag = 1; - } - - if (eNB_UE_stats == NULL) { - LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); - continue_flag = 1; - } - - //if (continue_flag != 1) { - // switch (get_tmode(module_idP, CC_id, UE_id)) { - // case 1: - // case 2: - // case 7: - // aggregation = get_aggregation(get_bw_index(module_idP, CC_id), - // eNB_UE_stats->dl_cqi, - // format1); - // break; - // case 3: - // aggregation = get_aggregation(get_bw_index(module_idP, CC_id), - // eNB_UE_stats->dl_cqi, - // format2A); - // break; - // default: - // LOG_W(MAC, "Unsupported transmission mode %d\n", get_tmode(module_idP, CC_id, UE_id)); - // aggregation = 2; - // } - //} - - if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated - CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, aggregation, rnti) - ) { - LOG_D(MAC, "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", - module_idP, frameP, UE_id, CC_id); - continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 - } - - //if (cc[CC_id].tdd_Config != NULL) { //TDD - // set_ue_dai(subframeP, - // UE_id, - // CC_id, - // cc[CC_id].tdd_Config->subframeAssignment, - // UE_list); - // // update UL DAI after DLSCH scheduling - // set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); - //} - - //if (continue_flag == 1) { - // add_ue_dlsch_info(module_idP, - // CC_id, - // UE_id, - // subframeP, - // S_DL_NONE); - // continue; - // } - - nb_available_rb = 6; // to be checked - harq_pid = ue_sched_ctl->harq_pid[CC_id]; - round = ue_sched_ctl->round[CC_id]; - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);x - UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; - UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - - sdu_length_total = 0; - num_sdus = 0; - - - //DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), - //eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); - - eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->dl_cqi]; //to be checked - eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, 15); - - - // store stats - UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi = eNB_UE_stats->dl_cqi; - - // initializing the rb allocation indicator for each UE - //to be checked - for (j = 0; j < N_RBG[CC_id]; j++) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; - } - - LOG_D(MAC, "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", - module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, nb_available_rb, - eNB_UE_stats->dl_cqi, eNB_UE_stats->dlsch_mcs1, - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); - - - - // process retransmission - - if (round > 0) - { - - - // choose r3 by default for RAR (Table 9.1.5-5) - rep = 2; - // get actual repetition count from Table 9.1.5-3 - reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep)); - - - // get freq_allocation - nb_rb = 6;//UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - - if (nb_rb <= nb_available_rb) - { - - - //if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - //} - //else { - // nb_rb_temp = nb_rb; - // j = 0; - - // while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - // if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - // UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - // if ((j == N_RBG[CC_id] - 1) && - // ((N_RB_DL[CC_id] == 25) || - // (N_RB_DL[CC_id] == 50))) { - // nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; - // } - // else { - // nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; - // } - // } - - // j = j + 1; - // } - //} - - nb_available_rb -= nb_rb; - - //eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - //eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - - //for(j=0; j<N_RBG[CC_id]; j++) { - //eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - //} - - - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - default: - { - - if ((UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt == 0) && - (mpdcch_sf_condition(eNB, CC_id, frameP, subframeP, rmax, TYPEUESPEC,UE_id) > 0)) - { - // MPDCCH configuration for RAR - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2 + sizeof(nfapi_dl_config_mpdcch_pdu)); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (UE_list->UE_template[CC_id][UE_id].rach_resource_type > 1) ? 11 : 10; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = narrowBandindex_index; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space - AssertFatal(cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, - "cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 4; // other-RNTI - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = rnti; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (UE_list->UE_template[CC_id][UE_id].rach_resource_type < 3) ? 1 : 2; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_id].physCellId; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB - - //[khalid] missing DCI format should be 10 for 6-1A - - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6); // Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; // adjust according to size of RAR, 208 bits with N1A_PRB=3 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = (round & 3); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = harq_pid; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1;// N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; - UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt++; - dl_req->number_pdu++; - - - - - //eNB_UE_stats->dlsch_trials[round]++; - UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; - - add_ue_dlsch_info(module_idP, - CC_id, - UE_id, - subframeP, - S_DL_SCHEDULED); - - } //repetition_count==0 && SF condition met - else if (UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt > 0) - { - // we're in a stream of repetitions - UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt++; - if (UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt == reps) - { - // this is the last mpdcch repetition - if (cc[CC_id].tdd_Config == NULL) { // FDD case - // wait 2 subframes for PDSCH transmission - if (subframeP > 7) UE_list->UE_template[CC_id][UE_id].Msg2_frame = (frameP + 1) & 1023; - else UE_list->UE_template[CC_id][UE_id].Msg2_frame = frameP; - UE_list->UE_template[CC_id][UE_id].Msg2_subframe = (subframeP + 2) % 10; // +2 is the "n+x" from Section 7.1.11 in 36.213 - } - else { - AssertFatal(1 == 0, "TDD case not done yet\n"); - } - } // mpdcch_repetition_count == reps - if ((UE_list->UE_template[CC_id][UE_id].Msg2_frame == frameP) && (UE_list->UE_template[CC_id][UE_id].Msg2_subframe == subframeP)) { - // Program PDSCH - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 4; // format 6-1A - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = (round & 3); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (UE_list->UE_template[CC_id][UE_id].rach_resource_type < 3) ? 1 : 2;; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; - dl_req->number_pdu++; - - - } - } - - } - - - - - } - - - - - } - else { - LOG_D(MAC, "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", - module_idP, frameP, CC_id, UE_id); - } - } - else - { - // This is a potentially new SDU opportunity // - - rlc_status.bytes_in_buffer = 0; - // Now check RLC information to compute number of required RBs - // get maximum TBS size for RLC request - - - - TBS = 408; - // check first for RLC data on DCCH - // add the length for all the control elements (timing adv, drx, etc) : header + payload - - ta_len = (ue_sched_ctl->ta_update != 0) ? 2 : 0; - - header_len_dcch = 2; // 2 bytes DCCH SDU subheader - - if (TBS - ta_len - header_len_dcch > 0) { - rlc_status = mac_rlc_status_ind( - module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH, - (TBS - ta_len - header_len_dcch)); // transport block set size - - sdu_lengths[0] = 0; - - if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit - LOG_D(MAC, "[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, CC_id, TBS - header_len_dcch); - sdu_lengths[0] = mac_rlc_data_req( - module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH, - TBS, //not used - (char *)&dlsch_buffer[0]); - - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(DCCH), T_INT(sdu_lengths[0])); - - LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", module_idP, CC_id, sdu_lengths[0]); - sdu_length_total = sdu_lengths[0]; - sdu_lcids[0] = DCCH; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; - num_sdus = 1; -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes :", module_idP, CC_id, sdu_lengths[0]); - - for (j = 0; j < sdu_lengths[0]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } - - LOG_T(MAC, "\n"); -#endif - } - else { - header_len_dcch = 0; - sdu_length_total = 0; - } - } - - // check for DCCH1 and update header information (assume 2 byte sub-header) - if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { - rlc_status = mac_rlc_status_ind( - module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH + 1, - (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and - // DCCH SDU - sdu_lengths[num_sdus] = 0; - - if (rlc_status.bytes_in_buffer > 0) { - LOG_I(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, CC_id, TBS - header_len_dcch - sdu_length_total); - sdu_lengths[num_sdus] += mac_rlc_data_req( - module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH + 1, - TBS, //not used - (char *)&dlsch_buffer[sdu_length_total]); - - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); - - sdu_lcids[num_sdus] = DCCH1; - sdu_length_total += sdu_lengths[num_sdus]; - header_len_dcch += 2; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; - num_sdus++; -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d][DCCH1] CC_id %d Got %d bytes :", module_idP, CC_id, sdu_lengths[num_sdus]); - - for (j = 0; j < sdu_lengths[num_sdus]; j++) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); - } - - LOG_T(MAC, "\n"); -#endif - - } - } - - // assume the max dtch header size, and adjust it later - header_len_dtch = 0; - header_len_dtch_last = 0; // the header length of the last mac sdu - // lcid has to be sorted before the actual allocation (similar struct as ue_list). - for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // TBD: check if the lcid is active - - header_len_dtch += 3; - header_len_dtch_last = 3; - LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, frameP, lcid, TBS, - TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch); - - if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? - rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch); - - - if (rlc_status.bytes_in_buffer > 0) { - - LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", - module_idP, frameP, TBS - header_len_dcch - sdu_length_total - header_len_dtch, lcid, header_len_dtch); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS, //not used - (char*)&dlsch_buffer[sdu_length_total]); - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(lcid), T_INT(sdu_lengths[num_sdus])); - - LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid); - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; - if (sdu_lengths[num_sdus] < 128) { - header_len_dtch--; - header_len_dtch_last--; - } - num_sdus++; - } // no data for this LCID - else { - header_len_dtch -= 3; - } - } // no TBS left - else { - header_len_dtch -= 3; - break; - } - } - if (header_len_dtch == 0) - header_len_dtch_last = 0; - // there is at least one SDU - // if (num_sdus > 0 ){ - if ((sdu_length_total + header_len_dcch + header_len_dtch) > 0) { - - // Now compute number of required RBs for total sdu length - // Assume RAH format 2 - // adjust header lengths - header_len_dcch_tmp = header_len_dcch; - header_len_dtch_tmp = header_len_dtch; - if (header_len_dtch == 0) { - header_len_dcch = (header_len_dcch > 0) ? 1 : 0;//header_len_dcch; // remove length field - } - else { - header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU - header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU - } - - //mcs = eNB_UE_stats->dlsch_mcs1; - //if (mcs == 0) { - // nb_rb = 4; // don't let the TBS get too small - //} - //else { - // nb_rb = min_rb_unit[CC_id]; - //} - - //[khalid]: maximum MCS (7 or 15) depend on the DCI formate used from UE_list->UE_template[CC_id [UE_id].rach_resource_type - - mcs = 4; - nb_rb = 6; - - - TBS = 408;//get_TBS_DL(mcs, nb_rb); - - //while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) { - // nb_rb += min_rb_unit[CC_id]; // - - // if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs - // // (can happen if N_RB_DL is odd) - // TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - // nb_rb = nb_available_rb; - // break; - // } - - // TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); - //} - - //if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - //} - //else - //{ - // nb_rb_temp = nb_rb; - // j = 0; - - // while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - // if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - // UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - // if ((j == N_RBG[CC_id] - 1) && - // ((N_RB_DL[CC_id] == 25) || - // (N_RB_DL[CC_id] == 50))) { - // nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; - // } - // else { - // nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; - // } - // } - - // j = j + 1; - // } - //} - - //RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - //RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - - //for(j=0; j<N_RBG[CC_id]; j++) { - //RC.eNB[module_idP][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - - //} - // - // decrease mcs until TBS falls below required length - //while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs > 0)) { - // mcs--; - // TBS = get_TBS_DL(mcs, nb_rb); - //} - - // if we have decreased too much or we don't have enough RBs, increase MCS - //while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) && (mcs < 28)) - // || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) && (mcs <= 15)))) { - // mcs++; - // TBS = get_TBS_DL(mcs, nb_rb); - //} - - LOG_D(MAC, "dlsch_mcs before and after the rate matching = (%d, %d)\n", eNB_UE_stats->dlsch_mcs1, mcs); - -#ifdef DEBUG_eNB_SCHEDULER - LOG_D(MAC, "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP, CC_id, mcs, TBS, nb_rb); - // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", - // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); -#endif - - if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { - padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); - post_padding = 0; - } - else { - padding = 0; - - // adjust the header len - if (header_len_dtch == 0) { - header_len_dcch = header_len_dcch_tmp; - } - else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) - header_len_dtch = header_len_dtch_tmp; - } - - post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header - } - - - offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - num_sdus, //num_sdus - sdu_lengths, // - sdu_lcids, - 255, // no drx - ue_sched_ctl->ta_update, // timing advance - NULL, // contention res id - padding, - post_padding); - - //#ifdef DEBUG_eNB_SCHEDULER - if (ue_sched_ctl->ta_update) { - LOG_I(MAC, - "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", - module_idP, frameP, UE_id, CC_id, sdu_length_total, num_sdus, sdu_lengths[0], sdu_lcids[0], offset, - ue_sched_ctl->ta_update, padding, post_padding, mcs, TBS, nb_rb, header_len_dcch, header_len_dtch); - } - //#endif -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); - - for (i = 0; i < 16; i++) { - LOG_T(MAC, "%x.", dlsch_buffer[i]); - } - - LOG_T(MAC, "\n"); -#endif - // cycle through SDUs and place in dlsch_buffer - memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); - // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); - - // fill remainder of DLSCH with random data - for (j = 0; j < (TBS - sdu_length_total - offset); j++) { - UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char)(taus() & 0xff); - } - - - if (opt_enabled == 1) { - trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - TBS, module_idP, 3, UE_RNTI(module_idP, UE_id), - eNB->frame, eNB->subframe, 0, 0); - LOG_D(OPT, "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, CC_id, frameP, UE_RNTI(module_idP, UE_id), TBS); - } - - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); - - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; - - add_ue_dlsch_info(module_idP, - CC_id, - UE_id, - subframeP, - S_DL_SCHEDULED); - // store stats - eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; - eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; - - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = 4;//eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; - - - - // do PUCCH power control - // this is the normalized RX power - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - normalized_rx_power = eNB_UE_stats->Po_PUCCH_dBm; - target_rx_power = get_target_pucch_rx_power(module_idP, CC_id) + 20; - - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - //int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; - //if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case - // ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around - // if (eNB_UE_stats->Po_PUCCH_update == 1) { - // eNB_UE_stats->Po_PUCCH_update = 0; - - // UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; - // UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; - - // if (normalized_rx_power > (target_rx_power + 1)) { - // tpc = 0; //-1 - // tpc_accumulated--; - // } - // else if (normalized_rx_power < (target_rx_power - 1)) { - // tpc = 2; //+1 - // tpc_accumulated++; - // } - // else { - // tpc = 1; //0 - // } - // - // - - // } // Po_PUCCH has been updated - // else { - // tpc = 1; //0 - // } // time to do TPC update - //else { - // tpc = 1; //0 - //} - - { - - // choose r3 by default for RAR (Table 9.1.5-5) - rep = 2; - // get actual repetition count from Table 9.1.5-3 - reps = (rmax <= 8) ? (1 << rep) : (rmax >> (3 - rep)); - - - - if ((UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt == 0) && - (mpdcch_sf_condition(eNB, CC_id, frameP, subframeP, rmax, TYPEUESPEC,UE_id) > 0)) - { - // MPDCCH configuration for RAR - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2 + sizeof(nfapi_dl_config_mpdcch_pdu)); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (UE_list->UE_template[CC_id][UE_id].rach_resource_type > 1) ? 11 : 10; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = narrowBandindex_index; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space - AssertFatal(cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, - "cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 16; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 4; // other-RNTI - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = rnti; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (UE_list->UE_template[CC_id][UE_id].rach_resource_type < 3) ? 1 : 2; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = cc[CC_id].physCellId; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV(6, 0, 6); // Note: still to be checked if it should not be (getRIV(N_RB_DL,first_rb,6)) : Check nFAPI specifications and what is done L1 with this parameter - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 4; // fix to 4 for now - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = harq_pid; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = rep; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 1;// N1A_PRB=3 (36.212); => 208 bits for mcs=4, choose mcs according t message size TBD - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; - UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt++; - dl_req->number_pdu++; - - - // Toggle NDI for next time - LOG_D(MAC, "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", - CC_id, frameP, subframeP, UE_id, - UE_list->UE_template[CC_id][UE_id].rnti, harq_pid, UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); - - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; - UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; - - eNB->TX_req[CC_id].sfn_sf = (frameP << 3) + subframeP; - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = TBS; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = TBS; - TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[harq_pid]; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - - } //repetition_count==0 && SF condition met - else if (UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt > 0) - { - // we're in a stream of repetitions - UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt++; - if (UE_list->UE_template[CC_id][UE_id].mpdcch_repetition_cnt == reps) - { - // this is the last mpdcch repetition - if (cc[CC_id].tdd_Config == NULL) { // FDD case - // wait 2 subframes for PDSCH transmission - if (subframeP > 7) UE_list->UE_template[CC_id][UE_id].Msg2_frame = (frameP + 1) & 1023; - else UE_list->UE_template[CC_id][UE_id].Msg2_frame = frameP; - UE_list->UE_template[CC_id][UE_id].Msg2_subframe = (subframeP + 2) % 10; // +2 is the "n+x" from Section 7.1.11 in 36.213 - } - else { - AssertFatal(1 == 0, "TDD case not done yet\n"); - } - } // mpdcch_repetition_count == reps - if ((UE_list->UE_template[CC_id][UE_id].Msg2_frame == frameP) && (UE_list->UE_template[CC_id][UE_id].Msg2_subframe == subframeP)) { - // Program PDSCH - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2 + sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 4; // format 6-1A - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 6); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (UE_list->UE_template[CC_id][UE_id].rach_resource_type < 3) ? 1 : 2;; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; - dl_req->number_pdu++; - - // Program UL processing for Msg3, same as regular LTE - //get_Msg3alloc(&cc[CC_idP], subframeP, frameP, &RA_template->Msg3_frame, &RA_template->Msg3_subframe); - - - //fill_rar_br(eNB, CC_idP, RA_template, frameP, subframeP, cc[CC_idP].RAR_pdu.payload, RA_template->rach_resource_type - 1); - //// DL request - //eNB->TX_req[CC_idP].sfn_sf = (frameP << 3) + subframeP; - //TX_req = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; - //TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble - //TX_req->pdu_index = eNB->pdu_index[CC_idP]++; - //TX_req->num_segments = 1; - //TX_req->segments[0].segment_length = 7; - //TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload; - //eNB->TX_req[CC_idP].tx_request_body.number_of_pdus++; - } - } - - } - - //dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - //memset((void*)dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); - //dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - //dl_config_pdu->pdu_size = (uint8_t)(2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), eNB_UE_stats->dl_cqi, format1); - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - ////deactivate second codeword - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; - //dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; - - //dl_req->number_dci++; - //dl_req->number_pdu++; - - - } - else { // There is no data from RLC or MAC header, so don't schedule - - } - } - - if (cc[CC_id].tdd_Config != NULL) { // TDD - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); - } - - } // UE_id loop - } // CC_id loop - - - fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); - - stop_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); - -} +/* +* Schedule the DLSCH */ - - -//------------------------------------------------------------------------------ void -schedule_ue_spec(module_id_t module_idP, int slice_idxP, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) +schedule_ue_spec(module_id_t module_idP, + int slice_idxP, + frame_t frameP, + sub_frame_t subframeP, + int *mbsfn_flag) //------------------------------------------------------------------------------ { int CC_id; @@ -1524,11 +470,19 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, int lcid, offset, num_sdus = 0; int nb_rb, nb_rb_temp, nb_available_rb; uint16_t sdu_lengths[NB_RB_MAX]; - int TBS, j, rnti, padding = 0, post_padding = 0; + int TBS, j, padding = 0, post_padding = 0; + rnti_t rnti; unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - int round = 0; + int round_DL = 0; int harq_pid = 0; + uint16_t release_num; + uint8_t ra_ii; eNB_UE_STATS *eNB_UE_stats = NULL; + UE_TEMPLATE *ue_template = NULL; + eNB_STATS *eNB_stats = NULL; + RRC_release_ctrl *release_ctrl = NULL; + DLSCH_PDU *dlsch_pdu = NULL; + RA_t *ra = NULL; int sdu_length_total = 0; eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = eNB->common_channels; @@ -1536,7 +490,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, int continue_flag = 0; int32_t normalized_rx_power, target_rx_power; int tpc = 1; - UE_sched_ctrl *ue_sched_ctl; + UE_sched_ctrl *ue_sched_ctrl; int mcs; int i; int min_rb_unit[NFAPI_CC_MAX]; @@ -1550,8 +504,11 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, int header_length_last; int header_length_total; rrc_eNB_ue_context_t *ue_contextP = NULL; + int nb_mac_CC = RC.nb_mac_CC[module_idP]; + long dl_Bandwidth; start_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, + VCD_FUNCTION_IN); // for TDD: check that we have to act here, otherwise return if (cc[0].tdd_Config) { @@ -1563,22 +520,17 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, break; case 1: - return; - break; - case 2: return; - break; case 3: - if ((tdd_sfa != 2) && (tdd_sfa != 5)) + if (tdd_sfa != 2 && tdd_sfa != 5) return; break; case 4: - if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) - && (tdd_sfa != 5)) + if (tdd_sfa != 1 && tdd_sfa != 2 && tdd_sfa != 4 && tdd_sfa != 5) return; break; @@ -1588,14 +540,13 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, case 6: case 7: - if ((tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 5)) + if (tdd_sfa != 3 && tdd_sfa != 4 && tdd_sfa != 5) return; break; case 8: - if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) - && (tdd_sfa != 5)) + if (tdd_sfa != 2 && tdd_sfa != 3 && tdd_sfa != 4 && tdd_sfa != 5) return; break; @@ -1608,12 +559,13 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } } - //weight = get_ue_weight(module_idP,UE_id); aggregation = 2; - for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { - N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); + for (CC_id = 0, eNB_stats = &eNB->eNB_stats[0]; CC_id < nb_mac_CC; CC_id++, eNB_stats++) { + dl_Bandwidth = cc[CC_id].mib->message.dl_Bandwidth; + N_RB_DL[CC_id] = to_prb(dl_Bandwidth); min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); + // get number of PRBs less those used by common channels total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; @@ -1621,18 +573,19 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, if (cc[CC_id].vrb_map[i] != 0) total_nb_available_rb[CC_id]--; - N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); + N_RBG[CC_id] = to_rbg(dl_Bandwidth); // store the global enb stats: - eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; - eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; - eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; + eNB_stats->num_dlactive_UEs = UE_list->num_UEs; + eNB_stats->available_prbs = total_nb_available_rb[CC_id]; + eNB_stats->total_available_prbs += total_nb_available_rb[CC_id]; + eNB_stats->dlsch_bytes_tx = 0; + eNB_stats->dlsch_pdus_tx = 0; } // CALLING Pre_Processor for downlink scheduling // (Returns estimation of RBs required by each UE and the allocation on sub-band) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, + VCD_FUNCTION_IN); start_meas(&eNB->schedule_dlsch_preprocessor); dlsch_scheduler_pre_processor(module_idP, slice_idxP, @@ -1641,86 +594,91 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, mbsfn_flag, eNB->slice_info.rballoc_sub); stop_meas(&eNB->schedule_dlsch_preprocessor); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); - - //RC.mac[module_idP]->slice_info.slice_counter--; - // Do the multiplexing and actual allocation only when all slices have been pre-processed. - //if (RC.mac[module_idP]->slice_info.slice_counter > 0) { - //stop_meas(&eNB->schedule_dlsch); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); - //return; - //} + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, + VCD_FUNCTION_OUT); if (RC.mac[module_idP]->slice_info.interslice_share_active) { - dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP, eNB->slice_info.rballoc_sub); + dlsch_scheduler_interslice_multiplexing(module_idP, + frameP, + subframeP, + eNB->slice_info.rballoc_sub); /* the interslice multiplexing re-sorts the UE_list for the slices it tries * to multiplex, so we need to sort it for the current slice again */ - sort_UEs(module_idP, slice_idxP, frameP, subframeP); + sort_UEs(module_idP, + slice_idxP, + frameP, + subframeP); } - for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { - LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); + for (CC_id = 0; CC_id < nb_mac_CC; CC_id++) { + LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", + CC_id); dl_req = &eNB->DL_req[CC_id].dl_config_request_body; if (mbsfn_flag[CC_id] > 0) continue; for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n", CC_id, UE_id); + LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n", + CC_id, + UE_id); + continue_flag = 0; // reset the flag to allow allocation for the remaining UEs rnti = UE_RNTI(module_idP, UE_id); - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + ue_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; + ue_template = &UE_list->UE_template[CC_id][UE_id]; - if (rnti == NOT_A_RNTI) { - LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", UE_id, UE_list->num_UEs); + if (ue_template->rach_resource_type > 0) { continue_flag = 1; } - if (UE_list->UE_template[CC_id][UE_id].rach_resource_type > 0) continue_flag=1; - - if (eNB_UE_stats == NULL) { + if (&(UE_list->eNB_UE_stats[CC_id][UE_id]) == NULL) { LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n"); continue_flag = 1; - } - - if (!ue_dl_slice_membership(module_idP, UE_id, slice_idxP)) { - LOG_D(MAC, "UE%d is not part of slice %d ID %d\n", - UE_id, slice_idxP, RC.mac[module_idP]->slice_info.dl[slice_idxP].id); - /* prevent execution of add_ue_dlsch_info(), it is done by the other - * slice */ - continue; + } else { + eNB_UE_stats = &(UE_list->eNB_UE_stats[CC_id][UE_id]); } if (continue_flag != 1) { - switch (get_tmode(module_idP, CC_id, UE_id)) { + switch (get_tmode(module_idP, + CC_id, + UE_id)) { case 1: case 2: case 7: - aggregation = get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], + aggregation = get_aggregation(get_bw_index(module_idP, + CC_id), + ue_sched_ctrl->dl_cqi[CC_id], format1); break; case 3: - aggregation = get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], + aggregation = get_aggregation(get_bw_index(module_idP, + CC_id), + ue_sched_ctrl->dl_cqi[CC_id], format2A); break; default: AssertFatal(1==0,"Unsupported transmission mode %d\n", get_tmode(module_idP, CC_id, UE_id)); aggregation = 2; + break; } } /* if (continue_flag != 1 */ - if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated - CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, - aggregation, rnti)) { - LOG_D(MAC, - "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", - module_idP, frameP, UE_id, CC_id); + if (ue_sched_ctrl->pre_nb_available_rbs[CC_id] == 0 || // no RBs allocated + CCE_allocation_infeasible(module_idP, + CC_id, + 1, + subframeP, + aggregation, + rnti)) { + LOG_D(MAC, "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", + module_idP, + frameP, + UE_id, + CC_id); continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 } @@ -1732,24 +690,36 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, cc[CC_id].tdd_Config->subframeAssignment, UE_list); // update UL DAI after DLSCH scheduling - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + set_ul_DAI(module_idP, + UE_id, + CC_id, + frameP, + subframeP); } if (continue_flag == 1) { - add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_NONE); + add_ue_dlsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_DL_NONE, + rnti); continue; } - nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); - round = ue_sched_ctl->round[CC_id][harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); - UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; - UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - - if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) { - LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", UE_id); + nb_available_rb = ue_sched_ctrl->pre_nb_available_rbs[CC_id]; + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, + frameP, + subframeP); + round_DL = ue_sched_ctrl->round[CC_id][harq_pid]; + eNB_UE_stats->crnti = rnti; + eNB_UE_stats->rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); + eNB_UE_stats->harq_pid = harq_pid; + eNB_UE_stats->harq_round = round_DL; + + if (eNB_UE_stats->rrc_status < RRC_CONNECTED) { + LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", + UE_id); continue; } @@ -1762,136 +732,164 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); */ - if (nfapi_mode) { - eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + if (NFAPI_MODE != NFAPI_MONOLITHIC) { + eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctrl->dl_cqi[CC_id]]; } else { // this operation is also done in the preprocessor eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, eNB->slice_info.dl[slice_idxP].maxmcs); // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); } // Store stats - // UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; + // eNB_UE_stats->dl_cqi= eNB_UE_stats->dl_cqi; // Initializing the rb allocation indicator for each UE for (j = 0; j < N_RBG[CC_id]; j++) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0; + ue_template->rballoc_subband[harq_pid][j] = 0; } - LOG_D(MAC, - "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", - module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, - nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], + LOG_D(MAC, "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", + module_idP, + frameP, + UE_id, + CC_id, + rnti, + harq_pid, + round_DL, + nb_available_rb, + ue_sched_ctrl->dl_cqi[CC_id], eNB_UE_stats->dlsch_mcs1, - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); + eNB_UE_stats->rrc_status); - /* process retransmission */ - if (round != 8) { + /* Process retransmission */ + if (round_DL != 8) { // get freq_allocation - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid], nb_rb); + nb_rb = ue_template->nb_rb[harq_pid]; + TBS = get_TBS_DL(ue_template->oldmcs1[harq_pid], + nb_rb); if (nb_rb <= nb_available_rb) { + /* CDRX */ + ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer + + if (ue_sched_ctrl->cdrx_configured) { + ue_sched_ctrl->drx_retransmission_timer[harq_pid] = 0; // stop drx retransmission + /* + * Note: contrary to the spec drx_retransmission_timer[harq_pid] is reset not stop. + */ + if (harq_pid == 0) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) ue_sched_ctrl->drx_retransmission_timer[0]); + } + } + if (cc[CC_id].tdd_Config != NULL) { - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id].DAI, subframeP); - LOG_D(MAC, - "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", - CC_id, subframeP, UE_id, - UE_list->UE_template[CC_id][UE_id].DAI); + ue_template->DAI++; + update_ul_dci(module_idP, + CC_id, + rnti, + ue_template->DAI, + subframeP); + LOG_D(MAC, "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", + CC_id, + subframeP, + UE_id, + ue_template->DAI); } - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; ++j) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + if (nb_rb == ue_sched_ctrl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band + ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j]; } } else { nb_rb_temp = nb_rb; j = 0; while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) - printf("WARN: rballoc_subband not free for retrans?\n"); + if (ue_sched_ctrl->rballoc_sub_UE[CC_id][j] == 1) { + if (ue_template->rballoc_subband[harq_pid][j]) + LOG_W(MAC, "WARN: rballoc_subband not free for retrans?\n"); - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j]; + nb_rb_temp -= min_rb_unit[CC_id]; - if ((j == N_RBG[CC_id] - 1) && ((N_RB_DL[CC_id] == 25) || (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; - } else { - nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]; - } + if ((j == N_RBG[CC_id] - 1) && (N_RB_DL[CC_id] == 25 || N_RB_DL[CC_id] == 50)) + nb_rb_temp++; } - j = j + 1; + j++; } } nb_available_rb -= nb_rb; - /* - eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - - for(j = 0; j < N_RBG[CC_id]; ++j) { - eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - } - */ switch (get_tmode(module_idP, CC_id, UE_id)) { case 1: case 2: case 7: default: - LOG_D(MAC, "retransmission DL_REQ: rnti:%x\n", rnti); + LOG_D(MAC, "retransmission DL_REQ: rnti:%x\n", + rnti); dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + memset((void *) dl_config_pdu, + 0, + sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], + get_aggregation(get_bw_index(module_idP, + CC_id), + ue_sched_ctrl->dl_cqi[CC_id], format1); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI: see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // Don't adjust power when retransmitting - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ue_template->oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = ue_template->oldmcs1[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round_DL & 3; // TDD if (cc[CC_id].tdd_Config != NULL) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = - (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - (UE_list->UE_template[CC_id][UE_id].DAI - 1), - UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (ue_template->DAI - 1) & 3; + LOG_D(MAC, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", + module_idP, + CC_id, + harq_pid, + round_DL, + ue_template->DAI - 1, + ue_template->oldmcs1[harq_pid]); } else { - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + LOG_D(MAC, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", + module_idP, + CC_id, + harq_pid, + round_DL, + ue_template->oldmcs1[harq_pid]); } - if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, rnti)) { + if (!CCE_allocation_infeasible(module_idP, + CC_id, + 1, + subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + rnti)) { dl_req->number_dci++; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1, - /* retransmission, no pdu_index */ - rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + fill_nfapi_dlsch_config(eNB, + dl_req, + TBS, + -1, // retransmission, no pdu_index + rnti, + 0, // type 0 allocation from 7.1.6 in 36.213 0, // virtual_resource_block_assignment_flag, unused here 0, // resource_block_coding, to be filled in later - getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), - round & 3, // redundancy version + getQm(ue_template->oldmcs1[harq_pid]), + round_DL & 3, // redundancy version 1, // transport blocks 0, // transport block to codeword swap flag cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme @@ -1899,56 +897,70 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, 1, // number of subbands // uint8_t codebook_index, 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, + ue_template->physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 0, // ngap 0, // nprb cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", - eNB->pdu_index[CC_id], round); - program_dlsch_acknak(module_idP, CC_id, UE_id, frameP, subframeP, + 0); // number of beamforming vectors, not used here + LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", + eNB->pdu_index[CC_id], + round_DL); + program_dlsch_acknak(module_idP, + CC_id, + UE_id, + frameP, + subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); // No TX request for retransmission (check if null request for FAPI) } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", - frameP, subframeP, UE_id, rnti); + LOG_W(MAC, "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", + frameP, + subframeP, + UE_id, + rnti); } } - add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_SCHEDULED); + add_ue_dlsch_info(module_idP, + CC_id, UE_id, + subframeP, + S_DL_SCHEDULED, + rnti); //eNB_UE_stats->dlsch_trials[round]++; - UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; + eNB_UE_stats->num_retransmission += 1; + eNB_UE_stats->rbs_used_retx = nb_rb; + eNB_UE_stats->total_rbs_used_retx += nb_rb; + eNB_UE_stats->dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; } else { LOG_D(MAC, "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", - module_idP, frameP, CC_id, UE_id); + module_idP, + frameP, + CC_id, + UE_id); } - } else { /* This is a potentially new SDU opportunity */ + } else { + /* This is a potentially new SDU opportunity */ rlc_status.bytes_in_buffer = 0; // Now check RLC information to compute number of required RBs // get maximum TBS size for RLC request - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, + nb_available_rb); // add the length for all the control elements (timing adv, drx, etc) : header + payload - if (ue_sched_ctl->ta_timer == 0) { - ta_update = ue_sched_ctl->ta_update; + if (ue_sched_ctrl->ta_timer == 0) { + ta_update = ue_sched_ctrl->ta_update; /* if we send TA then set timer to not send it for a while */ - if (ta_update != 31) - ue_sched_ctl->ta_timer = 20; + if (ta_update != 31) { + ue_sched_ctrl->ta_timer = 20; + } /* reset ta_update */ - ue_sched_ctl->ta_update = 31; + ue_sched_ctrl->ta_update = 31; } else { ta_update = 31; } @@ -1957,23 +969,41 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, // RLC data on DCCH if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, TBS - ta_len - header_length_total - sdu_length_total - 3 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + , 0 + , 0 #endif ); sdu_lengths[0] = 0; if (rlc_status.bytes_in_buffer > 0) { LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, subframeP, CC_id, + module_idP, + frameP, + subframeP, + CC_id, TBS - ta_len - header_length_total - sdu_length_total - 3); - sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + sdu_lengths[0] = mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, TBS, //not used (char *)&dlsch_buffer[0] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + , 0 + , 0 #endif ); pthread_mutex_lock(&rrc_release_freelist); @@ -1981,31 +1011,41 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) { uint16_t release_total = 0; - for(uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { - if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { + for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0]; + release_num < NUMBER_OF_UE_MAX; + release_num++, release_ctrl++) { + if(release_ctrl->flag > 0) { release_total++; } else { continue; } - if(rrc_release_info.RRC_release_ctrl[release_num].flag == 1) { - if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti) { + if(release_ctrl->flag == 1) { + if(release_ctrl->rnti == rnti) { for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { - if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) { - rrc_release_info.RRC_release_ctrl[release_num].flag = 3; - LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 1->3\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num); + if(release_ctrl->rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) { + release_ctrl->flag = 3; + LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 1->3\n", + release_num, + rnti, + rlc_am_mui.rrc_mui[mui_num], + mui_num); break; } } } } - if(rrc_release_info.RRC_release_ctrl[release_num].flag == 2) { - if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti) { - for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { - if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) { - rrc_release_info.RRC_release_ctrl[release_num].flag = 4; - LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num); + if(release_ctrl->flag == 2) { + if(release_ctrl->rnti == rnti) { + for (uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { + if(release_ctrl->rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) { + release_ctrl->flag = 4; + LOG_D(MAC, "DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n", + release_num, + rnti, + rlc_am_mui.rrc_mui[mui_num], + mui_num); break; } } @@ -2018,42 +1058,50 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } pthread_mutex_unlock(&rrc_release_freelist); - RA_t *ra = &eNB->common_channels[CC_id].ra[0]; - - for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++) { - if((ra[ra_ii].rnti == rnti) && (ra[ra_ii].state == MSGCRNTI)) { - for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { - if(ra[ra_ii].crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]) { - ra[ra_ii].crnti_harq_pid = harq_pid; - ra[ra_ii].state = MSGCRNTI_ACK; + + for (ra_ii = 0, ra = &eNB->common_channels[CC_id].ra[0]; ra_ii < NB_RA_PROC_MAX; ra_ii++, ra++) { + if ((ra->rnti == rnti) && (ra->state == MSGCRNTI)) { + for (uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { + if (ra->crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]) { + ra->crnti_harq_pid = harq_pid; + ra->state = MSGCRNTI_ACK; break; } } } } - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), + T(T_ENB_MAC_UE_DL_SDU, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(DCCH), T_INT(sdu_lengths[0])); LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", - module_idP, CC_id, sdu_lengths[0]); + module_idP, + CC_id, + sdu_lengths[0]); sdu_length_total = sdu_lengths[0]; sdu_lcids[0] = DCCH; - UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[0] = DCCH; - UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH] = sdu_lengths[0]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; + eNB_UE_stats->lcid_sdu[0] = DCCH; + eNB_UE_stats->sdu_length_tx[DCCH] = sdu_lengths[0]; + eNB_UE_stats->num_pdu_tx[DCCH] += 1; + eNB_UE_stats->num_bytes_tx[DCCH] += sdu_lengths[0]; header_length_last = 1 + 1 + (sdu_lengths[0] >= 128); header_length_total += header_length_last; num_sdus = 1; #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[0]); + LOG_T(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes :", + module_idP, + CC_id, + sdu_lengths[0]); for (j = 0; j < sdu_lengths[0]; ++j) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); + LOG_T(MAC, "%x ", + dlsch_buffer[j]); } LOG_T(MAC, "\n"); @@ -2063,10 +1111,18 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, // RLC data on DCCH1 if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH + 1, TBS - ta_len - header_length_total - sdu_length_total - 3 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + , 0 + , 0 #endif ); // DCCH SDU @@ -2076,33 +1132,46 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", module_idP, frameP, CC_id, TBS - ta_len - header_length_total - sdu_length_total - 3); - sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, + sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, DCCH + 1, TBS, //not used - (char *)&dlsch_buffer[sdu_length_total] + (char *) &dlsch_buffer[sdu_length_total] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + , 0 + , 0 #endif ); - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); + T(T_ENB_MAC_UE_DL_SDU, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(DCCH + 1), + T_INT(sdu_lengths[num_sdus])); sdu_lcids[num_sdus] = DCCH1; sdu_length_total += sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = DCCH1; - UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH1] = sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; + eNB_UE_stats->lcid_sdu[num_sdus] = DCCH1; + eNB_UE_stats->sdu_length_tx[DCCH1] = sdu_lengths[num_sdus]; + eNB_UE_stats->num_pdu_tx[DCCH1] += 1; + eNB_UE_stats->num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); header_length_total += header_length_last; num_sdus++; #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH1] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[num_sdus]); + LOG_T(MAC, "[eNB %d][DCCH1] CC_id %d Got %d bytes :", + module_idP, + CC_id, + sdu_lengths[num_sdus]); for (j = 0; j < sdu_lengths[num_sdus]; ++j) { - LOG_T(MAC, "%x ", dlsch_buffer[j]); + LOG_T(MAC, "%x ", + dlsch_buffer[j]); } LOG_T(MAC, "\n"); @@ -2131,7 +1200,8 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, lcid, TBS - ta_len - header_length_total - sdu_length_total - 3 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , 0, 0 + , 0 + , 0 #endif ); @@ -2150,9 +1220,10 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, MBMS_FLAG_NO, lcid, TBS, //not used - (char *)&dlsch_buffer[sdu_length_total] + (char *) &dlsch_buffer[sdu_length_total] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , 0, 0 + , 0 + , 0 #endif ); T(T_ENB_MAC_UE_DL_SDU, @@ -2170,16 +1241,18 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, lcid); sdu_lcids[num_sdus] = lcid; sdu_length_total += sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; - UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; - UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; + eNB_UE_stats->num_pdu_tx[lcid]++; + eNB_UE_stats->lcid_sdu[num_sdus] = lcid; + eNB_UE_stats->sdu_length_tx[lcid] = sdu_lengths[num_sdus]; + eNB_UE_stats->num_bytes_tx[lcid] += sdu_lengths[num_sdus]; header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); header_length_total += header_length_last; num_sdus++; - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + ue_sched_ctrl->uplane_inactivity_timer = 0; + // reset RRC inactivity timer after uplane activity ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti); + if (ue_contextP != NULL) { ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; } else { @@ -2194,7 +1267,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } } - /* last header does not have length field */ + /* Last header does not have length field */ if (header_length_total) { header_length_total -= header_length_last; header_length_total++; @@ -2220,25 +1293,27 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs // (can happen if N_RB_DL is odd) - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, + nb_available_rb); nb_rb = nb_available_rb; break; } - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, + nb_rb); } - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + if (nb_rb == ue_sched_ctrl->pre_nb_available_rbs[CC_id]) { for (j = 0; j < N_RBG[CC_id]; ++j) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j]; } } else { nb_rb_temp = nb_rb; j = 0; while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { - UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + if (ue_sched_ctrl->rballoc_sub_UE[CC_id][j] == 1) { + ue_template->rballoc_subband[harq_pid][j] = ue_sched_ctrl->rballoc_sub_UE[CC_id][j]; if ((j == N_RBG[CC_id] - 1) && ((N_RB_DL[CC_id] == 25) || (N_RB_DL[CC_id] == 50))) { nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1; @@ -2247,33 +1322,34 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } } - j = j + 1; + j++; } } // decrease mcs until TBS falls below required length while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) { mcs--; - TBS = get_TBS_DL(mcs, nb_rb); + TBS = get_TBS_DL(mcs, + nb_rb); } // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < sdu_length_total + header_length_total + ta_len) - && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) - && (mcs < 28)) - || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) - && (mcs <= 15)))) { + while (TBS < sdu_length_total + header_length_total + ta_len && + ((ue_sched_ctrl->dl_pow_off[CC_id] > 0 && mcs < 28) || (ue_sched_ctrl->dl_pow_off[CC_id] == 0 && mcs <= 15))) { mcs++; - TBS = get_TBS_DL(mcs, nb_rb); + TBS = get_TBS_DL(mcs, + nb_rb); } - LOG_D(MAC, - "dlsch_mcs before and after the rate matching = (%d, %d)\n", - eNB_UE_stats->dlsch_mcs1, mcs); + LOG_D(MAC, "dlsch_mcs before and after the rate matching = (%d, %d)\n", + eNB_UE_stats->dlsch_mcs1, + mcs); #ifdef DEBUG_eNB_SCHEDULER - LOG_D(MAC, - "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP, CC_id, mcs, TBS, nb_rb); + LOG_D(MAC, "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP, + CC_id, + mcs, TBS, + nb_rb); // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); #endif @@ -2289,19 +1365,32 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus sdu_lengths, // - sdu_lcids, 255, // no drx + sdu_lcids, + 255, // no drx ta_update, // timing advance NULL, // contention res id - padding, post_padding); + padding, + post_padding); //#ifdef DEBUG_eNB_SCHEDULER if (ta_update != 31) { LOG_D(MAC, "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_length %d\n", - module_idP, frameP, UE_id, CC_id, - sdu_length_total, num_sdus, sdu_lengths[0], - sdu_lcids[0], offset, ta_update, padding, - post_padding, mcs, TBS, nb_rb, + module_idP, + frameP, + UE_id, + CC_id, + sdu_length_total, + num_sdus, + sdu_lengths[0], + sdu_lcids[0], + offset, + ta_update, + padding, + post_padding, + mcs, + TBS, + nb_rb, header_length_total); } @@ -2309,77 +1398,100 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); - for (i = 0; i < 16; ++i) { - LOG_T(MAC, "%x.", dlsch_buffer[i]); + for (i = 0; i < 16; i++) { + LOG_T(MAC, "%x.", + dlsch_buffer[i]); } LOG_T(MAC, "\n"); #endif // cycle through SDUs and place in dlsch_buffer - memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); + dlsch_pdu = &UE_list->DLSCH_pdu[CC_id][0][UE_id]; + memcpy(&dlsch_pdu->payload[0][offset], + dlsch_buffer, + sdu_length_total); // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); // fill remainder of DLSCH with 0 for (j = 0; j < (TBS - sdu_length_total - offset); j++) { - UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0; + dlsch_pdu->payload[0][offset + sdu_length_total + j] = 0; } if (opt_enabled == 1) { trace_pdu(DIRECTION_DOWNLINK, - (uint8_t *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - TBS, module_idP, WS_C_RNTI, - UE_RNTI(module_idP, UE_id), eNB->frame, - eNB->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, CC_id, frameP, - UE_RNTI(module_idP, UE_id), TBS); + (uint8_t *) dlsch_pdu->payload[0], + TBS, + module_idP, + WS_C_RNTI, + UE_RNTI(module_idP, + UE_id), + eNB->frame, + eNB->subframe, + 0, + 0); + LOG_D(OPT, "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", + module_idP, + CC_id, + frameP, + UE_RNTI(module_idP, + UE_id), + TBS); } - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; - add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_SCHEDULED); + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_BUFFER(dlsch_pdu->payload[0], + TBS)); + ue_template->nb_rb[harq_pid] = nb_rb; + add_ue_dlsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_DL_SCHEDULED, + rnti); // store stats eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].num_mac_sdu_tx = num_sdus; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; + eNB_UE_stats->rbs_used = nb_rb; + eNB_UE_stats->num_mac_sdu_tx = num_sdus; + eNB_UE_stats->total_rbs_used += nb_rb; + eNB_UE_stats->dlsch_mcs2 = mcs; + eNB_UE_stats->TBS = TBS; + eNB_UE_stats->overhead_bytes = TBS - sdu_length_total; + eNB_UE_stats->total_sdu_bytes += sdu_length_total; + eNB_UE_stats->total_pdu_bytes += TBS; + eNB_UE_stats->total_num_pdus += 1; if (cc[CC_id].tdd_Config != NULL) { // TDD - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id].DAI, + ue_template->DAI++; + update_ul_dci(module_idP, + CC_id, + rnti, + ue_template->DAI, subframeP); } // do PUCCH power control // this is the normalized RX power - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - /* unit is not dBm, it's special from nfapi */ + // unit is not dBm, it's special from nfapi // converting to dBm: ToDo: Noise power hard coded to 30 - normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30; - target_rx_power= eNB->puCch10xSnr/10 + 30; + normalized_rx_power = (((5 * ue_sched_ctrl->pucch1_snr[CC_id]) - 640) / 10) + 30; + target_rx_power= (eNB->puCch10xSnr / 10) + 30; // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; + int32_t framex10psubframe = ue_template->pucch_tpc_tx_frame * 10 + ue_template->pucch_tpc_tx_subframe; - if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case - ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around - if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { - ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; + if (framex10psubframe + 10 <= (frameP * 10) + subframeP || //normal case + (framex10psubframe > (frameP * 10) + subframeP && 10240 - framex10psubframe + (frameP * 10) + subframeP >= 10)) //frame wrap-around + if (ue_sched_ctrl->pucch1_cqi_update[CC_id] == 1) { + ue_sched_ctrl->pucch1_cqi_update[CC_id] = 0; + ue_template->pucch_tpc_tx_frame = frameP; + ue_template->pucch_tpc_tx_subframe = subframeP; if (normalized_rx_power > (target_rx_power + 4)) { tpc = 0; //-1 @@ -2389,10 +1501,14 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, tpc = 1; //0 } - LOG_D(MAC, - "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, tpc, - normalized_rx_power, target_rx_power); + LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", + module_idP, + frameP, + subframeP, + harq_pid, + tpc, + normalized_rx_power, + target_rx_power); } // Po_PUCCH has been updated else { tpc = 1; //0 @@ -2402,20 +1518,24 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + memset((void *) dl_config_pdu, + 0, + sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index(module_idP, CC_id), ue_sched_ctl->dl_cqi[CC_id], format1); + get_aggregation(get_bw_index(module_idP, + CC_id), + ue_sched_ctrl->dl_cqi[CC_id], + format1); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = - 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1 - ue_template->oldNDI[harq_pid]; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; //deactivate second codeword @@ -2423,47 +1543,77 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = - (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; - LOG_D(MAC, - "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, - (UE_list->UE_template[CC_id][UE_id].DAI - 1), + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (ue_template->DAI - 1) & 3; + LOG_D(MAC, "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", + module_idP, + CC_id, + harq_pid, + (ue_template->DAI - 1), mcs); } else { - LOG_D(MAC, - "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", - module_idP, CC_id, harq_pid, mcs); + LOG_D(MAC, "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", + module_idP, + CC_id, + harq_pid, + mcs); } LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n", dl_req->number_pdu); - if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, rnti)) { - ue_sched_ctl->round[CC_id][harq_pid] = 0; + if (!CCE_allocation_infeasible(module_idP, + CC_id, + 1, + subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + rnti)) { + ue_sched_ctrl->round[CC_id][harq_pid] = 0; dl_req->number_dci++; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; eNB->DL_req[CC_id].sfn_sf = frameP << 4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + + /* CDRX */ + ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer + + if (ue_sched_ctrl->cdrx_configured) { + ue_sched_ctrl->drx_inactivity_timer = 1; // restart drx inactivity timer when new transmission + ue_sched_ctrl->drx_retransmission_timer[harq_pid] = 0; // stop drx retransmission + /* + * Note: contrary to the spec drx_retransmission_timer[harq_pid] is reset not stop. + */ + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) ue_sched_ctrl->drx_inactivity_timer); + if (harq_pid == 0) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_RETRANSMISSION_HARQ0, (unsigned long) ue_sched_ctrl->drx_retransmission_timer[0]); + } + } + // Toggle NDI for next time - LOG_D(MAC, - "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", - CC_id, frameP, subframeP, UE_id, rnti, harq_pid, - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; - UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, - "physicalConfigDedicated is NULL\n"); - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated != NULL, + LOG_D(MAC, "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", + CC_id, + frameP, + subframeP, + UE_id, + rnti, + harq_pid, + ue_template->oldNDI[harq_pid]); + ue_template->oldNDI[harq_pid] = 1 - ue_template->oldNDI[harq_pid]; + ue_template->oldmcs1[harq_pid] = mcs; + ue_template->oldmcs2[harq_pid] = 0; + AssertFatal(ue_template->physicalConfigDedicated != NULL, "physicalConfigDedicated is NULL\n"); + AssertFatal(ue_template->physicalConfigDedicated->pdsch_ConfigDedicated != NULL, "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); - fill_nfapi_dlsch_config(eNB, dl_req, TBS, eNB->pdu_index[CC_id], rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + fill_nfapi_dlsch_config(eNB, + dl_req, + TBS, + eNB->pdu_index[CC_id], + rnti, + 0, // type 0 allocation from 7.1.6 in 36.213 0, // virtual_resource_block_assignment_flag, unused here 0, // resource_block_coding, to be filled in later - getQm(mcs), 0, // redundancy version + getQm(mcs), + 0, // redundancy version 1, // transport blocks 0, // transport block to codeword swap flag cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme @@ -2471,57 +1621,73 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, 1, // number of subbands // uint8_t codebook_index, 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 + ue_template->physicalConfigDedicated->pdsch_ConfigDedicated->p_a, + 0, // delta_power_offset for TM5 0, // ngap 0, // nprb cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); + 0); // number of beamforming vectors, not used here eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, (frameP * 10) + subframeP, - TBS, eNB->pdu_index[CC_id], - eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0]); - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", + TBS, + eNB->pdu_index[CC_id], + dlsch_pdu->payload[0]); + LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", eNB->pdu_index[CC_id]); eNB->pdu_index[CC_id]++; - program_dlsch_acknak(module_idP, CC_id, UE_id, - frameP, subframeP, + program_dlsch_acknak(module_idP, + CC_id, + UE_id, + frameP, + subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", - frameP, subframeP, UE_id, rnti); + LOG_W(MAC, "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", + frameP, + subframeP, + UE_id, + rnti); } } else { // There is no data from RLC or MAC header, so don't schedule } } if (cc[CC_id].tdd_Config != NULL) { // TDD - set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); + set_ul_DAI(module_idP, + UE_id, + CC_id, + frameP, + subframeP); } } // UE_id loop } // CC_id loop - fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); + fill_DLSCH_dci(module_idP, + frameP, + subframeP, + mbsfn_flag); stop_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, + VCD_FUNCTION_OUT); } //------------------------------------------------------------------------------ -void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, - int frameP, - sub_frame_t subframeP, - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) +void +dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, + int frameP, + sub_frame_t subframeP, + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) //------------------------------------------------------------------------------ { // FIXME: I'm prototyping the algorithm, so there may be arrays and variables that carry redundant information here and in pre_processor_results struct. int UE_id, CC_id, rbg, i; int N_RB_DL, min_rb_unit, tm; int owned, used; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - slice_info_t *sli = &RC.mac[Mod_id]->slice_info; + eNB_MAC_INST *eNB = RC.mac[Mod_id]; + int nb_mac_CC = RC.nb_mac_CC[Mod_id]; + UE_list_t *UE_list = &eNB->UE_list; + slice_info_t *sli = &eNB->slice_info; UE_sched_ctrl *ue_sched_ctl; COMMON_channels_t *cc; int N_RBG[NFAPI_CC_MAX]; @@ -2539,11 +1705,11 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, // otherwise it contains the id of the slice it belongs to. // (Information about slicing must be retained to deal with isolation). // FIXME: This method does not consider RBGs that are free and belong to no slices - for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { - cc = &RC.mac[Mod_id]->common_channels[CC_id]; + for (CC_id = 0; CC_id < nb_mac_CC; CC_id++) { + cc = &eNB->common_channels[CC_id]; N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); - for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { + for (rbg = 0; rbg < N_RBG[CC_id]; rbg++) { for (i = 0; i < sli->n_dl; ++i) { owned = sli->pre_processor_results[i].slice_allocation_mask[CC_id][rbg]; @@ -2558,11 +1724,11 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, // Find out which slices need other resources. // FIXME: I don't think is really needed since we check nb_rbs_remaining later - for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { - for (i = 0; i < sli->n_dl; ++i) { + for (CC_id = 0; CC_id < nb_mac_CC; CC_id++) { + for (i = 0; i < sli->n_dl; i++) { has_traffic[CC_id][i] = 0; - for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { if (sli->pre_processor_results[i].nb_rbs_remaining[CC_id][UE_id] > 0) { has_traffic[CC_id][i] = 1; break; @@ -2571,13 +1737,15 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, } } - slice_priority_sort(Mod_id, slice_sorted_list); + slice_priority_sort(Mod_id, + slice_sorted_list); // MULTIPLEXING // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code - for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { - N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - min_rb_unit = get_min_rb_unit(Mod_id, CC_id); + for (CC_id = 0; CC_id < nb_mac_CC; ++CC_id) { + N_RB_DL = to_prb(eNB->common_channels[CC_id].mib->message.dl_Bandwidth); + min_rb_unit = get_min_rb_unit(Mod_id, + CC_id); for (i = 0; i < sli->n_dl; ++i) { slice_idx = slice_sorted_list[i]; @@ -2605,7 +1773,10 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, // Sort UE again // (UE list gets sorted every time pre_processor is called so it is probably dirty at this point) // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it - sort_UEs(Mod_id, slice_idx, frameP, subframeP); + sort_UEs(Mod_id, + slice_idx, + frameP, + subframeP); nb_rbs_remaining = sli->pre_processor_results[slice_idx].nb_rbs_remaining; nb_rbs_required = sli->pre_processor_results[slice_idx].nb_rbs_required; MIMO_mode_indicator = sli->pre_processor_results[slice_idx].MIMO_mode_indicator; @@ -2613,7 +1784,9 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, // Allocation for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - tm = get_tmode(Mod_id, CC_id, UE_id); + tm = get_tmode(Mod_id, + CC_id, + UE_id); for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { // FIXME: I think that some of these checks are redundant @@ -2641,8 +1814,8 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, ue_sched_ctl->dl_pow_off[CC_id] = 1; } - nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit + 1; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; + nb_rbs_remaining[CC_id][UE_id] -= (min_rb_unit - 1); + ue_sched_ctl->pre_nb_available_rbs[CC_id] += (min_rb_unit - 1); } } else { // Allocating a standard-sized RBG @@ -2656,36 +1829,43 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, ue_sched_ctl->dl_pow_off[CC_id] = 1; } - nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; + nb_rbs_remaining[CC_id][UE_id] -= min_rb_unit; + ue_sched_ctl->pre_nb_available_rbs[CC_id] += min_rb_unit; } } } } } } + + return; } //------------------------------------------------------------------------------ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_t subframeP) //------------------------------------------------------------------------------ { - int UE_id, CC_id, i; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + // int UE_id; + int CC_id, i; + // UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; slice_info_t *sli = &RC.mac[Mod_id]->slice_info; //UE_sched_ctrl *ue_sched_ctl; - for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { - for (i = 0; i < sli->n_dl; ++i) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + for (i = 0; i < sli->n_dl; i++) { // Sort UE again // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it - sort_UEs(Mod_id, (uint8_t)i, frameP, subframeP); - + sort_UEs(Mod_id, + (uint8_t)i, + frameP, + subframeP); + /* for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { //ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; // TODO: Do something here // ue_sched_ctl->pre_nb_available_rbs[CC_id]; } + */ } } } @@ -2693,197 +1873,225 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //------------------------------------------------------------------------------ +/* + * Default DLSCH scheduler for LTE-M + */ void -schedule_ue_spec_br( - module_id_t module_idP, - frame_t frameP, - sub_frame_t subframeP - ) { - int CC_id = 0,UE_id; - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc = mac->common_channels; - UE_list_t *UE_list = &mac->UE_list; - UE_TEMPLATE *UE_template; - UE_sched_ctrl *ue_sched_ctl; - int32_t tpc=1; +schedule_ue_spec_br(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) +//------------------------------------------------------------------------------ +{ + int CC_id = 0; + int UE_id = -1; int rvseq[4] = {0,2,3,1}; - mac_rlc_status_resp_t rlc_status; - unsigned char header_len_dcch=0, header_len_dcch_tmp=0; - unsigned char header_len_dtch=0, header_len_dtch_tmp=0, header_len_dtch_last=0; - unsigned char ta_len=0; - unsigned char sdu_lcids[NB_RB_MAX],lcid,offset,num_sdus=0; - uint16_t TBS,j,sdu_lengths[NB_RB_MAX],rnti,padding=0,post_padding=0; - unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - int round; - int ta_update; + int mcs = 0; + int round_DL = 0; + int ta_update = 0; + int32_t tpc = 1; + int32_t normalized_rx_power = 0; + int32_t target_rx_power = 0; + uint16_t TBS = 0; + uint16_t j = 0; + uint16_t sdu_lengths[NB_RB_MAX]; + uint16_t rnti = 0; + uint16_t padding = 0; + uint16_t post_padding = 0; uint16_t sdu_length_total = 0; - int mcs; - int32_t normalized_rx_power, target_rx_power; - - nfapi_dl_config_request_pdu_t *dl_config_pdu; - nfapi_ul_config_request_pdu_t *ul_config_pdu; - nfapi_tx_request_pdu_t *TX_req; - nfapi_dl_config_request_body_t *dl_req; - nfapi_ul_config_request_body_t *ul_req; - - struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach; - struct LTE_PUCCH_ConfigCommon_v1310 *ext4_pucch; - LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; - struct LTE_N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13; + mac_rlc_status_resp_t rlc_status; + rrc_eNB_ue_context_t *ue_contextP = NULL; + unsigned char header_len_dcch = 0; + unsigned char header_len_dcch_tmp = 0; + unsigned char header_len_dtch = 0; + unsigned char header_len_dtch_tmp = 0; + unsigned char header_len_dtch_last = 0; + unsigned char ta_len = 0; + unsigned char sdu_lcids[NB_RB_MAX]; + unsigned char lcid = 0; + unsigned char offset,num_sdus=0; + unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; + eNB_MAC_INST *mac = RC.mac[module_idP]; + COMMON_channels_t *cc = mac->common_channels; + UE_list_t *UE_list = &mac->UE_list; + UE_TEMPLATE *UE_template = NULL; + UE_sched_ctrl *ue_sched_ctl = NULL; + nfapi_dl_config_request_pdu_t *dl_config_pdu = NULL; + nfapi_ul_config_request_pdu_t *ul_config_pdu = NULL; + nfapi_tx_request_pdu_t *TX_req = NULL; + nfapi_dl_config_request_body_t *dl_req = NULL; + nfapi_ul_config_request_body_t *ul_req = NULL; + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = NULL; + struct LTE_PUCCH_ConfigCommon_v1310 *ext4_pucch = NULL; + LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL; + struct LTE_N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13 = NULL; int pucchreps[4] = { 1, 1, 1, 1 }; - int n1pucchan[4] = { 0, 0, 0, 0 }; + int n1pucchan[4] = { 0, 0, 0, 0 }; uint32_t ackNAK_absSF; int first_rb; + dl_req = &(mac->DL_req[CC_id].dl_config_request_body); + dl_config_pdu = &(dl_req->dl_config_pdu_list[dl_req->number_pdu]); - dl_req = &mac->DL_req[CC_id].dl_config_request_body; - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - - if ((frameP&1) == 0) return; + /* Return if frame is even */ + if ((frameP & 1) == 0) { + return; + } - if (cc[CC_id].mib->message.schedulingInfoSIB1_BR_r13 ==0) return; + if (cc[CC_id].mib->message.schedulingInfoSIB1_BR_r13 == 0) { + return; + } if (cc[CC_id].radioResourceConfigCommon_BR) { - ext4_prach = cc[CC_id].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; ext4_pucch = cc[CC_id].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310; prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13; AssertFatal (prach_ParametersListCE_r13 != NULL, "prach_ParametersListCE_r13 is null\n"); AssertFatal (pucch_N1PUCCH_AN_InfoList_r13 != NULL, "pucch_N1PUCCH_AN_InfoList_r13 is null\n"); - // check to verify CE-Level compatibility in SIB2_BR + /* Check to verify CE-Level compatibility in SIB2_BR */ AssertFatal (prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count, "prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n"); switch (prach_ParametersListCE_r13->list.count) { - case 4: - n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3]; - AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n"); - pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13); + case 4: + n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3]; + AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n"); + pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13); - case 3: - n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2]; - AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n"); - pucchreps[2] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13); - case 2: - n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1]; - AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n"); - pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13); - case 1: - n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0]; - AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n"); - pucchreps[0] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13); - break; - default: - AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", prach_ParametersListCE_r13->list.count); + case 3: + n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2]; + AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n"); + pucchreps[2] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13); + + case 2: + n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1]; + AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n"); + pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13); + + case 1: + n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0]; + AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n"); + pucchreps[0] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13); + break; + + default: + AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", prach_ParametersListCE_r13->list.count); } } - for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { - + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { int harq_pid = 0; + rnti = UE_RNTI(module_idP, UE_id); - rnti = UE_RNTI(module_idP,UE_id); - if (rnti==NOT_A_RNTI) continue; + if (rnti==NOT_A_RNTI) { + continue; + } - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - UE_template = &UE_list->UE_template[CC_id][UE_id]; + ue_sched_ctl = &(UE_list->UE_sched_ctrl[UE_id]); + UE_template = &(UE_list->UE_template[CC_id][UE_id]); - if (UE_template->rach_resource_type == 0) continue; - uint8_t rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); + if (UE_template->rach_resource_type == 0) { + continue; + } - if (rrc_status < RRC_CONNECTED) continue; + uint8_t rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); - round = ue_sched_ctl->round[CC_id][harq_pid]; + if (rrc_status < RRC_CONNECTED) { + continue; + } - AssertFatal (UE_template->physicalConfigDedicated != NULL, - "UE_template->physicalConfigDedicated is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, - "UE_template->physicalConfigDedicated->ext4 is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); + round_DL = ue_sched_ctl->round[CC_id][harq_pid]; + AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); - + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; - AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); - AssertFatal(epdcch_setconfig_r11->ext2!=NULL, "epdcch_setconfig_r11->ext2 is null\n"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present==LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); - AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310!=NULL, - "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present==LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, - "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); - - - // simple scheduler for 1 repetition, 1 HARQ + AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, + "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); + + /* Simple scheduler for 1 repetition, 1 HARQ */ if (subframeP == 5) { // MPDCCH + if (round_DL < 8) LOG_D(MAC, "MPDCCH round_DL = %d in frame %d subframe %d\n", round_DL, frameP, subframeP); - if (round == 8) { + if (round_DL == 8) { rlc_status.bytes_in_buffer = 0; - // Now check RLC information to compute number of required RBs - // get maximum TBS size for RLC request + /* Now check RLC information to compute number of required RBs */ + /* Get maximum TBS size for RLC request */ TBS = get_TBS_DL(9,6); - // check first for RLC data on DCCH - // add the length for all the control elements (timing adv, drx, etc) : header + payload + + /* Check first for RLC data on DCCH */ + + /* Add the length for all the control elements (timing adv, drx, etc) : header + payload */ if (ue_sched_ctl->ta_timer == 0) { ta_update = ue_sched_ctl->ta_update; - /* if we send TA then set timer to not send it for a while */ + + /* If we send TA then set timer to not send it for a while */ if (ta_update != 31) ue_sched_ctl->ta_timer = 20; - /* reset ta_update */ + + /* Reset ta_update */ ue_sched_ctl->ta_update = 31; } else { ta_update = 31; } ta_len = (ta_update != 31) ? 2 : 0; - header_len_dcch = 2; // 2 bytes DCCH SDU subheader - if ( TBS-ta_len-header_len_dcch > 0 ) { - LOG_I(MAC,"Calling mac_rlc_status_ind for DCCH\n"); - rlc_status = mac_rlc_status_ind( - module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH, - (TBS-ta_len-header_len_dcch) - ,0, 0 - ); // transport block set size - - sdu_lengths[0]=0; + if (TBS - ta_len-header_len_dcch > 0 ) { + LOG_D(MAC, "Calling mac_rlc_status_ind for DCCH\n"); + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, + (TBS-ta_len-header_len_dcch), + 0, + 0); // transport block set size + sdu_lengths[0] = 0; if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit - LOG_I(MAC,"[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP,frameP,CC_id,TBS-header_len_dcch); - sdu_lengths[0] = mac_rlc_data_req( - module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH, - TBS, //not used - (char *)&dlsch_buffer[0] - ,0, 0 -); - - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(DCCH), T_INT(sdu_lengths[0])); - - LOG_I(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",module_idP,CC_id,sdu_lengths[0]); + LOG_D(MAC, "[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, + frameP, + CC_id, + TBS-header_len_dcch); + sdu_lengths[0] = mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, + TBS, //not used + (char *)&dlsch_buffer[0], + 0, + 0); + T(T_ENB_MAC_UE_DL_SDU, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(DCCH), + T_INT(sdu_lengths[0])); + LOG_D(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", + module_idP, + CC_id, + sdu_lengths[0]); sdu_length_total = sdu_lengths[0]; sdu_lcids[0] = DCCH; UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH]+=1; @@ -2894,151 +2102,187 @@ schedule_ue_spec_br( sdu_length_total = 0; } } - - // check for DCCH1 and update header information (assume 2 byte sub-header) - if (TBS-ta_len-header_len_dcch-sdu_length_total > 0 ) { - rlc_status = mac_rlc_status_ind( - module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH+1, - (TBS-ta_len-header_len_dcch-sdu_length_total) - ,0, 0); // transport block set size less allocations for timing advance and - // DCCH SDU - sdu_lengths[num_sdus] = 0; - - if (rlc_status.bytes_in_buffer > 0) { - LOG_I(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP,frameP,CC_id,TBS-header_len_dcch-sdu_length_total); - sdu_lengths[num_sdus] += mac_rlc_data_req( - module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - DCCH+1, - TBS, //not used - (char *)&dlsch_buffer[sdu_length_total] - ,0, 0 - ); - - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(DCCH+1), T_INT(sdu_lengths[num_sdus])); + /* Check for DCCH1 and update header information (assume 2 byte sub-header) */ + if (TBS - ta_len-header_len_dcch - sdu_length_total > 0) { + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH + 1, + (TBS-ta_len-header_len_dcch-sdu_length_total), + 0, + 0); // transport block set size less allocations for timing advance and DCCH SDU + sdu_lengths[num_sdus] = 0; + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, + frameP, + CC_id, + TBS-header_len_dcch - sdu_length_total); + sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH+1, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total], + 0, + 0); + T(T_ENB_MAC_UE_DL_SDU, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(DCCH+1), + T_INT(sdu_lengths[num_sdus])); sdu_lcids[num_sdus] = DCCH1; sdu_length_total += sdu_lengths[num_sdus]; header_len_dcch += 2; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1]+=1; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]+=sdu_lengths[num_sdus]; - num_sdus++; - } + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; + num_sdus++; + } } - // assume the max dtch header size, and adjust it later - header_len_dtch=0; - header_len_dtch_last=0; // the header length of the last mac sdu - // lcid has to be sorted before the actual allocation (similar struct as ue_list). - for (lcid=NB_RB_MAX-1; lcid>=DTCH ; lcid--){ - // TBD: check if the lcid is active - - header_len_dtch+=3; - header_len_dtch_last=3; - LOG_D(MAC,"[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP,frameP,lcid,TBS, - TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); - - if (TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch > 0 ) { // NN: > 2 ? - rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch - ,0, 0); - - - if (rlc_status.bytes_in_buffer > 0) { - - LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", - module_idP,frameP,TBS-header_len_dcch-sdu_length_total-header_len_dtch,lcid, header_len_dtch); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS, //not used - (char*)&dlsch_buffer[sdu_length_total] - ,0, 0); - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(lcid), T_INT(sdu_lengths[num_sdus])); - - LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",module_idP,sdu_lengths[num_sdus],lcid); - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - - if (sdu_lengths[num_sdus] < 128) { - header_len_dtch--; - header_len_dtch_last--; - } - num_sdus++; - } // no data for this LCID - else { - header_len_dtch-=3; - } - } // no TBS left - else { - header_len_dtch-=3; - break; - } - } - if (header_len_dtch == 0 ) - header_len_dtch_last= 0; - // there is at least one SDU - // if (num_sdus > 0 ){ - if ((sdu_length_total + header_len_dcch + header_len_dtch )> 0) { - - // Now compute number of required RBs for total sdu length - // Assume RAH format 2 - // adjust header lengths - header_len_dcch_tmp = header_len_dcch; - header_len_dtch_tmp = header_len_dtch; - if (header_len_dtch==0) { - header_len_dcch = (header_len_dcch >0) ? 1 : 0;//header_len_dcch; // remove length field - } else { - header_len_dtch_last-=1; // now use it to find how many bytes has to be removed for the last MAC SDU - header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last :header_len_dtch; // remove length field for the last SDU - } + /* Assume the max dtch header size, and adjust it later */ + header_len_dtch = 0; + header_len_dtch_last = 0; // the header length of the last mac sdu + + /* lcid has to be sorted before the actual allocation (similar struct as ue_list) */ + for (lcid = NB_RB_MAX-1; lcid >= DTCH ; lcid--) { + /* TBD: check if the lcid is active */ + header_len_dtch += 3; + header_len_dtch_last = 3; + LOG_D(MAC,"[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, + frameP, + lcid, + TBS, + TBS - ta_len-header_len_dcch - sdu_length_total - header_len_dtch); + + if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch, + 0, + 0); + + if (rlc_status.bytes_in_buffer > 0) { + /* RRC inactivity LTE-M */ + /* Reset RRC inactivity timer after uplane activity */ + ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti); + + if (ue_contextP != NULL) { + ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + } else { + LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n", + module_idP, + CC_id, + rnti); + } + + LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", + module_idP, + frameP, + TBS - header_len_dcch - sdu_length_total - header_len_dtch, + lcid, + header_len_dtch); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS, //not used + (char *) &dlsch_buffer[sdu_length_total], + 0, + 0); + T(T_ENB_MAC_UE_DL_SDU, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(lcid), + T_INT(sdu_lengths[num_sdus])); + LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_idP, + sdu_lengths[num_sdus], + lcid); + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + + if (sdu_lengths[num_sdus] < 128) { + header_len_dtch--; + header_len_dtch_last--; + } + + num_sdus++; + } else { // no data for this LCID + header_len_dtch -= 3; + } + } else { // no TBS left + header_len_dtch -= 3; + break; + } + } // for loop LCID + + if (header_len_dtch == 0) { + header_len_dtch_last = 0; + } + + /* There is at least one SDU */ + if ((sdu_length_total + header_len_dcch + header_len_dtch) > 0) { + /* Now compute number of required RBs for total sdu length */ + /* Assume RAH format 2 */ + /* Adjust header lengths */ + header_len_dcch_tmp = header_len_dcch; + header_len_dtch_tmp = header_len_dtch; + + if (header_len_dtch == 0) { + header_len_dcch = (header_len_dcch > 0) ? 1 : 0; // remove length field + } else { + header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU + header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU + } mcs = 9; - // decrease mcs until TBS falls below required length + /* Decrease mcs until TBS falls below required length */ while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) { mcs--; TBS = get_TBS_DL(mcs,6); } - // if we have decreased too much or we don't have enough RBs, increase MCS + /* If we have decreased too much or we don't have enough RBs, increase MCS */ while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) { mcs++; TBS = get_TBS_DL(mcs,6); } - //#ifdef DEBUG_eNB_SCHEDULER - LOG_I(MAC,"[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP,CC_id,mcs,TBS,6); - // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", - // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); - + LOG_D(MAC, "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP, + CC_id, + mcs, + TBS, + 6); if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); @@ -3046,18 +2290,17 @@ schedule_ue_spec_br( } else { padding = 0; - // adjust the header len - if (header_len_dtch==0) { + /* Adjust the header len */ + if (header_len_dtch == 0) { header_len_dcch = header_len_dcch_tmp; - } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) + } else { // if ((header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) header_len_dtch = header_len_dtch_tmp; } - post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len ; // 1 is for the postpadding header + post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header } - - offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + offset = generate_dlsch_header((unsigned char *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus sdu_lengths, // sdu_lcids, @@ -3067,147 +2310,175 @@ schedule_ue_spec_br( padding, post_padding); - if (ta_update != 31) { LOG_D(MAC, "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", - module_idP,frameP, UE_id, CC_id, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset, - ta_update,padding,post_padding,mcs,TBS,6,header_len_dcch,header_len_dtch); - } - - + module_idP, + frameP, + UE_id, + CC_id, + sdu_length_total, + num_sdus, + sdu_lengths[0], + sdu_lcids[0], + offset, + ta_update, + padding, + post_padding, + mcs, + TBS, + 6, + header_len_dcch, + header_len_dtch); + } - // cycle through SDUs and place in dlsch_buffer - memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total); - // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); + /* Cycle through SDUs and place in dlsch_buffer */ + memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); - // fill remainder of DLSCH with random data - for (j=0; j<(TBS-sdu_length_total-offset); j++) { - UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff); + /* Fill remainder of DLSCH with random data */ + for (j = 0; j < (TBS - sdu_length_total - offset); j++) { + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char)(taus()&0xff); } - if (opt_enabled == 1) { - trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - TBS, module_idP, 3, UE_RNTI(module_idP,UE_id), - mac->frame, mac->subframe,0,0); + trace_pdu(1, + (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + TBS, + module_idP, + 3, + UE_RNTI(module_idP,UE_id), + mac->frame, + mac->subframe, + 0, + 0); LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), TBS); + module_idP, + CC_id, + frameP, + UE_RNTI(module_idP, UE_id), + TBS); } - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); + /* Do PUCCH power control */ + /* This is the normalized RX power */ + /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ + normalized_rx_power = (5 * ue_sched_ctl->pucch1_snr[CC_id]-640) / 10 + 30; + target_rx_power = mac->puCch10xSnr / 10 + 30; + /* This assumes accumulated tpc */ + /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */ + int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; - // do PUCCH power control - // this is the normalized RX power + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && + (((10240 - framex10psubframe +frameP * 10 + subframeP) >= 10)))) { // frame wrap-around + if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { + ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; - /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ - normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30; - target_rx_power = mac->puCch10xSnr/10+30; - - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; - if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case - ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around - if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { - ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; - - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP; - - if (normalized_rx_power>(target_rx_power+4)) { - tpc = 0; //-1 - } else if (normalized_rx_power<(target_rx_power-4)) { - tpc = 2; //+1 - } else { - tpc = 1; //0 - } - - LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", - module_idP,frameP, subframeP,harq_pid,tpc, - normalized_rx_power,target_rx_power); - - } // Po_PUCCH has been updated - else { - tpc = 1; //0 - } // time to do TPC update - else { - tpc = 1; //0 - } - - // Toggle NDI in first round - UE_template->oldNDI[harq_pid] = 1-UE_template->oldNDI[harq_pid]; - ue_sched_ctl->round[CC_id][harq_pid] = 0; - round=0; - } + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; //-1 + } else if (normalized_rx_power<(target_rx_power - 4)) { + tpc = 2; //+1 + } else { + tpc = 1; //0 + } + LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", + module_idP, + frameP, + subframeP, + harq_pid, + tpc, + normalized_rx_power, + target_rx_power); + } else { // Po_PUCCH has been updated + tpc = 1; // 0 + } + } else { // time to do TPC update + tpc = 1; //0 + } + + // Toggle NDI in first round + UE_template->oldNDI[harq_pid] = 1 - UE_template->oldNDI[harq_pid]; + ue_sched_ctl->round[CC_id][harq_pid] = 0; + round_DL = 0; + } // if ((sdu_length_total + header_len_dcch + header_len_dtch) > 0) } - if (round < 8) { - // fill in MDPDCCH - memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 11 : 10; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = epdcch_setconfig_r11->transmissionType_r11; - AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11!=NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); - - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 4; // t-CRNTI - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = rnti; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | ((epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1)<<5); - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 9; // adjust according to size of RAR, 208 bits with N1A_PRB=3 - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 0; // fix to 4 for now - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = rvseq[round&3]; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = UE_template->oldNDI[harq_pid]; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 3; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in - dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; - dl_req->number_pdu++; - UE_template->mcs[harq_pid] = dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs; + if (round_DL < 8) { + /* Fill in MDPDCCH */ + memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 11 : 10; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = epdcch_setconfig_r11->transmissionType_r11; + AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 4; // t-CRNTI + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = rnti; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | ((epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1)<<5); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = mcs; // adjust according to size of RAR, 208 bits with N1A_PRB=3 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 0; // fix to 4 for now + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = rvseq[round_DL&3]; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = UE_template->oldNDI[harq_pid]; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 3; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; + dl_req->number_pdu++; + UE_template->mcs[harq_pid] = dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs; } - } - else if ((subframeP == 7)&&(round<8)) { // DLSCH - - int absSF = (frameP * 10) + subframeP; - - // Have to check that MPDCCH was generated - LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating DLSCH (ce_level %d RNTI %x)\n", - module_idP, CC_id, frameP, subframeP, UE_template->rach_resource_type - 1,rnti); - - first_rb = narrowband_to_first_rb (&cc[CC_id], epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); + } else if ((subframeP == 7) && (round_DL < 8)) { // DLSCH + LOG_D(MAC, "DLSCH round_DL = %d in frame %d subframe %d\n", round_DL, frameP, subframeP); + int absSF = (frameP * 10) + subframeP; + /* Have to check that MPDCCH was generated */ + LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating DLSCH (ce_level %d RNTI %x)\n", + module_idP, + CC_id, + frameP, + subframeP, + UE_template->rach_resource_type - 1, + rnti); + first_rb = narrowband_to_first_rb(&cc[CC_id], epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_id]; @@ -3231,31 +2502,25 @@ schedule_ue_spec_br( dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_id].p_eNB == 1) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (UE_template->rach_resource_type < 3) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; dl_req->number_pdu++; - // DL request mac->TX_req[CC_id].sfn_sf = (frameP << 4) + subframeP; TX_req = &mac->TX_req[CC_id].tx_request_body.tx_pdu_list[mac->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = get_TBS_DL(UE_template->mcs[harq_pid], - 6); + TX_req->pdu_length = get_TBS_DL(UE_template->mcs[harq_pid], 6); TX_req->pdu_index = mac->pdu_index[CC_id]++; TX_req->num_segments = 1; TX_req->segments[0].segment_length = TX_req->pdu_length; TX_req->segments[0].segment_data = mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0]; mac->TX_req[CC_id].tx_request_body.number_of_pdus++; - ackNAK_absSF = absSF + 4; ul_req = &mac->UL_req_tmp[CC_id][ackNAK_absSF % 10].ul_config_request_body; ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_uci_harq_pdu)); ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this @@ -3266,35 +2531,56 @@ schedule_ue_spec_br( ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number = 0; if (cc[CC_id].tdd_Config == NULL) { // FDD case - ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = n1pucchan[UE_template->rach_resource_type - 1]; - // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case - // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level] - // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 => - // Delta_ARO = 0 from Table 10.1.2.1-1 - ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK - ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.number_of_pucch_resources = 1; + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = n1pucchan[UE_template->rach_resource_type - 1]; + // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case + // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level] + // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 => + // Delta_ARO = 0 from Table 10.1.2.1-1 + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.number_of_pucch_resources = 1; } else { - AssertFatal (1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n"); + AssertFatal (1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n"); } + ul_req->number_of_pdus++; - T (T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT (module_idP), T_INT (CC_id), T_INT (rnti), T_INT (frameP), T_INT (subframeP), - T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TX_req->pdu_length)); - + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, + T_INT (module_idP), + T_INT (CC_id), + T_INT (rnti), + T_INT (frameP), + T_INT (subframeP), + T_INT (0 /* harq_pid always 0? */ ), + T_BUFFER (&mac->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TX_req->pdu_length)); + if (opt_enabled == 1) { - trace_pdu (1, (uint8_t *) mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0], TX_req->pdu_length , UE_id, 3, rnti, frameP, subframeP, 0, 0); - LOG_D (OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", module_idP, CC_id, frameP, rnti, TX_req->pdu_length ); + trace_pdu(1, + (uint8_t *) mac->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0], + TX_req->pdu_length, + UE_id, + 3, + rnti, + frameP, + subframeP, + 0, + 0); + LOG_D(OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", + module_idP, + CC_id, + frameP, + rnti, + TX_req->pdu_length); } - - } - } - + } // end else if ((subframeP == 7) && (round_DL < 8)) + } // end loop on UE_id } #endif //------------------------------------------------------------------------------ void fill_DLSCH_dci(module_id_t module_idP, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flagP) + frame_t frameP, + sub_frame_t subframeP, + int *mbsfn_flagP) //------------------------------------------------------------------------------ { // loop over all allocated UEs and compute frequency allocations for PDSCH @@ -3313,12 +2599,15 @@ fill_DLSCH_dci(module_id_t module_idP, int N_RBG; int N_RB_DL; COMMON_channels_t *cc; + eNB_DLSCH_INFO *dlsch_info; + UE_TEMPLATE *ue_template; start_meas(&eNB->fill_DLSCH_dci); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, + VCD_FUNCTION_IN); for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { - LOG_D(MAC, "Doing fill DCI for CC_id %d\n", CC_id); + LOG_D(MAC, "Doing fill DCI for CC_id %d\n", + CC_id); if (mbsfn_flagP[CC_id] > 0) continue; @@ -3328,41 +2617,47 @@ fill_DLSCH_dci(module_id_t module_idP, N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); // UE specific DCIs - for (UE_id = UE_list->head; UE_id >= 0; - UE_id = UE_list->next[UE_id]) { - LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", CC_id, UE_id, - eNB_dlsch_info[module_idP][CC_id][UE_id].status); + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + dlsch_info = &eNB_dlsch_info[module_idP][CC_id][UE_id]; + LOG_T(MAC, "CC_id %d, UE_id: %d => status %d\n", + CC_id, + UE_id, + dlsch_info->status); - if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) { + if (dlsch_info->status == S_DL_SCHEDULED) { // clear scheduling flag - eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; + dlsch_info->status = S_DL_WAITING; rnti = UE_RNTI(module_idP, UE_id); - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP, + subframeP); + ue_template = &UE_list->UE_template[CC_id][UE_id]; + nb_rb = ue_template->nb_rb[harq_pid]; /// Synchronizing rballoc with rballoc_sub for (i = 0; i < N_RBG; i++) { - rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; + rballoc_sub[i] = ue_template->rballoc_subband[harq_pid][i]; } - nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; + nfapi_dl_config_request_body_t *dl_config_request_body = &RC.mac[module_idP]->DL_req[CC_id].dl_config_request_body; nfapi_dl_config_request_pdu_t *dl_config_pdu; - for (i = 0; - i < DL_req[CC_id].dl_config_request_body.number_pdu; - i++) { - dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; + for (i = 0; i < dl_config_request_body->number_pdu; i++) { + dl_config_pdu = &dl_config_request_body->dl_config_pdu_list[i]; - if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) - && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, + if (dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE && + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti && + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, + N_RB_DL, + N_RBG, rballoc_sub); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; - } else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) - && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) - && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) { - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, + } else if (dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE && + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti && + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0) { + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, + N_RB_DL, + N_RBG, rballoc_sub); } } @@ -3371,12 +2666,15 @@ fill_DLSCH_dci(module_id_t module_idP, } stop_meas(&eNB->fill_DLSCH_dci); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, + VCD_FUNCTION_OUT); } //------------------------------------------------------------------------------ unsigned char *get_dlsch_sdu(module_id_t module_idP, - int CC_id, frame_t frameP, rnti_t rntiP, + int CC_id, + frame_t frameP, + rnti_t rntiP, uint8_t TBindex) //------------------------------------------------------------------------------ { @@ -3385,96 +2683,108 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP, if (rntiP == SI_RNTI) { LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", - module_idP, CC_id, frameP); + module_idP, + CC_id, + frameP); return ((unsigned char *) &eNB->common_channels[CC_id].BCCH_pdu.payload[0]); } if (rntiP == P_RNTI) { - LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", + module_idP, + CC_id, + frameP); return ((unsigned char *) &eNB->common_channels[CC_id].PCCH_pdu.payload[0]); } UE_id = find_UE_id(module_idP, rntiP); if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", - module_idP, frameP, CC_id, rntiP, UE_id); + LOG_D(MAC, "[eNB %d] Frame %d: CC_id %d Get DLSCH sdu for rnti %x => UE_id %d\n", + module_idP, + frameP, + CC_id, + rntiP, + UE_id); return ((unsigned char *) &eNB->UE_list.DLSCH_pdu[CC_id][TBindex][UE_id].payload[0]); - } else { - LOG_E(MAC, - "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", - module_idP, frameP, CC_id, rntiP); - return NULL; } + + LOG_E(MAC, "[eNB %d] Frame %d: CC_id %d UE with RNTI %x does not exist\n", + module_idP, + frameP, + CC_id, + rntiP); + return NULL; } //------------------------------------------------------------------------------ void update_ul_dci(module_id_t module_idP, - uint8_t CC_idP, rnti_t rntiP, uint8_t daiP, sub_frame_t subframe) + uint8_t CC_idP, + rnti_t rntiP, + uint8_t daiP, + sub_frame_t subframe) //------------------------------------------------------------------------------ { - nfapi_hi_dci0_request_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe]; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; - COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; - int i; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; if (cc->tdd_Config != NULL) { // TDD - for (i = 0; - i <HI_DCI0_req->hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_hi; - i++) { - if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; + nfapi_hi_dci0_request_t *HI_DCI0_req = &eNB->HI_DCI0_req[CC_idP][subframe]; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; + int limit = HI_DCI0_req->hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_hi; + + for (int i = 0; i < limit; i++, hi_dci0_pdu++) { + if (hi_dci0_pdu->pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE && hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti == rntiP) + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; } } + + return; } //------------------------------------------------------------------------------ void set_ue_dai(sub_frame_t subframeP, - int UE_id, uint8_t CC_id, uint8_t tdd_config, + int UE_id, + uint8_t CC_id, + uint8_t tdd_config, UE_list_t *UE_list) //------------------------------------------------------------------------------ { switch (tdd_config) { case 0: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 3) - || (subframeP == 5) || (subframeP == 6) || (subframeP == 8)) { + if (subframeP == 0 || subframeP == 1 || subframeP == 3 || subframeP == 5 || subframeP == 6 || subframeP == 8) { UE_list->UE_template[CC_id][UE_id].DAI = 0; } break; case 1: - if ((subframeP == 0) || (subframeP == 4) || (subframeP == 5) - || (subframeP == 9)) { + if (subframeP == 0 || subframeP == 4 || subframeP == 5 || subframeP == 9) { UE_list->UE_template[CC_id][UE_id].DAI = 0; } break; case 2: - if ((subframeP == 4) || (subframeP == 5)) { + if (subframeP == 4 || subframeP == 5) { UE_list->UE_template[CC_id][UE_id].DAI = 0; } break; case 3: - if ((subframeP == 5) || (subframeP == 7) || (subframeP == 9)) { + if (subframeP == 5 || subframeP == 7 || subframeP == 9) { UE_list->UE_template[CC_id][UE_id].DAI = 0; } break; case 4: - if ((subframeP == 0) || (subframeP == 6)) { + if (subframeP == 0 || subframeP == 6) { UE_list->UE_template[CC_id][UE_id].DAI = 0; } @@ -3488,8 +2798,7 @@ set_ue_dai(sub_frame_t subframeP, break; case 6: - if ((subframeP == 0) || (subframeP == 1) || (subframeP == 5) - || (subframeP == 6) || (subframeP == 9)) { + if (subframeP == 0 || subframeP == 1 || subframeP == 5 || subframeP == 6 || subframeP == 9) { UE_list->UE_template[CC_id][UE_id].DAI = 0; } @@ -3497,12 +2806,18 @@ set_ue_dai(sub_frame_t subframeP, default: UE_list->UE_template[CC_id][UE_id].DAI = 0; - LOG_I(MAC, "unknown TDD config %d\n", tdd_config); + LOG_I(MAC, "unknown TDD config %d\n", + tdd_config); break; } + + return; } -void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { +void +schedule_PCH(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) { /* DCI:format 1A/1C P-RNTI:0xFFFE */ /* PDU:eNB_rrc_inst[Mod_idP].common_channels[CC_id].PCCH_pdu.payload */ uint16_t pcch_sdu_length; @@ -3516,9 +2831,10 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_tx_request_pdu_t *TX_req; nfapi_dl_config_request_body_t *dl_req; + UE_PF_PO_t *ue_pf_po; #ifdef FORMAT1C - int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */ - const int GAP_MAP [9][2] = { + int gap_index = 0; /* indicate which gap(1st or 2nd) is used (0:1st) */ + const int GAP_MAP [9][2] = { {-1, 0}, /* N_RB_DL [6-10] -1: |N_RB/2| 0: N/A*/ {4, 0}, /* N_RB_DL [11] */ {8, 0}, /* N_RB_DL [12-19] */ @@ -3529,11 +2845,11 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {32, 16}, /* N_RB_DL [64-79] */ {48, 16} /* N_RB_DL [80-110] */ }; - uint8_t n_rb_step = 0; - uint8_t n_gap = 0; - uint8_t n_vrb_dl = 0; - uint8_t Lcrbs = 0; - uint16_t rb_bit = 168; /* RB bit number value is unsure */ + uint8_t n_rb_step = 0; + uint8_t n_gap = 0; + uint8_t n_vrb_dl = 0; + uint8_t Lcrbs = 0; + uint16_t rb_bit = 168; /* RB bit number value is unsure */ #endif start_meas(&eNB->schedule_pch); @@ -3544,25 +2860,37 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_req = &eNB->DL_req[CC_id].dl_config_request_body; for (uint16_t i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (UE_PF_PO[CC_id][i].enable_flag != TRUE) { + ue_pf_po = &UE_PF_PO[CC_id][i]; + + if (ue_pf_po->enable_flag != TRUE) { continue; } - if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) { + if (frameP % ue_pf_po->T == ue_pf_po->PF_min && subframeP == ue_pf_po->PO) { pcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, - PCCH, 1, + PCCH, + 0xFFFE, + 1, &cc->PCCH_pdu.payload[0], i); // used for ue index if (pcch_sdu_length == 0) { - LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP, frameP, subframeP); + LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", + module_idP, + frameP, + subframeP); continue; } - LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, - frameP, subframeP, CC_id, i, pcch_sdu_length); + LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", + module_idP, + frameP, + subframeP, + CC_id, + i, + pcch_sdu_length); #ifdef FORMAT1C //NO SIB @@ -3657,7 +2985,10 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) } else { /* unexpected: pcch sdb size is over max value*/ LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n", - module_idP, frameP,CC_id, pcch_sdu_length); + module_idP, + frameP, + CC_id, + pcch_sdu_length); return; } @@ -3740,7 +3071,9 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) #endif dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + memset((void *) dl_config_pdu, + 0, + sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); #ifdef FORMAT1C @@ -3748,12 +3081,14 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap = n_gap; #else - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, + first_rb, + 4); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0; #endif dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; @@ -3762,25 +3097,38 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { - LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP); + if (!CCE_allocation_infeasible(module_idP, + CC_id, + 0, + subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + P_RNTI)) { + LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", + frameP, + subframeP); dl_req->number_dci++; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + memset((void *)dl_config_pdu, + 0, + sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->pdu_size = (uint8_t)(2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE; #ifdef FORMAT1C dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl / n_rb_step, + first_rb / n_rb_step, + Lcrbs / n_rb_step); #else - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, + first_rb, + 4); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized #endif dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK @@ -3811,17 +3159,21 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; #endif dl_req->number_pdu++; - eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; TX_req->pdu_length = pcch_sdu_length; TX_req->pdu_index = eNB->pdu_index[CC_id]++; TX_req->num_segments = 1; TX_req->segments[0].segment_length = pcch_sdu_length; TX_req->segments[0].segment_data = cc[CC_id].PCCH_pdu.payload; - eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; } else { - LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP); + LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n", + module_idP, + CC_id, + frameP, + subframeP); continue; } @@ -3837,18 +3189,30 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) 0, 0); LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, pcch_sdu_length); + module_idP, + frameP, + CC_id, + 0xffff, + pcch_sdu_length); } - eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1; - eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length; - eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length; - eNB->eNB_stats[CC_id].pcch_mcs=mcs; + eNB->eNB_stats[CC_id].total_num_pcch_pdu++; + eNB->eNB_stats[CC_id].pcch_buffer = pcch_sdu_length; + eNB->eNB_stats[CC_id].total_pcch_buffer += pcch_sdu_length; + eNB->eNB_stats[CC_id].pcch_mcs = mcs; //paging first_rb log LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n", - module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb); + module_idP, + frameP, + subframeP, + ue_pf_po->ue_index_value, + pcch_sdu_length, + mcs, + first_rb); pthread_mutex_lock(&ue_pf_po_mutex); - memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t)); + memset(ue_pf_po, + 0, + sizeof(UE_PF_PO_t)); pthread_mutex_unlock(&ue_pf_po_mutex); } } @@ -3859,7 +3223,10 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) return; } -static int slice_priority_compare(const void *_a, const void *_b, void *_c) { +static int +slice_priority_compare(const void *_a, + const void *_b, + void *_c) { const int slice_id1 = *(const int *) _a; const int slice_id2 = *(const int *) _b; const module_id_t Mod_id = *(int *) _c; @@ -3872,13 +3239,20 @@ static int slice_priority_compare(const void *_a, const void *_b, void *_c) { return 1; } -void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]) { +void +slice_priority_sort(module_id_t Mod_id, + int slice_list[MAX_NUM_SLICES]) { int i; + int n_dl = RC.mac[Mod_id]->slice_info.n_dl; - for (i = 0; i < RC.mac[Mod_id]->slice_info.n_dl; ++i) { + for (i = 0; i < n_dl; i++) { slice_list[i] = i; } - qsort_r(slice_list, RC.mac[Mod_id]->slice_info.n_dl, sizeof(int), - slice_priority_compare, &Mod_id); + qsort_r(slice_list, + n_dl, + sizeof(int), + slice_priority_compare, + &Mod_id); + return; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 86f7e16acfd028b5024ad2c4511fa1ef3c11b81d..2626a0466496310b6f612e7c9359c272912b3d65 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -40,6 +40,7 @@ #include "LAYER2/MAC/mac_extern.h" #include "LAYER2/MAC/eNB_scheduler_fairRR.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" @@ -49,7 +50,7 @@ #include "T.h" -extern uint8_t nfapi_mode; + #ifdef PHY_TX_THREAD extern volatile int16_t phy_tx_txdataF_end; extern int oai_exit; @@ -295,7 +296,8 @@ void dlsch_scheduler_pre_ue_select_fairRR( CC_id, UE_id, subframeP, - S_DL_NONE); + S_DL_NONE, + rnti); end_flag[CC_id] = 1; break; } @@ -418,7 +420,8 @@ void dlsch_scheduler_pre_ue_select_fairRR( CC_id, UE_id, subframeP, - S_DL_NONE); + S_DL_NONE, + rnti); end_flag[CC_id] = 1; break; } @@ -541,7 +544,8 @@ void dlsch_scheduler_pre_ue_select_fairRR( CC_id, UE_id, subframeP, - S_DL_NONE); + S_DL_NONE, + rnti); end_flag[CC_id] = 1; break; } @@ -810,7 +814,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP, unsigned char ta_len = 0; unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; uint16_t nb_rb, nb_rb_temp, nb_available_rb; - uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = 0, post_padding = 0; + uint16_t TBS, j, sdu_lengths[NB_RB_MAX], padding = 0, post_padding = 0; + rnti_t rnti = 0; unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; unsigned char round = 0; unsigned char harq_pid = 0; @@ -1007,13 +1012,13 @@ schedule_ue_spec_fairRR(module_id_t module_idP, DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); */ - if (nfapi_mode) { + if (NFAPI_MODE != NFAPI_MONOLITHIC) { eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; } else { eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; } - eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + //eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); // store stats //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; @@ -1215,8 +1220,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, } add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); + CC_id, + UE_id, + subframeP, + S_DL_SCHEDULED, + rnti); //eNB_UE_stats->dlsch_trials[round]++; UE_list->eNB_UE_stats[CC_id][UE_id]. num_retransmission += 1; @@ -1444,7 +1452,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, MBMS_FLAG_NO, lcid, TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, 0 #endif ); @@ -1465,7 +1473,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, lcid, TBS, //not used (char *)&dlsch_buffer[sdu_length_total] -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, 0 #endif ); @@ -1678,10 +1686,10 @@ schedule_ue_spec_fairRR(module_id_t module_idP, if (opt_enabled == 1) { trace_pdu(DIRECTION_DOWNLINK, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - TBS, module_idP, WS_RA_RNTI, UE_RNTI(module_idP,UE_id), + TBS, module_idP, WS_RA_RNTI, UE_RNTI(module_idP, UE_id), eNB->frame, eNB->subframe,0,0); LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), TBS); + module_idP, CC_id, frameP, UE_RNTI(module_idP, UE_id), TBS); } T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), @@ -1691,7 +1699,8 @@ schedule_ue_spec_fairRR(module_id_t module_idP, CC_id, UE_id, subframeP, - S_DL_SCHEDULED); + S_DL_SCHEDULED, + rnti); // store stats eNB->eNB_stats[CC_id].dlsch_bytes_tx+=sdu_length_total; eNB->eNB_stats[CC_id].dlsch_pdus_tx+=1; @@ -2583,7 +2592,7 @@ schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP, frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset, 0,//tdd_mapindex - frameP); //Nf + frameP); //Nf --> shouldn't it be sched_frame ??? ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = 6; ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = -1; ulsch_ue_select[CC_id].ue_num++; @@ -2985,10 +2994,10 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, last_ulsch_ue_id[CC_id] = ulsch_ue_select[CC_id].list[ulsch_ue_num].UE_id; } } else if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_RETRANS) { // round > 0 => retransmission + round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), + T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb), T_INT(ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb), T_INT(round)); - round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; uint8_t mcs_rv = 0; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 649f763f422dfc6777f7ae807b776c282761b552..faf36026d62e8346a0adac000a01125bb4f2b5e3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -542,7 +542,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, "[eNB %d] CC_id %d Frame %d Subframe %d: Schedule MCCH MESSAGE (area %d, sfAlloc %d)\n", module_idP, CC_id, frameP, subframeP, i, j); - mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 1, &cc->MCCH_pdu.payload[0], + mcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, frameP, MCCH, 0xFFFC, 1, &cc->MCCH_pdu.payload[0], i); // this is the mbsfn sync area index if (mcch_sdu_length > 0) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c index 881359f274dff57a844170abddc892761dce2a5d..2f566c0d7a0d48d1397c23b4fe4892cba59879dc 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c @@ -169,7 +169,7 @@ schedule_ue_spec_phy_test( 1, // number of subbands // uint8_t codebook_index, 4, // UE category capacity - LTE_PDSCH_ConfigDedicated__p_a_dB0, + LTE_PDSCH_ConfigDedicated__p_a_dB0, 0, // delta_power_offset for TM5 0, // ngap 0, // nprb diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 08a3bac640228e47ac6ba11c0016ab3d39dbcd94..0385ae673061972edf3e0ef8926c2d9c423a9507 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -36,6 +36,7 @@ #include "LAYER2/MAC/mac_proto.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" @@ -48,7 +49,7 @@ #include "pdcp.h" #if defined(ENABLE_ITTI) -#include "intertask_interface.h" + #include "intertask_interface.h" #endif #include "T.h" @@ -61,9 +62,13 @@ extern uint16_t frame_cnt; #include "SCHED/sched_common.h" extern RAN_CONTEXT_t RC; -extern uint8_t nfapi_mode; -int choose(int n, int k) + +//------------------------------------------------------------------------------ +int +choose(int n, + int k) +//------------------------------------------------------------------------------ { int res = 1; int res2 = 1; @@ -71,101 +76,124 @@ int choose(int n, int k) if (k > n) return (0); + if (n == k) return (1); for (i = n; i > k; i--) res *= i; + for (i = 2; i <= (n - k); i++) res2 *= i; return (res / res2); } +//------------------------------------------------------------------------------ // Patented algorithm from Yang et al, US Patent 2009, "Channel Quality Indexing and Reverse Indexing" -void reverse_index(int N, int M, int r, int *v) +void reverse_index(int N, + int M, + int r, + int *v) +//------------------------------------------------------------------------------ { int BaseValue = 0; int IncreaseValue, ThresholdValue; int sumV; int i; - r = choose(N, M) - 1 - r; memset((void *) v, 0, M * sizeof(int)); - sumV = 0; i = M; + while (i > 0 && r > 0) { - IncreaseValue = choose(N - M + 1 - sumV - v[i - 1] + i - 2, i - 1); + IncreaseValue = choose(N - M + 1 - sumV - v[i - 1] + i - 2, + i - 1); ThresholdValue = BaseValue + IncreaseValue; + if (r >= ThresholdValue) { v[i - 1]++; BaseValue = ThresholdValue; } else { - r = r - BaseValue; - sumV += v[i - 1]; - i--; + r -= BaseValue; + sumV += v[--i]; BaseValue = 0; } } } -int to_prb(int dl_Bandwidth) +//------------------------------------------------------------------------------ +int +to_prb(int dl_Bandwidth) +//------------------------------------------------------------------------------ { int prbmap[6] = { 6, 15, 25, 50, 75, 100 }; - AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth is 0..5\n"); return (prbmap[dl_Bandwidth]); } -int to_rbg(int dl_Bandwidth) +//------------------------------------------------------------------------------ +int +to_rbg(int dl_Bandwidth) +//------------------------------------------------------------------------------ { int rbgmap[6] = { 6, 8, 13, 17, 19, 25 }; - AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth is 0..5\n"); return (rbgmap[dl_Bandwidth]); } -int get_phich_resource_times6(COMMON_channels_t * cc) +//------------------------------------------------------------------------------ +int +get_phich_resource_times6(COMMON_channels_t *cc) +//------------------------------------------------------------------------------ { int phichmap[4] = { 1, 3, 6, 12 }; AssertFatal(cc != NULL, "cc is null\n"); AssertFatal(cc->mib != NULL, "cc->mib is null\n"); - AssertFatal((cc->mib->message.phich_Config.phich_Resource >= 0) && - (cc->mib->message.phich_Config.phich_Resource < 4), - "phich_Resource %d not in 0..3\n", - (int) cc->mib->message.phich_Config.phich_Resource); - - return (phichmap[cc->mib->message.phich_Config.phich_Resource]); + int phich_Resource = (int) cc->mib->message.phich_Config.phich_Resource; + AssertFatal(phich_Resource >= 0 && phich_Resource < 4, "phich_Resource %d not in 0..3\n", + phich_Resource); + return (phichmap[phich_Resource]); } -uint16_t mac_computeRIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs) +//------------------------------------------------------------------------------ +uint16_t +mac_computeRIV(uint16_t N_RB_DL, + uint16_t RBstart, + uint16_t Lcrbs) +//------------------------------------------------------------------------------ { - uint16_t RIV; - - if (Lcrbs <= (1 + (N_RB_DL >> 1))) RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart; - else RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); + if (Lcrbs <= (1 + (N_RB_DL >> 1))) { + return (N_RB_DL * (Lcrbs - 1)) + RBstart; + } - return (RIV); + return (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); } -uint8_t getQm(uint8_t mcs) +//------------------------------------------------------------------------------ +uint8_t +getQm(uint8_t mcs) +//------------------------------------------------------------------------------ { if (mcs < 10) return (2); else if (mcs < 17) return (4); - else return (6); + + return (6); } +//------------------------------------------------------------------------------ void get_Msg3alloc(COMMON_channels_t *cc, - sub_frame_t current_subframe, - frame_t current_frame, - frame_t *frame, - sub_frame_t *subframe) + sub_frame_t current_subframe, + frame_t current_frame, + frame_t *frame, + sub_frame_t *subframe) +//------------------------------------------------------------------------------ { // Fill in other TDD Configuration!!!! + int subframeAssignment; - if (cc->tdd_Config == NULL) { // FDD + if (cc->tdd_Config == NULL) { // FDD *subframe = current_subframe + 6; if (*subframe > 9) { @@ -174,108 +202,111 @@ get_Msg3alloc(COMMON_channels_t *cc, } else { *frame = current_frame; } - } else { // TDD - if (cc->tdd_Config->subframeAssignment == 1) { + } else { // TDD + subframeAssignment = (int) cc->tdd_Config->subframeAssignment; + + if (subframeAssignment == 1) { switch (current_subframe) { - - case 0: - *subframe = 7; - *frame = current_frame; - break; + case 0: + *subframe = 7; + *frame = current_frame; + break; - case 4: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; + case 4: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; - case 5: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 9: - *subframe = 7; - *frame = (current_frame + 1) & 1023; - break; + case 5: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; + + case 9: + *subframe = 7; + *frame = (current_frame + 1) & 1023; + break; } - } else if (cc->tdd_Config->subframeAssignment == 3) { + } else if (subframeAssignment == 3) { switch (current_subframe) { + case 0: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; - case 0: - case 5: - case 6: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 7: - *subframe = 3; - *frame = (current_frame + 1) & 1023; - break; - - case 8: - *subframe = 4; - *frame = (current_frame + 1) & 1023; - break; - - case 9: - *subframe = 2; - *frame = (current_frame + 2) & 1023; - break; + case 7: + *subframe = 3; + *frame = (current_frame + 1) & 1023; + break; + + case 8: + *subframe = 4; + *frame = (current_frame + 1) & 1023; + break; + + case 9: + *subframe = 2; + *frame = (current_frame + 2) & 1023; + break; } - } else if (cc->tdd_Config->subframeAssignment == 4) { + } else if (subframeAssignment == 4) { switch (current_subframe) { + case 0: + case 4: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; - case 0: - case 4: - case 5: - case 6: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 7: - *subframe = 3; - *frame = (current_frame + 1) & 1023; - break; - - case 8: - case 9: - *subframe = 2; - *frame = (current_frame + 2) & 1023; - break; + case 7: + *subframe = 3; + *frame = (current_frame + 1) & 1023; + break; + + case 8: + case 9: + *subframe = 2; + *frame = (current_frame + 2) & 1023; + break; } - } else if (cc->tdd_Config->subframeAssignment == 5) { + } else if (subframeAssignment == 5) { switch (current_subframe) { + case 0: + case 4: + case 5: + case 6: + *subframe = 2; + *frame = (current_frame + 1) & 1023; + break; - case 0: - case 4: - case 5: - case 6: - *subframe = 2; - *frame = (current_frame + 1) & 1023; - break; - - case 7: - case 8: - case 9: - *subframe = 2; - *frame = (current_frame + 2) & 1023; - break; + case 7: + case 8: + case 9: + *subframe = 2; + *frame = (current_frame + 2) & 1023; + break; } } } -} - + return; +} +//------------------------------------------------------------------------------ void -get_Msg3allocret(COMMON_channels_t * cc, - sub_frame_t current_subframe, - frame_t current_frame, - frame_t * frame, sub_frame_t * subframe) +get_Msg3allocret(COMMON_channels_t *cc, + sub_frame_t current_subframe, + frame_t current_frame, + frame_t *frame, + sub_frame_t *subframe) +//------------------------------------------------------------------------------ { - if (cc->tdd_Config == NULL) { //FDD + int subframeAssignment; + + if (cc->tdd_Config == NULL) { //FDD /* always retransmit in n+8 */ *subframe = current_subframe + 8; @@ -286,792 +317,837 @@ get_Msg3allocret(COMMON_channels_t * cc, *frame = current_frame; } } else { - if (cc->tdd_Config->subframeAssignment == 1) { + subframeAssignment = (int) cc->tdd_Config->subframeAssignment; + + if (subframeAssignment == 1) { // original PUSCH in 2, PHICH in 6 (S), ret in 2 // original PUSCH in 3, PHICH in 9, ret in 3 // original PUSCH in 7, PHICH in 1 (S), ret in 7 // original PUSCH in 8, PHICH in 4, ret in 8 *frame = (current_frame + 1) & 1023; - } else if (cc->tdd_Config->subframeAssignment == 3) { + } else if (subframeAssignment == 3) { // original PUSCH in 2, PHICH in 8, ret in 2 next frame // original PUSCH in 3, PHICH in 9, ret in 3 next frame // original PUSCH in 4, PHICH in 0, ret in 4 next frame *frame = (current_frame + 1) & 1023; - } else if (cc->tdd_Config->subframeAssignment == 4) { + } else if (subframeAssignment == 4) { // original PUSCH in 2, PHICH in 8, ret in 2 next frame // original PUSCH in 3, PHICH in 9, ret in 3 next frame *frame = (current_frame + 1) & 1023; - } else if (cc->tdd_Config->subframeAssignment == 5) { + } else if (subframeAssignment == 5) { // original PUSCH in 2, PHICH in 8, ret in 2 next frame *frame = (current_frame + 1) & 1023; } } + + return; } +//------------------------------------------------------------------------------ uint8_t -subframe2harqpid(COMMON_channels_t * cc, frame_t frame, - sub_frame_t subframe) +subframe2harqpid(COMMON_channels_t *cc, + frame_t frame, + sub_frame_t subframe) +//------------------------------------------------------------------------------ { - uint8_t ret = 255; - AssertFatal(cc != NULL, "cc is null\n"); - if (cc->tdd_Config == NULL) { // FDD + uint8_t ret = 255; + + if (cc->tdd_Config == NULL) { // FDD ret = (((frame << 1) + subframe) & 7); } else { switch (cc->tdd_Config->subframeAssignment) { - case 1: - if ((subframe == 2) || - (subframe == 3) || (subframe == 7) || (subframe == 8)) - switch (subframe) { - case 2: - case 3: - ret = (subframe - 2); - break; - case 7: - case 8: - ret = (subframe - 5); - break; - default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - break; - } + case 1: + if (subframe == 2 || subframe == 3 || subframe == 7 || subframe == 8) { + switch (subframe) { + case 2: + case 3: + ret = (subframe - 2); + break; - break; + case 7: + case 8: + ret = (subframe - 5); + break; - case 2: - AssertFatal((subframe == 2) || (subframe == 7), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); + default: + AssertFatal(1 == 0, "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + break; + } + } - ret = (subframe / 7); - break; + break; - case 3: - AssertFatal((subframe > 1) && (subframe < 5), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframe - 2); - break; + case 2: + AssertFatal(subframe == 2 || subframe == 7, "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframe / 7); + break; - case 4: - AssertFatal((subframe > 1) && (subframe < 4), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframe - 2); - break; + case 3: + AssertFatal(subframe > 1 && subframe < 5, "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframe - 2); + break; - case 5: - AssertFatal(subframe == 2, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframe, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframe - 2); - break; + case 4: + AssertFatal(subframe > 1 && subframe < 4, "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframe - 2); + break; - default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Unsupported TDD mode %d\n", - (int) cc->tdd_Config->subframeAssignment); + case 5: + AssertFatal(subframe == 2, "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframe, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframe - 2); + break; + + default: + AssertFatal(1 == 0, "subframe2_harq_pid, Unsupported TDD mode %d\n", + (int) cc->tdd_Config->subframeAssignment); + break; } } + return ret; } +//------------------------------------------------------------------------------ uint8_t -get_Msg3harqpid(COMMON_channels_t * cc, - frame_t frame, sub_frame_t current_subframe) +get_Msg3harqpid(COMMON_channels_t *cc, + frame_t frame, + sub_frame_t current_subframe) +//------------------------------------------------------------------------------ { uint8_t ul_subframe = 0; uint32_t ul_frame = 0; - if (cc->tdd_Config == NULL) { // FDD - ul_subframe = - (current_subframe > - 3) ? (current_subframe - 4) : (current_subframe + 6); + if (cc->tdd_Config == NULL) { // FDD + ul_subframe = (current_subframe > 3) ? (current_subframe - 4) : (current_subframe + 6); ul_frame = (current_subframe > 3) ? ((frame + 1) & 1023) : frame; } else { switch (cc->tdd_Config->subframeAssignment) { - case 1: - switch (current_subframe) { - case 9: - case 0: - ul_subframe = 7; - break; - case 5: - case 7: - ul_subframe = 2; - break; - } - break; - case 3: - switch (current_subframe) { - case 0: - case 5: - case 6: - ul_subframe = 2; - break; - case 7: - ul_subframe = 3; - break; - case 8: - ul_subframe = 4; - break; - case 9: - ul_subframe = 2; - break; - } - break; - case 4: - switch (current_subframe) { - case 0: + case 1: + switch (current_subframe) { + case 9: + case 0: + ul_subframe = 7; + break; + + case 5: + case 7: + ul_subframe = 2; + break; + } + + break; + + case 3: + switch (current_subframe) { + case 0: + case 5: + case 6: + ul_subframe = 2; + break; + + case 7: + ul_subframe = 3; + break; + + case 8: + ul_subframe = 4; + break; + + case 9: + ul_subframe = 2; + break; + } + + break; + + case 4: + switch (current_subframe) { + case 0: + case 5: + case 6: + case 8: + case 9: + ul_subframe = 2; + break; + + case 7: + ul_subframe = 3; + break; + } + + break; + case 5: - case 6: - case 8: - case 9: - ul_subframe = 2; - break; - case 7: - ul_subframe = 3; - break; - } - break; - case 5: - ul_subframe = 2; - break; - default: - LOG_E(PHY, - "get_Msg3_harq_pid: Unsupported TDD configuration %d\n", - (int) cc->tdd_Config->subframeAssignment); - AssertFatal(1 == 0, - "get_Msg3_harq_pid: Unsupported TDD configuration"); - break; + ul_subframe = 2; + break; + + default: + LOG_E(PHY, "get_Msg3_harq_pid: Unsupported TDD configuration %d\n", + (int) cc->tdd_Config->subframeAssignment); + AssertFatal(1 == 0, "get_Msg3_harq_pid: Unsupported TDD configuration"); + break; } } - return (subframe2harqpid(cc, ul_frame, ul_subframe)); + return (subframe2harqpid(cc, + ul_frame, + ul_subframe)); } +//------------------------------------------------------------------------------ uint32_t -pdcchalloc2ulframe(COMMON_channels_t * ccP, uint32_t frame, uint8_t n) +pdcchalloc2ulframe(COMMON_channels_t *ccP, + uint32_t frame, + uint8_t n) +//------------------------------------------------------------------------------ { - uint32_t ul_frame; - - if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 1) && ((n == 1) || (n == 6))) // tdd_config 0,1 SF 1,5 - ul_frame = (frame + (n == 1 ? 0 : 1)); - else if ((ccP->tdd_Config) && - (ccP->tdd_Config->subframeAssignment == 6) && - ((n == 0) || (n == 1) || (n == 5) || (n == 6))) - ul_frame = (frame + (n >= 5 ? 1 : 0)); - else if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 6) && (n == 9)) // tdd_config 6 SF 9 - ul_frame = (frame + 1); - else - ul_frame = (frame + (n >= 6 ? 1 : 0)); + uint32_t ul_frame = (frame + (n >= 6 ? 1 : 0)); - LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, - ul_frame); + if (ccP->tdd_Config) { + if (ccP->tdd_Config->subframeAssignment == 1) { + if (n == 1 || n == 6) { + ul_frame = (frame + (n == 1 ? 0 : 1)); + } + } else if (ccP->tdd_Config->subframeAssignment == 6) { + if (n == 0 || n == 1 || n == 5 || n == 6) { + ul_frame = (frame + (n >= 5 ? 1 : 0)); + } else if (n == 9) { + ul_frame = (frame + 1); + } + } + } + + LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", + frame, + n, + ul_frame); return ul_frame; } -uint8_t pdcchalloc2ulsubframe(COMMON_channels_t * ccP, uint8_t n) +//------------------------------------------------------------------------------ +uint8_t +pdcchalloc2ulsubframe(COMMON_channels_t *ccP, + uint8_t n) +//------------------------------------------------------------------------------ { uint8_t ul_subframe; - if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 1) && ((n == 1) || (n == 6))) // tdd_config 0,1 SF 1,5 + if (ccP->tdd_Config && ccP->tdd_Config->subframeAssignment == 1 && (n == 1 || n == 6)) // tdd_config 0,1 SF 1,5 ul_subframe = ((n + 6) % 10); - else if ((ccP->tdd_Config) && - (ccP->tdd_Config->subframeAssignment == 6) && - ((n == 0) || (n == 1) || (n == 5) || (n == 6))) + else if (ccP->tdd_Config && ccP->tdd_Config->subframeAssignment == 6 && (n == 0 || n == 1 || n == 5 || n == 6)) ul_subframe = ((n + 7) % 10); - else if ((ccP->tdd_Config) && (ccP->tdd_Config->subframeAssignment == 6) && (n == 9)) // tdd_config 6 SF 9 + else if (ccP->tdd_Config && ccP->tdd_Config->subframeAssignment == 6 && n == 9) // tdd_config 6 SF 9 ul_subframe = ((n + 5) % 10); else ul_subframe = ((n + 4) % 10); - LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe); + LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", + n, + ul_subframe); return ul_subframe; } -int is_UL_sf(COMMON_channels_t * ccP, sub_frame_t subframeP) +//------------------------------------------------------------------------------ +int +is_UL_sf(COMMON_channels_t *ccP, + sub_frame_t subframeP) +//------------------------------------------------------------------------------ { // if FDD return dummy value if (ccP->tdd_Config == NULL) - return (0); + return 0; switch (ccP->tdd_Config->subframeAssignment) { - case 1: - switch (subframeP) { - case 0: - case 4: - case 5: - case 9: - return (0); + case 1: + switch (subframeP) { + case 0: + case 4: + case 5: + case 9: + return 0; + + case 2: + case 3: + case 7: + case 8: + return 1; + + default: + return 0; + } + break; - case 2: + case 3: - case 7: - case 8: - return (1); - break; + if (subframeP <= 1 || subframeP >= 5) + return 0; + + return 1; + + case 4: + if (subframeP <= 1 || subframeP >= 4) + return 0; + + return 1; + + case 5: + if (subframeP <= 1 || subframeP >= 3) + return 0; + + return 1; + default: - return (0); + AssertFatal(1 == 0, "subframe %d Unsupported TDD configuration %d\n", + subframeP, + (int) ccP->tdd_Config->subframeAssignment); break; - } - break; - case 3: - if ((subframeP <= 1) || (subframeP >= 5)) - return (0); - else if ((subframeP > 1) && (subframeP < 5)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); - break; - case 4: - if ((subframeP <= 1) || (subframeP >= 4)) - return (0); - else if ((subframeP > 1) && (subframeP < 4)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); - break; - case 5: - if ((subframeP <= 1) || (subframeP >= 3)) - return (0); - else if ((subframeP > 1) && (subframeP < 3)) - return (1); - else - AssertFatal(1 == 0, "Unknown subframe number\n"); - break; - default: - AssertFatal(1 == 0, - "subframe %d Unsupported TDD configuration %d\n", - subframeP, (int) ccP->tdd_Config->subframeAssignment); - break; } + + return 0; } -int is_S_sf(COMMON_channels_t * ccP, sub_frame_t subframeP) +//------------------------------------------------------------------------------ +int +is_S_sf(COMMON_channels_t *ccP, + sub_frame_t subframeP) +//------------------------------------------------------------------------------ { - // if FDD return dummy value - if (ccP->tdd_Config == NULL) - return (0); + // if FDD return dummy value + if (ccP->tdd_Config == NULL) + return 0; - switch (subframeP) { + switch (subframeP) { case 1: - return (1); - break; + return 1; case 6: - if(ccP->tdd_Config->subframeAssignment == 0 || ccP->tdd_Config->subframeAssignment == 1 - || ccP->tdd_Config->subframeAssignment == 2 || ccP->tdd_Config->subframeAssignment == 6) - return (1); - break; + if (ccP->tdd_Config->subframeAssignment == 0 || ccP->tdd_Config->subframeAssignment == 1 || + ccP->tdd_Config->subframeAssignment == 2 || ccP->tdd_Config->subframeAssignment == 6) + return 1; + + break; default: - return (0); + break; + } + + return 0; +} + +//------------------------------------------------------------------------------ +uint8_t +ul_subframe2_k_phich(COMMON_channels_t *cc, + sub_frame_t ul_subframe) +//------------------------------------------------------------------------------ +{ + if(cc->tdd_Config) { //TODO fill other tdd config + switch(cc->tdd_Config->subframeAssignment) { + case 0: + break; + + case 1: + if(ul_subframe == 2 || ul_subframe == 7) + return 4; + else if(ul_subframe == 3 || ul_subframe == 8) + return 6; + + return 255; + + case 2: + case 3: + case 4: + case 5: break; } - return 0; -} + } -uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe){ + return 4; //idk sf_ahead? +} - if(cc->tdd_Config){//TODO fill other tdd config - switch(cc->tdd_Config->subframeAssignment){ - case 0: - break; - case 1: - if(ul_subframe == 2 || ul_subframe == 7) - return 4; - else if(ul_subframe == 3 || ul_subframe == 8) - return 6; - else return 255; - break; - case 2: - break; - case 3: - break; - case 4: - break; - case 5: - break; - } - } - return 4; //idk sf_ahead? -} - -uint16_t get_pucch1_absSF(COMMON_channels_t * cc, uint16_t dlsch_absSF) +//------------------------------------------------------------------------------ +uint16_t +get_pucch1_absSF(COMMON_channels_t *cc, + uint16_t dlsch_absSF) +//------------------------------------------------------------------------------ { uint16_t sf, f, nextf; + LTE_TDD_Config_t *tdd_Config = cc->tdd_Config; - if (cc->tdd_Config == NULL) { //FDD n+4 - return ((dlsch_absSF + 4) % 10240); - } else { - sf = dlsch_absSF % 10; - f = dlsch_absSF / 10; - nextf = (f + 1) & 1023; + if (tdd_Config == NULL) { //FDD n+4 + return (dlsch_absSF + 4) % 10240; + } - switch (cc->tdd_Config->subframeAssignment) { + sf = dlsch_absSF % 10; + f = dlsch_absSF / 10; + nextf = (f + 1) & 1023; + + switch (tdd_Config->subframeAssignment) { case 0: - if ((sf == 0) || (sf == 5)) - return ((10 * f) + sf + 4)% 10240; // ACK/NAK in SF 4,9 same frame - else if (sf == 6) - return ((10 * nextf) + 2)% 10240; // ACK/NAK in SF 2 next frame - else if (sf == 1) - return ((10 * f) + 7)% 10240; // ACK/NAK in SF 7 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 0\n", - sf); + if (sf == 0 || sf == 5) + return ((10 * f) + sf + 4) % 10240; // ACK/NAK in SF 4,9 same frame + + if (sf == 6) + return ((10 * nextf) + 2) % 10240; // ACK/NAK in SF 2 next frame + + if (sf == 1) + return ((10 * f) + 7) % 10240; // ACK/NAK in SF 7 same frame break; + case 1: - if ((sf == 5) || (sf == 6)) - return ((10 * nextf) + 2)% 10240; // ACK/NAK in SF 2 next frame - else if (sf == 9) - return ((10 * nextf) + 3)% 10240; // ACK/NAK in SF 3 next frame - else if ((sf == 0) || (sf == 1)) - return ((10 * f) + 7)% 10240; // ACK/NAK in SF 7 same frame - else if (sf == 4) - return ((10 * f) + 8)% 10240; // ACK/NAK in SF 8 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 1\n", - sf); + if (sf == 5 || sf == 6) + return ((10 * nextf) + 2) % 10240; // ACK/NAK in SF 2 next frame + + if (sf == 9) + return ((10 * nextf) + 3) % 10240; // ACK/NAK in SF 3 next frame + + if ((sf == 0) || (sf == 1)) + return ((10 * f) + 7) % 10240; // ACK/NAK in SF 7 same frame + + if (sf == 4) + return ((10 * f) + 8) % 10240; // ACK/NAK in SF 8 same frame + break; + case 2: - if ((sf == 4) || (sf == 5) || (sf == 6) || (sf == 8)) - return ((10 * nextf) + 2)% 10240; // ACK/NAK in SF 2 next frame - else if (sf == 9) - return ((10 * nextf) + 7)% 10240; // ACK/NAK in SF 7 next frame - else if ((sf == 0) || (sf == 1) || (sf == 3)) - return ((10 * f) + 7)% 10240; // ACK/NAK in SF 7 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 2\n", - sf); + if (sf == 4 || sf == 5 || sf == 6 || sf == 8) + return ((10 * nextf) + 2) % 10240; // ACK/NAK in SF 2 next frame + + if (sf == 9) + return ((10 * nextf) + 7) % 10240; // ACK/NAK in SF 7 next frame + + if (sf == 0 || sf == 1 || sf == 3) + return ((10 * f) + 7)% 10240; // ACK/NAK in SF 7 same frame + break; + case 3: - if ((sf == 5) || (sf == 6) || (sf == 7) || (sf == 8) - || (sf == 9)) - return ((10 * nextf) + ((sf-1) >> 1))% 10240; // ACK/NAK in 2,3,4 resp. next frame - else if (sf == 1) - return ((10 * nextf) + 2)% 10240; // ACK/NAK in 2 next frame - else if (sf == 0) - return ((10 * f) + 4)% 10240; // ACK/NAK in 4 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 3\n", - sf); + if (sf == 5 || sf == 6 || sf == 7 || sf == 8 || sf == 9) + return ((10 * nextf) + ((sf - 1) >> 1)) % 10240; // ACK/NAK in 2,3,4 resp. next frame + + if (sf == 1) + return ((10 * nextf) + 2) % 10240; // ACK/NAK in 2 next frame + + if (sf == 0) + return ((10 * f) + 4) % 10240; // ACK/NAK in 4 same frame + break; + case 4: - if ((sf == 6) || (sf == 7) || (sf == 8) || (sf == 9)) - return (((10 * nextf) + 3) % 10240); // ACK/NAK in SF 3 next frame - else if ((sf == 0) || (sf == 1) || (sf == 4) || (sf == 5)) - return (((10 * nextf) + 2) % 10240); // ACK/NAK in SF 2 next frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 4\n", - sf); + if (sf == 6 || sf == 7 || sf == 8 || sf == 9) + return ((10 * nextf) + 3) % 10240; // ACK/NAK in SF 3 next frame + else if (sf == 0 || sf == 1 || sf == 4 || sf == 5) + return ((10 * nextf) + 2) % 10240; // ACK/NAK in SF 2 next frame + break; + case 5: - if ((sf == 0) || (sf == 1) || (sf == 3) || (sf == 4) - || (sf == 5) || (sf == 6) || (sf == 7) || (sf == 8)) - return (((10 * nextf) + 2) % 10240); // ACK/NAK in SF 3 next frame - else if (sf == 9) - return (((10 * (1 + nextf)) + 2) % 10240); // ACK/NAK in SF 2 next frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 5\n", - sf); + if (sf == 0 || sf == 1 || sf == 3 || sf == 4 || sf == 5 || sf == 6 || sf == 7 || sf == 8) + return ((10 * nextf) + 2) % 10240; // ACK/NAK in SF 3 next frame + + if (sf == 9) + return ((10 * (1 + nextf)) + 2) % 10240; // ACK/NAK in SF 2 next frame + break; + case 6: - if ((sf == 5) || (sf == 6)) - return ((10 * f) + sf + 7)% 10240; // ACK/NAK in SF 2,3 next frame - else if (sf == 9) - return ((10 * nextf) + 4)% 10240; // ACK/NAK in SF 4 next frame - else if ((sf == 1) || (sf == 0)) - return ((10 * f) + sf + 7)% 10240; // ACK/NAK in SF 7 same frame - else - AssertFatal(1 == 0, - "Impossible dlsch subframe %d for TDD configuration 6\n", - sf); + if (sf == 5 || sf == 6) + return ((10 * f) + sf + 7) % 10240; // ACK/NAK in SF 2,3 next frame + + if (sf == 9) + return ((10 * nextf) + 4) % 10240; // ACK/NAK in SF 4 next frame + + if (sf == 1 || sf == 0) + return ((10 * f) + sf + 7) % 10240; // ACK/NAK in SF 7 same frame + break; + default: - AssertFatal(1 == 0, "Illegal TDD subframe Assigment %d\n", - (int) cc->tdd_Config->subframeAssignment); - break; - } + AssertFatal(1 == 0, "Illegal TDD subframe Assigment %ld\n", + tdd_Config->subframeAssignment); + return 0; } + AssertFatal(1 == 0, "Shouldn't get here\n"); } +//------------------------------------------------------------------------------ void -get_srs_pos(COMMON_channels_t * cc, uint16_t isrs, - uint16_t * psrsPeriodicity, uint16_t * psrsOffset) +get_srs_pos(COMMON_channels_t *cc, + uint16_t isrs, + uint16_t *psrsPeriodicity, + uint16_t *psrsOffset) +//------------------------------------------------------------------------------ { - if (cc->tdd_Config) { // TDD + if (cc->tdd_Config) { // TDD AssertFatal(isrs >= 10, "2 ms SRS periodicity not supported"); - if ((isrs > 9) && (isrs < 15)) { + if (isrs > 9 && isrs < 15) { *psrsPeriodicity = 5; *psrsOffset = isrs - 10; - } - if ((isrs > 14) && (isrs < 25)) { + } else if (isrs > 14 && isrs < 25) { *psrsPeriodicity = 10; *psrsOffset = isrs - 15; - } - if ((isrs > 24) && (isrs < 45)) { + } else if (isrs > 24 && isrs < 45) { *psrsPeriodicity = 20; *psrsOffset = isrs - 25; - } - if ((isrs > 44) && (isrs < 85)) { + } else if (isrs > 44 && isrs < 85) { *psrsPeriodicity = 40; *psrsOffset = isrs - 45; - } - if ((isrs > 84) && (isrs < 165)) { + } else if (isrs > 84 && isrs < 165) { *psrsPeriodicity = 80; *psrsOffset = isrs - 85; - } - if ((isrs > 164) && (isrs < 325)) { + } else if (isrs > 164 && isrs < 325) { *psrsPeriodicity = 160; *psrsOffset = isrs - 165; - } - if ((isrs > 324) && (isrs < 645)) { + } else if (isrs > 324 && isrs < 645) { *psrsPeriodicity = 320; *psrsOffset = isrs - 325; } AssertFatal(isrs <= 644, "Isrs out of range %d>644\n", isrs); - } // TDD - else { // FDD + } // TDD + else { // FDD if (isrs < 2) { *psrsPeriodicity = 2; *psrsOffset = isrs; - } - if ((isrs > 1) && (isrs < 7)) { + } else if (isrs > 1 && isrs < 7) { *psrsPeriodicity = 5; *psrsOffset = isrs - 2; - } - if ((isrs > 6) && (isrs < 17)) { + } else if (isrs > 6 && isrs < 17) { *psrsPeriodicity = 10; *psrsOffset = isrs - 7; - } - if ((isrs > 16) && (isrs < 37)) { + } else if (isrs > 16 && isrs < 37) { *psrsPeriodicity = 20; *psrsOffset = isrs - 17; - } - if ((isrs > 36) && (isrs < 77)) { + } else if (isrs > 36 && isrs < 77) { *psrsPeriodicity = 40; *psrsOffset = isrs - 37; - } - if ((isrs > 76) && (isrs < 157)) { + } else if (isrs > 76 && isrs < 157) { *psrsPeriodicity = 80; *psrsOffset = isrs - 77; - } - if ((isrs > 156) && (isrs < 317)) { + } else if (isrs > 156 && isrs < 317) { *psrsPeriodicity = 160; *psrsOffset = isrs - 157; - } - if ((isrs > 316) && (isrs < 637)) { + } else if (isrs > 316 && isrs < 637) { *psrsPeriodicity = 320; *psrsOffset = isrs - 317; } + AssertFatal(isrs <= 636, "Isrs out of range %d>636\n", isrs); } + + return; } +//------------------------------------------------------------------------------ +/* +* Get some CSI (CQI/PMI/RI) parameters for SFN and subframe number calculation +* with periodic report. +*/ void -get_csi_params(COMMON_channels_t * cc, - struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic, - uint16_t * Npd, uint16_t * N_OFFSET_CQI, int *H) +get_csi_params(COMMON_channels_t *cc, + struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic, + uint16_t *Npd, + uint16_t *N_OFFSET_CQI, + int *H) +//------------------------------------------------------------------------------ { - uint16_t cqi_PMI_ConfigIndex = - cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; + AssertFatal(cqi_ReportPeriodic != NULL, "cqi_ReportPeriodic is null!\n"); + uint16_t cqi_PMI_ConfigIndex = cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; - AssertFatal(cqi_ReportPeriodic != NULL, - "cqi_ReportPeriodic is null!\n"); - - if (cc->tdd_Config == NULL) { //FDD - if (cqi_PMI_ConfigIndex <= 1) { // 2 ms CQI_PMI period + if (cc->tdd_Config == NULL) { //FDD + if (cqi_PMI_ConfigIndex <= 1) { // 2 ms CQI_PMI period *Npd = 2; *N_OFFSET_CQI = cqi_PMI_ConfigIndex; - } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period *Npd = 5; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 2; - } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period *Npd = 10; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 7; - } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period *Npd = 20; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 17; - } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period *Npd = 40; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 37; - } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period *Npd = 80; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 77; - } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period *Npd = 160; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 157; } else if (cqi_PMI_ConfigIndex > 317) { - if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period + if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period *Npd = 32; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 318; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 318; } else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period - *Npd = 64; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 350; + *Npd = 64; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 350; } else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period - *Npd = 128; - *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 414; + *Npd = 128; + *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 414; } + } - } else { // TDD + + } else { // TDD if (cqi_PMI_ConfigIndex == 0) { // all UL subframes *Npd = 1; *N_OFFSET_CQI = 0; - } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period *Npd = 5; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 1; - } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 16) { // 10ms CQI_PMI period *Npd = 10; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 6; - } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period *Npd = 20; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 16; - } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period *Npd = 40; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 36; - } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period *Npd = 80; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 76; - } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period + } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period *Npd = 160; *N_OFFSET_CQI = cqi_PMI_ConfigIndex - 156; } } // get H - if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic. - present == - LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) - *H = 1 + - (Jtab[cc->mib->message.dl_Bandwidth] * - cqi_ReportPeriodic->choice.setup. - cqi_FormatIndicatorPeriodic.choice.subbandCQI.k); - else + if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { + *H = 1 + (Jtab[cc->mib->message.dl_Bandwidth] * cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.choice.subbandCQI.k); + } else { *H = 1; + } + + return; } +//------------------------------------------------------------------------------ uint8_t -get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, - uint8_t ri, - LTE_CQI_ReportModeAperiodic_t * - cqi_ReportModeAperiodic) +get_dl_cqi_pmi_size_pusch(COMMON_channels_t *cc, + uint8_t tmode, + uint8_t ri, + LTE_CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic) +//------------------------------------------------------------------------------ { int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; int N = Ntab[cc->mib->message.dl_Bandwidth]; int Ltab_uesel[6] = { 0, 6, 9, 13, 15, 18 }; int L = Ltab_uesel[cc->mib->message.dl_Bandwidth]; - - AssertFatal(cqi_ReportModeAperiodic != NULL, - "cqi_ReportPeriodic is null!\n"); + AssertFatal(cqi_ReportModeAperiodic != NULL, "cqi_ReportPeriodic is null!\n"); switch (*cqi_ReportModeAperiodic) { - case LTE_CQI_ReportModeAperiodic_rm12: - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm12\n", - tmode); - AssertFatal(cc->p_eNB <= 4, - "only up to 4 antenna ports supported here\n"); - if (ri == 1 && cc->p_eNB == 2) + case LTE_CQI_ReportModeAperiodic_rm12: + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, "Illegal TM (%d) for CQI_ReportModeAperiodic_rm12\n", + tmode); + AssertFatal(cc->p_eNB <= 4, "only up to 4 antenna ports supported here\n"); + + if (ri == 1 && cc->p_eNB == 2) + return (4 + (N << 1)); + + if (ri == 2 && cc->p_eNB == 2) + return (8 + N); + + if (ri == 1 && cc->p_eNB == 4) + return (4 + (N << 2)); + + if (ri > 1 && cc->p_eNB == 4) + return (8 + (N << 2)); + + break; + + case LTE_CQI_ReportModeAperiodic_rm20: + // Table 5.2.2.6.3-1 (36.212) + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 || tmode == 9 || tmode == 10, "Illegal TM (%d) for CQI_ReportModeAperiodic_rm20\n", + tmode); + AssertFatal(tmode != 9 && tmode != 10, "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm20\n"); + return (4 + 2 + L); + + case LTE_CQI_ReportModeAperiodic_rm22: + // Table 5.2.2.6.3-2 (36.212) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, "Illegal TM (%d) for CQI_ReportModeAperiodic_rm22\n", + tmode); + AssertFatal(tmode != 9 && tmode != 10, "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm22\n"); + + if (ri == 1 && cc->p_eNB == 2) + return (4 + 2 + 0 + 0 + L + 4); + + if (ri == 2 && cc->p_eNB == 2) + return (4 + 2 + 4 + 2 + L + 2); + + if (ri == 1 && cc->p_eNB == 4) + return (4 + 2 + 0 + 0 + L + 8); + + if (ri >= 2 && cc->p_eNB == 4) + return (4 + 2 + 4 + 2 + L + 8); + + break; + + case LTE_CQI_ReportModeAperiodic_rm30: + // Table 5.2.2.6.2-1 (36.212) + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 || tmode == 8 || tmode == 9 || tmode == 10, + "Illegal TM (%d) for CQI_ReportModeAperiodic_rm30\n", + tmode); + AssertFatal(tmode != 8 && tmode != 9 && tmode != 10, "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm30\n"); return (4 + (N << 1)); - else if (ri == 2 && cc->p_eNB == 2) - return (8 + N); - else if (ri == 1 && cc->p_eNB == 4) - return (4 + (N << 2)); - else if (ri > 1 && cc->p_eNB == 4) - return (8 + (N << 2)); - break; - case LTE_CQI_ReportModeAperiodic_rm20: - // Table 5.2.2.6.3-1 (36.212) - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 - || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm20\n", - tmode); - AssertFatal(tmode != 9 - && tmode != 10, - "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm20\n"); - return (4 + 2 + L); - break; - case LTE_CQI_ReportModeAperiodic_rm22: - // Table 5.2.2.6.3-2 (36.212) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm22\n", - tmode); - AssertFatal(tmode != 9 - && tmode != 10, - "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm22\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + 2 + 0 + 0 + L + 4); - if (ri == 2 && cc->p_eNB == 2) - return (4 + 2 + 4 + 2 + L + 2); - if (ri == 1 && cc->p_eNB == 4) - return (4 + 2 + 0 + 0 + L + 8); - if (ri >= 2 && cc->p_eNB == 4) - return (4 + 2 + 4 + 2 + L + 8); - break; - case LTE_CQI_ReportModeAperiodic_rm30: - // Table 5.2.2.6.2-1 (36.212) - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 - || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm30\n", - tmode); - AssertFatal(tmode != 8 && tmode != 9 - && tmode != 10, - "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm30\n"); - return (4 + (N << 1)); - break; - case LTE_CQI_ReportModeAperiodic_rm31: - // Table 5.2.2.6.2-2 (36.212) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm31\n", - tmode); - AssertFatal(tmode != 8 && tmode != 9 - && tmode != 10, - "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm31\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + (N << 1) + 0 + 0 + 2); - else if (ri == 2 && cc->p_eNB == 2) - return (4 + (N << 1) + 4 + (N << 1) + 1); - else if (ri == 1 && cc->p_eNB == 4) - return (4 + (N << 1) + 0 + 0 + 4); - else if (ri >= 2 && cc->p_eNB == 4) - return (4 + (N << 1) + 4 + (N << 1) + 4); - break; + + case LTE_CQI_ReportModeAperiodic_rm31: + // Table 5.2.2.6.2-2 (36.212) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, "Illegal TM (%d) for CQI_ReportModeAperiodic_rm31\n", + tmode); + AssertFatal(tmode != 8 && tmode != 9 && tmode != 10, "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm31\n"); + + if (ri == 1 && cc->p_eNB == 2) + return (4 + (N << 1) + 0 + 0 + 2); + + if (ri == 2 && cc->p_eNB == 2) + return (4 + (N << 1) + 4 + (N << 1) + 1); + + if (ri == 1 && cc->p_eNB == 4) + return (4 + (N << 1) + 0 + 0 + 4); + + if (ri >= 2 && cc->p_eNB == 4) + return (4 + (N << 1) + 4 + (N << 1) + 4); + + break; #if (LTE_RRC_VERSION >= MAKE_VERSION(12, 5, 0)) - case LTE_CQI_ReportModeAperiodic_rm32_v1250: - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm32\n", - tmode); - AssertFatal(1 == 0, - "CQI_ReportModeAperiodic_rm32_v1250 not supported yet\n"); - break; - case LTE_CQI_ReportModeAperiodic_rm10_v1310: - // Table 5.2.2.6.1-1F/G (36.212) - if (ri == 1) - return (4); // F - else - return (7); // G - break; - case LTE_CQI_ReportModeAperiodic_rm11_v1310: - // Table 5.2.2.6.1-1H (36.212) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal TM (%d) for CQI_ReportModeAperiodic_rm11\n", - tmode); - AssertFatal(cc->p_eNB <= 4, - "only up to 4 antenna ports supported here\n"); - if (ri == 1 && cc->p_eNB == 2) - return (4 + 0 + 2); - else if (ri == 2 && cc->p_eNB == 2) - return (4 + 4 + 1); - else if (ri == 1 && cc->p_eNB == 4) - return (4 + 0 + 4); - else if (ri > 1 && cc->p_eNB == 4) - return (4 + 4 + 4); - break; + case LTE_CQI_ReportModeAperiodic_rm32_v1250: + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, "Illegal TM (%d) for CQI_ReportModeAperiodic_rm32\n", + tmode); + AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm32_v1250 not supported yet\n"); + break; + + case LTE_CQI_ReportModeAperiodic_rm10_v1310: + + // Table 5.2.2.6.1-1F/G (36.212) + if (ri == 1) + return 4; // F + + return 7; // G + + case LTE_CQI_ReportModeAperiodic_rm11_v1310: + // Table 5.2.2.6.1-1H (36.212) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, "Illegal TM (%d) for CQI_ReportModeAperiodic_rm11\n", + tmode); + AssertFatal(cc->p_eNB <= 4, "only up to 4 antenna ports supported here\n"); + + if (ri == 1 && cc->p_eNB == 2) + return (4 + 0 + 2); + + if (ri == 2 && cc->p_eNB == 2) + return (4 + 4 + 1); + + if (ri == 1 && cc->p_eNB == 4) + return (4 + 0 + 4); + + if (ri > 1 && cc->p_eNB == 4) + return (4 + 4 + 4); + + break; #endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(12, 5, 0)) */ } + AssertFatal(1 == 0, "Shouldn't get here\n"); - return (0); + return 0; } +//------------------------------------------------------------------------------ uint8_t -get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP, - COMMON_channels_t * cc, uint8_t tmode, - struct LTE_CQI_ReportPeriodic * cqi_ReportPeriodic) +get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl, + int CC_idP, + COMMON_channels_t *cc, + uint8_t tmode, + struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic) +//------------------------------------------------------------------------------ { int no_pmi = 0; // Ltab[6] = {0,log2(15/4/2),log2(25/4/2),log2(50/6/3),log2(75/8/4),log2(100/8/4)}; - uint8_t Ltab[6] = { 0, 1, 2, 2, 2, 2 }; uint8_t ri = sched_ctl->periodic_ri_received[CC_idP]; - - AssertFatal(cqi_ReportPeriodic != NULL, - "cqi_ReportPeriodic is null!\n"); - AssertFatal(cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); - AssertFatal(cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present != LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic != NULL, "cqi_ReportPeriodic is null!\n"); + AssertFatal(cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_NOTHING, "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); switch (tmode) { - case 1: - case 2: - case 5: - case 6: - case 7: - no_pmi = 1; - break; - default: - no_pmi = 0; + case 1: + case 2: + case 5: + case 6: + case 7: + no_pmi = 1; + break; + + default: + no_pmi = 0; + break; } - if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) - || (sched_ctl->feedback_cnt[CC_idP] == 0)) { + if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI || + sched_ctl->feedback_cnt[CC_idP] == 0) { // send wideband report every opportunity if wideband reporting mode is selected, else every H opportunities - if (no_pmi == 1) return (4); - else if ((cc->p_eNB == 2) && (ri == 1)) return (6); - else if ((cc->p_eNB == 2) && (ri == 2)) return (8); - else if ((cc->p_eNB == 4) && (ri == 1)) return (8); - else if ((cc->p_eNB == 4) && (ri == 2)) return (11); - else - AssertFatal(1 == 0, - "illegal combination p %d, ri %d, no_pmi %d\n", - cc->p_eNB, ri, no_pmi); + if (no_pmi == 1) return 4; + + if (cc->p_eNB == 2 && ri == 1) return 6; + + if (cc->p_eNB == 2 && ri == 2) return 8; + + if (cc->p_eNB == 4 && ri == 1) return 8; + + if (cc->p_eNB == 4 && ri == 2) return 11; + + AssertFatal(1 == 0, "illegal combination p %d, ri %d, no_pmi %d\n", + cc->p_eNB, + ri, + no_pmi); } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { - if ((no_pmi == 1) || ri == 1) return (4 + Ltab[cc->mib->message.dl_Bandwidth]); - else return (7 + Ltab[cc->mib->message.dl_Bandwidth]); + if (no_pmi == 1 || ri == 1) return (4 + Ltab[cc->mib->message.dl_Bandwidth]); + + return (7 + Ltab[cc->mib->message.dl_Bandwidth]); } - AssertFatal(1 == 0, - "Shouldn't get here : cqi_ReportPeriodic->present %d\n", - cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present); + AssertFatal(1 == 0, "Shouldn't get here : cqi_ReportPeriodic->present %d\n", + cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present); + return 0; } - - +//------------------------------------------------------------------------------ void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu, - uint8_t aggregation_level, - uint16_t rnti, - uint8_t rnti_type, - uint8_t harq_process, - uint8_t tpc, - uint16_t resource_block_coding, - uint8_t mcs, - uint8_t ndi, - uint8_t rv, - uint8_t vrb_flag) + uint8_t aggregation_level, + uint16_t rnti, + uint8_t rnti_type, + uint8_t harq_process, + uint8_t tpc, + uint16_t resource_block_coding, + uint8_t mcs, + uint8_t ndi, + uint8_t rv, + uint8_t vrb_flag) +//------------------------------------------------------------------------------ { - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; @@ -1079,7 +1155,7 @@ fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation_level; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = rnti_type; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_process; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = resource_block_coding; @@ -1087,12 +1163,18 @@ fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t *dl_config_pdu, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = vrb_flag; + return; } +//------------------------------------------------------------------------------ void -program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP, - frame_t frameP, sub_frame_t subframeP, - uint8_t cce_idx) +program_dlsch_acknak(module_id_t module_idP, + int CC_idP, + int UE_idP, + frame_t frameP, + sub_frame_t subframeP, + uint8_t cce_idx) +//------------------------------------------------------------------------------ { eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = eNB->common_channels; @@ -1103,178 +1185,206 @@ program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP, int use_simultaneous_pucch_pusch = 0; nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = NULL; nfapi_ul_config_harq_information *harq_information = NULL; - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 2, 0)) + struct LTE_PhysicalConfigDedicated__ext2 *ext2 = UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2; - if ((UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2) - && (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020) - && (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10) - && (*UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 == LTE_PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true)) + if (ext2 && + ext2->pucch_ConfigDedicated_v1020 && + ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 && + *ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 == LTE_PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true) use_simultaneous_pucch_pusch = 1; -#endif +#endif // pucch1 and pusch feedback is similar, namely in n+k subframes from now // This is used in the following "if/else" condition to check if there isn't or is already an UL grant in n+k - int16_t ul_absSF = get_pucch1_absSF(&cc[CC_idP], subframeP + (10 * frameP)); + int16_t ul_absSF = get_pucch1_absSF(&cc[CC_idP], + subframeP + (10 * frameP)); - if ((ul_config_pdu = has_ul_grant(module_idP, CC_idP,ul_absSF, rnti)) == NULL) { + if ((ul_config_pdu = has_ul_grant(module_idP, + CC_idP, + ul_absSF, + rnti)) == NULL) { // no UL grant so // Program ACK/NAK alone Format 1a/b or 3 - - ul_req = &RC.mac[module_idP]->UL_req_tmp[CC_idP][ul_absSF %10].ul_config_request_body; + ul_req = &eNB->UL_req_tmp[CC_idP][ul_absSF % 10].ul_config_request_body; ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; // Do PUCCH fill_nfapi_uci_acknak(module_idP, - CC_idP, - rnti, (frameP * 10) + subframeP, cce_idx); + CC_idP, + rnti, + subframeP + (10 * frameP), + cce_idx); } else { /* there is already an existing UL grant so update it if needed * on top of some other UL resource (PUSCH,combined SR/CQI/HARQ on PUCCH, etc) */ switch (ul_config_pdu->pdu_type) { - /* [ulsch] to [ulsch + harq] or [ulsch + harq on pucch] */ - - case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: - if (use_simultaneous_pucch_pusch == 1) { - // Convert it to an NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE - harq_information = &ul_config_pdu->ulsch_uci_harq_pdu.harq_information; - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE; - LOG_D(MAC, - "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH UCI HARQ\n", - frameP, subframeP); - } else { - // Convert it to an NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE - ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information; - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet - LOG_D(MAC, - "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH HARQ\n", - frameP, subframeP); - } - break; - case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 0, - "Cannot be NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE, simultaneous_pucch_pusch is active"); - break; - case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 1, - "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); - break; + case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: + if (use_simultaneous_pucch_pusch == 1) { + // Convert it to an NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE + harq_information = &ul_config_pdu->ulsch_uci_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE; + LOG_D(MAC, "Frame %d, Subframe %d: Switched UCI HARQ to ULSCH UCI HARQ\n", + frameP, + subframeP); + } else { + // Convert it to an NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE + ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag + = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks + = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet + LOG_D(MAC,"Frame %d, Subframe %d: Switched UCI HARQ to ULSCH HARQ\n", + frameP, + subframeP); + } + + break; + + case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 0, "Cannot be NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE, simultaneous_pucch_pusch is active"); + break; + + case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 1, "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); + break; /* [ulsch + cqi] to [ulsch + cqi + harq] */ - case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: - // Convert it to an NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE - ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - /* TODO: check this - when converting from nfapi_ul_config_ulsch_cqi_ri_pdu to - * nfapi_ul_config_ulsch_cqi_harq_ri_pdu, shouldn't we copy initial_transmission_parameters - * from the one to the other? - * Those two types are not compatible. 'initial_transmission_parameters' is not at the - * place in both. - */ - ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet - break; - case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 0, - "Cannot be NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE, simultaneous_pucch_pusch is active\n"); - break; + case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: + // Convert it to an NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE + ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + /* TODO: check this - when converting from nfapi_ul_config_ulsch_cqi_ri_pdu to + * nfapi_ul_config_ulsch_cqi_harq_ri_pdu, shouldn't we copy initial_transmission_parameters + * from the one to the other? + * Those two types are not compatible. 'initial_transmission_parameters' is not at the + * place in both. + */ + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag + = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_config_pdu->ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks + = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet + break; + + case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 0, "Cannot be NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE, simultaneous_pucch_pusch is active\n"); + break; /* [ulsch + cqi on pucch] to [ulsch + cqi on pucch + harq on pucch] */ - case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: - // convert it to an NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE - harq_information = &ul_config_pdu->ulsch_csi_uci_harq_pdu.harq_information; - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE; - break; - case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: - AssertFatal(use_simultaneous_pucch_pusch == 1, - "Cannot be NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); - break; + case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: + // convert it to an NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE + harq_information = &ul_config_pdu->ulsch_csi_uci_harq_pdu.harq_information; + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE; + break; + + case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: + AssertFatal(use_simultaneous_pucch_pusch == 1, "Cannot be NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE, simultaneous_pucch_pusch is inactive\n"); + break; /* [sr] to [sr + harq] */ - case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: - // convert to NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; - harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information; - break; - case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: - /* nothing to do */ - break; + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: + // convert to NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information; + break; + + case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: + /* nothing to do */ + break; + /* [cqi] to [cqi + harq] */ - case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: - // convert to NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE; - harq_information = &ul_config_pdu->uci_cqi_harq_pdu.harq_information; - break; - case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: - /* nothing to do */ - break; + case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: + // convert to NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_cqi_harq_pdu.harq_information; + break; + + case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: + /* nothing to do */ + break; + /* [cqi + sr] to [cqr + sr + harq] */ - case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: - // convert to NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE; - harq_information = &ul_config_pdu->uci_cqi_sr_harq_pdu.harq_information; - break; - case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: - /* nothing to do */ - break; + case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: + // convert to NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE; + harq_information = &ul_config_pdu->uci_cqi_sr_harq_pdu.harq_information; + break; + + case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: + /* nothing to do */ + break; } } - if (ulsch_harq_information) fill_nfapi_ulsch_harq_information(module_idP, CC_idP, rnti, ulsch_harq_information, subframeP); + if (ulsch_harq_information) { + fill_nfapi_ulsch_harq_information(module_idP, + CC_idP, + rnti, + ulsch_harq_information, + subframeP); + } + + if (harq_information) { + fill_nfapi_harq_information(module_idP, + CC_idP, + rnti, + harq_information, + cce_idx); + } - if (harq_information) fill_nfapi_harq_information(module_idP, CC_idP, - rnti, - (frameP * 10) + subframeP, - harq_information, cce_idx); + return; } -uint8_t get_V_UL_DAI(module_id_t module_idP, int CC_idP, uint16_t rntiP,sub_frame_t subframeP) +//------------------------------------------------------------------------------ +uint8_t +get_V_UL_DAI(module_id_t module_idP, + int CC_idP, + uint16_t rntiP, + sub_frame_t subframeP) +//------------------------------------------------------------------------------ { nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframeP].hi_dci0_request_body; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[0]; for (int i = 0; i < HI_DCI0_req->number_of_dci; i++) { - if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && - (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) - return (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index); + if (hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE && + hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP) { + return hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index; + } } - return (4); // this is rule from Section 7.3 in 36.213 + + return 4; // this is rule from Section 7.3 in 36.213 } +//------------------------------------------------------------------------------ void fill_nfapi_ulsch_harq_information(module_id_t module_idP, - int CC_idP, - uint16_t rntiP, - nfapi_ul_config_ulsch_harq_information *harq_information, - sub_frame_t subframeP) + int CC_idP, + uint16_t rntiP, + nfapi_ul_config_ulsch_harq_information *harq_information, + sub_frame_t subframeP) +//------------------------------------------------------------------------------ { eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; UE_list_t *UE_list = &eNB->UE_list; - int UE_id = find_UE_id(module_idP, rntiP); - - LTE_PUSCH_ConfigDedicated_t *puschConfigDedicated; - // PUSCH_ConfigDedicated_v1020_t *puschConfigDedicated_v1020; - // PUSCH_ConfigDedicated_v1130_t *puschConfigDedicated_v1130; - // PUSCH_ConfigDedicated_v1250_t *puschConfigDedicated_v1250; - + nfapi_ul_config_ulsch_harq_information_rel10_t *harq_information_rel10 = &harq_information->harq_information_rel10; AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n"); AssertFatal(UE_list != NULL, "UE_list is null\n"); - AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, - "physicalConfigDedicated for rnti %x is null\n", rntiP); - AssertFatal((puschConfigDedicated = (LTE_PUSCH_ConfigDedicated_t *) - UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pusch_ConfigDedicated) != NULL, - "physicalConfigDedicated->puschConfigDedicated for rnti %x is null\n", - rntiP); + LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated; + AssertFatal(physicalConfigDedicated != NULL, "physicalConfigDedicated for rnti %x is null\n", + rntiP); + struct LTE_PUSCH_ConfigDedicated *puschConfigDedicated = physicalConfigDedicated->pusch_ConfigDedicated; + AssertFatal(puschConfigDedicated != NULL, "physicalConfigDedicated->puschConfigDedicated for rnti %x is null\n", + rntiP); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 2, 0)) /* if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2) puschConfigDedicated_v1020 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2->pusch_ConfigDedicated_v1020; #endif @@ -1286,146 +1396,181 @@ fill_nfapi_ulsch_harq_information(module_id_t module_ #endif */ #endif - harq_information->harq_information_rel10.delta_offset_harq = puschConfigDedicated->betaOffset_ACK_Index; - harq_information->harq_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG; - AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, - "pucch_ConfigDedicated is null!\n"); - if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) - && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == LTE_PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) - harq_information->harq_information_rel10.ack_nack_mode = 1; // multiplexing + harq_information_rel10->delta_offset_harq = puschConfigDedicated->betaOffset_ACK_Index; + harq_information_rel10->tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG; + struct LTE_PUCCH_ConfigDedicated *pucch_ConfigDedicated = physicalConfigDedicated->pucch_ConfigDedicated; + AssertFatal(pucch_ConfigDedicated != NULL, "pucch_ConfigDedicated is null!\n"); + + if (pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL && + *pucch_ConfigDedicated->tdd_AckNackFeedbackMode == LTE_PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing) + harq_information_rel10->ack_nack_mode = 1; // multiplexing else - harq_information->harq_information_rel10.ack_nack_mode = 0; // bundling + harq_information_rel10->ack_nack_mode = 0; // bundling switch (get_tmode(module_idP, CC_idP, UE_id)) { - case 1: - case 2: - case 5: - case 6: - case 7: - if (cc->tdd_Config == NULL) // FDD - harq_information->harq_information_rel10.harq_size = 1; - else { - if (harq_information->harq_information_rel10.ack_nack_mode == 1) - harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP, CC_idP, rntiP, subframeP); - else - harq_information->harq_information_rel10.harq_size = 1; - } - break; - default: // for any other TM we need 2 bits harq - if (cc->tdd_Config == NULL) { - harq_information->harq_information_rel10.harq_size = 2; - } else { - if (harq_information->harq_information_rel10.ack_nack_mode == 1) - harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP, CC_idP, rntiP, subframeP); - else - harq_information->harq_information_rel10.harq_size = 2; - } - break; - } // get Tmode + case 1: + case 2: + case 5: + case 6: + case 7: + if (cc->tdd_Config == NULL) // FDD + harq_information_rel10->harq_size = 1; + else { + if (harq_information_rel10->ack_nack_mode == 1) + harq_information_rel10->harq_size = get_V_UL_DAI(module_idP, + CC_idP, + rntiP, + subframeP); + else + harq_information_rel10->harq_size = 1; + } + break; + + default: // for any other TM we need 2 bits harq + if (cc->tdd_Config == NULL) { + harq_information_rel10->harq_size = 2; + } else { + if (harq_information_rel10->ack_nack_mode == 1) + harq_information_rel10->harq_size = get_V_UL_DAI(module_idP, + CC_idP, + rntiP, + subframeP); + else + harq_information_rel10->harq_size = 2; + } + break; + } // get Tmode + + return; } -uint8_t Np[6][4]= {{0,1,3,5}, - {0,3,8,13}, - {0,5,13,22}, - {0,11,27,44}, - {0,16,41,66}, - {0,22,55,88}}; +//------------------------------------------------------------------------------ +uint8_t +Np[6][4] = { + {0, 1, 3, 5}, + {0, 3, 8, 13}, + {0, 5, 13, 22}, + {0, 11, 27, 44}, + {0, 16, 41, 66}, + {0, 22, 55, 88} +}; +//------------------------------------------------------------------------------ // This is part of the PUCCH allocation procedure (see Section 10.1 36.213) -uint16_t getNp(int dl_Bandwidth,uint8_t nCCE,uint8_t plus1) +//------------------------------------------------------------------------------ +uint16_t +getNp(int dl_Bandwidth, + uint8_t nCCE, + uint8_t plus1) +//------------------------------------------------------------------------------ { - AssertFatal(dl_Bandwidth<6,"dl_Bandwidth %d>5\n",dl_Bandwidth); + AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth %d>5\n", dl_Bandwidth); - if (nCCE>=Np[dl_Bandwidth][2]) + if (nCCE >= Np[dl_Bandwidth][2]) { return(Np[dl_Bandwidth][2+plus1]); - else if (nCCE>=Np[dl_Bandwidth][1]) + } + + if (nCCE >= Np[dl_Bandwidth][1]) { return(Np[dl_Bandwidth][1+plus1]); - else - return(Np[dl_Bandwidth][0+plus1]); + } + + return(Np[dl_Bandwidth][0+plus1]); } +//------------------------------------------------------------------------------ void fill_nfapi_harq_information(module_id_t module_idP, - int CC_idP, - uint16_t rntiP, - uint16_t absSFP, - nfapi_ul_config_harq_information *harq_information, - uint8_t cce_idxP) + int CC_idP, + uint16_t rntiP, + nfapi_ul_config_harq_information *harq_information, + uint8_t cce_idxP) +//------------------------------------------------------------------------------ { eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; UE_list_t *UE_list = &eNB->UE_list; - - int UE_id = find_UE_id(module_idP, rntiP); - + int UE_id = find_UE_id(module_idP, + rntiP); AssertFatal(UE_id >= 0, "UE_id cannot be found, impossible\n"); AssertFatal(UE_list != NULL, "UE_list is null\n"); - harq_information->harq_information_rel11.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL11_TAG; harq_information->harq_information_rel11.num_ant_ports = 1; + LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated; + struct LTE_PUCCH_ConfigDedicated *pucch_ConfigDedicated = NULL; - switch (get_tmode(module_idP, CC_idP, UE_id)) { - case 1: - case 2: - case 5: - case 6: - case 7: - if (cc->tdd_Config != NULL) { -// AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, -// "pucch_ConfigDedicated is null for TDD!\n"); - if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL - && UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL - && (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) - && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == LTE_PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) - { - harq_information->harq_information_rel10_tdd.harq_size = 2; // 2-bit ACK/NAK - harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing - } else { - harq_information->harq_information_rel10_tdd.harq_size = 1; // 1-bit ACK/NAK - harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling - } - harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; - harq_information->harq_information_rel10_tdd.n_pucch_1_0 = getNp(cc->mib->message.dl_Bandwidth,cce_idxP,0) + - cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; - harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1; - } else { - harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; - harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1; - harq_information->harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK - harq_information->harq_information_rel9_fdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; - } - break; - default: // for any other TM we need 2 bits harq - if (cc->tdd_Config != NULL) { - AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, - "pucch_ConfigDedicated is null for TDD!\n"); - if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) - && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == LTE_PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) { - harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing + if (physicalConfigDedicated != NULL) pucch_ConfigDedicated = physicalConfigDedicated->pucch_ConfigDedicated; + + switch (get_tmode(module_idP, + CC_idP, + UE_id)) { + case 1: + case 2: + case 5: + case 6: + case 7: + if (cc->tdd_Config != NULL) { + // AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, + // "pucch_ConfigDedicated is null for TDD!\n"); + if (physicalConfigDedicated != NULL && pucch_ConfigDedicated != NULL && + pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL && + *pucch_ConfigDedicated->tdd_AckNackFeedbackMode == LTE_PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing) { + harq_information->harq_information_rel10_tdd.harq_size = 2; // 2-bit ACK/NAK + harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing + } else { + harq_information->harq_information_rel10_tdd.harq_size = 1; // 1-bit ACK/NAK + harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling + } + + harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; + harq_information->harq_information_rel10_tdd.n_pucch_1_0 + = getNp(cc->mib->message.dl_Bandwidth, cce_idxP, 0) + cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1; } else { - harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling + harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; + harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1; + harq_information->harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK + harq_information->harq_information_rel9_fdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; } - harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; - harq_information->harq_information_rel10_tdd.harq_size = 2; - harq_information->harq_information_rel10_tdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; - harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1; - } else { - harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; - harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1; - harq_information->harq_information_rel9_fdd.ack_nack_mode = 0; // 1a/b - harq_information->harq_information_rel9_fdd.harq_size = 2; - harq_information->harq_information_rel9_fdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; - } - break; - } // get Tmode + + break; + + default: // for any other TM we need 2 bits harq + if (cc->tdd_Config != NULL) { + AssertFatal(pucch_ConfigDedicated != NULL, "pucch_ConfigDedicated is null for TDD!\n"); + + if (pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL && + *pucch_ConfigDedicated->tdd_AckNackFeedbackMode == LTE_PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing) { + harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing + } else { + harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling + } + + harq_information->harq_information_rel10_tdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG; + harq_information->harq_information_rel10_tdd.harq_size = 2; + harq_information->harq_information_rel10_tdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1; + } else { + harq_information->harq_information_rel9_fdd.tl.tag = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG; + harq_information->harq_information_rel9_fdd.number_of_pucch_resources = 1; + harq_information->harq_information_rel9_fdd.ack_nack_mode = 0; // 1a/b + harq_information->harq_information_rel9_fdd.harq_size = 2; + harq_information->harq_information_rel9_fdd.n_pucch_1_0 = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP; + } + + break; + } // get Tmode + + return; } +//------------------------------------------------------------------------------ uint16_t fill_nfapi_uci_acknak(module_id_t module_idP, - int CC_idP, - uint16_t rntiP, - uint16_t absSFP, - uint8_t cce_idxP) + int CC_idP, + uint16_t rntiP, + uint16_t absSFP, + uint8_t cce_idxP) +//------------------------------------------------------------------------------ { eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; @@ -1433,25 +1578,25 @@ fill_nfapi_uci_acknak(module_id_t module_idP, nfapi_ul_config_request_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10]; nfapi_ul_config_request_body_t *ul_req_body = &ul_req->ul_config_request_body; nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus]; - memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_uci_harq_pdu)); ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG; ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = rntiP; - - fill_nfapi_harq_information(module_idP, CC_idP, - rntiP, - absSFP, - &ul_config_pdu->uci_harq_pdu.harq_information, cce_idxP); - LOG_D(MAC, - "Filled in UCI HARQ request for rnti %x SF %d.%d acknakSF %d.%d, cce_idxP %d-> n1_pucch %d\n", - rntiP, absSFP / 10, absSFP % 10, ackNAK_absSF / 10, - ackNAK_absSF % 10, cce_idxP, - ul_config_pdu->uci_harq_pdu. - harq_information.harq_information_rel9_fdd.n_pucch_1_0); - + fill_nfapi_harq_information(module_idP, + CC_idP, + rntiP, + &ul_config_pdu->uci_harq_pdu.harq_information, + cce_idxP); + LOG_D(MAC, "Filled in UCI HARQ request for rnti %x SF %d.%d acknakSF %d.%d, cce_idxP %d-> n1_pucch %d\n", + rntiP, + absSFP / 10, + absSFP % 10, + ackNAK_absSF / 10, + ackNAK_absSF % 10, + cce_idxP, + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0); ul_req_body->number_of_pdus++; ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; @@ -1460,38 +1605,37 @@ fill_nfapi_uci_acknak(module_id_t module_idP, return (((ackNAK_absSF / 10) << 4) + (ackNAK_absSF % 10)); } +//------------------------------------------------------------------------------ void -fill_nfapi_dlsch_config(eNB_MAC_INST * eNB, - nfapi_dl_config_request_body_t * dl_req, - uint16_t length, - int16_t pdu_index, - uint16_t rnti, - uint8_t resource_allocation_type, - uint8_t - virtual_resource_block_assignment_flag, - uint16_t resource_block_coding, - uint8_t modulation, - uint8_t redundancy_version, - uint8_t transport_blocks, - uint8_t transport_block_to_codeword_swap_flag, - uint8_t transmission_scheme, - uint8_t number_of_layers, - uint8_t number_of_subbands, - // uint8_t codebook_index, - uint8_t ue_category_capacity, - uint8_t pa, - uint8_t delta_power_offset_index, - uint8_t ngap, - uint8_t nprb, - uint8_t transmission_mode, - uint8_t num_bf_prb_per_subband, - uint8_t num_bf_vector) +fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, + nfapi_dl_config_request_body_t *dl_req, + uint16_t length, + int16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint8_t + virtual_resource_block_assignment_flag, + uint16_t resource_block_coding, + uint8_t modulation, + uint8_t redundancy_version, + uint8_t transport_blocks, + uint8_t transport_block_to_codeword_swap_flag, + uint8_t transmission_scheme, + uint8_t number_of_layers, + uint8_t number_of_subbands, + // uint8_t codebook_index, + uint8_t ue_category_capacity, + uint8_t pa, + uint8_t delta_power_offset_index, + uint8_t ngap, + uint8_t nprb, + uint8_t transmission_mode, + uint8_t num_bf_prb_per_subband, + uint8_t num_bf_vector) +//------------------------------------------------------------------------------ { - nfapi_dl_config_request_pdu_t *dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - + nfapi_dl_config_request_pdu_t *dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; @@ -1508,7 +1652,7 @@ fill_nfapi_dlsch_config(eNB_MAC_INST * eNB, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = transmission_scheme; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = number_of_layers; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = number_of_subbands; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = ue_category_capacity; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = delta_power_offset_index; @@ -1518,19 +1662,22 @@ fill_nfapi_dlsch_config(eNB_MAC_INST * eNB, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = num_bf_prb_per_subband; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; dl_req->number_pdu++; + return; } +//------------------------------------------------------------------------------ uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body, - uint16_t absSF, - uint16_t pdu_length, - int16_t pdu_index, - uint8_t *pdu) + uint16_t absSF, + uint16_t pdu_length, + int16_t pdu_index, + uint8_t *pdu) +//------------------------------------------------------------------------------ { nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; LOG_D(MAC, "Filling TX_req %d for pdu length %d\n", - tx_req_body->number_of_pdus, pdu_length); - + tx_req_body->number_of_pdus, + pdu_length); TX_req->pdu_length = pdu_length; TX_req->pdu_index = pdu_index; TX_req->num_segments = 1; @@ -1538,34 +1685,35 @@ fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body, TX_req->segments[0].segment_data = pdu; tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; tx_req_body->number_of_pdus++; - return (((absSF / 10) << 4) + (absSF % 10)); } +//------------------------------------------------------------------------------ void -fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pdu, - uint8_t cqi_req, - COMMON_channels_t *cc, - struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, - uint8_t tmode, - uint32_t handle, - uint16_t rnti, - uint8_t resource_block_start, - uint8_t number_of_resource_blocks, - uint8_t mcs, - uint8_t cyclic_shift_2_for_drms, - uint8_t frequency_hopping_enabled_flag, - uint8_t frequency_hopping_bits, - uint8_t new_data_indication, - uint8_t redundancy_version, - uint8_t harq_process_number, - uint8_t ul_tx_mode, - uint8_t current_tx_nb, - uint8_t n_srs, - uint16_t size) +fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint8_t cqi_req, + COMMON_channels_t *cc, + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, + uint8_t tmode, + uint32_t handle, + uint16_t rnti, + uint8_t resource_block_start, + uint8_t number_of_resource_blocks, + uint8_t mcs, + uint8_t cyclic_shift_2_for_drms, + uint8_t frequency_hopping_enabled_flag, + uint8_t frequency_hopping_bits, + uint8_t new_data_indication, + uint8_t redundancy_version, + uint8_t harq_process_number, + uint8_t ul_tx_mode, + uint8_t current_tx_nb, + uint8_t n_srs, + uint16_t size) +//------------------------------------------------------------------------------ { + uint8_t ri_size = 0; memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); - ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; @@ -1573,10 +1721,12 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pd ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = rnti; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = resource_block_start; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = number_of_resource_blocks; + if (mcs < 11) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2; else if (mcs < 21) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 4; else if(mcs < 29) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 6; else ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 0; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = cyclic_shift_2_for_drms; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = frequency_hopping_enabled_flag; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = frequency_hopping_bits; @@ -1595,166 +1745,199 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pd ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type = 1; ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; - LOG_D(MAC, "report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type); + LOG_D(MAC, "report_type %d\n", + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type); - if (cc->p_eNB <= 2 - && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) - ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; - else if (cc->p_eNB <= 2) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; - else if (cc->p_eNB == 4) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; + if (cc->p_eNB <= 2 && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) ri_size = 1; + else if (cc->p_eNB <= 2) ri_size = 0; + else if (cc->p_eNB == 4) ri_size = 2; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = ri_size; AssertFatal(physicalConfigDedicated->cqi_ReportConfig != NULL,"physicalConfigDedicated->cqi_ReportConfig is null!\n"); AssertFatal(physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic != NULL,"physicalConfigDedicated->cqi_ReportModeAperiodic is null!\n"); AssertFatal(physicalConfigDedicated->pusch_ConfigDedicated != NULL,"physicalConfigDedicated->puschConfigDedicated is null!\n"); + nfapi_ul_config_cqi_ri_information_rel9_t *ri_information = &ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9; + int max_ri = (1 << ri_information->aperiodic_cqi_pmi_ri_report.cc[0].ri_size); + + for (int ri = 0; ri < max_ri; ri++) { + ri_information->aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] + = get_dl_cqi_pmi_size_pusch(cc, + tmode, + 1 + ri, + physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic); + } - for (int ri = 0; - ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); - ri++) - ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = get_dl_cqi_pmi_size_pusch(cc,tmode,1 + ri,physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic); - - ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; - ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; + ri_information->delta_offset_cqi = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; + ri_information->delta_offset_ri = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; } + + return; } #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +//------------------------------------------------------------------------------ void -fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t * - ul_config_pdu, uint8_t ue_type, - uint16_t - total_number_of_repetitions, - uint16_t repetition_number, - uint16_t initial_transmission_sf_io) +fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint8_t ue_type, + uint16_t total_number_of_repetitions, + uint16_t repetition_number, + uint16_t initial_transmission_sf_io) +//------------------------------------------------------------------------------ { // Re13 fields - ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ue_type; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = total_number_of_repetitions; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = repetition_number; ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = initial_transmission_sf_io; + return; } -int get_numnarrowbands(long dl_Bandwidth) +//------------------------------------------------------------------------------ +int +get_numnarrowbands(long dl_Bandwidth) +//------------------------------------------------------------------------------ { int nb_tab[6] = { 1, 2, 4, 8, 12, 16 }; - AssertFatal(dl_Bandwidth < 7 || dl_Bandwidth >= 0, "dl_Bandwidth not in [0..6]\n"); return (nb_tab[dl_Bandwidth]); } -int get_numnarrowbandbits(long dl_Bandwidth) +//------------------------------------------------------------------------------ +int +get_numnarrowbandbits(long dl_Bandwidth) +//------------------------------------------------------------------------------ { int nbbits_tab[6] = { 0, 1, 2, 3, 4, 4 }; - AssertFatal(dl_Bandwidth < 7 || dl_Bandwidth >= 0, "dl_Bandwidth not in [0..6]\n"); return (nbbits_tab[dl_Bandwidth]); } //This implements the frame/subframe condition for first subframe of MPDCCH transmission (Section 9.1.5 36.213, Rel 13/14) -int startSF_fdd_RA_times2[8] = { 2, 3, 4, 5, 8, 10, 16, 20 }; -int startSF_tdd_RA[7] = { 1, 2, 4, 5, 8, 10, 20 }; +//------------------------------------------------------------------------------ +int +startSF_fdd_RA_times2[8] = { 2, 3, 4, 5, 8, 10, 16, 20 }; +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ int -mpdcch_sf_condition(eNB_MAC_INST * eNB, int CC_id, frame_t frameP, - sub_frame_t subframeP, int rmax, - MPDCCH_TYPES_t mpdcch_type, int UE_id) -{ - struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = - eNB->common_channels[CC_id].radioResourceConfigCommon_BR-> - ext4->prach_ConfigCommon_v1310; +startSF_tdd_RA[7] = { 1, 2, 4, 5, 8, 10, 20 }; +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +int +mpdcch_sf_condition(eNB_MAC_INST *eNB, + int CC_id, + frame_t frameP, + sub_frame_t subframeP, + int rmax, + MPDCCH_TYPES_t mpdcch_type, + int UE_id) +//------------------------------------------------------------------------------ +{ + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = eNB->common_channels[CC_id].radioResourceConfigCommon_BR-> ext4->prach_ConfigCommon_v1310; int T; LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11; switch (mpdcch_type) { - case TYPE0: - AssertFatal(1 == 0, "MPDCCH Type 0 not handled yet\n"); - break; - case TYPE1: - AssertFatal(1 == 0, "MPDCCH Type 1 not handled yet\n"); - break; - case TYPE1A: - AssertFatal(1 == 0, "MPDCCH Type 1A not handled yet\n"); - break; - case TYPE2: // RAR - AssertFatal(ext4_prach->mpdcch_startSF_CSS_RA_r13 != NULL, - "mpdcch_startSF_CSS_RA_r13 is null\n"); - AssertFatal(rmax > 0, "rmax is 0!\b"); - if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD - T = rmax *startSF_fdd_RA_times2[ext4_prach-> - mpdcch_startSF_CSS_RA_r13-> - choice.fdd_r13] >> 1; - else //TDD - T = rmax *startSF_tdd_RA[ext4_prach-> - mpdcch_startSF_CSS_RA_r13->choice.tdd_r13]; - break; - case TYPE2A: - AssertFatal(1 == 0, "MPDCCH Type 2A not handled yet\n"); - break; - case TYPEUESPEC: - epdcch_setconfig_r11 = - eNB->UE_list.UE_template[CC_id][UE_id].physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; - - AssertFatal(epdcch_setconfig_r11 != NULL, - " epdcch_setconfig_r11 is null for UE specific \n"); - AssertFatal(epdcch_setconfig_r11->ext2 != NULL, - " ext2 doesn't exist in epdcch config ' \n"); - - if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD - T = rmax *startSF_fdd_RA_times2[epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_StartSF_UESS_r13.choice.fdd_r13] >> 1; - else //TDD - T = rmax *startSF_tdd_RA[epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_StartSF_UESS_r13.choice.tdd_r13]; - break; - default: - return (0); + case TYPE0: + AssertFatal(1 == 0, "MPDCCH Type 0 not handled yet\n"); + break; + + case TYPE1: + AssertFatal(1 == 0, "MPDCCH Type 1 not handled yet\n"); + break; + + case TYPE1A: + AssertFatal(1 == 0, "MPDCCH Type 1A not handled yet\n"); + break; + + case TYPE2: // RAR + AssertFatal(ext4_prach->mpdcch_startSF_CSS_RA_r13 != NULL, "mpdcch_startSF_CSS_RA_r13 is null\n"); + AssertFatal(rmax > 0, "rmax is 0!\b"); + + if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD + T = (rmax * startSF_fdd_RA_times2[ext4_prach->mpdcch_startSF_CSS_RA_r13->choice.fdd_r13]) >> 1; + else //TDD + T = rmax * startSF_tdd_RA[ext4_prach->mpdcch_startSF_CSS_RA_r13->choice.tdd_r13]; + + break; + + case TYPE2A: + AssertFatal(1 == 0, "MPDCCH Type 2A not handled yet\n"); + break; + + case TYPEUESPEC: + epdcch_setconfig_r11 = + eNB->UE_list.UE_template[CC_id][UE_id].physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; + AssertFatal(epdcch_setconfig_r11 != NULL, " epdcch_setconfig_r11 is null for UE specific \n"); + AssertFatal(epdcch_setconfig_r11->ext2 != NULL, " ext2 doesn't exist in epdcch config ' \n"); + + if (eNB->common_channels[CC_id].tdd_Config == NULL) //FDD + T = (rmax * startSF_fdd_RA_times2[epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_StartSF_UESS_r13.choice.fdd_r13]) >> 1; + else //TDD + T = rmax * startSF_tdd_RA[epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_StartSF_UESS_r13.choice.tdd_r13]; + + break; + + default: + return 0; } AssertFatal(T > 0, "T is 0!\n"); - if (((10 * frameP) + subframeP) % T == 0) return (1); - else return (0); + + if (((10 * frameP) + subframeP) % T == 0) return 1; + + return 0; } -int narrowband_to_first_rb(COMMON_channels_t * cc, int nb_index) +//------------------------------------------------------------------------------ +int +narrowband_to_first_rb(COMMON_channels_t *cc, + int nb_index) +//------------------------------------------------------------------------------ { switch (cc->mib->message.dl_Bandwidth) { - case 0: // 6 PRBs, N_NB=1, i_0=0 - return (0); - break; - case 3: // 50 PRBs, N_NB=8, i_0=1 - return ((int) (1 + (6 * nb_index))); - break; - case 5: // 100 PRBs, N_NB=16, i_0=2 - return ((int) (2 + (6 * nb_index))); - break; - case 1: // 15 PRBs N_NB=2, i_0=1 - if (nb_index > 0) - return (1); - else - return (0); - break; - case 2: // 25 PRBs, N_NB=4, i_0=0 - if (nb_index > 1) + case 0: // 6 PRBs, N_NB=1, i_0=0 + return 0; + + case 3: // 50 PRBs, N_NB=8, i_0=1 return (1 + (6 * nb_index)); - else - return ((6 * nb_index)); - break; - case 4: // 75 PRBs, N_NB=12, i_0=1 - if (nb_index > 5) + + case 5: // 100 PRBs, N_NB=16, i_0=2 return (2 + (6 * nb_index)); - else + + case 1: // 15 PRBs N_NB=2, i_0=1 + if (nb_index > 0) + return 1; + + return 0; + + case 2: // 25 PRBs, N_NB=4, i_0=0 + if (nb_index > 1) + return (1 + (6 * nb_index)); + + return ((6 * nb_index)); + + case 4: // 75 PRBs, N_NB=12, i_0=1 + if (nb_index > 5) + return (2 + (6 * nb_index)); + return (1 + (6 * nb_index)); - break; - default: - AssertFatal(1 == 0, "Impossible dl_Bandwidth %d\n", - (int) cc->mib->message.dl_Bandwidth); - break; + + default: + AssertFatal(1 == 0, "Impossible dl_Bandwidth %d\n", + (int) cc->mib->message.dl_Bandwidth); + break; } + + return 0; } #endif //------------------------------------------------------------------------------ -void init_ue_sched_info(void) +void +init_ue_sched_info(void) //------------------------------------------------------------------------------ { module_id_t i, j, k; @@ -1762,92 +1945,104 @@ void init_ue_sched_info(void) for (i = 0; i < NUMBER_OF_eNB_MAX; i++) { for (k = 0; k < MAX_NUM_CCs; k++) { for (j = 0; j < MAX_MOBILES_PER_ENB; j++) { - // init DL - eNB_dlsch_info[i][k][j].weight = 0; - eNB_dlsch_info[i][k][j].subframe = 0; - eNB_dlsch_info[i][k][j].serving_num = 0; - eNB_dlsch_info[i][k][j].status = S_DL_NONE; - // init UL - eNB_ulsch_info[i][k][j].subframe = 0; - eNB_ulsch_info[i][k][j].serving_num = 0; - eNB_ulsch_info[i][k][j].status = S_UL_NONE; + // init DL + eNB_dlsch_info[i][k][j].weight = 0; + eNB_dlsch_info[i][k][j].subframe = 0; + eNB_dlsch_info[i][k][j].serving_num = 0; + eNB_dlsch_info[i][k][j].status = S_DL_NONE; + // init UL + eNB_ulsch_info[i][k][j].subframe = 0; + eNB_ulsch_info[i][k][j].serving_num = 0; + eNB_ulsch_info[i][k][j].status = S_UL_NONE; } } } -} - + return; +} //------------------------------------------------------------------------------ -unsigned char get_ue_weight(module_id_t module_idP, int CC_idP, int ue_idP) +unsigned char +get_ue_weight(module_id_t module_idP, + int CC_idP, + int ue_idP) //------------------------------------------------------------------------------ { return (eNB_dlsch_info[module_idP][CC_idP][ue_idP].weight); } //------------------------------------------------------------------------------ -int find_UE_id(module_id_t mod_idP, rnti_t rntiP) +int +find_UE_id(module_id_t mod_idP, + rnti_t rntiP) //------------------------------------------------------------------------------ { int UE_id; UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_list->active[UE_id] != TRUE) - continue; - if (UE_list->UE_template[UE_PCCID(mod_idP, UE_id)][UE_id].rnti == - rntiP) { - return (UE_id); + if (UE_list->active[UE_id] == TRUE) { + if (UE_list->UE_template[UE_PCCID(mod_idP, UE_id)][UE_id].rnti == rntiP) { + return UE_id; + } } } - return (-1); + return -1; } //------------------------------------------------------------------------------ -int find_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) +int +find_RA_id(module_id_t mod_idP, + int CC_idP, + rnti_t rntiP) //------------------------------------------------------------------------------ { int RA_id; AssertFatal(RC.mac[mod_idP], "RC.mac[%d] is null\n", mod_idP); - - RA_t *ra = (RA_t *) & RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; + RA_t *ra = (RA_t *) &RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) { - LOG_D(MAC, - "Checking RA_id %d for %x : state %d\n", - RA_id, rntiP, ra[RA_id].state); + LOG_D(MAC, "Checking RA_id %d for %x : state %d\n", + RA_id, + rntiP, + ra[RA_id].state); - if (ra[RA_id].state != IDLE && - ra[RA_id].rnti == rntiP) - return (RA_id); + if (ra[RA_id].state != IDLE && ra[RA_id].rnti == rntiP) + return RA_id; } - return (-1); + + return -1; } //------------------------------------------------------------------------------ -int UE_num_active_CC(UE_list_t * listP, int ue_idP) +int +UE_num_active_CC(UE_list_t *listP, + int ue_idP) //------------------------------------------------------------------------------ { return (listP->numactiveCCs[ue_idP]); } //------------------------------------------------------------------------------ -int UE_PCCID(module_id_t mod_idP, int ue_idP) +int +UE_PCCID(module_id_t mod_idP, + int ue_idP) //------------------------------------------------------------------------------ { - if (!RC.mac || !RC.mac[mod_idP]) return 0; return (RC.mac[mod_idP]->UE_list.pCC_id[ue_idP]); } //------------------------------------------------------------------------------ -rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) +rnti_t +UE_RNTI(module_id_t mod_idP, + int ue_idP) //------------------------------------------------------------------------------ { if (!RC.mac || !RC.mac[mod_idP]) return 0; - rnti_t rnti = - RC.mac[mod_idP]-> - UE_list.UE_template[UE_PCCID(mod_idP, ue_idP)][ue_idP].rnti; + + rnti_t rnti = RC.mac[mod_idP]->UE_list.UE_template[UE_PCCID(mod_idP, + ue_idP)][ue_idP].rnti; if (rnti > 0) { return (rnti); @@ -1859,86 +2054,117 @@ rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP) } //------------------------------------------------------------------------------ -boolean_t is_UE_active(module_id_t mod_idP, int ue_idP) +boolean_t +is_UE_active(module_id_t mod_idP, + int ue_idP) //------------------------------------------------------------------------------ { - if (!RC.mac || !RC.mac[mod_idP]) return 0; return (RC.mac[mod_idP]->UE_list.active[ue_idP]); } +//------------------------------------------------------------------------------ unsigned char -get_aggregation(uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt) +get_aggregation(uint8_t bw_index, + uint8_t cqi, + uint8_t dci_fmt) +//------------------------------------------------------------------------------ { unsigned char aggregation = 3; switch (dci_fmt) { - case format0: - aggregation = cqi2fmt0_agg[bw_index][cqi]; - break; - case format1: - case format1A: - case format1B: - case format1D: - aggregation = cqi2fmt1x_agg[bw_index][cqi]; - break; - case format2: - case format2A: - case format2B: - case format2C: - case format2D: - aggregation = cqi2fmt2x_agg[bw_index][cqi]; - break; - case format1C: - case format1E_2A_M10PRB: - case format3: - case format3A: - case format4: - default: - LOG_W(MAC, "unsupported DCI format %d\n", dci_fmt); - } + case format0: + aggregation = cqi2fmt0_agg[bw_index][cqi]; + break; + + case format1: + case format1A: + case format1B: + case format1D: + aggregation = cqi2fmt1x_agg[bw_index][cqi]; + break; + + case format2: + case format2A: + case format2B: + case format2C: + case format2D: + aggregation = cqi2fmt2x_agg[bw_index][cqi]; + break; - LOG_D(MAC, "Aggregation level %d (cqi %d, bw_index %d, format %d)\n", 1 << aggregation, cqi, bw_index, dci_fmt); + case format1C: + case format1E_2A_M10PRB: + case format3: + case format3A: + case format4: + default: + LOG_W(MAC, "unsupported DCI format %d\n", + dci_fmt); + break; + } + LOG_D(MAC, "Aggregation level %d (cqi %d, bw_index %d, format %d)\n", + 1 << aggregation, + cqi, + bw_index, + dci_fmt); return 1 << aggregation; } -void dump_ue_list(UE_list_t * listP, int ul_flag) +//------------------------------------------------------------------------------ +/* + * Dump the UL or DL UE_list into LOG_T(MAC) + */ +void +dump_ue_list(UE_list_t *listP, + int ul_flag) +//------------------------------------------------------------------------------ { - int j; - if (ul_flag == 0) { - for (j = listP->head; j >= 0; j = listP->next[j]) { - LOG_T(MAC, "node %d => %d\n", j, listP->next[j]); + for (int j = listP->head; j >= 0; j = listP->next[j]) { + LOG_T(MAC, "DL list node %d => %d\n", + j, + listP->next[j]); } } else { - for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { - LOG_T(MAC, "node %d => %d\n", j, listP->next_ul[j]); + for (int j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { + LOG_T(MAC, "UL list node %d => %d\n", + j, + listP->next_ul[j]); } } + + return; } -int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP +//------------------------------------------------------------------------------ +int +add_new_ue(module_id_t mod_idP, + int cc_idP, + rnti_t rntiP, + int harq_pidP #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , uint8_t rach_resource_type + , uint8_t rach_resource_type #endif - ) + ) +//------------------------------------------------------------------------------ { int UE_id; int i, j; - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - - LOG_D(MAC, - "[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n", - mod_idP, cc_idP, rntiP, UE_list->avail, UE_list->num_UEs); + LOG_D(MAC, "[eNB %d, CC_id %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n", + mod_idP, + cc_idP, + rntiP, + UE_list->avail, + UE_list->num_UEs); dump_ue_list(UE_list, 0); for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (UE_list->active[i] == TRUE) continue; + UE_id = i; - memset(&UE_list->UE_template[cc_idP][UE_id], 0, - sizeof(UE_TEMPLATE)); + memset(&UE_list->UE_template[cc_idP][UE_id], 0, sizeof(UE_TEMPLATE)); UE_list->UE_template[cc_idP][UE_id].rnti = rntiP; UE_list->UE_template[cc_idP][UE_id].configured = FALSE; UE_list->numactiveCCs[UE_id] = 1; @@ -1950,28 +2176,25 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP UE_list->active[UE_id] = TRUE; #if defined(USRP_REC_PLAY) // not specific to record/playback ? UE_list->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0; -#endif - +#endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - UE_list->UE_template[cc_idP][UE_id].rach_resource_type = - rach_resource_type; + UE_list->UE_template[cc_idP][UE_id].rach_resource_type = rach_resource_type; #endif - - memset((void *) &UE_list->UE_sched_ctrl[UE_id], 0, - sizeof(UE_sched_ctrl)); - memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0, - sizeof(eNB_UE_STATS)); + memset((void *) &UE_list->UE_sched_ctrl[UE_id], + 0, + sizeof(UE_sched_ctrl)); + memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], + 0, + sizeof(eNB_UE_STATS)); UE_list->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; - /* default slice in case there was something different */ UE_list->assoc_dl_slice_idx[UE_id] = 0; UE_list->assoc_ul_slice_idx[UE_id] = 0; - UE_list->UE_sched_ctrl[UE_id].ta_update = 31; for (j = 0; j < 8; j++) { - UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = (j == 0) ? 1 : 0; // 1 because first transmission is with format1A (Msg4) for harq_pid 0 - UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j == harq_pidP) ? 0 : 1; // 1st transmission is with Msg3; + UE_list->UE_template[cc_idP][UE_id].oldNDI[j] = (j == 0) ? 1 : 0; // 1 because first transmission is with format1A (Msg4) for harq_pid 0 + UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = (j == harq_pidP) ? 0 : 1; // 1st transmission is with Msg3; UE_list->UE_sched_ctrl[UE_id].round[cc_idP][j] = 8; UE_list->UE_sched_ctrl[UE_id].round_UL[cc_idP][j] = 0; } @@ -1979,159 +2202,211 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP eNB_ulsch_info[mod_idP][cc_idP][UE_id].status = S_UL_WAITING; eNB_dlsch_info[mod_idP][cc_idP][UE_id].status = S_DL_WAITING; LOG_D(MAC, "[eNB %d] Add UE_id %d on Primary CC_id %d: rnti %x\n", - mod_idP, UE_id, cc_idP, rntiP); - dump_ue_list(UE_list, 0); + mod_idP, + UE_id, + cc_idP, + rntiP); + dump_ue_list(UE_list, + 0); return (UE_id); } - printf("MAC: cannot add new UE for rnti %x\n", rntiP); - LOG_E(MAC, - "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n"); - dump_ue_list(UE_list, 0); - return (-1); + // printf("MAC: cannot add new UE for rnti %x\n", rntiP); + LOG_E(MAC, "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n"); + dump_ue_list(UE_list, + 0); + return -1; } //------------------------------------------------------------------------------ -int rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP) +/* + * Remove MAC context of UE + */ +int +rrc_mac_remove_ue(module_id_t mod_idP, + rnti_t rntiP) //------------------------------------------------------------------------------ { - - int j; UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; - int UE_id = find_UE_id(mod_idP,rntiP); - int pCC_id; - + int UE_id = find_UE_id(mod_idP, rntiP); + eNB_UE_STATS *ue_stats = NULL; + int pCC_id = -1; + if (UE_id == -1) { - LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP); + LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", + rntiP); return 0; } - - pCC_id = UE_PCCID(mod_idP,UE_id); - - LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP); - dump_ue_list(UE_list,0); - + + pCC_id = UE_PCCID(mod_idP, UE_id); + + LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n", + UE_id, + pCC_id, + rntiP); + + dump_ue_list(UE_list, 0); // DL list displayed in LOG_T(MAC) + UE_list->active[UE_id] = FALSE; UE_list->num_UEs--; - - if (UE_list->head == UE_id) UE_list->head=UE_list->next[UE_id]; - else UE_list->next[prev(UE_list,UE_id,0)]=UE_list->next[UE_id]; - if (UE_list->head_ul == UE_id) UE_list->head_ul=UE_list->next_ul[UE_id]; - else UE_list->next_ul[prev(UE_list,UE_id,0)]=UE_list->next_ul[UE_id]; - - // clear all remaining pending transmissions - /* UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0; - UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0; - - UE_list->UE_template[pCC_id][UE_id].ul_SR = 0; - UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI; - UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE; - */ - memset (&UE_list->UE_template[pCC_id][UE_id],0,sizeof(UE_TEMPLATE)); - - UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_retx = 0; - for ( j = 0; j < NB_RB_MAX; j++ ) { - UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_tx[j] = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_tx[j] = 0; + + /* If present, remove UE from DL list */ + if (UE_list->head == UE_id) { + UE_list->head = UE_list->next[UE_id]; + } else { + int previous = prev(UE_list, UE_id, 0); + + if (previous != -1) { + UE_list->next[previous] = UE_list->next[UE_id]; + } } - UE_list->eNB_UE_stats[pCC_id][UE_id].num_retransmission = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_sdu_bytes = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_rx = 0; - for ( j = 0; j < NB_RB_MAX; j++ ) { - UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_rx[j] = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_rx[j] = 0; + + /* If present, remove UE from UL list */ + if (UE_list->head_ul == UE_id) { + UE_list->head_ul = UE_list->next_ul[UE_id]; + } else { + int previous = prev(UE_list, UE_id, 1); + + if (previous != -1) { + UE_list->next_ul[previous] = UE_list->next_ul[UE_id]; + } } - UE_list->eNB_UE_stats[pCC_id][UE_id].num_errors_rx = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes_rx = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus_rx = 0; - UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_errors_rx = 0; - - eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; - eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE; - eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; - eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE; - + + /* Clear all remaining pending transmissions */ + memset(&UE_list->UE_template[pCC_id][UE_id], + 0, + sizeof(UE_TEMPLATE)); + ue_stats = &UE_list->eNB_UE_stats[pCC_id][UE_id]; + ue_stats->total_rbs_used = 0; + ue_stats->total_rbs_used_retx = 0; + + for (int j = 0; j < NB_RB_MAX; j++ ) { + ue_stats->num_pdu_tx[j] = 0; + ue_stats->num_bytes_tx[j] = 0; + } + + ue_stats->num_retransmission = 0; + ue_stats->total_sdu_bytes = 0; + ue_stats->total_pdu_bytes = 0; + ue_stats->total_num_pdus = 0; + ue_stats->total_rbs_used_rx = 0; + + for (int j = 0; j < NB_RB_MAX; j++ ) { + ue_stats->num_pdu_rx[j] = 0; + ue_stats->num_bytes_rx[j] = 0; + } + + ue_stats->num_errors_rx = 0; + ue_stats->total_pdu_bytes_rx = 0; + ue_stats->total_num_pdus_rx = 0; + ue_stats->total_num_errors_rx = 0; + + eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; + eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE; eNB_ulsch_info[mod_idP][pCC_id][UE_id].serving_num = 0; + + eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI; + eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE; eNB_dlsch_info[mod_idP][pCC_id][UE_id].serving_num = 0; - + // check if this has an RA process active - if(find_RA_id(mod_idP, pCC_id, rntiP) != -1) { - cancel_ra_proc(mod_idP, pCC_id, 0, rntiP); + if (find_RA_id(mod_idP, + pCC_id, + rntiP) != -1) { + cancel_ra_proc(mod_idP, + pCC_id, + 0, + rntiP); } pthread_mutex_lock(&rrc_release_freelist); - if(rrc_release_info.num_UEs > 0){ + + if (rrc_release_info.num_UEs > 0) { uint16_t release_total = 0; - for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){ + + for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { release_total++; - }else{ + } else { continue; } - if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rntiP){ + + if (rrc_release_info.RRC_release_ctrl[release_num].rnti == rntiP) { rrc_release_info.RRC_release_ctrl[release_num].flag = 0; rrc_release_info.num_UEs--; release_total--; } - if(release_total >= rrc_release_info.num_UEs){ + + if (release_total >= rrc_release_info.num_UEs) { break; } } } + pthread_mutex_unlock(&rrc_release_freelist); - return 0; } -int prev(UE_list_t * listP, int nodeP, int ul_flag) +//------------------------------------------------------------------------------ +/* + * Returns the previous UE_id in the scheduling list in UL or DL + */ +int +prev(UE_list_t *listP, + int nodeP, + int ul_flag) +//------------------------------------------------------------------------------ { - int j; - if (ul_flag == 0) { if (nodeP == listP->head) { - return (nodeP); + return nodeP; } - for (j = listP->head; j >= 0; j = listP->next[j]) { + for (int j = listP->head; j >= 0; j = listP->next[j]) { if (listP->next[j] == nodeP) { - return (j); + return j; } } } else { if (nodeP == listP->head_ul) { - return (nodeP); + return nodeP; } - for (j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { + for (int j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { if (listP->next_ul[j] == nodeP) { - return (j); + return j; } } } - LOG_E(MAC, - "error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n", - nodeP, (ul_flag == 0) ? "DL" : "UL"); - dump_ue_list(listP, ul_flag); - - return (-1); + LOG_E(MAC, "error in prev(), could not find previous to %d in UE_list %s, should never happen, Dumping UE list\n", + nodeP, + (ul_flag == 0) ? "DL" : "UL"); + dump_ue_list(listP, + ul_flag); + return -1; } -void swap_UEs(UE_list_t * listP, int nodeiP, int nodejP, int ul_flag) +//------------------------------------------------------------------------------ +void +swap_UEs(UE_list_t *listP, + int nodeiP, + int nodejP, + int ul_flag) +//------------------------------------------------------------------------------ { int prev_i, prev_j, next_i, next_j; - - LOG_T(MAC, "Swapping UE %d,%d\n", nodeiP, nodejP); - dump_ue_list(listP, ul_flag); - - prev_i = prev(listP, nodeiP, ul_flag); - prev_j = prev(listP, nodejP, ul_flag); - + LOG_T(MAC, "Swapping UE %d,%d\n", + nodeiP, + nodejP); + dump_ue_list(listP, + ul_flag); + prev_i = prev(listP, + nodeiP, + ul_flag); + prev_j = prev(listP, + nodejP, + ul_flag); AssertFatal((prev_i >= 0) && (prev_j >= 0), "swap_UEs: problem"); if (ul_flag == 0) { @@ -2143,252 +2418,267 @@ void swap_UEs(UE_list_t * listP, int nodeiP, int nodejP, int ul_flag) } LOG_T(MAC, "[%s] next_i %d, next_i, next_j %d, head %d \n", - (ul_flag == 0) ? "DL" : "UL", next_i, next_j, listP->head); + (ul_flag == 0) ? "DL" : "UL", + next_i, + next_j, + listP->head); if (ul_flag == 0) { - - if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... - LOG_T(MAC, - "Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); - + if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... + LOG_T(MAC, "Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); listP->next[nodeiP] = next_j; listP->next[nodejP] = nodeiP; - if (nodeiP == listP->head) { // case i j n(j) - listP->head = nodejP; + if (nodeiP == listP->head) { // case i j n(j) + listP->head = nodejP; } else { - listP->next[prev_i] = nodejP; + listP->next[prev_i] = nodejP; } - } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... - LOG_T(MAC, - "Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); + } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... + LOG_T(MAC, "Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); listP->next[nodejP] = next_i; listP->next[nodeiP] = nodejP; - if (nodejP == listP->head) { // case j i n(i) - listP->head = nodeiP; + if (nodejP == listP->head) { // case j i n(i) + listP->head = nodeiP; } else { - listP->next[prev_j] = nodeiP; + listP->next[prev_j] = nodeiP; } - } else { // case ... p(i) i n(i) ... p(j) j n(j) ... + } else { // case ... p(i) i n(i) ... p(j) j n(j) ... listP->next[nodejP] = next_i; listP->next[nodeiP] = next_j; if (nodeiP == listP->head) { - LOG_T(MAC, "changing head to %d\n", nodejP); - listP->head = nodejP; - listP->next[prev_j] = nodeiP; + LOG_T(MAC, "changing head to %d\n", + nodejP); + listP->head = nodejP; + listP->next[prev_j] = nodeiP; } else if (nodejP == listP->head) { - LOG_D(MAC, "changing head to %d\n", nodeiP); - listP->head = nodeiP; - listP->next[prev_i] = nodejP; + LOG_D(MAC, "changing head to %d\n", + nodeiP); + listP->head = nodeiP; + listP->next[prev_i] = nodejP; } else { - listP->next[prev_i] = nodejP; - listP->next[prev_j] = nodeiP; + listP->next[prev_i] = nodejP; + listP->next[prev_j] = nodeiP; } } - } else { // ul_flag - - if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... - LOG_T(MAC, - "[UL] Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); - + } else { // ul_flag + if (next_i == nodejP) { // case ... p(i) i j n(j) ... => ... p(j) j i n(i) ... + LOG_T(MAC, "[UL] Case ... p(i) i j n(j) ... => ... p(j) j i n(i) ...\n"); listP->next_ul[nodeiP] = next_j; listP->next_ul[nodejP] = nodeiP; - if (nodeiP == listP->head_ul) { // case i j n(j) - listP->head_ul = nodejP; + if (nodeiP == listP->head_ul) { // case i j n(j) + listP->head_ul = nodejP; } else { - listP->next_ul[prev_i] = nodejP; + listP->next_ul[prev_i] = nodejP; } - } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... - LOG_T(MAC, - "[UL]Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); + } else if (next_j == nodeiP) { // case ... p(j) j i n(i) ... => ... p(i) i j n(j) ... + LOG_T(MAC, "[UL]Case ... p(j) j i n(i) ... => ... p(i) i j n(j) ...\n"); listP->next_ul[nodejP] = next_i; listP->next_ul[nodeiP] = nodejP; - if (nodejP == listP->head_ul) { // case j i n(i) - listP->head_ul = nodeiP; + if (nodejP == listP->head_ul) { // case j i n(i) + listP->head_ul = nodeiP; } else { - listP->next_ul[prev_j] = nodeiP; + listP->next_ul[prev_j] = nodeiP; } - } else { // case ... p(i) i n(i) ... p(j) j n(j) ... - + } else { // case ... p(i) i n(i) ... p(j) j n(j) ... listP->next_ul[nodejP] = next_i; listP->next_ul[nodeiP] = next_j; if (nodeiP == listP->head_ul) { - LOG_T(MAC, "[UL]changing head to %d\n", nodejP); - listP->head_ul = nodejP; - listP->next_ul[prev_j] = nodeiP; + LOG_T(MAC, "[UL]changing head to %d\n", + nodejP); + listP->head_ul = nodejP; + listP->next_ul[prev_j] = nodeiP; } else if (nodejP == listP->head_ul) { - LOG_T(MAC, "[UL]changing head to %d\n", nodeiP); - listP->head_ul = nodeiP; - listP->next_ul[prev_i] = nodejP; + LOG_T(MAC, "[UL]changing head to %d\n", + nodeiP); + listP->head_ul = nodeiP; + listP->next_ul[prev_i] = nodejP; } else { - listP->next_ul[prev_i] = nodejP; - listP->next_ul[prev_j] = nodeiP; + listP->next_ul[prev_i] = nodejP; + listP->next_ul[prev_j] = nodeiP; } } } LOG_T(MAC, "After swap\n"); - dump_ue_list(listP, ul_flag); + dump_ue_list(listP, + ul_flag); + return; } // This has to be updated to include BSR information +//------------------------------------------------------------------------------ uint8_t -UE_is_to_be_scheduled(module_id_t module_idP, int CC_id, uint8_t UE_id) +UE_is_to_be_scheduled(module_id_t module_idP, + int CC_id, + uint8_t UE_id) +//------------------------------------------------------------------------------ { - UE_TEMPLATE *UE_template = - &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id]; - UE_sched_ctrl *UE_sched_ctl = - &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id]; + UE_TEMPLATE *UE_template = &RC.mac[module_idP]->UE_list.UE_template[CC_id][UE_id]; + UE_sched_ctrl *UE_sched_ctl = &RC.mac[module_idP]->UE_list.UE_sched_ctrl[UE_id]; // do not schedule UE if UL is not working - if (UE_sched_ctl->ul_failure_timer > 0) - return (0); - if (UE_sched_ctl->ul_out_of_sync > 0) - return (0); + if (UE_sched_ctl->ul_failure_timer > 0 || UE_sched_ctl->ul_out_of_sync > 0) + return 0; + + rnti_t ue_rnti = UE_RNTI(module_idP, UE_id); LOG_D(MAC, "[eNB %d][PUSCH] Checking UL requirements UE %d/%x\n", - module_idP, UE_id, UE_RNTI(module_idP, UE_id)); - - if ((UE_template->scheduled_ul_bytes < UE_template->estimated_ul_buffer) || - (UE_template->ul_SR > 0) || // uplink scheduling request - ((UE_sched_ctl->ul_inactivity_timer > 20) && (UE_sched_ctl->ul_scheduled == 0)) || // every 2 frames when RRC_CONNECTED - ((UE_sched_ctl->ul_inactivity_timer > 10) && (UE_sched_ctl->ul_scheduled == 0) && (mac_eNB_get_rrc_status(module_idP, UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED))) // every Frame when not RRC_CONNECTED - { - LOG_D(MAC, - "[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 estimated size %d, SR %d)\n", - module_idP, UE_id, UE_RNTI(module_idP, UE_id), - UE_template->ul_buffer_info[LCGID0], UE_template->ul_SR); - return (1); - } else { - return (0); + module_idP, + UE_id, + ue_rnti); + + if (UE_template->scheduled_ul_bytes < UE_template->estimated_ul_buffer || + UE_template->ul_SR > 0 || // uplink scheduling request + (UE_sched_ctl->ul_inactivity_timer > 20 && UE_sched_ctl->ul_scheduled == 0) || // every 2 frames when RRC_CONNECTED + (UE_sched_ctl->ul_inactivity_timer > 10 && + UE_sched_ctl->ul_scheduled == 0 && + mac_eNB_get_rrc_status(module_idP, + ue_rnti) < RRC_CONNECTED)) { // every Frame when not RRC_CONNECTED + LOG_D(MAC, "[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 estimated size %d, SR %d)\n", + module_idP, + UE_id, + ue_rnti, + UE_template->ul_buffer_info[LCGID0], + UE_template->ul_SR); + + return 1; } + + return 0; } -uint8_t get_tmode(module_id_t module_idP, int CC_idP, int UE_idP) +//------------------------------------------------------------------------------ +uint8_t +get_tmode(module_id_t module_idP, + int CC_idP, + int UE_idP) +//------------------------------------------------------------------------------ { eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated = eNB->UE_list.UE_template[CC_idP][UE_idP].physicalConfigDedicated; + if (physicalConfigDedicated == NULL) { // RRCConnectionSetup not received by UE yet + AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", + cc->p_eNB); + return (cc->p_eNB); + } - struct LTE_PhysicalConfigDedicated *physicalConfigDedicated = eNB->UE_list.UE_template[CC_idP][UE_idP].physicalConfigDedicated; + AssertFatal(physicalConfigDedicated->antennaInfo != NULL, + "antennaInfo (mod_id %d) is null for CCId %d, UEid %d, physicalConfigDedicated %p\n", + module_idP, + CC_idP, + UE_idP, + physicalConfigDedicated); + AssertFatal(physicalConfigDedicated->antennaInfo->present != LTE_PhysicalConfigDedicated__antennaInfo_PR_NOTHING, + "antennaInfo (mod_id %d, CC_id %d) is set to NOTHING\n", + module_idP, + CC_idP); + + if (physicalConfigDedicated->antennaInfo->present == LTE_PhysicalConfigDedicated__antennaInfo_PR_explicitValue) { + return (1 + physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); + } - if (physicalConfigDedicated == NULL) { // RRCConnectionSetup not received by UE yet + if (physicalConfigDedicated->antennaInfo->present == LTE_PhysicalConfigDedicated__antennaInfo_PR_defaultValue) { AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", - cc->p_eNB); + cc->p_eNB); return (cc->p_eNB); - } else { - AssertFatal(physicalConfigDedicated->antennaInfo != NULL, - "antennaInfo (mod_id %d) is null for CCId %d, UEid %d, physicalConfigDedicated %p\n", module_idP,CC_idP, - UE_idP,physicalConfigDedicated); - - AssertFatal(physicalConfigDedicated->antennaInfo->present != - LTE_PhysicalConfigDedicated__antennaInfo_PR_NOTHING, - "antennaInfo (mod_id %d, CC_id %d) is set to NOTHING\n", - module_idP, CC_idP); - - if (physicalConfigDedicated->antennaInfo->present == - LTE_PhysicalConfigDedicated__antennaInfo_PR_explicitValue) { - return (1+physicalConfigDedicated->antennaInfo-> - choice.explicitValue.transmissionMode); - } else if (physicalConfigDedicated->antennaInfo->present == - LTE_PhysicalConfigDedicated__antennaInfo_PR_defaultValue) { - AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", - cc->p_eNB); - return (cc->p_eNB); - } else - AssertFatal(1 == 0, "Shouldn't be here\n"); } + + AssertFatal(1 == 0, "Shouldn't be here\n"); + return 0; } +//------------------------------------------------------------------------------ int8_t -get_ULharq(module_id_t module_idP, int CC_idP, uint16_t frameP, - uint8_t subframeP) +get_ULharq(module_id_t module_idP, + int CC_idP, + uint16_t frameP, + uint8_t subframeP) +//------------------------------------------------------------------------------ { - uint8_t ret = -1; + int8_t ret = -1; eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - if (cc->tdd_Config == NULL) { // FDD + if (cc->tdd_Config == NULL) { // FDD ret = (((frameP << 1) + subframeP) & 7); } else { switch (cc->tdd_Config->subframeAssignment) { - case 1: - if ((subframeP == 2) || - (subframeP == 3) || (subframeP == 7) || (subframeP == 8)) - switch (subframeP) { - case 2: - case 3: - ret = (subframeP - 2); - break; - - case 7: - case 8: - ret = (subframeP - 5); - break; - - default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - break; - } + case 1: + switch (subframeP) { + case 2: + case 3: + ret = (subframeP - 2); + break; - break; + case 7: + case 8: + ret = (subframeP - 5); + break; - case 2: - AssertFatal((subframeP == 2) || (subframeP == 7), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP / 7); - break; + default: + AssertFatal(1 == 0, "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + break; + } - case 3: - AssertFatal((subframeP > 1) && (subframeP < 5), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP - 2); - break; + break; - case 4: - AssertFatal((subframeP > 1) && (subframeP < 4), - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP - 2); - break; + case 2: + AssertFatal((subframeP == 2) || (subframeP == 7), "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP / 7); + break; - case 5: - AssertFatal(subframeP == 2, - "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", - subframeP, - (int) cc->tdd_Config->subframeAssignment); - ret = (subframeP - 2); - break; + case 3: + AssertFatal((subframeP > 1) && (subframeP < 5), "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP - 2); + break; - default: - AssertFatal(1 == 0, - "subframe2_harq_pid, Unsupported TDD mode %d\n", - (int) cc->tdd_Config->subframeAssignment); - break; + case 4: + AssertFatal((subframeP > 1) && (subframeP < 4), "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP - 2); + break; + + case 5: + AssertFatal(subframeP == 2, "subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n", + subframeP, + (int) cc->tdd_Config->subframeAssignment); + ret = (subframeP - 2); + break; + + default: + AssertFatal(1 == 0, "subframe2_harq_pid, Unsupported TDD mode %d\n", + (int) cc->tdd_Config->subframeAssignment); + break; } } - AssertFatal(ret != -1, - "invalid harq_pid(%d) at SFN/SF = %d/%d\n", (int8_t) ret, - frameP, subframeP); + AssertFatal(ret != -1, "invalid harq_pid(%d) at SFN/SF = %d/%d\n", (int8_t) ret, + frameP, + subframeP); return ret; } - -uint16_t getRIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs) +//------------------------------------------------------------------------------ +uint16_t +getRIV(uint16_t N_RB_DL, + uint16_t RBstart, + uint16_t Lcrbs) +//------------------------------------------------------------------------------ { uint16_t RIV; @@ -2397,12 +2687,16 @@ uint16_t getRIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs) else RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart); - return (RIV); + return RIV; } +//------------------------------------------------------------------------------ uint32_t -allocate_prbs(int UE_id, unsigned char nb_rb, int N_RB_DL, - uint32_t * rballoc) +allocate_prbs(int UE_id, + unsigned char nb_rb, + int N_RB_DL, + uint32_t *rballoc) +//------------------------------------------------------------------------------ { int i; uint32_t rballoc_dci = 0; @@ -2430,188 +2724,219 @@ allocate_prbs(int UE_id, unsigned char nb_rb, int N_RB_DL, return (rballoc_dci); } -int get_bw_index(module_id_t module_id, uint8_t CC_id) +//------------------------------------------------------------------------------ +int +get_bw_index(module_id_t module_id, + uint8_t CC_id) +//------------------------------------------------------------------------------ { int bw_index = 0; - int N_RB_DL = to_prb(RC.mac[module_id]->common_channels[CC_id].mib->message.dl_Bandwidth); switch (N_RB_DL) { - case 6: // 1.4 MHz - bw_index = 0; - break; + case 6: // 1.4 MHz + bw_index = 0; + break; - case 25: // 5HMz - bw_index = 1; - break; + case 25: // 5HMz + bw_index = 1; + break; - case 50: // 10HMz - bw_index = 2; - break; + case 50: // 10HMz + bw_index = 2; + break; - case 100: // 20HMz - bw_index = 3; - break; + case 100: // 20HMz + bw_index = 3; + break; - default: - bw_index = 1; - LOG_W(MAC, - "[eNB %d] N_RB_DL %d unknown for CC_id %d, setting bw_index to 1\n", - module_id, N_RB_DL, CC_id); - break; + default: + bw_index = 1; + LOG_W(MAC, "[eNB %d] N_RB_DL %d unknown for CC_id %d, setting bw_index to 1\n", + module_id, + N_RB_DL, + CC_id); + break; } return bw_index; } -int get_min_rb_unit(module_id_t module_id, uint8_t CC_id) +//------------------------------------------------------------------------------ +int +get_min_rb_unit(module_id_t module_id, + uint8_t CC_id) +//------------------------------------------------------------------------------ { int min_rb_unit = 0; int N_RB_DL = to_prb(RC.mac[module_id]->common_channels[CC_id].mib->message.dl_Bandwidth); switch (N_RB_DL) { - case 6: // 1.4 MHz - min_rb_unit = 1; - break; + case 6: // 1.4 MHz + min_rb_unit = 1; + break; - case 25: // 5HMz - min_rb_unit = 2; - break; + case 25: // 5HMz + min_rb_unit = 2; + break; - case 50: // 10HMz - min_rb_unit = 3; - break; + case 50: // 10HMz + min_rb_unit = 3; + break; - case 100: // 20HMz - min_rb_unit = 4; - break; + case 100: // 20HMz + min_rb_unit = 4; + break; - default: - min_rb_unit = 2; - LOG_W(MAC, - "[eNB %d] N_DL_RB %d unknown for CC_id %d, setting min_rb_unit to 2\n", - module_id, N_RB_DL, CC_id); - break; + default: + min_rb_unit = 2; + LOG_W(MAC, "[eNB %d] N_DL_RB %d unknown for CC_id %d, setting min_rb_unit to 2\n", + module_id, + N_RB_DL, + CC_id); + break; } return min_rb_unit; } +//------------------------------------------------------------------------------ uint32_t -allocate_prbs_sub(int nb_rb, int N_RB_DL, int N_RBG, uint8_t * rballoc) +allocate_prbs_sub(int nb_rb, + int N_RB_DL, + int N_RBG, + uint8_t *rballoc) +//------------------------------------------------------------------------------ { - int check = 0; //check1=0,check2=0; + int check = 0; //check1=0,check2=0; uint32_t rballoc_dci = 0; //uint8_t number_of_subbands=13; - LOG_T(MAC, "*****Check1RBALLOC****: %d%d%d%d (nb_rb %d,N_RBG %d)\n", - rballoc[3], rballoc[2], rballoc[1], rballoc[0], nb_rb, N_RBG); - - while ((nb_rb > 0) && (check < N_RBG)) { + rballoc[3], + rballoc[2], + rballoc[1], + rballoc[0], + nb_rb, + N_RBG); + + while (nb_rb > 0 && check < N_RBG) { //printf("rballoc[%d] %d\n",check,rballoc[check]); if (rballoc[check] == 1) { rballoc_dci |= (1 << ((N_RBG - 1) - check)); switch (N_RB_DL) { - case 6: - nb_rb--; - break; + case 6: + nb_rb--; + break; - case 25: - if ((check == N_RBG - 1)) { - nb_rb--; - } else { - nb_rb -= 2; - } + case 25: + if ((check == N_RBG - 1)) { + nb_rb--; + } else { + nb_rb -= 2; + } - break; + break; - case 50: - if ((check == N_RBG - 1)) { - nb_rb -= 2; - } else { - nb_rb -= 3; - } + case 50: + if ((check == N_RBG - 1)) { + nb_rb -= 2; + } else { + nb_rb -= 3; + } - break; + break; - case 100: - nb_rb -= 4; - break; + case 100: + nb_rb -= 4; + break; } } + // printf("rb_alloc %x\n",rballoc_dci); - check = check + 1; + check++; // check1 = check1+2; } // rballoc_dci = (rballoc_dci)&(0x1fff); - LOG_T(MAC, "*********RBALLOC : %x\n", rballoc_dci); + LOG_T(MAC, "*********RBALLOC : %x\n", + rballoc_dci); // exit(-1); - return (rballoc_dci); + return rballoc_dci; } -int get_subbandsize(uint8_t dl_Bandwidth) +//------------------------------------------------------------------------------ +int +get_subbandsize(uint8_t dl_Bandwidth) +//------------------------------------------------------------------------------ { uint8_t ss[6] = { 6, 4, 4, 6, 8, 8 }; - AssertFatal(dl_Bandwidth < 6, "dl_Bandwidth %d is out of bounds\n", - dl_Bandwidth); - + dl_Bandwidth); return (ss[dl_Bandwidth]); } -int get_nb_subband(int N_RB_DL) +//------------------------------------------------------------------------------ +int +get_nb_subband(int N_RB_DL) +//------------------------------------------------------------------------------ { int nb_sb = 0; switch (N_RB_DL) { - case 6: - nb_sb = 0; - break; + case 6: + nb_sb = 0; + break; - case 15: - nb_sb = 4; // sb_size =4 + case 15: + nb_sb = 4; // sb_size =4 + break; - case 25: - nb_sb = 7; // sb_size =4, 1 sb with 1PRB, 6 with 2 RBG, each has 2 PRBs - break; + case 25: + nb_sb = 7; // sb_size =4, 1 sb with 1PRB, 6 with 2 RBG, each has 2 PRBs + break; - case 50: // sb_size =6 - nb_sb = 9; - break; + case 50: // sb_size =6 + nb_sb = 9; + break; - case 75: // sb_size =8 - nb_sb = 10; - break; + case 75: // sb_size =8 + nb_sb = 10; + break; - case 100: // sb_size =8 , 1 sb with 1 RBG + 12 sb with 2RBG, each RBG has 4 PRBs - nb_sb = 13; - break; + case 100: // sb_size =8 , 1 sb with 1 RBG + 12 sb with 2RBG, each RBG has 4 PRBs + nb_sb = 13; + break; - default: - nb_sb = 0; - break; + default: + nb_sb = 0; + break; } return nb_sb; } -void init_CCE_table(int module_idP, int CC_idP) +//------------------------------------------------------------------------------ +void +init_CCE_table(int *CCE_table) +//------------------------------------------------------------------------------ { - memset(RC.mac[module_idP]->CCE_table[CC_idP], 0, 800 * sizeof(int)); + memset(CCE_table, 0, 800 * sizeof(int)); } - +//------------------------------------------------------------------------------ int get_nCCE_offset(int *CCE_table, - const unsigned char L, - const int nCCE, - const int common_dci, - const unsigned short rnti, const unsigned char subframe) + const unsigned char L, + const int nCCE, + const int common_dci, + const unsigned short rnti, + const unsigned char subframe) +//------------------------------------------------------------------------------ { int search_space_free, m, nb_candidates = 0, l, i; unsigned int Yk; + /* printf("CCE Allocation: "); for (i=0;i<nCCE;i++) @@ -2626,40 +2951,41 @@ get_nCCE_offset(int *CCE_table, // printf("Common DCI nb_candidates %d, L %d\n",nb_candidates,L); for (m = nb_candidates - 1; m >= 0; m--) { - search_space_free = 1; - for (l = 0; l < L; l++) { - // printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]); - if (CCE_table[(m * L) + l] == 1) { - search_space_free = 0; - break; - } + for (l = 0; l < L; l++) { + // printf("CCE_table[%d] %d\n",(m*L)+l,CCE_table[(m*L)+l]); + if (CCE_table[(m * L) + l] == 1) { + search_space_free = 0; + break; + } } if (search_space_free == 1) { + // printf("returning %d\n",m*L); + for (l = 0; l < L; l++) { + CCE_table[(m * L) + l] = 1; + } - // printf("returning %d\n",m*L); - - for (l = 0; l < L; l++) - CCE_table[(m * L) + l] = 1; - return (m * L); + return (m * L); } } - return (-1); + return -1; + } - } else { // Find first available in ue specific search space - // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) - // compute Yk - Yk = (unsigned int) rnti; + // Find first available in ue specific search space + // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) + // compute Yk + Yk = (unsigned int) rnti; - for (i = 0; i <= subframe; i++) - Yk = (Yk * 39827) % 65537; + for (i = 0; i <= subframe; i++) { + Yk = (Yk * 39827) % 65537; + } - Yk = Yk % (nCCE / L); + Yk = Yk % (nCCE / L); - switch (L) { + switch (L) { case 1: case 2: nb_candidates = 6; @@ -2671,92 +2997,113 @@ get_nCCE_offset(int *CCE_table, break; default: - DevParam(L, nCCE, rnti); + DevParam(L, + nCCE, + rnti); break; - } - - LOG_D(MAC, "rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n", - rnti, Yk, nCCE, nCCE / L, nb_candidates); + } - for (m = 0; m < nb_candidates; m++) { - search_space_free = 1; + LOG_D(MAC, "rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n", + rnti, + Yk, + nCCE, + nCCE / L, + nb_candidates); - for (l = 0; l < L; l++) { - int cce = (((Yk + m) % (nCCE / L)) * L) + l; - if (cce >= nCCE || CCE_table[cce] == 1) { - search_space_free = 0; - break; - } - } + for (m = 0; m < nb_candidates; m++) { + search_space_free = 1; - if (search_space_free == 1) { - for (l = 0; l < L; l++) - CCE_table[(((Yk + m) % (nCCE / L)) * L) + l] = 1; + for (l = 0; l < L; l++) { + int cce = (((Yk + m) % (nCCE / L)) * L) + l; - return (((Yk + m) % (nCCE / L)) * L); + if (cce >= nCCE || CCE_table[cce] == 1) { + search_space_free = 0; + break; } } - return (-1); + if (search_space_free == 1) { + for (l = 0; l < L; l++) { + CCE_table[(((Yk + m) % (nCCE / L)) * L) + l] = 1; + } + + return (((Yk + m) % (nCCE / L)) * L); + } } + + return -1; } +//------------------------------------------------------------------------------ void -dump_CCE_table(int *CCE_table, const int nCCE, - const unsigned short rnti, const int subframe, int L) +dump_CCE_table(int *CCE_table, + const int nCCE, + const unsigned short rnti, + const int subframe, + int L) +//------------------------------------------------------------------------------ { int nb_candidates = 0, i; unsigned int Yk; - printf("CCE 0: "); + for (i = 0; i < nCCE; i++) { printf("%1d.", CCE_table[i]); + if ((i & 7) == 7) - printf("\n CCE %d: ", i); + printf("\n CCE %d: ", + i); } Yk = (unsigned int) rnti; - for (i = 0; i <= subframe; i++) + for (i = 0; i <= subframe; i++) { Yk = (Yk * 39827) % 65537; + } Yk = Yk % (nCCE / L); switch (L) { - case 1: - case 2: - nb_candidates = 6; - break; + case 1: + case 2: + nb_candidates = 6; + break; - case 4: - case 8: - nb_candidates = 2; - break; + case 4: + case 8: + nb_candidates = 2; + break; - default: - DevParam(L, nCCE, rnti); - break; + default: + DevParam(L, nCCE, rnti); + break; } - printf("rnti %x, Yk*L = %d, nCCE %d (nCCE/L %d),nb_cand*L %d\n", rnti, - Yk * L, nCCE, nCCE / L, nb_candidates * L); + LOG_I(PHY, "rnti %x, Yk*L = %u, nCCE %d (nCCE/L %d),nb_cand*L %d\n", + rnti, + Yk * L, + nCCE, + nCCE / L, + nb_candidates * L); } +//------------------------------------------------------------------------------ uint16_t -getnquad(COMMON_channels_t * cc, uint8_t num_pdcch_symbols, uint8_t mi) +getnquad(COMMON_channels_t *cc, + uint8_t num_pdcch_symbols, + uint8_t mi) +//------------------------------------------------------------------------------ { uint16_t Nreg = 0; - AssertFatal(cc != NULL, "cc is null\n"); AssertFatal(cc->mib != NULL, "cc->mib is null\n"); - int N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth); int phich_resource = get_phich_resource_times6(cc); - uint8_t Ngroup_PHICH = (phich_resource * N_RB_DL) / 48; - if (((phich_resource * N_RB_DL) % 48) > 0) + if (((phich_resource * N_RB_DL) % 48) > 0) { Ngroup_PHICH++; + } if (cc->Ncp == 1) { Ngroup_PHICH <<= 1; @@ -2764,517 +3111,527 @@ getnquad(COMMON_channels_t * cc, uint8_t num_pdcch_symbols, uint8_t mi) Ngroup_PHICH *= mi; - if ((num_pdcch_symbols > 0) && (num_pdcch_symbols < 4)) + if (num_pdcch_symbols > 0 && num_pdcch_symbols < 4) switch (N_RB_DL) { - case 6: - Nreg = 12 + (num_pdcch_symbols - 1) * 18; - break; + case 6: + Nreg = 12 + (num_pdcch_symbols - 1) * 18; + break; - case 25: - Nreg = 50 + (num_pdcch_symbols - 1) * 75; - break; + case 25: + Nreg = 50 + (num_pdcch_symbols - 1) * 75; + break; - case 50: - Nreg = 100 + (num_pdcch_symbols - 1) * 150; - break; + case 50: + Nreg = 100 + (num_pdcch_symbols - 1) * 150; + break; - case 100: - Nreg = 200 + (num_pdcch_symbols - 1) * 300; - break; + case 100: + Nreg = 200 + (num_pdcch_symbols - 1) * 300; + break; - default: - return (0); + default: + return 0; } + // printf("Nreg %d (%d)\n",Nreg,Nreg - 4 - (3*Ngroup_PHICH)); return (Nreg - 4 - (3 * Ngroup_PHICH)); } +//------------------------------------------------------------------------------ uint16_t -getnCCE(COMMON_channels_t * cc, uint8_t num_pdcch_symbols, uint8_t mi) +getnCCE(COMMON_channels_t *cc, + uint8_t num_pdcch_symbols, + uint8_t mi) +//------------------------------------------------------------------------------ { AssertFatal(cc != NULL, "cc is null\n"); - return (getnquad(cc, num_pdcch_symbols, mi) / 9); + return (getnquad(cc, + num_pdcch_symbols, + mi) / 9); } -uint8_t getmi(COMMON_channels_t * cc, int subframe) +//------------------------------------------------------------------------------ +uint8_t +getmi(COMMON_channels_t *cc, + int subframe) +//------------------------------------------------------------------------------ { AssertFatal(cc != NULL, "cc is null\n"); // for FDD - if (cc->tdd_Config == NULL) // FDD + if (cc->tdd_Config == NULL) // FDD return 1; // for TDD switch (cc->tdd_Config->subframeAssignment) { - case 0: - if ((subframe == 0) || (subframe == 5)) - return (2); - else - return (1); + case 0: + if (subframe == 0 || subframe == 5) { + return 2; + } - break; + return 1; - case 1: - if ((subframe == 0) || (subframe == 5)) - return (0); - else - return (1); + case 1: + if (subframe == 0 || subframe == 5) { + return 0; + } - break; + return 1; - case 2: - if ((subframe == 3) || (subframe == 8)) - return (1); - else - return (0); + case 2: + if (subframe == 3 || subframe == 8) { + return 0; + } - break; + return 1; - case 3: - if ((subframe == 0) || (subframe == 8) || (subframe == 9)) - return (1); - else - return (0); + case 3: + if (subframe == 0 || subframe == 8 || subframe == 9) { + return 1; + } - break; + return 0; - case 4: - if ((subframe == 8) || (subframe == 9)) - return (1); - else - return (0); + case 4: + if (subframe == 8 || subframe == 9) { + return 1; + } - break; + return 0; - case 5: - if (subframe == 8) - return (1); - else - return (0); + case 5: + if (subframe == 8) { + return 1; + } - break; + return 0; - case 6: - return (1); - break; + case 6: + return 1; - default: - return (0); + default: + break; } + + return 0; } +//------------------------------------------------------------------------------ uint16_t -get_nCCE_max(COMMON_channels_t * cc, int num_pdcch_symbols, int subframe) +get_nCCE_max(COMMON_channels_t *cc, + int num_pdcch_symbols, + int subframe) +//------------------------------------------------------------------------------ { AssertFatal(cc != NULL, "cc is null\n"); - return (getnCCE(cc, num_pdcch_symbols, getmi(cc, subframe))); + return (getnCCE(cc, + num_pdcch_symbols, + getmi(cc, + subframe))); } // Allocate the CCEs +//------------------------------------------------------------------------------ int -allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, int test_onlyP) +allocate_CCEs(int module_idP, + int CC_idP, + frame_t frameP, + sub_frame_t subframeP, + int test_onlyP) +//------------------------------------------------------------------------------ { - int *CCE_table = RC.mac[module_idP]->CCE_table[CC_idP]; - nfapi_dl_config_request_body_t *DL_req = - &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body; - nfapi_hi_dci0_request_body_t *HI_DCI0_req = - &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframeP].hi_dci0_request_body; - nfapi_dl_config_request_pdu_t *dl_config_pdu = - &DL_req->dl_config_pdu_list[0]; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_pdu_list[0]; - int nCCE_max = - get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], 1, - subframeP); + eNB_MAC_INST *eNB = RC.mac[module_idP]; + int *CCE_table = eNB->CCE_table[CC_idP]; + nfapi_dl_config_request_body_t *DL_req = &eNB->DL_req[CC_idP].dl_config_request_body; + nfapi_hi_dci0_request_body_t *HI_DCI0_req = &eNB->HI_DCI0_req[CC_idP][subframeP].hi_dci0_request_body; + nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req->dl_config_pdu_list[0]; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[0]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + int nCCE_max = get_nCCE_max(cc, 1, subframeP); int fCCE; int i, j, idci; int nCCE = 0; int max_symbol; - - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; int ackNAK_absSF = get_pucch1_absSF(cc, (frameP*10+subframeP)); + nfapi_dl_config_request_pdu_t *dl_config_pduLoop; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pduLoop; + if (cc->tdd_Config!=NULL && is_S_sf(cc,subframeP) > 0) max_symbol = 2; else max_symbol = 3; nfapi_ul_config_request_body_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10].ul_config_request_body; - - LOG_D(MAC, - "Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n", - subframeP, test_onlyP, DL_req->number_pdu, DL_req->number_dci, - HI_DCI0_req->number_of_dci); - DL_req->number_pdcch_ofdm_symbols = 2; - - try_again: - init_CCE_table(module_idP, CC_idP); + LOG_D(MAC, "Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n", + subframeP, + test_onlyP, + DL_req->number_pdu, + DL_req->number_dci, + HI_DCI0_req->number_of_dci); + DL_req->number_pdcch_ofdm_symbols = 1; +try_again: + init_CCE_table(CCE_table); nCCE = 0; for (i = 0, idci = 0; i < DL_req->number_pdu; i++) { + dl_config_pduLoop = &dl_config_pdu[i]; + // allocate DL common DCIs first - if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == - 2)) { - LOG_D(MAC, - "Trying to allocate COMMON DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, HI_DCI0_req->number_of_dci, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - - if (nCCE + - (dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) - goto failed; - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; + if (dl_config_pduLoop->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE && + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 2) { + LOG_D(MAC, "Trying to allocate COMMON DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + idci, + DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + nCCE, + nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + + if (nCCE + (dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) + return -1; + + LOG_D(MAC, "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = get_nCCE_max(cc, DL_req->number_pdcch_ofdm_symbols, subframeP); + goto try_again; } + // number of CCEs left can potentially hold this allocation fCCE = get_nCCE_offset(CCE_table, - dl_config_pdu[i]. - dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, nCCE_max, 1, - dl_config_pdu[i]. - dci_dl_pdu.dci_dl_pdu_rel8.rnti, - subframeP); + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + nCCE_max, + 1, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti, + subframeP); + if (fCCE == -1) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { - LOG_D(MAC, - "subframe %d: Dropping Allocation for RNTI %x\n", - subframeP, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8. - rnti); - for (j = 0; j <= i; j++) { - if (dl_config_pdu[j].pdu_type == - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - LOG_D(MAC, - "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - j, - DL_req->number_dci + - HI_DCI0_req->number_of_dci, - DL_req->number_dci, - HI_DCI0_req->number_of_dci, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8.dci_format, - dl_config_pdu[j]. - dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - } - //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); - goto failed; - } - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = get_nCCE_max(&RC.mac[module_idP]-> - common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } // fCCE==-1 + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { + LOG_D(MAC, "subframe %d: Dropping Allocation for RNTI %x\n", + subframeP, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti); + + for (j = 0; j <= i; j++) { + dl_config_pduLoop = &dl_config_pdu[j]; + + if (dl_config_pduLoop->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + LOG_D(MAC, "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + j, + DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.dci_format, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + nCCE, nCCE_max, DL_req->number_pdcch_ofdm_symbols); + } + + //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); + return -1; + } + + LOG_D(MAC, "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = get_nCCE_max(cc, DL_req->number_pdcch_ofdm_symbols, subframeP); + goto try_again; + } // fCCE==-1 // the allocation is feasible, rnti rule passes - nCCE += dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level; + nCCE += dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level; LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); + if ((test_onlyP%2) == 0) { - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; - LOG_D(MAC, - "Allocate COMMON DCI CCEs subframe %d, test %d => L %d fCCE %d\n", - subframeP, test_onlyP, - dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, fCCE); + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; + LOG_D(MAC, "Allocate COMMON DCI CCEs subframe %d, test %d => L %d fCCE %d\n", + subframeP, + test_onlyP, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + fCCE); } + idci++; } - } // for i = 0 ... num_DL_DCIs + } // for i = 0 ... num_DL_DCIs - // no try to allocate UL DCIs - for (i = 0; i < HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi; - i++) { + // now try to allocate UL DCIs + for (i = 0; i < HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi; i++) { + hi_dci0_pduLoop = &hi_dci0_pdu[i]; // allocate UL DCIs if (hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) { - - LOG_D(MAC, - "Trying to allocate format 0 DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, HI_DCI0_req->number_of_dci, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level, - nCCE, nCCE_max, DL_req->number_pdcch_ofdm_symbols); - - if (nCCE + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level) > nCCE_max) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) - goto failed; - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; + LOG_D(MAC, "Trying to allocate format 0 DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + idci, + DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.rnti, + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level, + nCCE, nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + + if (nCCE + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level > nCCE_max) { + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) + return -1; + + LOG_D(MAC, "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = get_nCCE_max(cc, DL_req->number_pdcch_ofdm_symbols, subframeP); + goto try_again; } + // number of CCEs left can potentially hold this allocation fCCE = get_nCCE_offset(CCE_table, - hi_dci0_pdu[i].dci_pdu. - dci_pdu_rel8.aggregation_level, - nCCE_max, 0, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8. - rnti, subframeP); + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level, + nCCE_max, + 0, + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.rnti, + subframeP); + if (fCCE == -1) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { - LOG_D(MAC, - "subframe %d: Dropping Allocation for RNTI %x\n", - subframeP, - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti); - for (j = 0; j <= i; j++) { - if (hi_dci0_pdu[j].pdu_type == - NFAPI_HI_DCI0_DCI_PDU_TYPE) - LOG_D(MAC, - "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - j, - DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, - HI_DCI0_req->number_of_dci, - hi_dci0_pdu[j].dci_pdu.dci_pdu_rel8.rnti, - hi_dci0_pdu[j].dci_pdu.dci_pdu_rel8. - dci_format, - hi_dci0_pdu[j].dci_pdu. - dci_pdu_rel8.aggregation_level, nCCE, - nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - } - //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); - goto failed; - } - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } // fCCE==-1 + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { + LOG_D(MAC, "subframe %d: Dropping Allocation for RNTI %x\n", + subframeP, + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.rnti); + + for (j = 0; j <= i; j++) { + hi_dci0_pduLoop = &hi_dci0_pdu[j]; + + if (hi_dci0_pdu[j].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) + LOG_D(MAC, "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + j, + DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.rnti, + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.dci_format, + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level, + nCCE, nCCE_max, DL_req->number_pdcch_ofdm_symbols); + } + + //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); + return -1; + } + + LOG_D(MAC, "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = get_nCCE_max(cc, DL_req->number_pdcch_ofdm_symbols, subframeP); + goto try_again; + } // fCCE==-1 // the allocation is feasible, rnti rule passes - nCCE += hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level; - LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); + nCCE += hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.aggregation_level; + LOG_D(MAC, "Allocating at nCCE %d\n", + fCCE); + if ((test_onlyP%2) == 0) { - hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.cce_index = fCCE; - LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", - subframeP, test_onlyP); + hi_dci0_pduLoop->dci_pdu.dci_pdu_rel8.cce_index = fCCE; + LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", + subframeP, + test_onlyP); } + idci++; } - } // for i = 0 ... num_UL_DCIs + } // for i = 0 ... num_UL_DCIs for (i = 0; i < DL_req->number_pdu; i++) { + dl_config_pduLoop = &dl_config_pdu[i]; + // allocate DL UE specific DCIs if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - && (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == - 1)) { - LOG_D(MAC, - "Trying to allocate DL UE-SPECIFIC DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - idci, DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, HI_DCI0_req->number_of_dci, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[i].dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, nCCE, nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - - if (nCCE + (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) - goto failed; - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; + && (dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type == 1)) { + LOG_D(MAC, "Trying to allocate DL UE-SPECIFIC DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + idci, + DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, HI_DCI0_req->number_of_dci, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + nCCE, + nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + + if (nCCE + (dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level) > nCCE_max) { + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) + return -1; + + LOG_D(MAC, "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = get_nCCE_max(cc, DL_req->number_pdcch_ofdm_symbols, subframeP); + goto try_again; } + // number of CCEs left can potentially hold this allocation fCCE = get_nCCE_offset(CCE_table, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, nCCE_max, 0, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti, - subframeP); + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + nCCE_max, + 0, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti, + subframeP); + if (fCCE == -1) { - if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { - LOG_I(MAC, - "subframe %d: Dropping Allocation for RNTI %x\n", - subframeP, - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8. - rnti); - for (j = 0; j <= i; j++) { - if (dl_config_pdu[j].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) - LOG_D(MAC, - "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", - j, - DL_req->number_dci + HI_DCI0_req->number_of_dci, - DL_req->number_dci, - HI_DCI0_req->number_of_dci, - dl_config_pdu[j].dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu[j].dci_dl_pdu.dci_dl_pdu_rel8.dci_format, - dl_config_pdu[j].dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, - nCCE, - nCCE_max, - DL_req->number_pdcch_ofdm_symbols); - } - //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); - goto failed; - } - LOG_D(MAC, - "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", - DL_req->number_pdcch_ofdm_symbols); - - DL_req->number_pdcch_ofdm_symbols++; - nCCE_max = - get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP], - DL_req->number_pdcch_ofdm_symbols, - subframeP); - goto try_again; - } // fCCE==-1 + if (DL_req->number_pdcch_ofdm_symbols == max_symbol) { + LOG_I(MAC, "subframe %d: Dropping Allocation for RNTI %x\n", + subframeP, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti); + + for (j = 0; j <= i; j++) { + dl_config_pduLoop = &dl_config_pdu[j]; + + if (dl_config_pduLoop->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + LOG_D(MAC, "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n", + j, + DL_req->number_dci + HI_DCI0_req->number_of_dci, + DL_req->number_dci, + HI_DCI0_req->number_of_dci, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.rnti, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.dci_format, + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, + nCCE, + nCCE_max, + DL_req->number_pdcch_ofdm_symbols); + } + + //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L); + return -1; + } + + LOG_D(MAC, "Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n", + DL_req->number_pdcch_ofdm_symbols); + DL_req->number_pdcch_ofdm_symbols++; + nCCE_max = get_nCCE_max(cc, DL_req->number_pdcch_ofdm_symbols, subframeP); + goto try_again; + } // fCCE==-1 // the allocation is feasible, rnti rule passes - nCCE += dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level; - LOG_D(MAC, "Allocating at nCCE %d\n", fCCE); + nCCE += dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level; + LOG_D(MAC, "Allocating at nCCE %d\n", + fCCE); + if ((test_onlyP%2) == 0) { - dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; - LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", - subframeP, test_onlyP); + dl_config_pduLoop->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE; + LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n", + subframeP, + test_onlyP); } + if ((test_onlyP/2) == 1) { - for(int ack_int = 0;ack_int < ul_req->number_of_pdus; ack_int++){ - if(((ul_req->ul_config_pdu_list[ack_int].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) || - (ul_req->ul_config_pdu_list[ack_int].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE)) && - (ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.ue_information.ue_information_rel8.rnti == dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti)){ - if (cc->tdd_Config==NULL) - ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + fCCE; - else - ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.harq_information.harq_information_rel10_tdd.n_pucch_1_0 = - cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + fCCE + getNp(cc->mib->message.dl_Bandwidth,fCCE,0) ; + for(int ack_int = 0; ack_int < ul_req->number_of_pdus; ack_int++) { + if(((ul_req->ul_config_pdu_list[ack_int].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) || + (ul_req->ul_config_pdu_list[ack_int].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE)) && + (ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.ue_information.ue_information_rel8.rnti == dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti)) { + if (cc->tdd_Config==NULL) + ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = + cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + fCCE; + else + ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.harq_information.harq_information_rel10_tdd.n_pucch_1_0 = + cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + fCCE + getNp(cc->mib->message.dl_Bandwidth,fCCE,0) ; + } } - } } + idci++; } - } // for i = 0 ... num_DL_DCIs + } // for i = 0 ... num_DL_DCIs return 0; - - failed: - return -1; } -nfapi_ul_config_request_pdu_t *has_ul_grant(module_id_t module_idP, - int CC_idP, uint16_t absSFP, - uint16_t rnti) +//------------------------------------------------------------------------------ +nfapi_ul_config_request_pdu_t * +has_ul_grant(module_id_t module_idP, + int CC_idP, + uint16_t absSFP, + uint16_t rnti) +//------------------------------------------------------------------------------ { - nfapi_ul_config_request_body_t *ul_req; - nfapi_ul_config_request_pdu_t *ul_config_pdu; - - ul_req = &RC.mac[module_idP]->UL_req_tmp[CC_idP][absSFP % 10].ul_config_request_body; - ul_config_pdu = &ul_req->ul_config_pdu_list[0]; - LOG_D(MAC, - "Checking for rnti %x UL grant in subframeP %d (num pdu %d)\n", - rnti, absSFP % 10, ul_req->number_of_pdus); - - for (int i = 0; i < ul_req->number_of_pdus; i++) { - LOG_D(MAC, "PDU %d : type %d,rnti %x\n", i,ul_config_pdu[i].pdu_type, rnti); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) - && (ul_config_pdu[i].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) - && (ul_config_pdu[i].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) - && (ul_config_pdu[i].ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) - && (ul_config_pdu[i].ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_pdu.ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE) - && (ul_config_pdu[i].uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_sr_pdu.ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE) - && (ul_config_pdu[i].uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE) - && (ul_config_pdu[i].ulsch_uci_csi_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].ulsch_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); - if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE) - && (ul_config_pdu[i].ulsch_csi_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) - return (&ul_config_pdu[i]); + nfapi_ul_config_request_body_t *ul_req = &RC.mac[module_idP]->UL_req_tmp[CC_idP][absSFP % 10].ul_config_request_body; + nfapi_ul_config_request_pdu_t *ul_config_pdu = &ul_req->ul_config_pdu_list[0]; + uint8_t pdu_type; + LOG_D(MAC, "Checking for rnti %x UL grant in subframeP %d (num pdu %d)\n", + rnti, + absSFP % 10, + ul_req->number_of_pdus); + + for (int i = 0; i < ul_req->number_of_pdus; i++, ul_config_pdu++) { + pdu_type = ul_config_pdu->pdu_type; + LOG_D(MAC, "PDU %d : type %d,rnti %x\n", + i, + pdu_type, + rnti); + + if (pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE && ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE && ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE && ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE && ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE && ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE && ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE && ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE && ul_config_pdu->uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE && ul_config_pdu->uci_cqi_sr_pdu.ue_information.ue_information_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE && ul_config_pdu->uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE && ul_config_pdu->ulsch_uci_csi_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE && ul_config_pdu->ulsch_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + return ul_config_pdu; + + if (pdu_type == NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE && ul_config_pdu->ulsch_csi_uci_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) + return ul_config_pdu; } - return (NULL); // no ul grant at all for this UE + return (NULL); // no ul grant at all for this UE } +//------------------------------------------------------------------------------ boolean_t CCE_allocation_infeasible(int module_idP, - int CC_idP, - int format_flag, - int subframe, int aggregation, int rnti) + int CC_idP, + int format_flag, + int subframe, + int aggregation, + int rnti) +//------------------------------------------------------------------------------ { nfapi_dl_config_request_body_t *DL_req = &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body; nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu]; nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe].hi_dci0_request_body; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi]; - int ret; - boolean_t res = FALSE; + boolean_t res = TRUE; - if (format_flag != 2) { // DL DCI + if (format_flag != 2) { // DL DCI if (DL_req->number_pdu == MAX_NUM_DL_PDU) { - LOG_W(MAC, - "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", - subframe, rnti); + LOG_W(MAC, "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", subframe, rnti); } else { dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; @@ -3282,244 +3639,298 @@ CCE_allocation_infeasible(int module_idP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0) ? 2 : 1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation; DL_req->number_pdu++; - LOG_D(MAC, - "Subframe %d: Checking CCE feasibility format %d : (%x,%d) (%x,%d,%d)\n", - subframe, format_flag, rnti, aggregation, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - aggregation_level, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type); - ret = allocate_CCEs(module_idP, CC_idP, 0, subframe, 0); - if (ret == -1) res = TRUE; + LOG_D(MAC, "Subframe %d: Checking CCE feasibility format %d : (%x,%d) \n", + subframe, format_flag, rnti, aggregation); + + if (allocate_CCEs(module_idP, CC_idP, 0, subframe, 0) != -1) + res = FALSE; + DL_req->number_pdu--; } - } else { // ue-specific UL DCI + } else { // ue-specific UL DCI if (HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi == MAX_NUM_HI_DCI0_PDU) { - LOG_W(MAC, - "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n", - subframe, rnti); + LOG_W(MAC, "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n", subframe, rnti); } else { hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; HI_DCI0_req->number_of_dci++; - ret = allocate_CCEs(module_idP, CC_idP, 0, subframe, 0); - if (ret == -1) res = TRUE; + + if (allocate_CCEs(module_idP, CC_idP, 0, subframe, 0) != -1) + res = FALSE; + HI_DCI0_req->number_of_dci--; } } return res; } -void get_retransmission_timing(LTE_TDD_Config_t *tdd_Config, frame_t *frameP, - sub_frame_t *subframeP) -{ - if (tdd_Config == NULL) - { - if (*subframeP > 1) - *frameP = (*frameP + 1) % 1024; - *subframeP = (*subframeP + 8) % 10; +//------------------------------------------------------------------------------ +void +get_retransmission_timing(LTE_TDD_Config_t *tdd_Config, + frame_t *frameP, + sub_frame_t *subframeP) +//------------------------------------------------------------------------------ +{ + if (tdd_Config == NULL) { + if (*subframeP > 1) { + *frameP = (*frameP + 1) % 1024; } - else - { - switch (tdd_Config->subframeAssignment)//TODO fill in other TDD configs - { - default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort(); - case 1: - if (*subframeP == 0 || *subframeP == 5) - { - *subframeP += 19; - *frameP = (*frameP + *subframeP/10) % 1024; - *subframeP %= 10; - } - else if (*subframeP == 4 || *subframeP == 9) - { - *subframeP += 16; - *frameP = (*frameP + *subframeP/10) % 1024; - *subframeP %= 10; - } - else - { - AssertFatal(2 == 1, - "Illegal dl subframe %d for tdd config %ld\n", *subframeP, - tdd_Config->subframeAssignment); - } - break; + + *subframeP = (*subframeP + 8) % 10; + } else { + switch (tdd_Config->subframeAssignment) { //TODO fill in other TDD configs + default: + printf("%s:%d: TODO\n", + __FILE__, + __LINE__); + abort(); + break; + + case 1: + if (*subframeP == 0 || *subframeP == 5) { + *subframeP += 19; + *frameP = (*frameP + (*subframeP / 10)) % 1024; + *subframeP %= 10; + } else if (*subframeP == 4 || *subframeP == 9) { + *subframeP += 16; + *frameP = (*frameP + (*subframeP / 10)) % 1024; + *subframeP %= 10; + } else { + AssertFatal(2 == 1, "Illegal dl subframe %d for tdd config %ld\n", + *subframeP, + tdd_Config->subframeAssignment); } + + break; } + } + + return; } -uint8_t get_dl_subframe_count(int tdd_config_sfa, sub_frame_t subframeP){ +//------------------------------------------------------------------------------ +uint8_t +get_dl_subframe_count(int tdd_config_sfa, + sub_frame_t subframeP) +//------------------------------------------------------------------------------ +{ + uint8_t tdd1[10] = {1, -1, -1, -1, 2, 3, -1, -1, -1, 4}; // special subframes 1,6 are excluded - uint8_t tdd1[10] = {1,-1,-1,-1,2,3,-1,-1,-1,4}; // special subframes 1,6 are excluded + switch (tdd_config_sfa) {// TODO fill in other tdd configs + case 1: + return tdd1[subframeP]; + } - switch(tdd_config_sfa){// TODO fill in other tdd configs - case 1 : - return tdd1[subframeP]; - break; - } - return -1; + return -1; } -uint8_t frame_subframe2_dl_harq_pid(LTE_TDD_Config_t *tdd_Config, int abs_frameP, sub_frame_t subframeP){ - int harq_pid; - if(tdd_Config){ - - switch(tdd_Config->subframeAssignment){ //TODO fill in other tdd config - case 1: - harq_pid = (((frame_cnt*1024 + abs_frameP) * 4) - 1 + get_dl_subframe_count(tdd_Config->subframeAssignment,subframeP))%7;//4 dl subframe in a frame - if(harq_pid < 0) - harq_pid += 7; - LOG_D(MAC,"[frame_subframe2_dl_harq_pid] (%d,%d) calculate harq_pid ((( %d * 1024 + %d) *4) - 1 + %d) = %d \n", - (abs_frameP+1024)%1024,subframeP,frame_cnt,abs_frameP, - get_dl_subframe_count(tdd_Config->subframeAssignment,subframeP),harq_pid); - return harq_pid; - break; +//------------------------------------------------------------------------------ +uint8_t +frame_subframe2_dl_harq_pid(LTE_TDD_Config_t *tdd_Config, + int abs_frameP, + sub_frame_t subframeP) +//------------------------------------------------------------------------------ +{ + int harq_pid; + uint8_t count; + + if (tdd_Config) { + switch(tdd_Config->subframeAssignment) { //TODO fill in other tdd config + case 1: + count = get_dl_subframe_count(tdd_Config->subframeAssignment, + subframeP); + harq_pid = (((frame_cnt * 1024 + abs_frameP) * 4) - 1 + count) % 7;//4 dl subframe in a frame + + if (harq_pid < 0) { + harq_pid += 7; } - }else{ - return ((abs_frameP*10)+subframeP)&7; + + LOG_D(MAC,"[frame_subframe2_dl_harq_pid] (%d,%d) calculate harq_pid ((( %d * 1024 + %d) *4) - 1 + %d) = %d \n", + (abs_frameP + 1024) % 1024, + subframeP, + frame_cnt, + abs_frameP, + count, + harq_pid); + return harq_pid; } - return -1; + } else { + return ((abs_frameP * 10) + subframeP) & 7; + } + + return -1; } -unsigned char ul_ACK_subframe2M(LTE_TDD_Config_t *tdd_Config,unsigned char subframe) +//------------------------------------------------------------------------------ +unsigned char +ul_ACK_subframe2M(LTE_TDD_Config_t *tdd_Config, + unsigned char subframe) +//------------------------------------------------------------------------------ { - if (tdd_Config == NULL) { - return(1); - } else { - switch (tdd_Config->subframeAssignment) { + return 1; + } + + switch (tdd_Config->subframeAssignment) { case 1: - return 1; // don't ACK special subframe for now + return 1; // don't ACK special subframe for now + + /* + if (subframe == 2) { // ACK subframes 5 and 6 + return(2); + } else if (subframe == 3) { // ACK subframe 9 + return(1); // To be updated + } else if (subframe == 7) { // ACK subframes 0 and 1 + return(2); // To be updated + } else if (subframe == 8) { // ACK subframe 4 + return(1); // To be updated + } else { + AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n", + subframe,tdd_Config->subframeAssignment); + } + break; + */ + case 3: if (subframe == 2) { // ACK subframes 5 and 6 - return(2); - } else if (subframe == 3) { // ACK subframe 9 - return(1); // To be updated - } else if (subframe == 7) { // ACK subframes 0 and 1 - return(2); // To be updated - } else if (subframe == 8) { // ACK subframe 4 - return(1); // To be updated - } else { - AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n", - subframe,tdd_Config->subframeAssignment); + return 2; // should be 3 + } + if (subframe == 3) { // ACK subframes 7 and 8 + return 2; // To be updated } - break; - case 3: - if (subframe == 2) { // ACK subframes 5 and 6 - return(2); // should be 3 - } else if (subframe == 3) { // ACK subframes 7 and 8 - return(2); // To be updated - } else if (subframe == 4) { // ACK subframes 9 and 0 - return(2); - } else { - AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n", - subframe,tdd_Config->subframeAssignment); + if (subframe == 4) { // ACK subframes 9 and 0 + return 2; } + AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n", + subframe, + tdd_Config->subframeAssignment); break; case 4: - if (subframe == 2) { // ACK subframes 0,4 and 5 - return(3); // should be 4 - } else if (subframe == 3) { // ACK subframes 6,7,8 and 9 - return(4); - } else { - AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n", - subframe,tdd_Config->subframeAssignment); - } + if (subframe == 2) { // ACK subframes 0,4 and 5 + return 3; // should be 4 + } - break; + if (subframe == 3) { // ACK subframes 6,7,8 and 9 + return 4; + } + + AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n", + subframe, + tdd_Config->subframeAssignment); + break; case 5: - if (subframe == 2) { // ACK subframes 0,3,4,5,6,7,8 and 9 - return(8); // should be 3 - } else { - AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n", - subframe,tdd_Config->subframeAssignment); - } + if (subframe == 2) { // ACK subframes 0,3,4,5,6,7,8 and 9 + return 8; // should be 3 + } - break; - } + AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n", + subframe, + tdd_Config->subframeAssignment); + break; } - return(0); + return 0; } -unsigned char ul_ACK_subframe2dl_subframe(LTE_TDD_Config_t *tdd_Config,unsigned char subframe,unsigned char ACK_index) +//------------------------------------------------------------------------------ +unsigned char +ul_ACK_subframe2dl_subframe(LTE_TDD_Config_t *tdd_Config, + unsigned char subframe, + unsigned char ACK_index) +//------------------------------------------------------------------------------ { - if (tdd_Config == NULL) { - return((subframe<4) ? subframe+6 : subframe-4); - } else { - switch (tdd_Config->subframeAssignment) { + return ((subframe < 4) ? subframe + 6 : subframe - 4); + } + + switch (tdd_Config->subframeAssignment) { case 3: if (subframe == 2) { // ACK subframes 5 and 6 - if (ACK_index==2) - return(1); - - return(5+ACK_index); - } else if (subframe == 3) { // ACK subframes 7 and 8 - return(7+ACK_index); // To be updated - } else if (subframe == 4) { // ACK subframes 9 and 0 - return((9+ACK_index)%10); - } else { - AssertFatal(1==0,"illegal subframe %d for tdd_config->subframeAssignment %ld\n", - subframe,tdd_Config->subframeAssignment); + if (ACK_index == 2) return 1; + + return (5 + ACK_index); + } + + if (subframe == 3) { // ACK subframes 7 and 8 + return (7 + ACK_index); // To be updated } + if (subframe == 4) { // ACK subframes 9 and 0 + return ((9 + ACK_index) % 10); + } + + AssertFatal(1==0, "illegal subframe %d for tdd_config->subframeAssignment %ld\n", + subframe, + tdd_Config->subframeAssignment); break; case 4: - if (subframe == 2) { // ACK subframes 0, 4 and 5 - //if (ACK_index==2) - // return(1); TBC - if (ACK_index==2) - return(0); - - return(4+ACK_index); - } else if (subframe == 3) { // ACK subframes 6, 7 8 and 9 - return(6+ACK_index); // To be updated - } else { - AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n", - subframe,tdd_Config->subframeAssignment); - } + if (subframe == 2) { // ACK subframes 0, 4 and 5 + //if (ACK_index==2) + // return(1); TBC + if (ACK_index == 2) return 0; - break; + return (4 + ACK_index); + } + + if (subframe == 3) { // ACK subframes 6, 7 8 and 9 + return (6 + ACK_index); // To be updated + } + + AssertFatal(1 == 0, "illegal subframe %d for tdd_config %ld\n", + subframe, + tdd_Config->subframeAssignment); + break; case 1: if (subframe == 2) { // ACK subframes 5 and 6 - return(5+ACK_index); - } else if (subframe == 3) { // ACK subframe 9 - return(9); // To be updated - } else if (subframe == 7) { // ACK subframes 0 and 1 - return(ACK_index); // To be updated - } else if (subframe == 8) { // ACK subframe 4 - return(4); // To be updated - } else { - AssertFatal(1==0,"illegal subframe %d for tdd_config %ld\n", - subframe,tdd_Config->subframeAssignment); + return (5 + ACK_index); } + if (subframe == 3) { // ACK subframe 9 + return 9; // To be updated + } + + if (subframe == 7) { // ACK subframes 0 and 1 + return ACK_index; // To be updated + } + + if (subframe == 8) { // ACK subframe 4 + return 4; // To be updated + } + + AssertFatal(1 == 0, "illegal subframe %d for tdd_config %ld\n", + subframe, + tdd_Config->subframeAssignment); break; - } } - return(0); + return 0; } +//------------------------------------------------------------------------------ void -extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, - frame_t frameP, sub_frame_t subframeP, - void *harq_indication, int format) +extract_harq(module_id_t mod_idP, + int CC_idP, + int UE_id, + frame_t frameP, + sub_frame_t subframeP, + void *harq_indication, + int format) +//------------------------------------------------------------------------------ { - UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + eNB_MAC_INST *eNB = RC.mac[mod_idP]; + UE_list_t *UE_list = &eNB->UE_list; UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; rnti_t rnti = UE_RNTI(mod_idP, UE_id); - COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; + COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; nfapi_harq_indication_fdd_rel13_t *harq_indication_fdd; nfapi_harq_indication_tdd_rel13_t *harq_indication_tdd; uint16_t num_ack_nak; @@ -3532,603 +3943,746 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, sub_frame_t subframe_tx; int frame_tx; uint8_t harq_pid; - #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - if (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated != NULL && - UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL && - (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7) - && (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13) - && (((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUCCH_r13) && (format == 0)) - || ((UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUSCH_r13) - && (format == 1)))) + LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated; + + if (physicalConfigDedicated != NULL && physicalConfigDedicated->pucch_ConfigDedicated != NULL && + physicalConfigDedicated->ext7 != NULL && physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13 != NULL && + ((physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUCCH_r13 && format == 0) || + (physicalConfigDedicated->ext7->pucch_ConfigDedicated_r13->spatialBundlingPUSCH_r13 && format == 1))) { spatial_bundling = 1; + } + #endif - for (i = 0; i < numCC; i++) - tmode[i] = get_tmode(mod_idP, i, UE_id); - + + for (i = 0; i < numCC; i++) { + tmode[i] = get_tmode(mod_idP, + i, + UE_id); + } + if (cc->tdd_Config) { harq_indication_tdd = (nfapi_harq_indication_tdd_rel13_t *) harq_indication; // pdu = &harq_indication_tdd->harq_tb_n[0]; - num_ack_nak = harq_indication_tdd->number_of_ack_nack; - + switch (harq_indication_tdd->mode) { - case 0: // Format 1a/b bundling - AssertFatal(numCC == 1, "numCC %d > 1, should not be using Format1a/b\n", numCC); - int M = ul_ACK_subframe2M(cc->tdd_Config,subframeP); - for(m=0;m<M;m++){ - subframe_tx = ul_ACK_subframe2dl_subframe(cc->tdd_Config,subframeP,m); - if(frameP==1023&&subframeP>5) - frame_tx=-1; - else - frame_tx = subframeP < 4 ? frameP -1 : frameP; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame_tx,subframe_tx); - RA_t *ra = &RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; - - if(num_ack_nak==1){ - if(harq_indication_tdd->harq_data[0].bundling.value_0==1){ //ack - sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process - sched_ctl->tbcnt[CC_idP][harq_pid] = 0; - LOG_D(MAC,"frame %d subframe %d Acking (%d,%d) harq_pid %d round %d\n",frameP,subframeP,frame_tx,subframe_tx,harq_pid,sched_ctl->round[CC_idP][harq_pid]); - }else{ //nack - if( sched_ctl->round[CC_idP][harq_pid]<8) sched_ctl->round[CC_idP][harq_pid]++; - if (sched_ctl->round[CC_idP][harq_pid] == 4) { - sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process - sched_ctl->tbcnt[CC_idP][harq_pid] = 0; - } - LOG_D(MAC,"frame %d subframe %d Nacking (%d,%d) harq_pid %d round %d\n",frameP,subframeP,frame_tx,subframe_tx,harq_pid,sched_ctl->round[CC_idP][harq_pid]); - if(sched_ctl->round[CC_idP][harq_pid] == 8){ - for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)){ - //Msg NACK num to MAC ,remove UE - // add UE info to freeList - LOG_I(RRC, "put UE %x into freeList\n", rnti); - put_UE_in_freelist(mod_idP, rnti, 1); - } - } - } - } - } - for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if ((ra[ra_i].rnti == rnti) && (ra[ra_i].state == MSGCRNTI_ACK) && (ra[ra_i].crnti_harq_pid == harq_pid)) { - LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n",harq_indication_tdd->harq_data[0].bundling.value_0,rnti,sched_ctl->round[CC_idP][harq_pid],frameP,subframeP); - if(num_ack_nak == 1 && harq_indication_tdd->harq_data[0].bundling.value_0 == 1) { - cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); - }else{ - if(sched_ctl->round[CC_idP][harq_pid] == 7){ - cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); + case 0: // Format 1a/b bundling + AssertFatal(numCC == 1, "numCC %d > 1, should not be using Format1a/b\n", + numCC); + int M = ul_ACK_subframe2M(cc->tdd_Config, + subframeP); + + for (m=0; m<M; m++) { + subframe_tx = ul_ACK_subframe2dl_subframe(cc->tdd_Config, + subframeP, + m); + + if (frameP==1023&&subframeP>5) frame_tx=-1; + else frame_tx = subframeP < 4 ? frameP -1 : frameP; + + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, + frame_tx, + subframe_tx); + RA_t *ra = &eNB->common_channels[CC_idP].ra[0]; + + if(num_ack_nak == 1) { + if (harq_indication_tdd->harq_data[0].bundling.value_0 == 1) { //ack + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + LOG_D(MAC, "frame %d subframe %d Acking (%d,%d) harq_pid %d round %d\n", + frameP, + subframeP, + frame_tx, + subframe_tx, + harq_pid, + sched_ctl->round[CC_idP][harq_pid]); + } else { //nack + if (sched_ctl->round[CC_idP][harq_pid] < 8) sched_ctl->round[CC_idP][harq_pid]++; + + if (sched_ctl->round[CC_idP][harq_pid] == 4) { + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + } + + LOG_D(MAC,"frame %d subframe %d Nacking (%d,%d) harq_pid %d round %d\n", + frameP, + subframeP, + frame_tx, + subframe_tx, + harq_pid, + sched_ctl->round[CC_idP][harq_pid]); + + if (sched_ctl->round[CC_idP][harq_pid] == 8) { + for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { + if (ra[ra_i].rnti == rnti && ra[ra_i].state == WAITMSG4ACK) { + //Msg NACK num to MAC ,remove UE + // add UE info to freeList + LOG_I(RRC, "put UE %x into freeList\n", + rnti); + put_UE_in_freelist(mod_idP, + rnti, + 1); + } + } + } + } + } + + for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { + if (ra[ra_i].rnti == rnti && ra[ra_i].state == MSGCRNTI_ACK && ra[ra_i].crnti_harq_pid == harq_pid) { + LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n", + harq_indication_tdd->harq_data[0].bundling.value_0, + rnti, + sched_ctl->round[CC_idP][harq_pid], + frameP, + subframeP); + + if (num_ack_nak == 1 && harq_indication_tdd->harq_data[0].bundling.value_0 == 1) { + cancel_ra_proc(mod_idP, + CC_idP, + frameP, + ra[ra_i].rnti); + } else { + if(sched_ctl->round[CC_idP][harq_pid] == 7) { + cancel_ra_proc(mod_idP, + CC_idP, + frameP, + ra[ra_i].rnti); + } + } + + break; + } } - } - break; } - } - } - break; - case 1: // Channel Selection - break; - case 2: // Format 3 - break; - case 3: // Format 4 - break; - case 4: // Format 5 - break; + + break; + + case 1: // Channel Selection + case 2: // Format 3 + case 3: // Format 4 + case 4: // Format 5 + break; } } else { harq_indication_fdd = (nfapi_harq_indication_fdd_rel13_t *) harq_indication; num_ack_nak = harq_indication_fdd->number_of_ack_nack; pdu = &harq_indication_fdd->harq_tb_n[0]; - harq_pid = ((10 * frameP) + subframeP + 10236) & 7; - - LOG_D(MAC,"frame %d subframe %d harq_pid %d mode %d tmode[0] %d num_ack_nak %d round %d\n",frameP,subframeP,harq_pid,harq_indication_fdd->mode,tmode[0],num_ack_nak,sched_ctl->round[CC_idP][harq_pid]); + LOG_D(MAC, "frame %d subframe %d harq_pid %d mode %d tmode[0] %d num_ack_nak %d round %d\n", + frameP, + subframeP, + harq_pid, + harq_indication_fdd->mode, + tmode[0], + num_ack_nak, + sched_ctl->round[CC_idP][harq_pid]); // use 1 HARQ proces of BL/CE UE for now if (UE_list->UE_template[pCCid][UE_id].rach_resource_type > 0) harq_pid = 0; switch (harq_indication_fdd->mode) { - case 0: // Format 1a/b (10.1.2.1) - AssertFatal(numCC == 1, - "numCC %d > 1, should not be using Format1a/b\n", - numCC); - if (tmode[0] == 1 || tmode[0] == 2 || tmode[0] == 5 || tmode[0] == 6 || tmode[0] == 7) { // NOTE: have to handle the case of TM9-10 with 1 antenna port - // single ACK/NAK bit - AssertFatal(num_ack_nak == 1, - "num_ack_nak %d > 1 for 1 CC and single-layer transmission frame:%d subframe:%d\n", - num_ack_nak,frameP,subframeP); - - // In case of nFAPI, sometimes timing of eNB and UE become different. - // So if nfapi_mode == 2(VNF) , this function don't check assertion to avoid process exit. - if (nfapi_mode != 2){ - AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8, - "Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n", - harq_pid, UE_id, rnti); - } else { - if(sched_ctl->round[CC_idP][harq_pid] == 8){ - LOG_E(MAC,"Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n",harq_pid, UE_id, rnti); - return; - } - } - AssertFatal(pdu[0] == 1 || pdu[0] == 2 - || pdu[0] == 4, - "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n", - pdu[0], harq_pid, UE_id, rnti); - LOG_D(MAC, "Received %d for harq_pid %d\n", pdu[0], - harq_pid); - - RA_t *ra = &RC.mac[mod_idP]->common_channels[CC_idP].ra[0]; - for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if ((ra[ra_i].rnti == rnti) && (ra[ra_i].state == MSGCRNTI_ACK) && - (ra[ra_i].crnti_harq_pid == harq_pid)) { - LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n",pdu[0],rnti,sched_ctl->round[CC_idP][harq_pid],frameP,subframeP); - if(pdu[0] == 1){ - cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); - }else{ - if(sched_ctl->round[CC_idP][harq_pid] == 7){ - cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti); - } - } - break; - } - } - - if (pdu[0] == 1) { // ACK - sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process - sched_ctl->tbcnt[CC_idP][harq_pid] = 0; - } else if (pdu[0] == 2 || pdu[0] == 4) { // NAK (treat DTX as NAK) - sched_ctl->round[CC_idP][harq_pid]++; // increment round - if (sched_ctl->round[CC_idP][harq_pid] == 4) { - sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process - sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + case 0: // Format 1a/b (10.1.2.1) + AssertFatal(numCC == 1, "numCC %d > 1, should not be using Format1a/b\n", + numCC); + + if (tmode[0] == 1 || tmode[0] == 2 || tmode[0] == 5 || tmode[0] == 6 || tmode[0] == 7) { // NOTE: have to handle the case of TM9-10 with 1 antenna port + // single ACK/NAK bit + AssertFatal(num_ack_nak == 1, "num_ack_nak %d > 1 for 1 CC and single-layer transmission frame:%d subframe:%d\n", + num_ack_nak, + frameP, + subframeP); + + // In case of nFAPI, sometimes timing of eNB and UE become different. + // So if nfapi_mode == 2(VNF), this function don't check assertion to avoid process exit. + if (NFAPI_MODE != NFAPI_MODE_VNF) { + AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8, "Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n", + harq_pid, + UE_id, + rnti); + } else { + if (sched_ctl->round[CC_idP][harq_pid] == 8) { + LOG_E(MAC,"Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n", + harq_pid, + UE_id, + rnti); + return; + } } - if (sched_ctl->round[CC_idP][harq_pid] == 8){ - for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { - if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)){ - //Msg NACK num to MAC ,remove UE - // add UE info to freeList - LOG_I(RRC, "put UE %x into freeList\n", rnti); - put_UE_in_freelist(mod_idP, rnti, 1); + + AssertFatal(pdu[0] == 1 || pdu[0] == 2 || pdu[0] == 4, "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n", + pdu[0], + harq_pid, + UE_id, + rnti); + LOG_D(MAC, "Received %d for harq_pid %d\n", + pdu[0], + harq_pid); + RA_t *ra = &eNB->common_channels[CC_idP].ra[0]; + + for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { + if (ra[ra_i].rnti == rnti && ra[ra_i].state == MSGCRNTI_ACK && ra[ra_i].crnti_harq_pid == harq_pid) { + LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n", + pdu[0], + rnti, + sched_ctl->round[CC_idP][harq_pid], + frameP, + subframeP); + + if (pdu[0] == 1) { + cancel_ra_proc(mod_idP, + CC_idP, + frameP, + ra[ra_i].rnti); + } else { + if (sched_ctl->round[CC_idP][harq_pid] == 7) { + cancel_ra_proc(mod_idP, + CC_idP, + frameP, + ra[ra_i].rnti); + } + } + + break; } - } } - } - } else { - // one or two ACK/NAK bits - AssertFatal(num_ack_nak <= 2, - "num_ack_nak %d > 2 for 1 CC and TM3/4/8/9/10\n", - num_ack_nak); - if ((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1) - && (pdu[0] == 1) && (pdu[1] == 1)) { - sched_ctl->round[CC_idP][harq_pid] = 8; - sched_ctl->tbcnt[CC_idP][harq_pid] = 0; - } - if ((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1) - && (pdu[0] == 2) && (pdu[1] == 2)) { - sched_ctl->round[CC_idP][harq_pid]++; - if (sched_ctl->round[CC_idP][harq_pid] == 4) { - sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + + LOG_D(MAC, "In extract_harq(): pdu[0] = %d for harq_pid = %d\n", pdu[0], harq_pid); + + if (pdu[0] == 1) { // ACK + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + + /* CDRX: PUCCH gives an ACK, so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; + + } else if (pdu[0] == 2 || pdu[0] == 4) { // NAK (treat DTX as NAK) + sched_ctl->round[CC_idP][harq_pid]++; // increment round + + if (sched_ctl->round[CC_idP][harq_pid] == 4) { + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + + /* CDRX: PUCCH gives an NACK and max number of repetitions reached so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; + } + + if (sched_ctl->round[CC_idP][harq_pid] == 8) { + for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) { + if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)) { + // Msg NACK num to MAC ,remove UE + // add UE info to freeList + LOG_I(RRC, "put UE %x into freeList\n", + rnti); + put_UE_in_freelist(mod_idP, + rnti, + 1); + } + } + } } - } - else if (((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[0][harq_pid] == 2) - && (pdu[0] == 1) && (pdu[1] == 2)) - || ((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[CC_idP][harq_pid] == 2) - && (pdu[0] == 2) && (pdu[1] == 1))) { - sched_ctl->round[CC_idP][harq_pid]++; - sched_ctl->tbcnt[CC_idP][harq_pid] = 1; - if (sched_ctl->round[CC_idP][harq_pid] == 4) { - sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process - sched_ctl->tbcnt[CC_idP][harq_pid] = 0; /* TODO: do we have to set it to 0? */ - } - } else if ((num_ack_nak == 2) - && (sched_ctl->round[CC_idP][harq_pid] < 8) - && (sched_ctl->tbcnt[CC_idP][harq_pid] == 2) - && (pdu[0] == 2) && (pdu[1] == 2)) { - sched_ctl->round[CC_idP][harq_pid]++; - if (sched_ctl->round[CC_idP][harq_pid] == 4) { - sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + } else { + // one or two ACK/NAK bits + AssertFatal(num_ack_nak <= 2, "num_ack_nak %d > 2 for 1 CC and TM3/4/8/9/10\n", + num_ack_nak); + + if (num_ack_nak == 2 && sched_ctl->round[CC_idP][harq_pid] < 8 && sched_ctl->tbcnt[CC_idP][harq_pid] == 1 && pdu[0] == 1 && pdu[1] == 1) { + sched_ctl->round[CC_idP][harq_pid] = 8; sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + + /* CDRX: PUCCH gives an ACK, so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; } + + if ((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[CC_idP][harq_pid] == 1) + && (pdu[0] == 2) && (pdu[1] == 2)) { + sched_ctl->round[CC_idP][harq_pid]++; + + if (sched_ctl->round[CC_idP][harq_pid] == 4) { + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + + /* CDRX: PUCCH gives an NACK and max number of repetitions reached so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; + } + } else if (((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[0][harq_pid] == 2) + && (pdu[0] == 1) && (pdu[1] == 2)) + || ((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[CC_idP][harq_pid] == 2) + && (pdu[0] == 2) && (pdu[1] == 1))) { + sched_ctl->round[CC_idP][harq_pid]++; + sched_ctl->tbcnt[CC_idP][harq_pid] = 1; + + if (sched_ctl->round[CC_idP][harq_pid] == 4) { + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; /* TODO: do we have to set it to 0? */ + + /* CDRX: PUCCH gives an NACK and max number of repetitions reached so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; + } + } else if ((num_ack_nak == 2) + && (sched_ctl->round[CC_idP][harq_pid] < 8) + && (sched_ctl->tbcnt[CC_idP][harq_pid] == 2) + && (pdu[0] == 2) && (pdu[1] == 2)) { + sched_ctl->round[CC_idP][harq_pid]++; + + if (sched_ctl->round[CC_idP][harq_pid] == 4) { + sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process + sched_ctl->tbcnt[CC_idP][harq_pid] = 0; + + /* CDRX: PUCCH gives an NACK and max number of repetitions reached so reset corresponding HARQ RTT */ + sched_ctl->harq_rtt_timer[CC_idP][harq_pid] = 0; + } + } else + AssertFatal(1 == 0, "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n", + num_ack_nak, + sched_ctl->round[CC_idP][harq_pid], + sched_ctl->round[CC_idP][harq_pid], + pdu[0], + pdu[1], + harq_pid, + UE_id, + rnti); } - else - AssertFatal(1 == 0, - "Illegal ACK/NAK/round combination (%d,%d,%d,%d,%d) for harq_pid %d, UE %d/%x\n", - num_ack_nak, - sched_ctl->round[CC_idP][harq_pid], - sched_ctl->round[CC_idP][harq_pid], pdu[0], - pdu[1], harq_pid, UE_id, rnti); - } - break; - case 1: // FDD Channel Selection (10.1.2.2.1), must be received for 2 serving cells - AssertFatal(numCC == 2, - "Should not receive harq indication with channel selection with %d active CCs\n", - numCC); - - if ((num_ack_nak == 2) - && (sched_ctl->round[pCCid][harq_pid] < 8) - && (sched_ctl->round[1 - pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 1) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - if (pdu[0] == 1) - sched_ctl->round[pCCid][harq_pid] = 8; - else { - sched_ctl->round[pCCid][harq_pid]++; - if (sched_ctl->round[pCCid][harq_pid] == 4) - sched_ctl->round[pCCid][harq_pid] = 8; - } - if (pdu[1] == 1) - sched_ctl->round[1 - pCCid][harq_pid] = 8; - else { - sched_ctl->round[1 - pCCid][harq_pid]++; - if (sched_ctl->round[1 - pCCid][harq_pid] == 4) - sched_ctl->round[1 - pCCid][harq_pid] = 8; - } - } // A=2 - else if ((num_ack_nak == 3) - && (sched_ctl->round[pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 2) - && (sched_ctl->round[1 - pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", - pdu[2]); - AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 2, - "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", - pCCid, harq_pid, UE_id, rnti); - AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1, - "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", - 1 - pCCid, harq_pid, UE_id, rnti); - if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK - sched_ctl->round[pCCid][harq_pid] = 8; - sched_ctl->tbcnt[pCCid][harq_pid] = 0; - } else if (((pdu[0] == 2) && (pdu[1] == 1)) || - ((pdu[0] == 1) && (pdu[1] == 2))) { - sched_ctl->round[pCCid][harq_pid]++; - sched_ctl->tbcnt[pCCid][harq_pid] = 1; - if (sched_ctl->round[pCCid][harq_pid] == 4) { - sched_ctl->round[pCCid][harq_pid] = 8; - sched_ctl->tbcnt[pCCid][harq_pid] = 0; /* TODO: do we have to set it to 0? */ + + break; + + case 1: // FDD Channel Selection (10.1.2.2.1), must be received for 2 serving cells + AssertFatal(numCC == 2, "Should not receive harq indication with channel selection with %d active CCs\n", + numCC); + + if ((num_ack_nak == 2) + && (sched_ctl->round[pCCid][harq_pid] < 8) + && (sched_ctl->round[1 - pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 1) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + + if (pdu[0] == 1) + sched_ctl->round[pCCid][harq_pid] = 8; + else { + sched_ctl->round[pCCid][harq_pid]++; + + if (sched_ctl->round[pCCid][harq_pid] == 4) + sched_ctl->round[pCCid][harq_pid] = 8; } - } else { - sched_ctl->round[pCCid][harq_pid]++; - if (sched_ctl->round[pCCid][harq_pid] == 4) { - sched_ctl->round[pCCid][harq_pid] = 8; - sched_ctl->tbcnt[pCCid][harq_pid] = 0; + + if (pdu[1] == 1) + sched_ctl->round[1 - pCCid][harq_pid] = 8; + else { + sched_ctl->round[1 - pCCid][harq_pid]++; + + if (sched_ctl->round[1 - pCCid][harq_pid] == 4) + sched_ctl->round[1 - pCCid][harq_pid] = 8; } - } + } // A=2 + else if ((num_ack_nak == 3) + && (sched_ctl->round[pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 2) + && (sched_ctl->round[1 - pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", + pdu[2]); + AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 2, "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", + pCCid, + harq_pid, + UE_id, + rnti); + AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 1, "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", + 1 - pCCid, + harq_pid, + UE_id, + rnti); + + if (pdu[0] == 1 && pdu[1] == 1) { // both ACK + sched_ctl->round[pCCid][harq_pid] = 8; + sched_ctl->tbcnt[pCCid][harq_pid] = 0; + } else if ((pdu[0] == 2 && pdu[1] == 1) || (pdu[0] == 1 && pdu[1] == 2)) { + sched_ctl->round[pCCid][harq_pid]++; + sched_ctl->tbcnt[pCCid][harq_pid] = 1; + + if (sched_ctl->round[pCCid][harq_pid] == 4) { + sched_ctl->round[pCCid][harq_pid] = 8; + sched_ctl->tbcnt[pCCid][harq_pid] = 0; /* TODO: do we have to set it to 0? */ + } + } else { + sched_ctl->round[pCCid][harq_pid]++; - if (pdu[2] == 1) - sched_ctl->round[1 - pCCid][harq_pid] = 8; - else { - sched_ctl->round[1 - pCCid][harq_pid]++; - if (sched_ctl->round[1 - pCCid][harq_pid] == 4) { - sched_ctl->round[1 - pCCid][harq_pid] = 8; + if (sched_ctl->round[pCCid][harq_pid] == 4) { + sched_ctl->round[pCCid][harq_pid] = 8; + sched_ctl->tbcnt[pCCid][harq_pid] = 0; + } } - } - } // A=3 primary cell has 2 TBs - else if ((num_ack_nak == 3) - && (sched_ctl->round[1 - pCCid][harq_pid] < 8) - && (sched_ctl->round[pCCid][harq_pid] < 8) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 1)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", - pdu[2]); - AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2, - "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", - 1 - pCCid, harq_pid, UE_id, rnti); - AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 1, - "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", - pCCid, harq_pid, UE_id, rnti); - if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK - sched_ctl->round[1 - pCCid][harq_pid] = 8; - sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; - } else if (((pdu[0] >= 2) && (pdu[1] == 1)) - || ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK - sched_ctl->round[1 - pCCid][harq_pid]++; - sched_ctl->tbcnt[1 - pCCid][harq_pid] = 1; - if (sched_ctl->round[1 - pCCid][harq_pid] == 4) { - sched_ctl->round[1 - pCCid][harq_pid] = 8; - sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; + + if (pdu[2] == 1) sched_ctl->round[1 - pCCid][harq_pid] = 8; + else { + sched_ctl->round[1 - pCCid][harq_pid]++; + + if (sched_ctl->round[1 - pCCid][harq_pid] == 4) { + sched_ctl->round[1 - pCCid][harq_pid] = 8; + } } - } else { // both NAK/DTX - sched_ctl->round[1 - pCCid][harq_pid]++; - if (sched_ctl->round[1 - pCCid][harq_pid] == 4) { - sched_ctl->round[1 - pCCid][harq_pid] = 8; - sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; + } // A=3 primary cell has 2 TBs + else if ((num_ack_nak == 3) + && (sched_ctl->round[1 - pCCid][harq_pid] < 8) + && (sched_ctl->round[pCCid][harq_pid] < 8) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 1)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", + pdu[2]); + AssertFatal(sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2, "sched_ctl->tbcnt[%d][%d] != 2 for UE %d/%x\n", + 1 - pCCid, + harq_pid, + UE_id, + rnti); + AssertFatal(sched_ctl->tbcnt[pCCid][harq_pid] == 1, "sched_ctl->tbcnt[%d][%d] != 1 for UE %d/%x\n", + pCCid, + harq_pid, + UE_id, + rnti); + + if (pdu[0] == 1 && pdu[1] == 1) { // both ACK + sched_ctl->round[1 - pCCid][harq_pid] = 8; + sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; + } else if ((pdu[0] >= 2 && pdu[1] == 1) || (pdu[0] == 1 && pdu[1] >= 2)) { // one ACK + sched_ctl->round[1 - pCCid][harq_pid]++; + sched_ctl->tbcnt[1 - pCCid][harq_pid] = 1; + + if (sched_ctl->round[1 - pCCid][harq_pid] == 4) { + sched_ctl->round[1 - pCCid][harq_pid] = 8; + sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; + } + } else { // both NAK/DTX + sched_ctl->round[1 - pCCid][harq_pid]++; + + if (sched_ctl->round[1 - pCCid][harq_pid] == 4) { + sched_ctl->round[1 - pCCid][harq_pid] = 8; + sched_ctl->tbcnt[1 - pCCid][harq_pid] = 0; + } } - } - if (pdu[2] == 1) - sched_ctl->round[pCCid][harq_pid] = 8; - else { - sched_ctl->round[pCCid][harq_pid]++; - if (sched_ctl->round[pCCid][harq_pid] == 4) { - sched_ctl->round[pCCid][harq_pid] = 8; + if (pdu[2] == 1) sched_ctl->round[pCCid][harq_pid] = 8; + else { + sched_ctl->round[pCCid][harq_pid]++; + + if (sched_ctl->round[pCCid][harq_pid] == 4) { + sched_ctl->round[pCCid][harq_pid] = 8; + } } - } - } // A=3 secondary cell has 2 TBs + } // A=3 secondary cell has 2 TBs + #if MAX_NUM_CCs>1 - else if ((num_ack_nak == 4) - && (sched_ctl->round[0][harq_pid] < 8) - && (sched_ctl->round[1][harq_pid] < 8) - && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) - && (sched_ctl->tbcnt[pCCid][harq_pid] == 2)) { - AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", - pdu[0]); - AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", - pdu[1]); - AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", - pdu[2]); - AssertFatal(pdu[3] <= 3, "pdu[3] %d is not ACK/NAK/DTX\n", - pdu[3]); - AssertFatal(sched_ctl->tbcnt[0][harq_pid] == 2, - "sched_ctl->tbcnt[0][%d] != 2 for UE %d/%x\n", - harq_pid, UE_id, rnti); - AssertFatal(sched_ctl->tbcnt[1][harq_pid] == 2, - "sched_ctl->tbcnt[1][%d] != 2 for UE %d/%x\n", - harq_pid, UE_id, rnti); - if ((pdu[0] == 1) && (pdu[1] == 1)) { // both ACK - sched_ctl->round[0][harq_pid] = 8; - sched_ctl->tbcnt[0][harq_pid] = 0; - } else if (((pdu[0] >= 2) && (pdu[1] == 1)) - || ((pdu[0] == 1) && (pdu[1] >= 2))) { // one ACK - sched_ctl->round[0][harq_pid]++; - sched_ctl->tbcnt[0][harq_pid] = 1; - if (sched_ctl->round[0][harq_pid] == 4) { - sched_ctl->round[0][harq_pid] = 8; - sched_ctl->tbcnt[0][harq_pid] = 0; - } - } else { // both NAK/DTX - sched_ctl->round[0][harq_pid]++; - if (sched_ctl->round[0][harq_pid] == 4) { - sched_ctl->round[0][harq_pid] = 8; - sched_ctl->tbcnt[0][harq_pid] = 0; - } - } + else if ((num_ack_nak == 4) + && (sched_ctl->round[0][harq_pid] < 8) + && (sched_ctl->round[1][harq_pid] < 8) + && (sched_ctl->tbcnt[1 - pCCid][harq_pid] == 2) + && (sched_ctl->tbcnt[pCCid][harq_pid] == 2)) { + AssertFatal(pdu[0] <= 3, "pdu[0] %d is not ACK/NAK/DTX\n", + pdu[0]); + AssertFatal(pdu[1] <= 3, "pdu[1] %d is not ACK/NAK/DTX\n", + pdu[1]); + AssertFatal(pdu[2] <= 3, "pdu[2] %d is not ACK/NAK/DTX\n", + pdu[2]); + AssertFatal(pdu[3] <= 3, "pdu[3] %d is not ACK/NAK/DTX\n", + pdu[3]); + AssertFatal(sched_ctl->tbcnt[0][harq_pid] == 2, "sched_ctl->tbcnt[0][%d] != 2 for UE %d/%x\n", + harq_pid, + UE_id, + rnti); + AssertFatal(sched_ctl->tbcnt[1][harq_pid] == 2, "sched_ctl->tbcnt[1][%d] != 2 for UE %d/%x\n", + harq_pid, + UE_id, + rnti); + + if (pdu[0] == 1 && pdu[1] == 1) { // both ACK + sched_ctl->round[0][harq_pid] = 8; + sched_ctl->tbcnt[0][harq_pid] = 0; + } else if ((pdu[0] >= 2 && pdu[1] == 1) || (pdu[0] == 1 && pdu[1] >= 2)) { // one ACK + sched_ctl->round[0][harq_pid]++; + sched_ctl->tbcnt[0][harq_pid] = 1; + + if (sched_ctl->round[0][harq_pid] == 4) { + sched_ctl->round[0][harq_pid] = 8; + sched_ctl->tbcnt[0][harq_pid] = 0; + } + } else { // both NAK/DTX + sched_ctl->round[0][harq_pid]++; - if ((pdu[2] == 1) && (pdu[3] == 1)) { // both ACK - sched_ctl->round[1][harq_pid] = 8; - sched_ctl->tbcnt[1][harq_pid] = 0; - } else if (((pdu[2] >= 2) && (pdu[3] == 1)) - || ((pdu[2] == 1) && (pdu[3] >= 2))) { // one ACK - sched_ctl->round[1][harq_pid]++; - sched_ctl->tbcnt[1][harq_pid] = 1; - if (sched_ctl->round[1][harq_pid] == 4) { - sched_ctl->round[1][harq_pid] = 8; - sched_ctl->tbcnt[1][harq_pid] = 0; + if (sched_ctl->round[0][harq_pid] == 4) { + sched_ctl->round[0][harq_pid] = 8; + sched_ctl->tbcnt[0][harq_pid] = 0; + } } - } else { // both NAK/DTX - sched_ctl->round[1][harq_pid]++; - if (sched_ctl->round[1][harq_pid] == 4) { - sched_ctl->round[1][harq_pid] = 8; - sched_ctl->tbcnt[1][harq_pid] = 0; + + if (pdu[2] == 1 && pdu[3] == 1) { // both ACK + sched_ctl->round[1][harq_pid] = 8; + sched_ctl->tbcnt[1][harq_pid] = 0; + } else if ((pdu[2] >= 2 && pdu[3] == 1) || (pdu[2] == 1 && pdu[3] >= 2)) { // one ACK + sched_ctl->round[1][harq_pid]++; + sched_ctl->tbcnt[1][harq_pid] = 1; + + if (sched_ctl->round[1][harq_pid] == 4) { + sched_ctl->round[1][harq_pid] = 8; + sched_ctl->tbcnt[1][harq_pid] = 0; + } + } else { // both NAK/DTX + sched_ctl->round[1][harq_pid]++; + + if (sched_ctl->round[1][harq_pid] == 4) { + sched_ctl->round[1][harq_pid] = 8; + sched_ctl->tbcnt[1][harq_pid] = 0; + } } - } - } // A=4 both serving cells have 2 TBs + } // A=4 both serving cells have 2 TBs + #endif - break; - case 2: // Format 3 - AssertFatal(numCC > 2, - "Should not receive harq indication with FDD format 3 with %d < 3 active CCs\n", - numCC); - for (i = 0, j = 0; i < numCC; i++) { - if ((sched_ctl->round[i][harq_pid] < 8)) { - if (tmode[i] == 1 || tmode[i] == 2 || tmode[0] == 5 - || tmode[0] == 6 || tmode[0] == 7) { - if (pdu[j] == 1) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } else if (pdu[j] == 2) { - sched_ctl->round[i][harq_pid]++; - if (sched_ctl->round[i][harq_pid] == 4) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; + break; + + case 2: // Format 3 + AssertFatal(numCC > 2, "Should not receive harq indication with FDD format 3 with %d < 3 active CCs\n", + numCC); + + for (i = 0, j = 0; i < numCC; i++) { + if (sched_ctl->round[i][harq_pid] < 8) { + if (tmode[i] == 1 || tmode[i] == 2 || tmode[0] == 5 || tmode[0] == 6 || tmode[0] == 7) { + if (pdu[j] == 1) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } else if (pdu[j] == 2) { + sched_ctl->round[i][harq_pid]++; + + if (sched_ctl->round[i][harq_pid] == 4) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } + } else + AssertFatal(1 == 0, "Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n", + i, + harq_pid, + pdu[j], + UE_id, + rnti); + + j++; + } else if (spatial_bundling == 0) { + if (sched_ctl->tbcnt[i][harq_pid] == 2 && pdu[j] == 1 && pdu[j + 1] == 1) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } else if (sched_ctl->tbcnt[i][harq_pid] == 2 && pdu[j] == 1 && pdu[j + 1] == 2) { + sched_ctl->round[i][harq_pid]++; + sched_ctl->tbcnt[i][harq_pid] = 1; + + if (sched_ctl->round[i][harq_pid] == 4) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } + } else if (sched_ctl->tbcnt[i][harq_pid] == 2 && pdu[j] == 2 && pdu[j + 1] == 1) { + sched_ctl->round[i][harq_pid]++; + sched_ctl->tbcnt[i][harq_pid] = 1; + + if (sched_ctl->round[i][harq_pid] == 4) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } + } else if (sched_ctl->tbcnt[i][harq_pid] == 2 && pdu[j] == 2 && pdu[j + 1] == 2) { + sched_ctl->round[i][harq_pid]++; + + if (sched_ctl->round[i][harq_pid] == 4) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } + } else + AssertFatal(1 == 0, "Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n", + i, + harq_pid, + sched_ctl->tbcnt[i][harq_pid], + pdu[j], + pdu[j + 1], + UE_id, + rnti); + + j += 2; + } else if (spatial_bundling == 1) { + if (pdu[j] == 1) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } else if (pdu[j] == 2) { + sched_ctl->round[i][harq_pid]++; + + if (sched_ctl->round[i][harq_pid] == 4) { + sched_ctl->round[i][harq_pid] = 8; + sched_ctl->tbcnt[i][harq_pid] = 0; + } + } else { + AssertFatal(1 == 0, "Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n", + pdu[j], + i, + harq_pid, + UE_id, + rnti); } + + j++; + } else { + AssertFatal(1 == 0, "Illegal value for spatial_bundling %d\n", + spatial_bundling); } - else - AssertFatal(1 == 0, - "Illegal harq_ack value for CC %d harq_pid %d (%d) UE %d/%x\n", - i, harq_pid, pdu[j], UE_id, rnti); - j++; - } else if (spatial_bundling == 0) { - if ((sched_ctl->tbcnt[i][harq_pid] == 2) - && (pdu[j] == 1) && (pdu[j + 1] == 1)) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) - && (pdu[j] == 1) && (pdu[j + 1] == 2)) { - sched_ctl->round[i][harq_pid]++; - sched_ctl->tbcnt[i][harq_pid] = 1; - if (sched_ctl->round[i][harq_pid] == 4) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } - } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) - && (pdu[j] == 2) && (pdu[j + 1] == 1)) { - sched_ctl->round[i][harq_pid]++; - sched_ctl->tbcnt[i][harq_pid] = 1; - if (sched_ctl->round[i][harq_pid] == 4) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } - } else if ((sched_ctl->tbcnt[i][harq_pid] == 2) - && (pdu[j] == 2) && (pdu[j + 1] == 2)) { - sched_ctl->round[i][harq_pid]++; - if (sched_ctl->round[i][harq_pid] == 4) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } - } else - AssertFatal(1 == 0, - "Illegal combination for CC %d harq_pid %d (%d,%d,%d) UE %d/%x\n", - i, harq_pid, - sched_ctl->tbcnt[i][harq_pid], - pdu[j], pdu[j + 1], UE_id, rnti); - j += 2; - } else if (spatial_bundling == 1) { - if (pdu[j] == 1) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } else if (pdu[j] == 2) { - sched_ctl->round[i][harq_pid]++; - if (sched_ctl->round[i][harq_pid] == 4) { - sched_ctl->round[i][harq_pid] = 8; - sched_ctl->tbcnt[i][harq_pid] = 0; - } - } else - AssertFatal(1 == 0, - "Illegal hack_nak value %d for CC %d harq_pid %d UE %d/%x\n", - pdu[j], i, harq_pid, UE_id, rnti); - j++; - } else - AssertFatal(1 == 0, - "Illegal value for spatial_bundling %d\n", - spatial_bundling); - } - } - break; - case 3: // Format 4 - AssertFatal(1 == 0, - "Should not receive harq indication with Format 4\n"); - break; - case 4: // Format 5 - AssertFatal(1 == 0, - "Should not receive harq indication with Format 5\n"); - break; + } + } + + break; + + case 3: // Format 4 + AssertFatal(1 == 0, "Should not receive harq indication with Format 4\n"); + break; + + case 4: // Format 5 + AssertFatal(1 == 0, "Should not receive harq indication with Format 5\n"); + break; } } + + return; } +//------------------------------------------------------------------------------ void -extract_pucch_csi(module_id_t mod_idP, int CC_idP, int UE_id, - frame_t frameP, sub_frame_t subframeP, - uint8_t * pdu, uint8_t length) +extract_pucch_csi(module_id_t mod_idP, + int CC_idP, + int UE_id, + frame_t frameP, + sub_frame_t subframeP, + uint8_t *pdu, + uint8_t length) +//------------------------------------------------------------------------------ { UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic; int no_pmi; uint8_t Ltab[6] = { 0, 2, 4, 4, 4, 4 }; uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; int feedback_cnt; - - AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, - "physicalConfigDedicated is null for UE %d\n", UE_id); - AssertFatal(UE_list-> - UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, - "cqi_ReportConfig is null for UE %d\n", UE_id); - AssertFatal((cqi_ReportPeriodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) != NULL, - "cqi_ReportPeriodic is null for UE %d\n", UE_id); - + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n", + UE_id); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, "cqi_ReportConfig is null for UE %d\n", + UE_id); + struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic; + AssertFatal(cqi_ReportPeriodic != NULL, "cqi_ReportPeriodic is null for UE %d\n", + UE_id); // determine feedback mode - AssertFatal(cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->present == LTE_CQI_ReportPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_NOTHING, "cqi_ReportPeriodic->present == LTE_CQI_ReportPeriodic_PR_NOTHING!\n"); AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); - + "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); uint16_t Npd, N_OFFSET_CQI; int H, K, bandwidth_part, L, Lmask; int ri = sched_ctl->periodic_ri_received[CC_idP]; - - get_csi_params(cc, cqi_ReportPeriodic, &Npd, &N_OFFSET_CQI, &H); + get_csi_params(cc, + cqi_ReportPeriodic, + &Npd, + &N_OFFSET_CQI, + &H); K = (H - 1) / Jtab[cc->mib->message.dl_Bandwidth]; L = Ltab[cc->mib->message.dl_Bandwidth]; Lmask = L - 1; feedback_cnt = (((frameP * 10) + subframeP) / Npd) % H; - if (feedback_cnt > 0) - bandwidth_part = (feedback_cnt - 1) % K; - else - bandwidth_part = 0; - - switch (get_tmode(mod_idP, CC_idP, UE_id)) { - case 1: - case 2: - case 3: - case 7: - no_pmi = 1; - break; - case 4: - case 5: - case 6: - no_pmi = 0; - break; - default: - // note: need to check TM8-10 without PMI/RI or with 1 antenna port (see Section 5.2.3.3.1 from 36.213) - no_pmi = 0; + if (feedback_cnt > 0) bandwidth_part = (feedback_cnt - 1) % K; + else bandwidth_part = 0; + + switch (get_tmode(mod_idP, + CC_idP, + UE_id)) { + case 1: + case 2: + case 3: + case 7: + no_pmi = 1; + break; + + case 4: + case 5: + case 6: + no_pmi = 0; + break; + + default: + // note: need to check TM8-10 without PMI/RI or with 1 antenna port (see Section 5.2.3.3.1 from 36.213) + no_pmi = 0; + break; } - if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) - || (feedback_cnt == 0)) { + if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI || + feedback_cnt == 0) { // Note: This implements only Tables: 5.3.3.1-1,5.3.3.1-1A and 5.3.3.1-2 from 36.213 (1,2,4 antenna ports Wideband CQI/PMI) - - if (no_pmi == 1) { // get spatial_diffcqi if needed + if (no_pmi == 1) { // get spatial_diffcqi if needed sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = - (pdu[0] >> 4) & 7; - } else if ((cc->p_eNB == 2) && (ri == 1)) { + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = (pdu[0] >> 4) & 7; + } else if (cc->p_eNB == 2 && ri == 1) { // p=2 Rank 1 wideband CQI/PMI 6 bits sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 4) & 3; - } else if ((cc->p_eNB == 2) && (ri > 1)) { + } else if (cc->p_eNB == 2 && ri > 1) { // p=2 Rank 2 wideband CQI/PMI 8 bits sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = - (pdu[0] >> 4) & 7; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = (pdu[0] >> 4) & 7; sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 1; - } else if ((cc->p_eNB == 4) && (ri == 1)) { + } else if (cc->p_eNB == 4 && ri == 1) { // p=4 Rank 1 wideband CQI/PMI 8 bits sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_pmi[CC_idP] = - (pdu[0] >> 4) & 0x0F; - } else if ((cc->p_eNB == 4) && (ri > 1)) { + sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 4) & 0x0F; + } else if (cc->p_eNB == 4 && ri > 1) { // p=4 Rank 2 wideband CQI/PMI 11 bits sched_ctl->periodic_wideband_cqi[CC_idP] = pdu[0] & 0xF; - sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = - (pdu[0] >> 4) & 7; + sched_ctl->periodic_wideband_spatial_diffcqi[CC_idP] = (pdu[0] >> 4) & 7; sched_ctl->periodic_wideband_pmi[CC_idP] = (pdu[0] >> 7) & 0xF; } else - AssertFatal(1 == 0, - "illegal combination p %d, ri %d, no_pmi %d\n", - cc->p_eNB, ri, no_pmi); - } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) - { - // This is Table 5.2.3.3.2-2 for 36.213 - if (ri == 1) { - //4+Ltab[cc->mib->message.dl_Bandwidth] bits - sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) +((pdu[0] >> 4) & Lmask)] = pdu[0] & 0xF; - } else if (ri > 1) { - //7+Ltab[cc->mib->message.dl_Bandwidth] bits; - sched_ctl->periodic_subband_spatial_diffcqi[CC_idP][(bandwidth_part * L) + ((pdu[0] >> 7) & Lmask)] = (pdu[0] >> 4) & 7; - sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) + ((pdu[0] >> 7) & Lmask)] = - pdu[0] & 0xF; - } + AssertFatal(1 == 0, "illegal combination p %d, ri %d, no_pmi %d\n", + cc->p_eNB, + ri, + no_pmi); + } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { + // This is Table 5.2.3.3.2-2 for 36.213 + if (ri == 1) { + //4+Ltab[cc->mib->message.dl_Bandwidth] bits + sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) +((pdu[0] >> 4) & Lmask)] = pdu[0] & 0xF; + } else if (ri > 1) { + //7+Ltab[cc->mib->message.dl_Bandwidth] bits; + sched_ctl->periodic_subband_spatial_diffcqi[CC_idP][(bandwidth_part * L) + ((pdu[0] >> 7) & Lmask)] = (pdu[0] >> 4) & 7; + sched_ctl->periodic_subband_cqi[CC_idP][(bandwidth_part * L) + ((pdu[0] >> 7) & Lmask)] = pdu[0] & 0xF; } + } + + return; } +//------------------------------------------------------------------------------ void -extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, - frame_t frameP, sub_frame_t subframeP, - uint8_t * pdu, uint8_t length) +extract_pusch_csi(module_id_t mod_idP, + int CC_idP, + int UE_id, + frame_t frameP, + sub_frame_t subframeP, + uint8_t *pdu, + uint8_t length) +//------------------------------------------------------------------------------ { UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; @@ -4141,15 +4695,14 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, int i; uint64_t p = *(uint64_t *) pdu; int curbyte, curbit; - LTE_CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic; - - AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, - "physicalConfigDedicated is null for UE %d\n", UE_id); - AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, - "cqi_ReportConfig is null for UE %d\n", UE_id); - AssertFatal((cqi_ReportModeAperiodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) != NULL, - "cqi_ReportModeAperiodic is null for UE %d\n", UE_id); - + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n", + UE_id); + AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig != NULL, "cqi_ReportConfig is null for UE %d\n", + UE_id); + LTE_CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic + = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; + AssertFatal(cqi_ReportModeAperiodic != NULL, "cqi_ReportModeAperiodic is null for UE %d\n", + UE_id); int N = Ntab[cc->mib->message.dl_Bandwidth]; int tmode = get_tmode(mod_idP, CC_idP, UE_id); int ri = sched_ctl->aperiodic_ri_received[CC_idP]; @@ -4158,277 +4711,313 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, int m; switch (*cqi_ReportModeAperiodic) { - case LTE_CQI_ReportModeAperiodic_rm12: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - // wideband multiple PMI (TM4/6), Table 5.2.2.6.1-1 (for TM4/6) - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm12\n", - tmode); - if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 - if ((ri == 1) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x03); - p >>= 2; - } - } - if ((ri == 2) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); - p >>= 4; - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); - p >>= 1; - } - } - if ((ri == 1) && (cc->p_eNB == 4)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x03); - p >>= 4; - } - } - if ((ri == 2) && (cc->p_eNB == 4)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); - p >>= 4; - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); - p >>= 4; - } + case LTE_CQI_ReportModeAperiodic_rm12: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + // wideband multiple PMI (TM4/6), Table 5.2.2.6.1-1 (for TM4/6) + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm12\n", + tmode); + + if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 + if (ri == 1 && cc->p_eNB == 2) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x03); + p >>= 2; + } + } + + if (ri == 2 && cc->p_eNB == 2) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); + p >>= 1; + } + } + + if (ri == 1 && cc->p_eNB == 4) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x03); + p >>= 4; + } + } + + if (ri == 2 && cc->p_eNB == 4) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); + p >>= 4; + } + } + } // if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 + else { + AssertFatal(1 == 0, "support for TM 8-10 to be done\n"); } - } // if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213 - else { - AssertFatal(1 == 0, "support for TM 8-10 to be done\n"); - } - break; - case LTE_CQI_ReportModeAperiodic_rm20: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - // UE-selected subband CQI no PMI (TM1/2/3/7) , Table 5.2.2.6.3-1 from 36.213 - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 - || tmode == 7, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm20\n", - tmode); - - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); - p >>= 4; - diffcqi0 = (uint8_t) (p & 0x03); - p >>= 2; - r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); - reverse_index(Ntab_uesel[bw], Mtab_uesel[bw], r, v); - for (m = 0; m < Mtab_uesel[bw]; m++) - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; - break; - case LTE_CQI_ReportModeAperiodic_rm22: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - // UE-selected subband CQI multiple PMI (TM4/6) Table 5.2.2.6.3-2 from 36.213 - - AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm22\n", - tmode); - - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); - p >>= 4; - diffcqi0 = (uint8_t) (p & 0x03); - p >>= 2; - - if (ri > 1) { - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); + break; + + case LTE_CQI_ReportModeAperiodic_rm20: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + // UE-selected subband CQI no PMI (TM1/2/3/7) , Table 5.2.2.6.3-1 from 36.213 + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7, "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm20\n", + tmode); + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); p >>= 4; - diffcqi1 = (uint8_t) (p & 0x03); + diffcqi0 = (uint8_t) (p & 0x03); p >>= 2; - } - r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); - p >>= Ltab_uesel[bw]; - reverse_index(Ntab_uesel[bw], Mtab_uesel[bw], r, v); - if ((ri == 1) && (cc->p_eNB == 2)) { - pmi_uesel = p & 0x3; - p >>= 2; - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x3; - } else if ((ri == 2) && (cc->p_eNB == 2)) { - pmi_uesel = p & 0x1; - p >>= 1; - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x1; - } else if (cc->p_eNB == 4) { - pmi_uesel = p & 0x0F; - p >>= 4; - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; - } - for (m = 0; m < Mtab_uesel[bw]; m++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; - if (ri > 1) - sched_ctl->aperiodic_subband_diffcqi1[CC_idP][v[m]] = - diffcqi1; - sched_ctl->aperiodic_subband_pmi[CC_idP][v[m]] = pmi_uesel; - } - break; - case LTE_CQI_ReportModeAperiodic_rm30: - //subband CQI no PMI (TM1/2/3/7) - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 - || tmode == 7, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm30\n", - tmode); - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = pdu[0] >> 4; - curbyte = 0; - curbit = 3; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = - (pdu[curbyte] >> (curbit - 1)) & 0x03; - curbit -= 2; - if (curbit < 0) { - curbit = 7; - curbyte++; + r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); + reverse_index(Ntab_uesel[bw], + Mtab_uesel[bw], + r, + v); + + for (m = 0; m < Mtab_uesel[bw]; m++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; } - } - sched_ctl->dl_cqi[CC_idP] = - sched_ctl->aperiodic_wideband_cqi0[CC_idP]; - break; - case LTE_CQI_ReportModeAperiodic_rm31: - AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); - //subband CQI single PMI (TM4/5/6) - AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 - || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm31\n", - tmode); - - if ((ri == 1) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); + + break; + + case LTE_CQI_ReportModeAperiodic_rm22: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + // UE-selected subband CQI multiple PMI (TM4/6) Table 5.2.2.6.3-2 from 36.213 + AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm22\n", + tmode); + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = - (uint8_t) (p & 0x03); - p >>= 2; + diffcqi0 = (uint8_t) (p & 0x03); + p >>= 2; + + if (ri > 1) { + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = + (uint8_t) (p & 0x0F); + p >>= 4; + diffcqi1 = (uint8_t) (p & 0x03); + p >>= 2; } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x03; - } - if ((ri == 2) && (cc->p_eNB == 2)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; + + r = (uint8_t) (p & ((1 >> Ltab_uesel[bw]) - 1)); + p >>= Ltab_uesel[bw]; + reverse_index(Ntab_uesel[bw], + Mtab_uesel[bw], + r, + v); + + if (ri == 1 && cc->p_eNB == 2) { + pmi_uesel = p & 0x3; + p >>= 2; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x3; + } else if (ri == 2 && cc->p_eNB == 2) { + pmi_uesel = p & 0x1; + p >>= 1; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x1; + } else if (cc->p_eNB == 4) { + pmi_uesel = p & 0x0F; + p >>= 4; + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; } - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; + + for (m = 0; m < Mtab_uesel[bw]; m++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; + + if (ri > 1) sched_ctl->aperiodic_subband_diffcqi1[CC_idP][v[m]] = diffcqi1; + + sched_ctl->aperiodic_subband_pmi[CC_idP][v[m]] = pmi_uesel; } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x01; - } - if ((ri == 1) && (cc->p_eNB == 4)) { - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; + + break; + + case LTE_CQI_ReportModeAperiodic_rm30: + //subband CQI no PMI (TM1/2/3/7) + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7, "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm30\n", + tmode); + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = pdu[0] >> 4; + curbyte = 0; + curbit = 3; + for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = - (uint8_t) (p & 0x03); - p >>= 2; + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = + (pdu[curbyte] >> (curbit - 1)) & 0x03; + curbit -= 2; + + if (curbit < 0) { + curbit = 7; + curbyte++; + } } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; - } - if ((ri > 1) && (cc->p_eNB == 4)) { // Note : 64 bits for 20 MHz - sched_ctl->aperiodic_wideband_cqi0[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 1; + + sched_ctl->dl_cqi[CC_idP] = sched_ctl->aperiodic_wideband_cqi0[CC_idP]; + break; + + case LTE_CQI_ReportModeAperiodic_rm31: + AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); + //subband CQI single PMI (TM4/5/6) + AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm31\n", + tmode); + + if (ri == 1 && cc->p_eNB == 2) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = (uint8_t) (p & 0x03); + p >>= 2; + } + + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x03; } - sched_ctl->aperiodic_wideband_cqi1[CC_idP] = - (uint8_t) (p & 0x0F); - p >>= 4; - for (i = 0; i < N; i++) { - sched_ctl->aperiodic_subband_pmi[CC_idP][i] = - (uint8_t) (p & 0x01); - p >>= 2; + + if (ri == 2 && cc->p_eNB == 2) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); + p >>= 1; + } + + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); + p >>= 1; + } + + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x01; } - sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; - } - break; + if (ri == 1 && cc->p_eNB == 4) { + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = (uint8_t) (p & 0x03); + p >>= 2; + } + + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + + if (ri > 1 && cc->p_eNB == 4) { // Note : 64 bits for 20 MHz + sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); + p >>= 1; + } + + sched_ctl->aperiodic_wideband_cqi1[CC_idP] = (uint8_t) (p & 0x0F); + p >>= 4; + + for (i = 0; i < N; i++) { + sched_ctl->aperiodic_subband_pmi[CC_idP][i] = (uint8_t) (p & 0x01); + p >>= 2; + } + + sched_ctl->aperiodic_wideband_pmi[CC_idP] = p & 0x0F; + } + + break; #if (LTE_RRC_VERSION >= MAKE_VERSION(12, 5, 0)) - case LTE_CQI_ReportModeAperiodic_rm32_v1250: - AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 - || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm32\n", - tmode); - AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm32 to be done\n"); - break; + + case LTE_CQI_ReportModeAperiodic_rm32_v1250: + AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm32\n", + tmode); + AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm32 to be done\n"); + break; #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 1, 0)) - case LTE_CQI_ReportModeAperiodic_rm10_v1310: - AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 - || tmode == 7, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm10\n", - tmode); - AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm10 to be done\n"); - break; - case LTE_CQI_ReportModeAperiodic_rm11_v1310: - AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 - || tmode == 9 - || tmode == 10, - "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm11\n", - tmode); - AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm11 to be done\n"); - break; + + case LTE_CQI_ReportModeAperiodic_rm10_v1310: + AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7, "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm10\n", + tmode); + AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm10 to be done\n"); + break; + + case LTE_CQI_ReportModeAperiodic_rm11_v1310: + AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, + "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm11\n", + tmode); + AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm11 to be done\n"); + break; #endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 1, 0)) */ } + + return; } +//------------------------------------------------------------------------------ void -cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, - sub_frame_t subframeP, rnti_t rntiP, - nfapi_cqi_indication_rel9_t * rel9, uint8_t * pdu, - nfapi_ul_cqi_information_t * ul_cqi_information) +cqi_indication(module_id_t mod_idP, + int CC_idP, + frame_t frameP, + sub_frame_t subframeP, + rnti_t rntiP, + nfapi_cqi_indication_rel9_t *rel9, + uint8_t *pdu, + nfapi_ul_cqi_information_t *ul_cqi_information) +//------------------------------------------------------------------------------ { int UE_id = find_UE_id(mod_idP, rntiP); UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + if (UE_id == -1) { LOG_W(MAC, "cqi_indication: UE %x not found\n", rntiP); return; } + UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; if (UE_id >= 0) { + LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n", + __FUNCTION__, + UE_id, + ul_cqi_information->channel, + ul_cqi_information->ul_cqi); - LOG_D(MAC,"%s() UE_id:%d channel:%d cqi:%d\n", __FUNCTION__, UE_id, ul_cqi_information->channel, ul_cqi_information->ul_cqi); - - if (ul_cqi_information->channel == 0) { // PUCCH - + if (ul_cqi_information->channel == 0) { // PUCCH // extract pucch csi information before changing RI information - extract_pucch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP, - pdu, rel9->length); - + extract_pucch_csi(mod_idP, + CC_idP, + UE_id, + frameP, + subframeP, + pdu, rel9->length); memcpy((void *) sched_ctl->periodic_ri_received, - (void *) rel9->ri, rel9->number_of_cc_reported); - + (void *) rel9->ri, + rel9->number_of_cc_reported); // SNR for PUCCH2 sched_ctl->pucch2_snr[CC_idP] = ul_cqi_information->ul_cqi; - } else { //PUSCH + } else { //PUSCH memcpy((void *) sched_ctl->aperiodic_ri_received, - (void *) rel9->ri, rel9->number_of_cc_reported); - - extract_pusch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP, - pdu, rel9->length); - - LOG_D(MAC,"Frame %d Subframe %d update CQI:%d\n",frameP,subframeP,sched_ctl->dl_cqi[CC_idP]); - + (void *) rel9->ri, + rel9->number_of_cc_reported); + extract_pusch_csi(mod_idP, + CC_idP, + UE_id, + frameP, + subframeP, + pdu, + rel9->length); + LOG_D(MAC,"Frame %d Subframe %d update CQI:%d\n", + frameP, + subframeP, + sched_ctl->dl_cqi[CC_idP]); sched_ctl->cqi_req_flag &= (~(1 << subframeP)); sched_ctl->cqi_received = 1; } @@ -4437,146 +5026,242 @@ cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sched_ctl->timing_advance = rel9->timing_advance; sched_ctl->timing_advance_r9 = rel9->timing_advance_r9; } + + return; } +//------------------------------------------------------------------------------ void -SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, - sub_frame_t subframeP, rnti_t rntiP, uint8_t ul_cqi) +SR_indication(module_id_t mod_idP, + int cc_idP, + frame_t frameP, + sub_frame_t subframeP, + rnti_t rntiP, + uint8_t ul_cqi) +//------------------------------------------------------------------------------ { - T(T_ENB_MAC_SCHEDULING_REQUEST, T_INT(mod_idP), T_INT(cc_idP), - T_INT(frameP), T_INT(subframeP), T_INT(rntiP)); - + T(T_ENB_MAC_SCHEDULING_REQUEST, + T_INT(mod_idP), + T_INT(cc_idP), + T_INT(frameP), + T_INT(subframeP), + T_INT(rntiP)); int UE_id = find_UE_id(mod_idP, rntiP); UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; + UE_sched_ctrl *UE_scheduling_ctrl = NULL; if (UE_id != -1) { - if (mac_eNB_get_rrc_status(mod_idP, UE_RNTI(mod_idP, UE_id)) < - RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n", - mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); - - UE_list->UE_template[cc_idP][UE_id].ul_SR = 1; - UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0); + UE_scheduling_ctrl = &(UE_list->UE_sched_ctrl[UE_id]); + + if ((UE_scheduling_ctrl->cdrx_configured == TRUE) && + (UE_scheduling_ctrl->dci0_ongoing_timer > 0) && + (UE_scheduling_ctrl->dci0_ongoing_timer < 8)) { + LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d. \ + The SR is not set do to ongoing DCI0 with CDRX activated\n", + mod_idP, + rntiP, + frameP, + subframeP, + UE_id, + cc_idP); + } else { + if (mac_eNB_get_rrc_status(mod_idP, UE_RNTI(mod_idP, UE_id)) < RRC_CONNECTED) { + LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n", + mod_idP, + rntiP, + frameP, + subframeP, + UE_id, + cc_idP); + } + UE_list->UE_template[cc_idP][UE_id].ul_SR = 1; + UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0); + } } else { - // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); - // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); - LOG_D(MAC, - "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UEid) on CC_id %d\n", - mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); + LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d (unknown UE_id) on CC_id %d\n", + mod_idP, + rntiP, + frameP, + subframeP, + UE_id, + cc_idP); } + + return; } +//------------------------------------------------------------------------------ void -UL_failure_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, - rnti_t rntiP, sub_frame_t subframeP) +UL_failure_indication(module_id_t mod_idP, + int cc_idP, + frame_t frameP, + rnti_t rntiP, + sub_frame_t subframeP) +//------------------------------------------------------------------------------ { int UE_id = find_UE_id(mod_idP, rntiP); UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d][UE %d/%x] Frame %d subframeP %d Signaling UL Failure for UE %d on CC_id %d (timer %d)\n", - mod_idP, UE_id, rntiP, frameP, subframeP, UE_id, cc_idP, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0) - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; + LOG_D(MAC, "[eNB %d][UE %d/%x] Frame %d subframeP %d Signaling UL Failure for UE %d on CC_id %d (timer %d)\n", + mod_idP, + UE_id, + rntiP, + frameP, + subframeP, + UE_id, + cc_idP, + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); + + if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0) UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; } else { // AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP); // AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP); - LOG_W(MAC, - "[eNB %d][SR %x] Frame %d subframeP %d Signaling UL Failure for UE %d (unknown UEid) on CC_id %d\n", - mod_idP, rntiP, frameP, subframeP, UE_id, cc_idP); + LOG_W(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling UL Failure for UE %d (unknown UEid) on CC_id %d\n", + mod_idP, + rntiP, + frameP, + subframeP, + UE_id, + cc_idP); } } -static int nack_or_dtx_reported( - COMMON_channels_t *cc, - nfapi_harq_indication_pdu_t *harq_pdu) +//------------------------------------------------------------------------------ +static int +nack_or_dtx_reported(COMMON_channels_t *cc, + nfapi_harq_indication_pdu_t *harq_pdu) +//------------------------------------------------------------------------------ { int i; if (cc->tdd_Config) { nfapi_harq_indication_tdd_rel13_t *hi = &harq_pdu->harq_indication_tdd_rel13; - for (i = 0; i < hi->number_of_ack_nack; hi++) + + for (i = 0; i < hi->number_of_ack_nack; hi++) { if (hi->harq_data[0].bundling.value_0 != 1) //only bundling is used for tdd for now return 1; + } + return 0; - } else { - nfapi_harq_indication_fdd_rel13_t *hi = &harq_pdu->harq_indication_fdd_rel13; - for (i = 0; i < hi->number_of_ack_nack; hi++) - if (hi->harq_tb_n[i] != 1) - return 1; - return 0; } + + nfapi_harq_indication_fdd_rel13_t *hi = &harq_pdu->harq_indication_fdd_rel13; + + for (i = 0; i < hi->number_of_ack_nack; hi++) { + if (hi->harq_tb_n[i] != 1) + return 1; + } + + return 0; } +//------------------------------------------------------------------------------ void -harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, - sub_frame_t subframeP, - nfapi_harq_indication_pdu_t * harq_pdu) +harq_indication(module_id_t mod_idP, + int CC_idP, + frame_t frameP, + sub_frame_t subframeP, + nfapi_harq_indication_pdu_t *harq_pdu) +//------------------------------------------------------------------------------ { rnti_t rnti = harq_pdu->rx_ue_information.rnti; uint8_t ul_cqi = harq_pdu->ul_cqi_information.ul_cqi; uint8_t channel = harq_pdu->ul_cqi_information.channel; int UE_id = find_UE_id(mod_idP, rnti); + if (UE_id == -1) { - LOG_W(MAC, "harq_indication: UE %x not found\n", rnti); + LOG_W(MAC, "harq_indication: UE %x not found\n", + rnti); return; } + UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; // extract HARQ Information - LOG_D(MAC, - "Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x, ul_cqi %d\n", - frameP, subframeP, channel, UE_id, rnti, ul_cqi); - if (cc->tdd_Config) - extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, - (void *) &harq_pdu->harq_indication_tdd_rel13, - channel); - else - extract_harq(mod_idP, CC_idP, UE_id, frameP, subframeP, - (void *) &harq_pdu->harq_indication_fdd_rel13, - channel); + LOG_D(MAC, "Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x, ul_cqi %d\n", + frameP, + subframeP, + channel, + UE_id, + rnti, + ul_cqi); + + if (cc->tdd_Config) { + extract_harq(mod_idP, + CC_idP, + UE_id, + frameP, + subframeP, + (void *) &harq_pdu->harq_indication_tdd_rel13, + channel); + } else { + extract_harq(mod_idP, + CC_idP, + UE_id, + frameP, + subframeP, + (void *) &harq_pdu->harq_indication_fdd_rel13, + channel); + } + /* don't care about cqi reporting if NACK/DTX is there */ - if (channel == 0 && !nack_or_dtx_reported(cc, harq_pdu)) { + if (channel == 0 && !nack_or_dtx_reported(cc, + harq_pdu)) { sched_ctl->pucch1_snr[CC_idP] = ul_cqi; sched_ctl->pucch1_cqi_update[CC_idP] = 1; } + + return; } // Flexran Slicing functions - -uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs) +//------------------------------------------------------------------------------ +uint16_t +nb_rbs_allowed_slice(float rb_percentage, + int total_rbs) +//------------------------------------------------------------------------------ { - return (uint16_t) floor(rb_percentage * total_rbs); + return (uint16_t) floor(rb_percentage * total_rbs); } -int ue_dl_slice_membership(module_id_t mod_id, int UE_id, int slice_idx) +//------------------------------------------------------------------------------ +int +ue_dl_slice_membership(module_id_t mod_id, + int UE_id, + int slice_idx) +//------------------------------------------------------------------------------ { - if ((slice_idx < 0) - || (slice_idx >= RC.mac[mod_id]->slice_info.n_dl)) { + eNB_MAC_INST *eNB = RC.mac[mod_id]; + + if (slice_idx < 0 || slice_idx >= eNB->slice_info.n_dl) { LOG_W(MAC, "out of range slice index %d (slice ID %d)\n", - slice_idx, RC.mac[mod_id]->slice_info.dl[slice_idx].id); + slice_idx, + eNB->slice_info.dl[slice_idx].id); return 0; } - return RC.mac[mod_id]->UE_list.active[UE_id] == TRUE - && RC.mac[mod_id]->UE_list.assoc_dl_slice_idx[UE_id] == slice_idx; + + return eNB->UE_list.active[UE_id] == TRUE && eNB->UE_list.assoc_dl_slice_idx[UE_id] == slice_idx; } -int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx) +//------------------------------------------------------------------------------ +int +ue_ul_slice_membership(module_id_t mod_id, + int UE_id, + int slice_idx) +//------------------------------------------------------------------------------ { - if ((slice_idx < 0) - || (slice_idx >= RC.mac[mod_id]->slice_info.n_ul)) { + eNB_MAC_INST *eNB = RC.mac[mod_id]; + + if (slice_idx < 0 || slice_idx >= eNB->slice_info.n_ul) { LOG_W(MAC, "out of range slice index %d (slice ID %d)\n", - slice_idx, RC.mac[mod_id]->slice_info.dl[slice_idx].id); + slice_idx, + eNB->slice_info.dl[slice_idx].id); return 0; } - return RC.mac[mod_id]->UE_list.active[UE_id] == TRUE - && RC.mac[mod_id]->UE_list.assoc_ul_slice_idx[UE_id] == slice_idx; + + return eNB->UE_list.active[UE_id] == TRUE && eNB->UE_list.assoc_ul_slice_idx[UE_id] == slice_idx; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index c4a6a59e2b482dd66fdc8e11ddd4a1752cdeb07f..4f1f431508f90a6fb67020624a11f41bf06423e0 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -31,13 +31,12 @@ /* indented with: indent -kr eNB_scheduler_RA.c */ - - #include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac_proto.h" #include "LAYER2/MAC/mac_extern.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" @@ -47,7 +46,6 @@ #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "assertions.h" -//#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" #if defined(ENABLE_ITTI) @@ -73,16 +71,25 @@ extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req); extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); extern uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset); extern int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req); -extern uint8_t nfapi_mode; + // This table holds the allowable PRB sizes for ULSCH transmissions uint8_t rb_table[34] = { - 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, - 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100 + 1, 2, 3, 4, 5, // 0-4 + 6, 8, 9, 10, 12, // 5-9 + 15, 16, 18, 20, 24, // 10-14 + 25, 27, 30, 32, 36, // 15-19 + 40, 45, 48, 50, 54, // 20-24 + 60, 64, 72, 75, 80, // 25-29 + 81, 90, 96, 100 // 30-33 }; -extern mui_t rrc_eNB_mui; +extern mui_t rrc_eNB_mui; +//----------------------------------------------------------------------------- +/* +* When data are received on PHY and transmitted to MAC +*/ void rx_sdu(const module_id_t enb_mod_idP, const int CC_idP, @@ -91,116 +98,160 @@ rx_sdu(const module_id_t enb_mod_idP, const rnti_t rntiP, uint8_t *sduP, const uint16_t sdu_lenP, - const uint16_t timing_advance, const uint8_t ul_cqi) { - int current_rnti = rntiP; - unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; + const uint16_t timing_advance, + const uint8_t ul_cqi) +//----------------------------------------------------------------------------- +{ + int current_rnti = 0; + int UE_id = -1; + int RA_id = 0; + int old_rnti = -1; + int old_UE_id = -1; + int crnti_rx = 0; + int harq_pid = 0; + int first_rb = 0; + unsigned char num_ce = 0; + unsigned char num_sdu = 0; + unsigned char *payload_ptr = NULL; + unsigned char rx_ces[MAX_NUM_CE]; unsigned char rx_lcids[NB_RB_MAX]; unsigned short rx_lengths[NB_RB_MAX]; - int UE_id = find_UE_id(enb_mod_idP, current_rnti); - int RA_id; - int ii, j; - eNB_MAC_INST *mac = RC.mac[enb_mod_idP]; - int harq_pid = - subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); + uint8_t lcgid = 0; int lcgid_updated[4] = {0, 0, 0, 0}; - UE_list_t *UE_list = &mac->UE_list; - int crnti_rx = 0; - int first_rb = 0; + eNB_MAC_INST *mac = NULL; + UE_list_t *UE_list = NULL; rrc_eNB_ue_context_t *ue_contextP = NULL; + UE_sched_ctrl *UE_scheduling_control = NULL; + UE_TEMPLATE *UE_template_ptr = NULL; + + /* Init */ + current_rnti = rntiP; + UE_id = find_UE_id(enb_mod_idP, current_rnti); + mac = RC.mac[enb_mod_idP]; + harq_pid = subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); + UE_list = &mac->UE_list; + memset(rx_ces, 0, MAX_NUM_CE * sizeof(unsigned char)); + memset(rx_lcids, 0, NB_RB_MAX * sizeof(unsigned char)); + memset(rx_lengths, 0, NB_RB_MAX * sizeof(unsigned short)); start_meas(&mac->rx_ulsch_sdu); - - if ((UE_id > MAX_MOBILES_PER_ENB) || (UE_id == -1)) - for (ii = 0; ii < NB_RB_MAX; ii++) { - rx_lengths[ii] = 0; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); if (opt_enabled == 1) { - trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP, - 0, 0); - LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", - enb_mod_idP, frameP, current_rnti, sdu_lenP); + trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP, 0, 0); + LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", + enb_mod_idP, + frameP, + current_rnti, + sdu_lenP); } if (UE_id != -1) { - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP,frameP,subframeP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], - current_rnti, UE_id, ul_cqi); - AssertFatal(UE_list->UE_sched_ctrl[UE_id]. - round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); + + LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", + enb_mod_idP, + harq_pid, + CC_idP, + frameP, + subframeP, + UE_scheduling_control->round_UL[CC_idP][harq_pid], + current_rnti, + UE_id, + ul_cqi); + + AssertFatal(UE_scheduling_control->round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); if (sduP != NULL) { - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); + UE_scheduling_control->ul_inactivity_timer = 0; + UE_scheduling_control->ul_failure_timer = 0; + UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid)); /* Update with smoothing: 3/4 of old value and 1/4 of new. * This is the logic that was done in the function * lte_est_timing_advance_pusch, maybe it's not necessary? * maybe it's even not correct at all? */ - UE_list->UE_sched_ctrl[UE_id].ta_update = (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + timing_advance) / 4; - UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; - UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0; - first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; - - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, - subframeP, UE_RNTI(enb_mod_idP, - UE_id)); - } - - /* update scheduled bytes */ - UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid]; + UE_scheduling_control->ta_update = (UE_scheduling_control->ta_update * 3 + timing_advance) / 4; + UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; + UE_scheduling_control->ul_consecutive_errors = 0; - if (UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes < 0) - UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0; - } else { // we've got an error - LOG_I(MAC, - "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP,frameP,subframeP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], - ul_cqi); + first_rb = UE_template_ptr->first_rb_ul[harq_pid]; - if(ul_cqi>200) { // too high energy pattern - UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; + if (UE_scheduling_control->ul_out_of_sync > 0) { + UE_scheduling_control->ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, current_rnti); } + /* Update bytes to schedule */ + UE_template_ptr->scheduled_ul_bytes -= UE_template_ptr->TBS_UL[harq_pid]; + + if (UE_template_ptr->scheduled_ul_bytes < 0) { + UE_template_ptr->scheduled_ul_bytes = 0; + } + } else { // sduP == NULL => error + LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x\n", + enb_mod_idP, + harq_pid, + CC_idP, + frameP, + subframeP, + UE_scheduling_control->round_UL[CC_idP][harq_pid], + ul_cqi, + UE_id, + current_rnti); + + if (ul_cqi > 200) { // too high energy pattern + UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; + LOG_W(MAC, "[MAC] Too high energy pattern\n"); + } - // AssertFatal(1==0,"ulsch in error\n"); - if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) { - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + if (UE_scheduling_control->round_UL[CC_idP][harq_pid] == 3) { + UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid)); + UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0; - if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10) - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; + if (UE_scheduling_control->ul_consecutive_errors++ == 10) { + UE_scheduling_control->ul_failure_timer = 1; + } - /* update scheduled bytes */ - UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid]; + /* Update scheduled bytes */ + UE_template_ptr->scheduled_ul_bytes -= UE_template_ptr->TBS_UL[harq_pid]; - if (UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes < 0) - UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0; + if (UE_template_ptr->scheduled_ul_bytes < 0) { + UE_template_ptr->scheduled_ul_bytes = 0; + } - if (find_RA_id(enb_mod_idP, CC_idP, current_rnti) != -1) + if (find_RA_id(enb_mod_idP, CC_idP, current_rnti) != -1) { cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); - } else - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; - - first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; - // Program NACK for PHICH - LOG_D(MAC, - "Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n", - current_rnti, harq_pid, first_rb); - nfapi_hi_dci0_request_t *hi_dci0_req; + } + } else { + UE_scheduling_control->round_UL[CC_idP][harq_pid]++; + } + + /* CDRX UL HARQ timers */ + if (UE_scheduling_control->cdrx_configured == TRUE) { + /* Synchronous UL HARQ */ + UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5; + /* + * The NACK is programmed in n+4 subframes, so UE will have drxRetransmission running. + * Setting ul_synchronous_harq_timer = 5 will trigger drxRetransmission timer. + * Note: in case of asynchronous UL HARQ process restart here relevant RTT timer. + * Start corresponding CDRX ULRetransmission timer. + */ + } + + first_rb = UE_template_ptr->first_rb_ul[harq_pid]; + + /* Program NACK for PHICH */ + LOG_D(MAC, "Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n", + current_rnti, + harq_pid, + first_rb); + + nfapi_hi_dci0_request_t *hi_dci0_req = NULL; uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP); - hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10]; + hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP + sf_ahead_dl) % 10]; nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); @@ -209,50 +260,56 @@ rx_sdu(const module_id_t enb_mod_idP, hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; hi_dci0_req_body->number_of_hi++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0); + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 0); hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl); + hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; return; } - } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti - RA_t *ra = (RA_t *) & mac->common_channels[CC_idP].ra[RA_id]; - + // if UE_id == -1 + } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti + RA_t *ra = (RA_t *) &(mac->common_channels[CC_idP].ra[RA_id]); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (ra->rach_resource_type > 0) harq_pid=0; + + if (ra->rach_resource_type > 0) { + harq_pid = 0; + } + #endif - AssertFatal(mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx > 1, + AssertFatal(mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx > 1, "maxHARQ %d should be greater than 1\n", - (int) mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx); - LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, ra->msg3_round, - current_rnti, RA_id, ul_cqi); + (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); + LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", + enb_mod_idP, + harq_pid, + CC_idP, + ra->msg3_round, + current_rnti, + RA_id, + ul_cqi); first_rb = ra->msg3_first_rb; if (sduP == NULL) { // we've got an error on Msg3 - LOG_D(MAC, - "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", - enb_mod_idP, CC_idP, RA_id, + LOG_D(MAC, "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", + enb_mod_idP, + CC_idP, + RA_id, ra->msg3_round, - (int) mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx); + (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx); if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); } else { - first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; + // first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!! ra->msg3_round++; - // prepare handling of retransmission + /* Prepare handling of retransmission */ get_Msg3allocret(&mac->common_channels[CC_idP], - ra->Msg3_subframe, ra->Msg3_frame, - &ra->Msg3_frame, &ra->Msg3_subframe); + ra->Msg3_subframe, + ra->Msg3_frame, + &ra->Msg3_frame, + &ra->Msg3_subframe); + // prepare handling of retransmission add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP); } @@ -260,183 +317,249 @@ rx_sdu(const module_id_t enb_mod_idP, return; } } else { - LOG_W(MAC, - "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", - current_rnti); + LOG_W(MAC, "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", current_rnti); return; } payload_ptr = parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_lenP); - if(payload_ptr == NULL) { + if (payload_ptr == NULL) { LOG_E(MAC,"[eNB %d][PUSCH %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n", - enb_mod_idP, harq_pid, CC_idP,current_rnti, UE_id); + enb_mod_idP, + harq_pid, + CC_idP, + current_rnti, + UE_id); return; } - T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu)); - T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), + T(T_ENB_MAC_UE_UL_PDU, + T_INT(enb_mod_idP), + T_INT(CC_idP), + T_INT(current_rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(sdu_lenP), + T_INT(num_ce), + T_INT(num_sdu)); + T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, + T_INT(enb_mod_idP), + T_INT(CC_idP), + T_INT(current_rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(sdu_lenP), + T_INT(num_ce), + T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP)); mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP; mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP; mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; - // control element - for (i = 0; i < num_ce; i++) { - T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), + if (UE_id != -1) { + UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0; + } + + /* Control element */ + for (int i = 0; i < num_ce; i++) { + T(T_ENB_MAC_UE_UL_CE, + T_INT(enb_mod_idP), + T_INT(CC_idP), + T_INT(current_rnti), + T_INT(frameP), + T_INT(subframeP), T_INT(rx_ces[i])); - switch (rx_ces[i]) { // implement and process BSR + CRNTI + + switch (rx_ces[i]) { // implement and process PHR + CRNTI + BSR case POWER_HEADROOM: if (UE_id != -1) { - UE_list->UE_template[CC_idP][UE_id].phr_info = - (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_list->UE_template[CC_idP][UE_id].nb_rb_ul[harq_pid]-1]/100); + UE_template_ptr->phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_template_ptr->nb_rb_ul[harq_pid] - 1] / 100); - if(UE_list->UE_template[CC_idP][UE_id].phr_info > 40) - UE_list->UE_template[CC_idP][UE_id].phr_info = 40; + if (UE_template_ptr->phr_info > 40) { + UE_template_ptr->phr_info = 40; + } - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", - enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].phr_info); - UE_list->UE_template[CC_idP][UE_id].phr_info_configured = - 1; - UE_list->UE_sched_ctrl[UE_id].phr_received = 1; + LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", + enb_mod_idP, + CC_idP, + rx_ces[i], + UE_template_ptr->phr_info); + + UE_template_ptr->phr_info_configured = 1; + UE_scheduling_control->phr_received = 1; } payload_ptr += sizeof(POWER_HEADROOM_CMD); break; - case CRNTI: { - int old_rnti = - (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; - int old_UE_id = find_UE_id(enb_mod_idP, old_rnti); - LOG_D(MAC, - "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", - enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, - num_ce, old_rnti, old_UE_id); - - /* receiving CRNTI means that the current rnti has to go away */ - //cancel_ra_proc(enb_mod_idP, CC_idP, frameP, - // current_rnti); + case CRNTI: + old_rnti = (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; + old_UE_id = find_UE_id(enb_mod_idP, old_rnti); + LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", + enb_mod_idP, + frameP, + subframeP, + CC_idP, + rx_ces[i], + i, + num_ce, + old_rnti, + old_UE_id); + + /* Receiving CRNTI means that the current rnti has to go away */ if (old_UE_id != -1) { - /* TODO: if the UE did random access (followed by a MAC uplink with - * CRNTI) because none of its scheduling request was granted, then - * according to 36.321 5.4.4 the UE's MAC will notify RRC to release - * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply - * default configuration for CQI reporting and scheduling requests, - * which basically means that the CQI requests won't work anymore and - * that the UE won't do any scheduling request anymore as long as the - * eNB doesn't reconfigure the UE. - * We have to take care of this. As the code is, nothing is done and - * the UE state in the eNB is wrong. - */ - for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { - RA_t *ra = &mac->common_channels[CC_idP].ra[ii]; - - if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { + if (mac_eNB_get_rrc_status(enb_mod_idP,old_rnti) == RRC_HO_EXECUTION) { + LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Handover case\n", + enb_mod_idP, + frameP, + subframeP, + CC_idP, + old_rnti, + old_UE_id); + + UE_id = old_UE_id; + current_rnti = old_rnti; + /* Clear timer */ + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); + + UE_scheduling_control->uplane_inactivity_timer = 0; + UE_scheduling_control->ul_inactivity_timer = 0; + UE_scheduling_control->ul_failure_timer = 0; + + if (UE_scheduling_control->ul_out_of_sync > 0) { + UE_scheduling_control->ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, + CC_idP, + frameP, + subframeP, + old_rnti); + } + UE_template_ptr->ul_SR = 1; + UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; + UE_list->UE_template[UE_PCCID(enb_mod_idP, UE_id)][UE_id].configured = 1; + cancel_ra_proc(enb_mod_idP, + CC_idP, + frameP, + current_rnti); + } else { + /* TODO: if the UE did random access (followed by a MAC uplink with + * CRNTI) because none of its scheduling request was granted, then + * according to 36.321 5.4.4 the UE's MAC will notify RRC to release + * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply + * default configuration for CQI reporting and scheduling requests, + * which basically means that the CQI requests won't work anymore and + * that the UE won't do any scheduling request anymore as long as the + * eNB doesn't reconfigure the UE. + * We have to take care of this. As the code is, nothing is done and + * the UE state in the eNB is wrong. + */ + RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti); + + if (RA_id != -1) { + RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]); mac_rrc_data_ind(enb_mod_idP, CC_idP, frameP, subframeP, + UE_id, old_rnti, DCCH, (uint8_t *) payload_ptr, rx_lengths[i], 0 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,ra->rach_resource_type>0 + ,ra->rach_resource_type > 0 #endif - ); - // prepare transmission of Msg4(RRCConnectionReconfiguration) + ); + /* Received a new rnti */ ra->state = MSGCRNTI; - LOG_I(MAC, - "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) RRCConnectionReconfiguration(Msg4)\n", - enb_mod_idP, frameP, subframeP, CC_idP, old_rnti, old_UE_id); + LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Received rnti(Msg4)\n", + enb_mod_idP, + frameP, + subframeP, + CC_idP, + old_rnti, + old_UE_id); UE_id = old_UE_id; current_rnti = old_rnti; ra->rnti = old_rnti; ra->crnti_rrc_mui = rrc_eNB_mui-1; ra->crnti_harq_pid = -1; - //clear timer - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, - subframeP, old_rnti); - } - UE_list->UE_template[CC_idP][UE_id].ul_SR = 1; - UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 1; - break; + /* Clear timer */ + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); + + UE_scheduling_control->uplane_inactivity_timer = 0; + UE_scheduling_control->ul_inactivity_timer = 0; + UE_scheduling_control->ul_failure_timer = 0; + + if (UE_scheduling_control->ul_out_of_sync > 0) { + UE_scheduling_control->ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, old_rnti); + } + UE_template_ptr->ul_SR = 1; + UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1; + // break; } } } else { - cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti); + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); + LOG_W(MAC, "[MAC] Can't find old UE_id\n"); } crnti_rx = 1; - payload_ptr += 2; + payload_ptr += 2; // sizeof(CRNTI) break; - } case TRUNCATED_BSR: - case SHORT_BSR: { - uint8_t lcgid; + case SHORT_BSR: lcgid = (payload_ptr[0] >> 6); - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - enb_mod_idP, CC_idP, rx_ces[i], lcgid, + LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + enb_mod_idP, + CC_idP, + rx_ces[i], + lcgid, payload_ptr[0] & 0x3f); - if (crnti_rx == 1) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - enb_mod_idP, CC_idP, rx_ces[i], lcgid, - payload_ptr[0] & 0x3f); - if (UE_id != -1) { - int bsr = payload_ptr[0] & 0x3f; + int bsr = 0; + bsr = payload_ptr[0] & 0x3f; lcgid_updated[lcgid] = 1; - // update buffer info - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] = BSR_TABLE[bsr]; - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; - //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + /* Update buffer info */ + UE_template_ptr->ul_buffer_info[lcgid] = BSR_TABLE[bsr]; + UE_template_ptr->estimated_ul_buffer = + UE_template_ptr->ul_buffer_info[LCGID0] + + UE_template_ptr->ul_buffer_info[LCGID1] + + UE_template_ptr->ul_buffer_info[LCGID2] + + UE_template_ptr->ul_buffer_info[LCGID3]; + RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, - RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr - [UE_id][(frameP * 10) + subframeP]); + if (UE_id == UE_list->head) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, (payload_ptr[0] & 0x3f)); + } - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] = frameP; + if (UE_template_ptr->ul_buffer_creation_time[lcgid] == 0) { + UE_template_ptr->ul_buffer_creation_time[lcgid] = frameP; } - if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : estimated_ul_buffer = %d (lcg increment %d)\n", - enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer, - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]); + if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) { + LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : estimated_ul_buffer = %d (lcg increment %d)\n", + enb_mod_idP, + CC_idP, + rx_ces[i], + UE_template_ptr->estimated_ul_buffer, + UE_template_ptr->ul_buffer_info[lcgid]); + } } else { + /* Need error message */ } - payload_ptr += 1; //sizeof(SHORT_BSR); // fixme - } - break; + payload_ptr += 1; // sizeof(SHORT_BSR) + break; case LONG_BSR: if (UE_id != -1) { @@ -448,197 +571,203 @@ rx_sdu(const module_id_t enb_mod_idP, lcgid_updated[LCGID1] = 1; lcgid_updated[LCGID2] = 1; lcgid_updated[LCGID3] = 1; - // update buffer info - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] = BSR_TABLE[bsr1]; - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] = BSR_TABLE[bsr2]; - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; - //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, - rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]); - - if (crnti_rx == 1) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, - CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]); - - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = 0; - } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = 0; - } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = frameP; - } - - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = 0; - } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = frameP; + /* Update buffer info */ + UE_template_ptr->ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; + UE_template_ptr->ul_buffer_info[LCGID1] = BSR_TABLE[bsr1]; + UE_template_ptr->ul_buffer_info[LCGID2] = BSR_TABLE[bsr2]; + UE_template_ptr->ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; + + UE_template_ptr->estimated_ul_buffer = + UE_template_ptr->ul_buffer_info[LCGID0] + + UE_template_ptr->ul_buffer_info[LCGID1] + + UE_template_ptr->ul_buffer_info[LCGID2] + + UE_template_ptr->ul_buffer_info[LCGID3]; + + LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = %u LCGID2 = %u LCGID3 = %u\n", + enb_mod_idP, + CC_idP, + rx_ces[i], + UE_template_ptr->ul_buffer_info[LCGID0], + UE_template_ptr->ul_buffer_info[LCGID1], + UE_template_ptr->ul_buffer_info[LCGID2], + UE_template_ptr->ul_buffer_info[LCGID3]); + + if (crnti_rx == 1) { + LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received CRNTI.\n", + enb_mod_idP, + CC_idP, + rx_ces[i]); } - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = 0; - } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = frameP; + for(int lcgid = 0; lcgid <= LCGID3; lcgid++) { + if (UE_template_ptr->ul_buffer_info[lcgid] == 0) { + UE_template_ptr->ul_buffer_creation_time[lcgid] = 0; + } else if (UE_template_ptr->ul_buffer_creation_time[lcgid] == 0) { + UE_template_ptr->ul_buffer_creation_time[lcgid] = frameP; + } } } - payload_ptr += 3; ////sizeof(LONG_BSR); + payload_ptr += 3; // sizeof(LONG_BSR) break; default: - LOG_E(MAC, - "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", - enb_mod_idP, CC_idP, rx_ces[i]); + LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", + enb_mod_idP, + CC_idP, + rx_ces[i]); break; - } - } + } // end switch on control element + } // end for loop on control element - for (i = 0; i < num_sdu; i++) { + for (int i = 0; i < num_sdu; i++) { LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", - i, rx_lcids[i], rx_lengths[i]); - T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); - T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), - T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), - T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, - rx_lengths - [i])); + i, + rx_lcids[i], + rx_lengths[i]); + T(T_ENB_MAC_UE_UL_SDU, + T_INT(enb_mod_idP), + T_INT(CC_idP), + T_INT(current_rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(rx_lcids[i]), + T_INT(rx_lengths[i])); + T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, + T_INT(enb_mod_idP), + T_INT(CC_idP), + T_INT(current_rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(rx_lcids[i]), + T_INT(rx_lengths[i]), + T_BUFFER(payload_ptr, rx_lengths[i])); switch (rx_lcids[i]) { - case CCCH: - if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { - LOG_E(MAC, - "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - CCCH_PAYLOAD_SIZE_MAX, sdu_lenP); - break; - } - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", - enb_mod_idP, CC_idP, frameP, payload_ptr[0], - payload_ptr[1], payload_ptr[2], payload_ptr[3], - payload_ptr[4], payload_ptr[5], current_rnti); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); - for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { - RA_t *ra = &mac->common_channels[CC_idP].ra[ii]; - - LOG_D(MAC, - "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", - enb_mod_idP, CC_idP, ii, ra->rnti, - current_rnti, ra->state); - - if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { - - //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); - - if (UE_id < 0) { - memcpy(&ra->cont_res_id[0], payload_ptr, 6); - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - payload_ptr - sduP); - - if ((UE_id = add_new_ue(enb_mod_idP, CC_idP, - mac->common_channels[CC_idP]. - ra->rnti, harq_pid + case CCCH: + if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { + LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + CCCH_PAYLOAD_SIZE_MAX, + sdu_lenP); + break; + } + + LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", + enb_mod_idP, + CC_idP, + frameP, + payload_ptr[0], payload_ptr[1], payload_ptr[2], payload_ptr[3], payload_ptr[4], payload_ptr[5], + current_rnti); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); + RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti); + + if (RA_id != -1) { + RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]); + LOG_D(MAC, "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", + enb_mod_idP, + CC_idP, + RA_id, + ra->rnti, + current_rnti, + ra->state); + + if (UE_id < 0) { + memcpy(&(ra->cont_res_id[0]), payload_ptr, 6); + LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + payload_ptr - sduP); + + if ((UE_id = add_new_ue(enb_mod_idP, CC_idP, ra->rnti, harq_pid #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - mac->common_channels[CC_idP]. - ra->rach_resource_type + , ra->rach_resource_type #endif - )) == -1) { + )) == -1) { LOG_E(MAC,"[MAC][eNB] Max user count reached\n"); - cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti); + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); // send Connection Reject ??? break; - // kill RA procedure - } else - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", - enb_mod_idP, CC_idP, frameP, ra->rnti, - UE_id); - } else { - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", - enb_mod_idP, CC_idP, frameP, UE_id, - rx_lengths[i], payload_ptr - sduP); - // kill RA procedure - } - - mac_rrc_data_ind(enb_mod_idP, - CC_idP, - frameP, subframeP, - current_rnti, - CCCH, - (uint8_t *) payload_ptr, - rx_lengths[i], - 0 + // kill RA proc + } else { + LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", + enb_mod_idP, + CC_idP, + frameP, + ra->rnti, + UE_id); + + UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]); + } + } else { + LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", + enb_mod_idP, + CC_idP, + frameP, + UE_id, + rx_lengths[i], + payload_ptr - sduP); + // kill RA proc + } + + mac_rrc_data_ind(enb_mod_idP, + CC_idP, + frameP, subframeP, + UE_id, + current_rnti, + CCCH, + (uint8_t *) payload_ptr, + rx_lengths[i], + 0 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,ra->rach_resource_type>0 + ,ra->rach_resource_type > 0 #endif - ); - - - if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest - // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); - } - // prepare transmission of Msg4 - ra->state = MSG4; - - if(mac->common_channels[CC_idP].tdd_Config!=NULL) { - switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment) { - case 1: - ra->Msg4_frame = frameP + ((subframeP > 2) ? 1 : 0); - ra->Msg4_subframe = (subframeP + 7) % 10; - break; - - default: - printf("%s:%d: TODO\n", __FILE__, __LINE__); - abort(); - // TODO need to be complete for other tdd configs. - } - } else { - // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different - ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); - ra->Msg4_subframe = (subframeP + 4) % 10; - } - - UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; - } // if process is active - } // loop on RA processes - - break; - - case DCCH: - case DCCH1: - // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ + ); + + if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest + // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); + } + + // prepare transmission of Msg4 + ra->state = MSG4; + + if(mac->common_channels[CC_idP].tdd_Config != NULL) { + switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment) { + case 1: + ra->Msg4_frame = frameP + ((subframeP > 2) ? 1 : 0); + ra->Msg4_subframe = (subframeP + 7) % 10; + break; + + default: + printf("%s:%d: TODO\n", __FILE__, __LINE__); + abort(); + // TODO need to be complete for other tdd configs. + } + } else { + /* Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, + * Check if this is ok for BL/CE, or if the rule is different + */ + ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); + ra->Msg4_subframe = (subframeP + 4) % 10; + } + + UE_scheduling_control->crnti_reconfigurationcomplete_flag = 0; + } // if RA process is active + + break; + + case DCCH: + case DCCH1: #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "offset: %d\n", - (unsigned char) ((unsigned char *) payload_ptr - sduP)); + LOG_T(MAC, "offset: %d\n", (unsigned char) ((unsigned char *) payload_ptr - sduP)); - for (j = 0; j < 32; j++) { + for (int j = 0; j < 32; j++) { LOG_T(MAC, "%x ", payload_ptr[j]); } @@ -646,19 +775,19 @@ rx_sdu(const module_id_t enb_mod_idP, #endif if (UE_id != -1) { - if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { - // adjust buffer occupancy of the correponding logical channel group - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) { + /* Adjust buffer occupancy of the correponding logical channel group */ + if (UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) + UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; else - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; - - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; - //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] = 0; + + UE_template_ptr->estimated_ul_buffer = + UE_template_ptr->ul_buffer_info[0] + + UE_template_ptr->ul_buffer_info[1] + + UE_template_ptr->ul_buffer_info[2] + + UE_template_ptr->ul_buffer_info[3]; + //UE_template_ptr->estimated_ul_buffer += UE_template_ptr->estimated_ul_buffer / 4; } LOG_D(MAC, @@ -670,8 +799,6 @@ rx_sdu(const module_id_t enb_mod_idP, UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; } - /* UE_id != -1 */ - // } break; // all the DRBS @@ -681,7 +808,7 @@ rx_sdu(const module_id_t enb_mod_idP, LOG_T(MAC, "offset: %d\n", (unsigned char) ((unsigned char *) payload_ptr - sduP)); - for (j = 0; j < 32; j++) { + for (int j = 0; j < 32; j++) { LOG_T(MAC, "%x ", payload_ptr[j]); } @@ -698,7 +825,7 @@ rx_sdu(const module_id_t enb_mod_idP, rx_lcids[i]); if (UE_id != -1) { - // adjust buffer occupancy of the correponding logical channel group + /* Adjust buffer occupancy of the correponding logical channel group */ LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", enb_mod_idP, CC_idP, @@ -706,31 +833,33 @@ rx_sdu(const module_id_t enb_mod_idP, rx_lengths[i], UE_id, rx_lcids[i], - UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]); + UE_template_ptr->lcgidmap[rx_lcids[i]], + UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]]); - if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) { + if (UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) { + UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; } else { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] = 0; } - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + UE_template_ptr->estimated_ul_buffer = + UE_template_ptr->ul_buffer_info[0] + + UE_template_ptr->ul_buffer_info[1] + + UE_template_ptr->ul_buffer_info[2] + + UE_template_ptr->ul_buffer_info[3]; } if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; - //clear uplane_inactivity_timer - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - // reset RRC inactivity timer after uplane activity + /* Clear uplane_inactivity_timer */ + UE_scheduling_control->uplane_inactivity_timer = 0; + + /* Reset RRC inactivity timer after uplane activity */ ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], current_rnti); + if (ue_contextP != NULL) { ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; } else { @@ -739,7 +868,7 @@ rx_sdu(const module_id_t enb_mod_idP, CC_idP, current_rnti); } - } else { /* rx_length[i] */ + } else { /* rx_length[i] Max size */ UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", enb_mod_idP, @@ -764,16 +893,32 @@ rx_sdu(const module_id_t enb_mod_idP, payload_ptr += rx_lengths[i]; } - // Program ACK for PHICH - LOG_D(MAC, - "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", - current_rnti, harq_pid, first_rb); + /* CDRX UL HARQ timers */ + if (UE_id != -1) { + if (UE_scheduling_control->cdrx_configured == TRUE) { + /* Synchronous UL HARQ */ + UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5; + /* + * The ACK is programmed in n+4 subframes, so UE will have drxRetransmission running. + * Setting ul_synchronous_harq_timer = 5 will trigger drxRetransmission timer. + * Note: in case of asynchronous UL HARQ process restart here relevant RTT timer + * Stop corresponding CDRX ULRetransmission timer + */ + } + } + + /* Program ACK for PHICH */ + LOG_D(MAC, "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", + current_rnti, + harq_pid, + first_rb); + nfapi_hi_dci0_request_t *hi_dci0_req; uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP); hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10]; nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + + hi_dci0_req_body->number_of_hi]; memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); @@ -791,14 +936,6 @@ rx_sdu(const module_id_t enb_mod_idP, if ((num_sdu == 0) && (num_ce == 0)) { if (UE_id != -1) UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1; - - /* - if (msg3_flagP != NULL) { - if( *msg3_flagP == 1 ) { - LOG_I(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP); - *msg3_flagP=0; - } - } */ } else { if (UE_id != -1) { UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx = sdu_lenP; @@ -811,7 +948,14 @@ rx_sdu(const module_id_t enb_mod_idP, stop_meas(&mac->rx_ulsch_sdu); } -uint32_t bytes_to_bsr_index(int32_t nbytes) { +//----------------------------------------------------------------------------- +/* + * Return the BSR table index corresponding to the number of bytes in input + */ +uint32_t +bytes_to_bsr_index(int32_t nbytes) +//----------------------------------------------------------------------------- +{ uint32_t i = 0; if (nbytes < 0) { @@ -825,26 +969,47 @@ uint32_t bytes_to_bsr_index(int32_t nbytes) { return (i - 1); } +//----------------------------------------------------------------------------- +/* + * Add ue info in eNB_ulsch_info[module_idP][CC_id][UE_id] struct + */ void -add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, - sub_frame_t subframeP, UE_ULSCH_STATUS status) { +add_ue_ulsch_info(module_id_t module_idP, + int CC_id, + int UE_id, + sub_frame_t subframeP, + UE_ULSCH_STATUS status) +//----------------------------------------------------------------------------- +{ eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = UE_RNTI(module_idP, UE_id); eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++; } -unsigned char *parse_ulsch_header(unsigned char *mac_header, - unsigned char *num_ce, - unsigned char *num_sdu, - unsigned char *rx_ces, - unsigned char *rx_lcids, - unsigned short *rx_lengths, - unsigned short tb_length) { - unsigned char not_done = 1, num_ces = 0, num_sdus = - 0, lcid, num_sdu_cnt; - unsigned char *mac_header_ptr = mac_header; +//----------------------------------------------------------------------------- +/* + * Parse MAC header from ULSCH + */ +unsigned char * +parse_ulsch_header(unsigned char *mac_header, + unsigned char *num_ce, + unsigned char *num_sdu, + unsigned char *rx_ces, + unsigned char *rx_lcids, + unsigned short *rx_lengths, + unsigned short tb_length) +//----------------------------------------------------------------------------- +{ + unsigned char not_done = 1; + unsigned char num_ces = 0; + unsigned char num_sdus = 0; + unsigned char lcid = 0; + unsigned char num_sdu_cnt = 0; + unsigned char *mac_header_ptr = NULL; unsigned short length, ce_len = 0; + /* Init */ + mac_header_ptr = mac_header; while (not_done == 1) { if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { @@ -858,8 +1023,7 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, mac_header_ptr++; length = tb_length - (mac_header_ptr - mac_header) - ce_len; - for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; - num_sdu_cnt++) { + for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; num_sdu_cnt++) { length -= rx_lengths[num_sdu_cnt]; } } else { @@ -867,22 +1031,22 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); } else { // F = 1 - length = - ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & - 0x7f) << 8) | (((SCH_SUBHEADER_LONG *) - mac_header_ptr)->L_LSB & 0xff); + length = ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & 0x7f) << 8) | + (((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB & 0xff); mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); } } - LOG_D(MAC, - "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", - num_sdus, lcid, tb_length, length, + LOG_D(MAC, "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", + num_sdus, + lcid, + tb_length, + length, mac_header_ptr - mac_header); rx_lcids[num_sdus] = lcid; rx_lengths[num_sdus] = length; num_sdus++; - } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI + } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI if (lcid == SHORT_PADDING) { mac_header_ptr++; } else { @@ -894,13 +1058,10 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, ce_len += 3; } else if (lcid == CRNTI) { ce_len += 2; - } else if ((lcid == POWER_HEADROOM) - || (lcid == TRUNCATED_BSR) - || (lcid == SHORT_BSR)) { + } else if ((lcid == POWER_HEADROOM) || (lcid == TRUNCATED_BSR) || (lcid == SHORT_BSR)) { ce_len++; } else { LOG_E(MAC, "unknown CE %d \n", lcid); - //AssertFatal(1 == 0, "unknown CE"); return NULL; } } @@ -912,47 +1073,67 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, return (mac_header_ptr); } +//----------------------------------------------------------------------------- /* This function is called by PHY layer when it schedules some * uplink for a random access message 3. * The MAC scheduler has to skip the RBs used by this message 3 * (done below in schedule_ulsch). + * This function seems to be unused, the Msg3_subframe is set somewhere else... + * In NFAPI?? */ void set_msg3_subframe(module_id_t mod_id, int CC_id, - int frame, - int subframe, int rnti, int Msg3_frame, - int Msg3_subframe) { - eNB_MAC_INST *mac = RC.mac[mod_id]; - int i; - - for (i = 0; i < NB_RA_PROC_MAX; i++) { - if (mac->common_channels[CC_id].ra[i].state != IDLE && - mac->common_channels[CC_id].ra[i].rnti == rnti) { - mac->common_channels[CC_id].ra[i].Msg3_subframe = - Msg3_subframe; - break; - } + int frame, // Not used, remove? + int subframe, // Not used, remove? + int rnti, + int Msg3_frame, // Not used, remove? + int Msg3_subframe) +//----------------------------------------------------------------------------- +{ + int RA_id = 0; + /* Init */ + RA_id = find_RA_id(mod_id, CC_id, rnti); // state == WAITMSG3 instead of state != IDLE (?) + + if (RA_id != -1) { + RC.mac[mod_id]->common_channels[CC_id].ra[RA_id].Msg3_subframe = Msg3_subframe; + } else { + LOG_E(MAC, "[MAC] Unknown RAPROC associated to RNTI %x\n", rnti); } + + return; } +//----------------------------------------------------------------------------- +/* + * Main function called for uplink scheduling (DCI0). + */ void -schedule_ulsch(module_id_t module_idP, frame_t frameP, - sub_frame_t subframeP) { - uint16_t first_rb[NFAPI_CC_MAX], i; - int CC_id; - eNB_MAC_INST *mac = RC.mac[module_idP]; - slice_info_t *sli = &RC.mac[module_idP]->slice_info; - COMMON_channels_t *cc; - start_meas(&mac->schedule_ulsch); - int sched_frame=frameP; - int sched_subframe = (subframeP + 4) % 10; - cc = &mac->common_channels[0]; - int tdd_sfa; - - // for TDD: check subframes where we have to act and return if nothing should be done now - if (cc->tdd_Config) { - tdd_sfa = cc->tdd_Config->subframeAssignment; +schedule_ulsch(module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP) +//----------------------------------------------------------------------------- +{ + uint16_t first_rb[NFAPI_CC_MAX]; + eNB_MAC_INST *mac = NULL; + slice_info_t *sli = NULL; + COMMON_channels_t *cc = NULL; + int sched_subframe; + int sched_frame; + + /* Init */ + mac = RC.mac[module_idP]; + sli = &(mac->slice_info); + memset(first_rb, 0, NFAPI_CC_MAX * sizeof(uint16_t)); + start_meas(&(mac->schedule_ulsch)); + + sched_subframe = (subframeP + 4) % 10; + sched_frame = frameP; + cc = mac->common_channels; + + /* For TDD: check subframes where we have to act and return if nothing should be done now */ + if (cc->tdd_Config) { // Done only for CC_id = 0, assume tdd_Config for all CC_id + int tdd_sfa = cc->tdd_Config->subframeAssignment; switch (subframeP) { case 0: @@ -975,10 +1156,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, break; - default: - return; - - case 2: // Don't schedule UL in subframe 2 for TDD + case 2: // Don't schedule UL in subframe 2 for TDD return; case 3: @@ -1037,387 +1215,459 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, return; break; + + default: + return; } } + if (sched_subframe < subframeP) { + sched_frame++; + sched_frame %= 1024; + } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - int emtc_active[5]; - memset(emtc_active,0,5*sizeof(int)); + int emtc_active[5]; + memset(emtc_active, 0, 5 * sizeof(int)); schedule_ulsch_rnti_emtc(module_idP, frameP, subframeP, sched_subframe, emtc_active); #endif - if (sched_subframe < subframeP) sched_frame++; - - - //leave out first RB for PUCCH and first narrowband if emtc - for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { - //leave out first RB for PUCCH - first_rb[CC_id] = 1; - + /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */ + for (int CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++, cc++) { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) first_rb[CC_id] = (emtc_active[CC_id] == 1) ? 7 : 1; #else - first_rb[CC_id] = 1; + /* Note: the size of PUCCH is arbitrary, to be done properly. */ + switch (RC.eNB[module_idP][CC_id]->frame_parms.N_RB_DL) { + case 25: first_rb[CC_id] = 1; break; // leave out first RB for PUCCH + case 50: first_rb[CC_id] = 2; break; // leave out first RB for PUCCH + case 100: first_rb[CC_id] = 3; break; // leave out first RB for PUCCH + default: LOG_E(MAC, "nb RBs not handled, todo.\n"); exit(1); + } #endif - // UE data info; - // check which UE has data to transmit - // function to decide the scheduling - // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB) - - // default function for default scheduling - // - - // output of scheduling, the UE numbers in RBs, where it is in the code??? - // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 - // Msg3 is using 1 PRB so we need to increase first_rb accordingly - // not sure about the break (can there be more than 1 active RA procedure?) - - for (i = 0; i < NB_RA_PROC_MAX; i++) { - if ((cc->ra[i].state == WAITMSG3) && - (cc->ra[i].Msg3_subframe == sched_subframe)) { - if (first_rb[CC_id] < cc->ra[i].msg3_first_rb + cc->ra[i].msg3_nb_rb) - first_rb[CC_id] = cc->ra[i].msg3_first_rb + cc->ra[i].msg3_nb_rb; - - // cc->ray[i].Msg3_subframe = -1; - break; + RA_t *ra_ptr = cc->ra; + + /* From Louis-Adrien to François: + * The comment bloc below is to configure with a command line. + * I took it from the equivalent part in the fairRR scheduler (around line 2578 in eNB_scheduler_fairRR.c). + * As said in the meeting, it seems to work only for small TBS. + * The cause of false RA still present with this fix is to investigate. + * + * Note: in the get_prach_prb_offset() function below, the last argument is frameP in eNB_scheduler_fairRR.c + * I think it should be sched_frame instead. This parameter has only impacts in case TDD and preamble format 4. + * To confirm. + */ + /* + int start_rb = 0; + int nb_rb = 6; + LTE_DL_FRAME_PARMS *frame_parms = &(RC.eNB[module_idP][CC_id]->frame_parms); + + if (is_prach_subframe(frame_parms, sched_frame, sched_subframe) == 1) { + start_rb = get_prach_prb_offset(frame_parms, + frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset, + 0, // tdd_mapindex + sched_frame); // Nf + + first_rb[CC_id] = start_rb + nb_rb; + } + */ + + /* + * Check if RA (Msg3) is active in this subframeP, if so skip the PRB used for Msg3 + * Msg3 is using 1 PRB so we need to increase first_rb accordingly + * Not sure about the break (can there be more than 1 active RA procedure per CC_id and per subframe?) + */ + for (int ra_index = 0; ra_index < NB_RA_PROC_MAX; ra_index++, ra_ptr++) { + if ((ra_ptr->state == WAITMSG3) && (ra_ptr->Msg3_subframe == sched_subframe)) { + if (first_rb[CC_id] < ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb) { + first_rb[CC_id] = ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb; + } + + /* Louis-Adrien: I couldn't find an interdiction of multiple Msg3 scheduling + * on the same time resources. Also the performance improvement of breaking is low, + * since we will loop until the end, most of the time. + * I'm letting the break as a reminder, in case of misunderstanding the spec. + */ + // break; } } } - for (i = 0; i < sli->n_ul; i++) { - // Run each enabled slice-specific schedulers one by one + /* Run each enabled slice-specific schedulers one by one */ + for (int i = 0; i < sli->n_ul; i++) { + /* By default the scheduler is schedule_ulsch_rnti (see below) */ sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb); } stop_meas(&mac->schedule_ulsch); } - -void schedule_ulsch_rnti(module_id_t module_idP, - int slice_idx, - frame_t frameP, - sub_frame_t subframeP, - unsigned char sched_subframeP, uint16_t * first_rb) +//----------------------------------------------------------------------------- +/* +* Schedule the DCI0 for ULSCH +*/ +void +schedule_ulsch_rnti(module_id_t module_idP, + int slice_idx, + frame_t frameP, + sub_frame_t subframeP, + unsigned char sched_subframeP, + uint16_t *first_rb) +//----------------------------------------------------------------------------- { - int UE_id; - uint8_t aggregation = 2; rnti_t rnti = -1; - uint8_t round = 0; + uint8_t aggregation = 2; + uint8_t round_index = 0; uint8_t harq_pid = 0; uint8_t status = 0; uint8_t rb_table_index = -1; - uint32_t cqi_req, cshift, ndi, tpc; - int32_t normalized_rx_power, target_rx_power; + uint8_t dlsch_flag = 0; + uint16_t ul_req_index = 0; + uint32_t cqi_req = 0; + uint32_t cshift = 0; + uint32_t ndi = 0; + uint32_t tpc = 0; + int32_t normalized_rx_power = 0; + int32_t target_rx_power = 0; + int32_t framex10psubframe = 0; static int32_t tpc_accumulated = 0; - int n; + int sched_frame = 0; int CC_id = 0; - int drop_ue = 0; - int N_RB_UL; - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc = mac->common_channels; - UE_list_t *UE_list = &mac->UE_list; - slice_info_t *sli = &RC.mac[module_idP]->slice_info; - UE_TEMPLATE *UE_template; - UE_sched_ctrl *UE_sched_ctrl; - int sched_frame = frameP; - int rvidx_tab[4] = { 0, 2, 3, 1 }; - uint16_t ul_req_index; - uint8_t dlsch_flag; + eNB_MAC_INST *mac = NULL; + COMMON_channels_t *cc = NULL; + UE_list_t *UE_list = NULL; + slice_info_t *sli = NULL; + UE_TEMPLATE *UE_template_ptr = NULL; + UE_sched_ctrl *UE_sched_ctrl_ptr = NULL; + int rvidx_tab[4] = {0, 2, 3, 1}; int first_rb_slice[NFAPI_CC_MAX]; - - if (sched_subframeP < subframeP) + int n_rb_ul_tab[NFAPI_CC_MAX]; + /* Init */ + mac = RC.mac[module_idP]; + cc = mac->common_channels; + UE_list = &(mac->UE_list); + sli = &(mac->slice_info); + memset(first_rb_slice, 0, NFAPI_CC_MAX * sizeof(int)); + memset(n_rb_ul_tab, 0, NFAPI_CC_MAX * sizeof(int)); + sched_frame = frameP; + + if (sched_subframeP < subframeP) { sched_frame++; + sched_frame %= 1024; + } - nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id][subframeP]; - nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; + /* NFAPI struct init */ + nfapi_hi_dci0_request_t *hi_dci0_req = &(mac->HI_DCI0_req[CC_id][subframeP]); + nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &(hi_dci0_req->hi_dci0_request_body); nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; - nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][sched_subframeP]; - nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; + nfapi_ul_config_request_t *ul_req_tmp = &(mac->UL_req_tmp[CC_id][sched_subframeP]); + nfapi_ul_config_request_body_t *ul_req_tmp_body = &(ul_req_tmp->ul_config_request_body); nfapi_ul_config_ulsch_harq_information *ulsch_harq_information; + hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; - for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; ++CC_id) { - N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); - UE_list->first_rb_offset[CC_id][slice_idx] = cmin(N_RB_UL, sli->ul[slice_idx].first_rb); + /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */ + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { + n_rb_ul_tab[CC_id] = to_prb(cc[CC_id].ul_Bandwidth); // return total number of PRB + /* HACK: let's remove the PUCCH from available RBs + * we suppose PUCCH size is: + * - for 25 RBs: 1 RB (top and bottom of ressource grid) + * - for 50: 2 RBs + * - for 100: 3 RBs + * This is totally arbitrary and might even be wrong. + * We suppose 'first_rb[]' has been correctly populated by the caller, + * so we only remove the top part of the resource grid. + */ + switch (n_rb_ul_tab[CC_id]) { + case 25: n_rb_ul_tab[CC_id] -= 1; break; + case 50: n_rb_ul_tab[CC_id] -= 2; break; + case 100: n_rb_ul_tab[CC_id] -= 3; break; + default: LOG_E(MAC, "RBs setting not handled. Todo.\n"); exit(1); + } + UE_list->first_rb_offset[CC_id][slice_idx] = cmin(n_rb_ul_tab[CC_id], sli->ul[slice_idx].first_rb); } - //LOG_D(MAC, "entering ulsch preprocesor\n"); - ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_subframeP, first_rb); + /* + * ULSCH preprocessor: set UE_template-> + * pre_allocated_nb_rb_ul[slice_idx] + * pre_assigned_mcs_ul + * pre_allocated_rb_table_index_ul + */ + ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_frame, sched_subframeP, first_rb); - for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_idx]; } - //LOG_D(MAC, "exiting ulsch preprocesor\n"); - hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; - - // loop over all active UEs - for (UE_id = UE_list->head_ul; UE_id >= 0; - UE_id = UE_list->next_ul[UE_id]) { - if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) + // loop over all active UEs until end of function + for (int UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { + if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) { continue; - - // don't schedule if Msg4 is not received yet - if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. - configured == FALSE) { - LOG_D(MAC, - "[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", - module_idP, frameP, subframeP, UE_id); + } + + if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].rach_resource_type > 0) continue; + + // don't schedule if Msg5 is not received yet + if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured == FALSE) { + LOG_D(MAC, "[eNB %d] frame %d, subframe %d, UE %d: not configured, skipping UE scheduling \n", + module_idP, + frameP, + subframeP, + UE_id); continue; } rnti = UE_RNTI(module_idP, UE_id); if (rnti == NOT_A_RNTI) { - LOG_W(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", - module_idP, frameP, subframeP, UE_id); - continue; - } - - drop_ue = 0; - - /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ - /* TODO: refine? - - for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - - if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id); - drop_ue = 1; - break; - } - } */ - if (drop_ue == 1) { - /* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ - abort(); - - /* TODO: this is a hack. Sometimes the UE has no PHY context but - * is still present in the MAC with 'ul_failure_timer' = 0 and - * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's - * start an UL out of sync procedure in this case. - * The root cause of this problem has to be found and corrected. - * In the meantime, this hack... - */ - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - // inform RRC of failure and clear timer - mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, - subframeP, rnti); - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; - } - + LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d: no RNTI \n", + module_idP, + frameP, + subframeP, + UE_id); continue; } - // loop over all active UL CC_ids for this UE - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list + // loop over all active UL CC_ids for this UE until end of function + for (int n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + /* This is the actual CC_id in the list */ CC_id = UE_list->ordered_ULCCids[n][UE_id]; - N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); - - /* - aggregation=get_aggregation(get_bw_index(module_idP,CC_id), - eNB_UE_stats->dl_cqi, - format0); - */ - - if (CCE_allocation_infeasible - (module_idP, CC_id, 1, subframeP, aggregation, rnti)) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - continue; // break; - } - - /* be sure that there are some free RBs */ - if (first_rb_slice[CC_id] >= N_RB_UL - 1) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - continue; - } - // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel - UE_template = &UE_list->UE_template[CC_id][UE_id]; - UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; + UE_template_ptr = &(UE_list->UE_template[CC_id][UE_id]); + UE_sched_ctrl_ptr = &(UE_list->UE_sched_ctrl[UE_id]); harq_pid = subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP); - round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; - AssertFatal(round < 8, "round %d > 7 for UE %d/%x\n", round, - UE_id, rnti); - LOG_D(MAC, - "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", - module_idP, frameP, subframeP, sched_frame, sched_subframeP, harq_pid, UE_id, rnti, - CC_id, aggregation, N_RB_UL); - RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] = UE_template->estimated_ul_buffer; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * - 10) + - subframeP]); - - if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round > 0) // || ((frameP%10)==0)) - // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames - { - LOG_D(MAC, - "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", - module_idP, harq_pid, frameP, subframeP, UE_id, rnti, - round, UE_template->ul_SR, - UE_sched_ctrl->ul_inactivity_timer, - UE_sched_ctrl->ul_failure_timer, - UE_sched_ctrl->cqi_req_timer); - // reset the scheduling request - UE_template->ul_SR = 0; - status = mac_eNB_get_rrc_status(module_idP, rnti); - cqi_req = 0; - - if (status >= RRC_CONNECTED && UE_sched_ctrl->cqi_req_timer > 30) { - if (UE_sched_ctrl->cqi_received == 0) { - if (nfapi_mode) { - cqi_req = 0; - } else { - cqi_req = 1; - - // To be safe , do not ask CQI in special Subframes:36.213/7.2.3 CQI definition - if (cc[CC_id].tdd_Config) { - switch (cc[CC_id].tdd_Config->subframeAssignment) { - case 1: - if( subframeP == 1 || subframeP == 6 ) cqi_req=0; + round_index = UE_sched_ctrl_ptr->round_UL[CC_id][harq_pid]; + AssertFatal(round_index < 8, "round %d > 7 for UE %d/%x\n", + round_index, + UE_id, + rnti); + LOG_D(MAC, "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", + module_idP, + frameP, + subframeP, + sched_frame, + sched_subframeP, + harq_pid, + UE_id, + rnti, + CC_id, + aggregation, + n_rb_ul_tab[CC_id]); + /* Seems unused, only for debug */ + RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] = UE_template_ptr->estimated_ul_buffer; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template_ptr->estimated_ul_buffer); - break; + /* + * If there is information on BSR of DCCH, DTCH or if there is UL_SR, + * or if there is a packet to retransmit, or we want to schedule a periodic feedback + */ + if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round_index > 0) { + LOG_D(MAC, "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", + module_idP, + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + round_index, + UE_template_ptr->ul_SR, + UE_sched_ctrl_ptr->ul_inactivity_timer, + UE_sched_ctrl_ptr->ul_failure_timer, + UE_sched_ctrl_ptr->cqi_req_timer); + + /* Reset the scheduling request */ + UE_template_ptr->ul_SR = 0; + status = mac_eNB_get_rrc_status(module_idP, rnti); - case 3: - if( subframeP == 1 ) cqi_req=0; + /* New transmission */ + if (round_index == 0) { + /* Be sure that there are some free RBs */ + if (first_rb_slice[CC_id] >= n_rb_ul_tab[CC_id]) { + LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", + module_idP, + frameP, + subframeP, + UE_id, + rnti, + CC_id); + + continue; + } - break; + /* Should format_flag be 2 in CCE_allocation_infeasible??? */ + /* This test seems to be way too long, can we provide an optimization? */ + if (CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, aggregation, rnti)) { + LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: not enough CCE\n", + module_idP, + frameP, + subframeP, + UE_id, + rnti, + CC_id); + + continue; + } + + /* Handle the aperiodic CQI report */ + cqi_req = 0; + + if (status >= RRC_CONNECTED && UE_sched_ctrl_ptr->cqi_req_timer > 30) { + if (UE_sched_ctrl_ptr->cqi_received == 0) { + if (NFAPI_MODE != NFAPI_MONOLITHIC) { + cqi_req = 0; + } else { + cqi_req = 1; + + /* TDD: to be safe, do not ask CQI in special Subframes:36.213/7.2.3 CQI definition */ + if (cc[CC_id].tdd_Config) { + switch (cc[CC_id].tdd_Config->subframeAssignment) { + case 1: + if(subframeP == 1 || subframeP == 6) { + cqi_req=0; + } + break; + + case 3: + if(subframeP == 1) { + cqi_req=0; + } + break; + + default: + LOG_E(MAC," TDD config not supported\n"); + break; + } + } - default: - LOG_E(MAC," TDD config not supported\n"); - break; + if(cqi_req == 1) { + UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP; } } - - if(cqi_req == 1) UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; + } else { + UE_sched_ctrl_ptr->cqi_req_flag = 0; + UE_sched_ctrl_ptr->cqi_received = 0; + UE_sched_ctrl_ptr->cqi_req_timer = 0; } - } else if (UE_sched_ctrl->cqi_received == 1) { - UE_sched_ctrl->cqi_req_flag = 0; - UE_sched_ctrl->cqi_received = 0; - UE_sched_ctrl->cqi_req_timer = 0; } - } - //power control - //compute the expected ULSCH RX power (for the stats) - // this is the normalized RX power and this should be constant (regardless of mcs - //is not in dBm, unit from nfapi, converting to dBm: ToDo: Noise power hard coded to 30 - normalized_rx_power = (5*UE_sched_ctrl->pusch_snr[CC_id]-640)/10+30; - target_rx_power= mac->puSch10xSnr/10 + 30; - //printf("\n mac->puSch10xSnr = %d, normalized_rx_power = %d, target_rx_power = %d \n",mac->puSch10xSnr,normalized_rx_power,target_rx_power); - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe; + /* Power control */ + /* + * Compute the expected ULSCH RX power (for the stats) + * This is the normalized RX power and this should be constant (regardless of mcs) + * Is not in dBm, unit from nfapi, converting to dBm + * ToDo: Noise power hard coded to 30 + */ + normalized_rx_power = ((5 * UE_sched_ctrl_ptr->pusch_snr[CC_id] - 640) / 10) + 30; + target_rx_power = (mac->puSch10xSnr / 10) + 30; - if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case - ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { //frame wrap-around - UE_template->pusch_tpc_tx_frame = frameP; - UE_template->pusch_tpc_tx_subframe = subframeP; + /* + * This assumes accumulated tpc + * Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + */ + framex10psubframe = (UE_template_ptr->pusch_tpc_tx_frame * 10) + UE_template_ptr->pusch_tpc_tx_subframe; - if (normalized_rx_power > (target_rx_power + 4)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power < (target_rx_power - 4)) { - tpc = 2; //+1 - tpc_accumulated++; + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { //frame wrap-around + + UE_template_ptr->pusch_tpc_tx_frame = frameP; + UE_template_ptr->pusch_tpc_tx_subframe = subframeP; + + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; // -1 + tpc_accumulated--; + } else if (normalized_rx_power < (target_rx_power - 4)) { + tpc = 2; // +1 + tpc_accumulated++; + } else { + tpc = 1; // 0 + } } else { - tpc = 1; //0 + tpc = 1; // 0 } - } else { - tpc = 1; //0 - } - //tpc = 1; - if (tpc != 1) { - LOG_D(MAC, - "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, tpc, - tpc_accumulated, normalized_rx_power, - target_rx_power); - } + if (tpc != 1) { + LOG_D(MAC, "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP, + frameP, + subframeP, + harq_pid, + tpc, + tpc_accumulated, + normalized_rx_power, + target_rx_power); + } - // new transmission - if (round == 0) { - ndi = 1 - UE_template->oldNDI_UL[harq_pid]; - UE_template->oldNDI_UL[harq_pid] = ndi; + ndi = 1 - UE_template_ptr->oldNDI_UL[harq_pid]; // NDI: new data indicator + UE_template_ptr->oldNDI_UL[harq_pid] = ndi; UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; - UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs); - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template->mcs_UL[harq_pid]; + UE_template_ptr->mcs_UL[harq_pid] = cmin(UE_template_ptr->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs); + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template_ptr->mcs_UL[harq_pid]; + + /* CDRX */ + if (UE_sched_ctrl_ptr->cdrx_configured) { + UE_sched_ctrl_ptr->drx_inactivity_timer = 1; // reset drx inactivity timer when new transmission + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) UE_sched_ctrl_ptr->drx_inactivity_timer); + UE_sched_ctrl_ptr->dci0_ongoing_timer = 1; // when set the UE_template_ptr->ul_SR cannot be set to 1, + // see definition for more information + } - //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS - if (UE_template->pre_allocated_rb_table_index_ul >= 0) { - rb_table_index = UE_template->pre_allocated_rb_table_index_ul; + if (UE_template_ptr->pre_allocated_rb_table_index_ul >= 0) { + rb_table_index = UE_template_ptr->pre_allocated_rb_table_index_ul; } else { - UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs); + UE_template_ptr->mcs_UL[harq_pid] = 10; rb_table_index = 5; // for PHR } - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; - // buffer_occupancy = UE_template->ul_total_buffer; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template_ptr->mcs_UL[harq_pid]; - while (((rb_table[rb_table_index] > (N_RB_UL - first_rb_slice[CC_id])) - || (rb_table[rb_table_index] > 45)) - && (rb_table_index > 0)) { + while (((rb_table[rb_table_index] > (n_rb_ul_tab[CC_id] - first_rb_slice[CC_id])) || + (rb_table[rb_table_index] > 45)) && (rb_table_index > 0)) { rb_table_index--; } - UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], - rb_table[rb_table_index]); + UE_template_ptr->TBS_UL[harq_pid] = get_TBS_UL(UE_template_ptr->mcs_UL[harq_pid], rb_table[rb_table_index]); UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template->TBS_UL[harq_pid]; - // buffer_occupancy -= TBS; - T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template_ptr->TBS_UL[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template_ptr->TBS_UL[harq_pid]; + T(T_ENB_MAC_UE_UL_SCHEDULE, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(UE_template_ptr->mcs_UL[harq_pid]), T_INT(first_rb_slice[CC_id]), T_INT(rb_table[rb_table_index]), - T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); - - if (mac_eNB_get_rrc_status(module_idP, rnti) < RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", - module_idP, harq_pid, rnti, CC_id, frameP, - subframeP, UE_id, - UE_template->mcs_UL[harq_pid], - first_rb_slice[CC_id], rb_table[rb_table_index], - rb_table_index, - UE_template->TBS_UL[harq_pid], harq_pid); - - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) - //store for possible retransmission - UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; - UE_template->first_rb_ul[harq_pid] = first_rb_slice[CC_id]; - UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); - - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, - UE_sched_ctrl->ul_scheduled); + T_INT(UE_template_ptr->TBS_UL[harq_pid]), + T_INT(ndi)); + /* Store information for possible retransmission */ + UE_template_ptr->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; + UE_template_ptr->first_rb_ul[harq_pid] = first_rb_slice[CC_id]; + UE_template_ptr->cqi_req[harq_pid] = cqi_req; + UE_sched_ctrl_ptr->ul_scheduled |= (1 << harq_pid); + + if (UE_id == UE_list->head) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, UE_sched_ctrl_ptr->ul_scheduled); + } - // adjust scheduled UL bytes by TBS, wait for UL sdus to do final update - LOG_D(MAC, - "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n", - module_idP, CC_id, UE_id, rnti, - UE_template->scheduled_ul_bytes, - UE_template->TBS_UL[harq_pid]); - UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid]; - LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes); - // Cyclic shift for DM RS + /* Adjust scheduled UL bytes by TBS, wait for UL sdus to do final update */ + LOG_D(MAC, "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n", + module_idP, + CC_id, + UE_id, + rnti, + UE_template_ptr->scheduled_ul_bytes, + UE_template_ptr->TBS_UL[harq_pid]); + UE_template_ptr->scheduled_ul_bytes += UE_template_ptr->TBS_UL[harq_pid]; + LOG_D(MAC, "scheduled_ul_bytes, new %d\n", + UE_template_ptr->scheduled_ul_bytes); + /* Cyclic shift for DM-RS */ cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) - // save it for a potential retransmission - UE_template->cshift[harq_pid] = cshift; + /* Save it for a potential retransmission */ + UE_template_ptr->cshift[harq_pid] = cshift; + /* Setting DCI0 NFAPI struct */ hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; memset((void *) hi_dci0_pdu, 0,sizeof(nfapi_hi_dci0_request_pdu_t)); hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; @@ -1429,23 +1679,27 @@ void schedule_ulsch_rnti(module_id_t module_idP, hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb_slice[CC_id]; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template->mcs_UL[harq_pid]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template_ptr->mcs_UL[harq_pid]; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template_ptr->DAI_ul[sched_subframeP]; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; hi_dci0_req_body->number_of_dci++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); //(frameP, subframeP, 4); + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! + hi_dci0_req->sfn_sf = frameP << 4 | subframeP; hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - LOG_D(MAC, - "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, frameP, subframeP, UE_id, rnti, - sched_frame, sched_subframeP); + LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP); ul_req_index = 0; dlsch_flag = 0; @@ -1453,48 +1707,55 @@ void schedule_ulsch_rnti(module_id_t module_idP, if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) { dlsch_flag = 1; - LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); + LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n", + frameP, + subframeP, + rnti, + ul_req_index); break; } } - // Add UL_config PDUs - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, - first_rb_slice[CC_id], // resource_block_start + /* Add UL_config PDUs */ + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], + cqi_req, + cc, + UE_template_ptr->physicalConfigDedicated, + get_tmode(module_idP, CC_id, UE_id), + mac->ul_handle, + rnti, + first_rb_slice[CC_id], // resource_block_start rb_table[rb_table_index], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - ndi, // new_data_indication - 0, // redundancy_version + UE_template_ptr->mcs_UL[harq_pid], + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + 0, // redundancy_version harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - get_TBS_UL - (UE_template-> - mcs_UL[harq_pid], - rb_table - [rb_table_index])); + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL(UE_template_ptr->mcs_UL[harq_pid], rb_table[rb_table_index])); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * - 10) + - subframeP); + /* This is a BL/CE UE allocation */ + if (UE_template_ptr->rach_resource_type > 0) { + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], + UE_template_ptr->rach_resource_type > 2 ? 2 : 1, + 1, // total_number_of_repetitions + 1, // repetition_number + (frameP * 10) + subframeP); } - #endif - if(dlsch_flag == 1) { - if(cqi_req == 1) { + if (dlsch_flag == 1) { + if (cqi_req == 1) { ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag= + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; } else { @@ -1514,65 +1775,92 @@ void schedule_ulsch_rnti(module_id_t module_idP, ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; mac->ul_handle++; - uint16_t ul_sched_frame = sched_frame; - uint16_t ul_sched_subframeP = sched_subframeP; - //add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); - ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; - add_ue_ulsch_info(module_idP, - CC_id, UE_id, subframeP, - S_UL_SCHEDULED); - LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP, CC_id, frameP, subframeP, UE_id); - LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); - // increment first rb for next UE allocation + ul_req_tmp->sfn_sf = sched_frame << 4 | sched_subframeP; + add_ue_ulsch_info(module_idP, CC_id, UE_id, subframeP, S_UL_SCHEDULED); + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", + module_idP, + CC_id, + frameP, + subframeP, + UE_id); + LOG_D(MAC, "[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", + harq_pid, + frameP, + subframeP, + sched_frame, + sched_subframeP, + cqi_req, + UE_id, + rnti); + /* Increment first rb for next UE allocation */ first_rb_slice[CC_id] += rb_table[rb_table_index]; - } else { // round > 0 => retransmission + } else { // round_index > 0 => retransmission T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, - T_INT(module_idP), T_INT(CC_id), T_INT(rnti), - T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb_slice[CC_id]), - T_INT(rb_table[rb_table_index]), T_INT(round)); - // Add UL_config PDUs - LOG_D(MAC, - "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, frameP, subframeP, UE_id, rnti, - sched_frame, sched_subframeP); + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(UE_template_ptr->mcs_UL[harq_pid]), + T_INT(UE_template_ptr->first_rb_ul[harq_pid]), + T_INT(UE_template_ptr->nb_rb_ul[harq_pid]), + T_INT(round_index)); + /* Add UL_config PDUs */ + LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP); ul_req_index = 0; dlsch_flag = 0; + cqi_req = UE_template_ptr->cqi_req[harq_pid]; for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) { if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) { dlsch_flag = 1; - LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); + LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n", + frameP, + subframeP, + rnti, + ul_req_index); break; } } - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, - UE_template->first_rb_ul[harq_pid], // resource_block_start - UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round & 3], // redundancy_version + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], + cqi_req, + cc, + UE_template_ptr->physicalConfigDedicated, + get_tmode(module_idP, CC_id, UE_id), + mac->ul_handle, + rnti, + UE_template_ptr->first_rb_ul[harq_pid], // resource_block_start + UE_template_ptr->nb_rb_ul[harq_pid], // number_of_resource_blocks + UE_template_ptr->mcs_UL[harq_pid], + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template_ptr->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round_index & 3], // redundancy_version harq_pid, // harq_process_number 0, // ul_tx_mode 0, // current_tx_nb 0, // n_srs - UE_template-> - TBS_UL[harq_pid]); + UE_template_ptr->TBS_UL[harq_pid]); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - - if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * - 10) + - subframeP); + /* This is a BL/CE UE allocation */ + if (UE_template_ptr->rach_resource_type > 0) { + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], + UE_template_ptr->rach_resource_type > 2 ? 2 : 1, + 1, // total_number_of_repetitions + 1, // repetition_number + (frameP * 10) + subframeP); } - #endif if(dlsch_flag == 1) { @@ -1583,7 +1871,7 @@ void schedule_ulsch_rnti(module_id_t module_idP, NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = - UE_template->nb_rb_ul[harq_pid]; + UE_template_ptr->nb_rb_ul[harq_pid]; } else { ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; @@ -1591,10 +1879,10 @@ void schedule_ulsch_rnti(module_id_t module_idP, NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = - UE_template->nb_rb_ul[harq_pid]; + UE_template_ptr->nb_rb_ul[harq_pid]; } - fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); + fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information, subframeP); } else { ul_req_tmp_body->number_of_pdus++; } @@ -1603,464 +1891,467 @@ void schedule_ulsch_rnti(module_id_t module_idP, ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP; ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,cqi_req); - } /* - - else if (round > 0) { //we schedule a retransmission - - ndi = UE_template->oldNDI_UL[harq_pid]; - - if ((round&3)==0) { - mcs = openair_daq_vars.target_ue_ul_mcs; - } else { - mcs = rvidx_tab[round&3] + 28; //not correct for round==4! - - } - - LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", - module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, - first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], - harq_pid, round); - - rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, - first_rb[CC_id], - UE_template->nb_rb_ul[harq_pid]); - first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation - - UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; - } - */ - } // UE_is_to_be_scheduled - } // loop over UE_id - } // loop of CC_id + LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP, + cqi_req); + + /* HACK: RBs used by retransmission have to be reserved. + * The current mechanism uses the notion of 'first_rb', so + * we skip all RBs below the ones retransmitted. This is + * not correct. Imagine only RB 23 is retransmitted, then all + * RBs < 23 will be marked unusable for new transmissions (case where round == 0). + * Note also that this code works only if the preprocessor orders + * UEs with retransmission with higher priority than UEs with new + * transmission. + * All this should be cleaned up properly. + */ + if (first_rb_slice[CC_id] < UE_template_ptr->first_rb_ul[harq_pid] + UE_template_ptr->nb_rb_ul[harq_pid]) + first_rb_slice[CC_id] = UE_template_ptr->first_rb_ul[harq_pid] + UE_template_ptr->nb_rb_ul[harq_pid]; + } // end of round > 0 + } // UE_is_to_be_scheduled + } // loop over all active CC_ids + } // loop over UE_ids } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +//----------------------------------------------------------------------------- +/* + * default ULSCH scheduler for LTE-M + */ void schedule_ulsch_rnti_emtc(module_id_t module_idP, - frame_t frameP, - sub_frame_t subframeP, - unsigned char sched_subframeP, - int *emtc_active) + frame_t frameP, + sub_frame_t subframeP, + unsigned char sched_subframeP, + int *emtc_active) +//----------------------------------------------------------------------------- { - int UE_id; + int UE_id = -1; rnti_t rnti = -1; - uint8_t round = 0; + uint8_t round_UL = 0; uint8_t harq_pid = 0; uint8_t status = 0; - uint32_t cshift,ndi; - int32_t normalized_rx_power; - int32_t target_rx_power=-90; - int n; + uint32_t cshift = 0; + uint32_t ndi = 0; + int32_t normalized_rx_power = 0; + int32_t target_rx_power = -90; + int n = 0; int CC_id = 0; - int N_RB_UL; + int N_RB_UL = 0; + int sched_frame = frameP; + int rvidx_tab[4] = {0,2,3,1}; + int tpc = 0; + int cqi_req = 0; eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = eNB->common_channels; - UE_list_t *UE_list=&eNB->UE_list; - UE_TEMPLATE *UE_template; - UE_sched_ctrl *UE_sched_ctrl; - int sched_frame=frameP; - int rvidx_tab[4] = {0,2,3,1}; - int tpc=0; - int cqi_req=0; - - if (sched_subframeP<subframeP) sched_frame++; + UE_list_t *UE_list = &(eNB->UE_list); + UE_TEMPLATE *UE_template = NULL; + UE_sched_ctrl *UE_sched_ctrl = NULL; - nfapi_hi_dci0_request_body_t *hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; - nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; + if (sched_subframeP < subframeP) { + sched_frame++; + } - nfapi_ul_config_request_body_t *ul_req_tmp = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body; + nfapi_hi_dci0_request_body_t *hi_dci0_req = &(eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body); + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = NULL; + nfapi_ul_config_request_body_t *ul_req_tmp = &(eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body); - // loop over all active UEs - if ((frameP&1) == 1) return; + /* If frameP odd don't schedule */ + if ((frameP & 1) == 1) { + return; + } - for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) { + /* Loop over all active UEs */ + for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { + UE_template = &(UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]); - if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].rach_resource_type == 0) continue; + /* LTE-M device */ + if (UE_template->rach_resource_type == 0) { + continue; + } - // don't schedule if Msg4 is not received yet - if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) { - LOG_D(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", - module_idP,frameP,subframeP,UE_id); + /* Don't schedule if Msg4 is not received yet */ + if (UE_template->configured == FALSE) { + LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d: not configured, skipping UE scheduling \n", + module_idP, + frameP, + subframeP, + UE_id); continue; } - rnti = UE_RNTI(module_idP,UE_id); + rnti = UE_RNTI(module_idP, UE_id); - if (rnti==NOT_A_RNTI) { - LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id); + if (rnti == NOT_A_RNTI) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d: no RNTI \n", + module_idP, + frameP, + subframeP, + UE_id); continue; } - // loop over all active UL CC_ids for this UE - for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list + /* Loop over all active UL CC_ids for this UE */ + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + /* This is the actual CC_id in the list */ CC_id = UE_list->ordered_ULCCids[n][UE_id]; N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); - - - UE_template = &UE_list->UE_template[CC_id][UE_id]; + UE_template = &(UE_list->UE_template[CC_id][UE_id]); UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; harq_pid = 0; - round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; - AssertFatal(round<8,"round %d > 7 for UE %d/%x\n",round,UE_id,rnti); + round_UL = UE_sched_ctrl->round_UL[CC_id][harq_pid]; + AssertFatal(round_UL < 8,"round_UL %d > 7 for UE %d/%x\n", + round_UL, + UE_id, + rnti); LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for BL/CE UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", - module_idP,frameP,subframeP,harq_pid,UE_id,rnti,CC_id, 24,N_RB_UL); - + module_idP, + frameP, + subframeP, + harq_pid, + UE_id, + rnti, + CC_id, + 24, // agregation level + N_RB_UL); RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]); - if ((UE_template->ul_SR >0 || round > 0 || status < RRC_CONNECTED)&&(subframeP==5)) - // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames - { - LOG_I(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", - module_idP,harq_pid,frameP,subframeP,UE_id,rnti,round,UE_template->ul_SR, - UE_sched_ctrl->ul_inactivity_timer, - - UE_sched_ctrl->ul_failure_timer, - - UE_sched_ctrl->cqi_req_timer); - // reset the scheduling request - emtc_active[CC_id]=1; - UE_template->ul_SR = 0; - status = mac_eNB_get_rrc_status(module_idP,rnti); - - /* - if (status < RRC_CONNECTED) - cqi_req = 0; - else if (UE_sched_ctrl->cqi_req_timer>300) { - cqi_req = 1; - UE_sched_ctrl->cqi_req_timer=0; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template->estimated_ul_buffer); + + //if ((UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0) && (subframeP == 5)) { + if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == 5)) { + /* + * if there is information on bsr of DCCH, DTCH, + * or if there is UL_SR, + * or if there is a packet to retransmit, + * or we want to schedule a periodic feedback every frame + */ + LOG_D(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round_UL %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", + module_idP, + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + round_UL, + UE_template->ul_SR, + UE_sched_ctrl->ul_inactivity_timer, + UE_sched_ctrl->ul_failure_timer, + UE_sched_ctrl->cqi_req_timer); + /* Reset the scheduling request */ + emtc_active[CC_id] = 1; + UE_template->ul_SR = 0; + status = mac_eNB_get_rrc_status(module_idP,rnti); + cqi_req = 0; + /* Power control: compute the expected ULSCH RX power (for the stats) */ + /* This is the normalized RX power and this should be constant (regardless of mcs) */ + normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; + target_rx_power = 178; + /* This assumes accumulated tpc */ + /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */ + int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe; - } - else - cqi_req = 0; - */ - cqi_req = 0; - - - //power control - //compute the expected ULSCH RX power (for the stats) - - // this is the normalized RX power and this should be constant (regardless of mcs - normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id]; - target_rx_power = 178; - - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe; - if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case - ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around - { - UE_template->pusch_tpc_tx_frame=frameP; - UE_template->pusch_tpc_tx_subframe=subframeP; - if (normalized_rx_power>(target_rx_power+4)) { - tpc = 0; //-1 - UE_sched_ctrl->tpc_accumulated[CC_id]--; - } else if (normalized_rx_power<(target_rx_power-4)) { - tpc = 2; //+1 - UE_sched_ctrl->tpc_accumulated[CC_id]++; - } else { - tpc = 1; //0 - } - } else { + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { // frame wrap-around + UE_template->pusch_tpc_tx_frame = frameP; + UE_template->pusch_tpc_tx_subframe = subframeP; + + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; //-1 + UE_sched_ctrl->tpc_accumulated[CC_id]--; + } else if (normalized_rx_power < (target_rx_power - 4)) { + tpc = 2; //+1 + UE_sched_ctrl->tpc_accumulated[CC_id]++; + } else { tpc = 1; //0 } - //tpc = 1; - + } else { + tpc = 1; //0 + } - if (tpc!=1) { - LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP,frameP,subframeP,harq_pid,tpc, - UE_sched_ctrl->tpc_accumulated[CC_id],normalized_rx_power,target_rx_power); - } + if (tpc != 1) { + LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP, + frameP, + subframeP, + harq_pid, + tpc, + UE_sched_ctrl->tpc_accumulated[CC_id], + normalized_rx_power, + target_rx_power); + } - // new transmission - if (round==0) { - - ndi = 1-UE_template->oldNDI_UL[harq_pid]; - UE_template->oldNDI_UL[harq_pid]=ndi; - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=4; - UE_template->mcs_UL[harq_pid] = 4; - - - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=UE_template->mcs_UL[harq_pid]; - // buffer_occupancy = UE_template->ul_total_buffer; - - - - UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],6); - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=6; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid]; - // buffer_occupancy -= TBS; - - T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(0), T_INT(6), - T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); - - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) - //store for possible retransmission - UE_template->nb_rb_ul[harq_pid] = 6; - - - UE_sched_ctrl->ul_scheduled |= (1<<harq_pid); - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled); - - // adjust total UL buffer status by TBS, wait for UL sdus to do final update - UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid]; - - LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes); - - - // Cyclic shift for DM RS - cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) - // save it for a potential retransmission - UE_template->cshift[harq_pid] = cshift; - - AssertFatal (UE_template->physicalConfigDedicated != NULL, - "UE_template->physicalConfigDedicated is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, - "UE_template->physicalConfigDedicated->ext4 is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); - LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; - AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); - AssertFatal(epdcch_setconfig_r11->ext2!=NULL, "epdcch_setconfig_r11->ext2 is null\n"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present==LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); - AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310!=NULL, - "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present==LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, - "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); - - LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,(int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); - - UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); - hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; - memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); - - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1; - - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted - - AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11!=NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); - - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0; // Note: this should be dynamic - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13== - LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1-epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1; - - hi_dci0_req->number_of_dci++; - - - LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS mpdcch narrowband %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP, - (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); - - - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], - cqi_req, - cc, - UE_template->physicalConfigDedicated, - get_tmode(module_idP,CC_id,UE_id), - eNB->ul_handle, - rnti, - UE_template->first_rb_ul[harq_pid], // resource_block_start - UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], - cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round&3], // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - UE_template->TBS_UL[harq_pid] - ); - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], - UE_template->rach_resource_type>2 ? 2 : 1, - 1, //total_number_of_repetitions - 1, //repetition_number - (frameP*10)+subframeP); - - - ul_req_tmp->number_of_pdus++; - eNB->ul_handle++; - - add_ue_ulsch_info(module_idP, - CC_id, - UE_id, - subframeP, - S_UL_SCHEDULED); - - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id); + /* New transmission */ + if (round_UL == 0) { + ndi = 1 - UE_template->oldNDI_UL[harq_pid]; + UE_template->oldNDI_UL[harq_pid] = ndi; + UE_template->mcs_UL[harq_pid] = 4; + UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], 6); + UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = 4; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += 6; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; + T(T_ENB_MAC_UE_UL_SCHEDULE, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(0), + T_INT(6), + T_INT(UE_template->TBS_UL[harq_pid]), + T_INT(ndi)); + /* Store for possible retransmission */ + UE_template->nb_rb_ul[harq_pid] = 6; + UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); + if (UE_id == UE_list->head) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, UE_sched_ctrl->ul_scheduled); } - else { // round > 0 => retransmission - T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(0), T_INT(6), - T_INT(round)); - - AssertFatal (UE_template->physicalConfigDedicated != NULL, - "UE_template->physicalConfigDedicated is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, - "UE_template->physicalConfigDedicated->ext4 is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); - AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); - LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; - AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); - AssertFatal(epdcch_setconfig_r11->ext2!=NULL, "epdcch_setconfig_r11->ext2 is null\n"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present==LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); - AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310!=NULL, - "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); - AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present==LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, - "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); - - LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,(int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); - - UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); - hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; - memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); - - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1; - - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted - - AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11!=NULL, - "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); - - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0; // Note: this should be dynamic - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; - AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13== - LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, - "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1-epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = rvidx_tab[round&3]; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = harq_pid; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1; - - hi_dci0_req->number_of_dci++; - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], - cqi_req, - cc, - UE_template->physicalConfigDedicated, - get_tmode(module_idP,CC_id,UE_id), - eNB->ul_handle, - rnti, - UE_template->first_rb_ul[harq_pid], // resource_block_start - UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], - cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round&3], // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - UE_template->TBS_UL[harq_pid] - ); - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], - UE_template->rach_resource_type>2 ? 2 : 1, - 1, //total_number_of_repetitions - 1, //repetition_number - (frameP*10)+subframeP); - - ul_req_tmp->number_of_pdus++; - eNB->ul_handle++; - } - } // UE_is_to_be_scheduled + /* Adjust total UL buffer status by TBS, wait for UL sdus to do final update */ + UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid]; + LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes); + /* Cyclic shift for DMRS */ + cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) + /* save it for a potential retransmission */ + UE_template->cshift[harq_pid] = cshift; + AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); + LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; + AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, + "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS MPDCCH Narrowband %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP, + (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); + UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); + hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci + hi_dci0_req->number_of_hi]); + memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted + AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; // already set above... + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB = 3 + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1; + hi_dci0_req->number_of_dci++; + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG. Request for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS mpdcch narrowband %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP, + (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], + cqi_req, + cc, + UE_template->physicalConfigDedicated, + get_tmode(module_idP,CC_id,UE_id), + eNB->ul_handle, + rnti, + UE_template->first_rb_ul[harq_pid], // resource_block_start + UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round_UL&3], // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + UE_template->TBS_UL[harq_pid] + ); + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], + UE_template->rach_resource_type > 2 ? 2 : 1, + 1, // total_number_of_repetitions + 1, // repetition_number + (frameP * 10) + subframeP); + ul_req_tmp->number_of_pdus++; + eNB->ul_handle++; + add_ue_ulsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_UL_SCHEDULED); + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", + module_idP, + CC_id, + frameP, + subframeP, + UE_id); + } else { // round_UL > 0 => retransmission + /* In LTE-M the UL HARQ process is asynchronous */ + T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(0), + T_INT(6), + T_INT(round_UL)); + AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); + LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; + AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, + "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n", + harq_pid, + frameP, + subframeP, + UE_id, + rnti, + sched_frame, + sched_subframeP, + (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1); + UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb(cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); + hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]); + memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted + AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = rvidx_tab[round_UL&3]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = harq_pid; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1; + hi_dci0_req->number_of_dci++; + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], + cqi_req, + cc, + UE_template->physicalConfigDedicated, + get_tmode(module_idP,CC_id,UE_id), + eNB->ul_handle, + rnti, + UE_template->first_rb_ul[harq_pid], // resource_block_start + UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round_UL&3], // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + UE_template->TBS_UL[harq_pid] + ); + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], + UE_template->rach_resource_type>2 ? 2 : 1, + 1, //total_number_of_repetitions + 1, //repetition_number + (frameP * 10) + subframeP); + ul_req_tmp->number_of_pdus++; + eNB->ul_handle++; + } + } // UE_is_to_be_scheduled } // ULCCs } // loop over UE_id } diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 4c8e81cc0d624b2a64d6984b77cf5a2fa53f342a..8f9a1b94f61014c339ffba776d7cf6d40cb13029 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -88,6 +88,7 @@ * @{ */ +#define MAX_MAC_INST 16 #define BCCH_PAYLOAD_SIZE_MAX 128 #define CCCH_PAYLOAD_SIZE_MAX 128 #define PCCH_PAYLOAD_SIZE_MAX 128 @@ -564,6 +565,7 @@ typedef struct { uint16_t serving_num; UE_ULSCH_STATUS status; } eNB_ULSCH_INFO; + /*! \brief temp struct for DLSCH sched */ typedef struct { rnti_t rnti; @@ -572,6 +574,7 @@ typedef struct { uint16_t serving_num; UE_DLSCH_STATUS status; } eNB_DLSCH_INFO; + /*! \brief eNB overall statistics */ typedef struct { /// num BCCH PDU per CC @@ -646,6 +649,7 @@ typedef struct { int missed_deadlines; } eNB_STATS; + /*! \brief eNB statistics for the connected UEs*/ typedef struct { /// CRNTI of UE @@ -789,6 +793,7 @@ typedef struct { } eNB_UE_STATS; /*! \brief eNB template for UE context information */ + typedef struct { /// C-RNTI of UE rnti_t rnti; @@ -826,6 +831,9 @@ typedef struct { /// Number of Allocated RBs for UL after scheduling uint16_t first_rb_ul[8]; // num_max_harq + /// Is CQI requested for UL after scheduling 1st transmission + uint8_t cqi_req[8]; // num_max_harq + /// Cyclic shift for DMRS after scheduling uint16_t cshift[8]; // num_max_harq @@ -1006,7 +1014,64 @@ typedef struct { int32_t uplane_inactivity_timer; uint8_t crnti_reconfigurationcomplete_flag; uint8_t cqi_req_flag; + + /* HARQ RRT Timers */ + /// (UL) HARQ RTT timers, especially used for CDRX operations, one timer per cell per harq process (and per user) + uint8_t harq_rtt_timer[NFAPI_CC_MAX][8]; + uint8_t ul_harq_rtt_timer[NFAPI_CC_MAX][8]; // Note: UL HARQ RTT timers are only for asynchronous HARQ processes + uint8_t ul_synchronous_harq_timer[NFAPI_CC_MAX][8]; // These timers are used for UL synchronous HARQ processes + + /* C-DRX related timers */ + /* Note: only valid for FDD and LTE UE when this comment is written (11-01-19)*/ + /// is TRUE if the cqi mask feature is activated by RRC configuration + boolean_t cqi_mask_boolean; + /// is TRUE if the following drx parameters are configured for UE + boolean_t cdrx_configured; + /* + * if TRUE, the eNB has configured the CDRX locally, but is waiting for the UE to acknowledge + * the activation. This is needed, during the RRC configuration process, when the context is + * configured on the eNB side, but not yet on the UE side... + */ + boolean_t cdrx_waiting_ack; + /* + * Is set when a ULSCH scheduling is done and run until the first corresponding transmission is done (4 subframes). + * When set, SR cannot be set for the UE. This allows OAI to avoid concidering a SR as uncompleted if the UE sends + * a SR just after a periodic DCI0 ULSCH scheduling. Without CDRX there is no problem, but with CDRX this case would + * create a lost in timers synchronization. + */ + uint8_t dci0_ongoing_timer; + /// is TRUE if the UE is in "Active Time", hence listening to PDCCH + boolean_t in_active_time; + /// OnDurationTimer + uint16_t on_duration_timer; + uint16_t on_duration_timer_thres; + /// drx-InactivityTimer + uint16_t drx_inactivity_timer; + uint16_t drx_inactivity_timer_thres; + /// is TRUE if UE is currently in short DRX cycle + boolean_t in_short_drx_cycle; + /// drxShortCycleTimer int (1..16) (number of short DRX cycles duration before long DRX cycles) + uint8_t drx_shortCycle_timer_value; + /// shortDRX-Cycle (duration of one short DRX cycle) + uint16_t short_drx_cycle_duration; + /// DRX short cycle timer before switching to long DRX cycle = drx_shortCycle_timer_value * short_drx_cycle_duration + uint16_t drx_shortCycle_timer; + uint16_t drx_shortCycle_timer_thres; + /// is TRUE if UE is currently in long DRX cycle + boolean_t in_long_drx_cycle; + /// longDRX-CycleStartOffset (long DRX cycle timer) + uint16_t drx_longCycle_timer; + uint16_t drx_longCycle_timer_thres; + /// longDRX-CycleStartOffset (offset value) + uint16_t drx_start_offset; + /// DRX retransmission timer, one per DL HARQ process + uint8_t drx_retransmission_timer[8]; + uint8_t drx_retransmission_timer_thres[8]; + /// DRX UL retransmission timer, one per UL HARQ process + /* Not implemented yet */ + /* End of C-DRX related timers */ } UE_sched_ctrl; + /*! \brief eNB template for the Random access information */ typedef struct { /// Flag to indicate this process is active @@ -1021,6 +1086,8 @@ typedef struct { sub_frame_t Msg3_subframe; /// Frame where Msg3 is to be sent frame_t Msg3_frame; + /// Delay cnt for Msg4 transmission (waiting for RRC message piggyback) + int Msg4_delay_cnt; /// Subframe where Msg4 is to be sent sub_frame_t Msg4_subframe; /// Frame where Msg4 is to be sent @@ -1109,13 +1176,13 @@ typedef struct { int avail; int num_UEs; boolean_t active[MAX_MOBILES_PER_ENB]; - + /// Sorting criteria for the UE list in the MAC preprocessor uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM]; uint16_t first_rb_offset[NFAPI_CC_MAX][MAX_NUM_SLICES]; - + int assoc_dl_slice_idx[MAX_MOBILES_PER_ENB]; - int assoc_ul_slice_idx[MAX_MOBILES_PER_ENB]; + int assoc_ul_slice_idx[MAX_MOBILES_PER_ENB]; } UE_list_t; /*! \brief deleting control information*/ @@ -1502,6 +1569,7 @@ typedef struct { int16_t bucket_size[MAX_NUM_LCID]; } UE_SCHEDULING_INFO; /*!\brief Top level UE MAC structure */ + typedef struct { uint16_t Node_id; /// RX frame counter diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index e8a5d29b058a1a9a71e5061981dc0cf004b1b984..8c5c69519395948a1513d856469f5e196c07155f 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -452,7 +452,7 @@ void init_ue_sched_info(void); void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframe, UE_ULSCH_STATUS status); void add_ue_dlsch_info(module_id_t module_idP, int CC_id, int UE_id, - sub_frame_t subframe, UE_DLSCH_STATUS status); + sub_frame_t subframe, UE_DLSCH_STATUS status, rnti_t rnti); int find_UE_id(module_id_t module_idP, rnti_t rnti); int find_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP); rnti_t UE_RNTI(module_id_t module_idP, int UE_id); @@ -463,7 +463,7 @@ uint8_t get_aggregation(uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt); int8_t find_active_UEs_with_traffic(module_id_t module_idP); -void init_CCE_table(int module_idP, int CC_idP); +void init_CCE_table(int *CCE_table); int get_nCCE_offset(int *CCE_table, const unsigned char L, @@ -727,8 +727,6 @@ int rrc_mac_remove_ue(module_id_t Mod_id, rnti_t rntiP); void store_dlsch_buffer(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframeP); void assign_rbs_required(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframe, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], int min_rb_unit[NFAPI_CC_MAX]); -int maxround(module_id_t Mod_id, uint16_t rnti, int frame, - sub_frame_t subframe, uint8_t ul_flag); void swap_UEs(UE_list_t * listP, int nodeiP, int nodejP, int ul_flag); int prev(UE_list_t * listP, int nodeP, int ul_flag); void dump_ue_list(UE_list_t * listP, int ul_flag); @@ -746,11 +744,11 @@ void set_ul_DAI(int module_idP, void ulsch_scheduler_pre_processor(module_id_t module_idP, int slice_idx, int frameP, sub_frame_t subframeP, + int sched_frameP, unsigned char sched_subframeP, uint16_t * first_rb); void store_ulsch_buffer(module_id_t module_idP, int frameP, sub_frame_t subframeP); -void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP); void assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, sub_frame_t subframeP, uint16_t * first_rb); void adjust_bsr_info(int buffer_occupancy, uint16_t TBS, @@ -1246,7 +1244,6 @@ void fill_nfapi_dlsch_config(eNB_MAC_INST * eNB, void fill_nfapi_harq_information(module_id_t module_idP, int CC_idP, uint16_t rntiP, - uint16_t absSFP, nfapi_ul_config_harq_information * harq_information, uint8_t cce_idxP); @@ -1258,9 +1255,10 @@ void fill_nfapi_ulsch_harq_information(module_id_t module_idP, sub_frame_t subframeP); uint16_t fill_nfapi_uci_acknak(module_id_t module_idP, - int CC_idP, - uint16_t rntiP, - uint16_t absSFP, uint8_t cce_idxP); + int CC_idP, + uint16_t rntiP, + uint16_t absSFP, + uint8_t cce_idxP); void fill_nfapi_dl_dci_1A(nfapi_dl_config_request_pdu_t * dl_config_pdu, uint8_t aggregation_level, @@ -1312,11 +1310,15 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]); #endif -/*Slice related functions */ +/* Slice related functions */ uint16_t nb_rbs_allowed_slice(float rb_percentage, int total_rbs); int ue_dl_slice_membership(module_id_t mod_id, int UE_id, int slice_idx); int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx); +/* DRX Configuration */ +/* Configure local DRX timers and thresholds in UE context, following the drx_configuration input */ +void eNB_Config_Local_DRX(module_id_t Mod_id, rnti_t rnti, LTE_DRX_Config_t *drx_Configuration); + /* from here: prototypes to get rid of compilation warnings: doc to be written by function author */ uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe); #endif diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c index 1168ed265abde1667da8f9e28f5395c96d093bc4..f482806e1d198ef7ed98a3e97f6cf6c1192e5ab2 100644 --- a/openair2/LAYER2/MAC/main_ue.c +++ b/openair2/LAYER2/MAC/main_ue.c @@ -39,120 +39,95 @@ #include "LAYER2/PDCP_v10.1.0/pdcp.h" #include "RRC/LTE/rrc_defs.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "common/ran_context.h" extern FILL_UL_INFO_MUTEX_t fill_ul_mutex; -extern uint8_t nfapi_mode; -extern void openair_rrc_top_init_ue( int eMBMS_active, char* uecap_xer, uint8_t cba_group_active, uint8_t HO_active); - -void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) //init as MR -{ - LOG_D(MAC, "[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n", - module_idP, frameP, eNB_index); -#if defined(ENABLE_USE_MME) - int mme_enabled = 1; -#else - int mme_enabled = 0; -#endif - - if (first_sync == 1 && !(mme_enabled == 1)) { - //layer2_init_UE(module_idP); - openair_rrc_ue_init(module_idP, eNB_index); - } else { - rrc_in_sync_ind(module_idP, frameP, eNB_index); - } +extern void openair_rrc_top_init_ue( int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active); + +void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) { //init as MR + LOG_D(MAC, "[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n", + module_idP, frameP, eNB_index); + + if (first_sync == 1 && !(EPC_MODE_ENABLED)) { + //layer2_init_UE(module_idP); + openair_rrc_ue_init(module_idP, eNB_index); + } else { + rrc_in_sync_ind(module_idP, frameP, eNB_index); + } } void mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP, - uint16_t eNB_index) -{ - - // Mac_rlc_xface->mac_out_of_sync_ind(Mod_id, frameP, eNB_index); + uint16_t eNB_index) { + // Mac_rlc_xface->mac_out_of_sync_ind(Mod_id, frameP, eNB_index); } int mac_top_init_ue(int eMBMS_active, char *uecap_xer, - uint8_t cba_group_active, uint8_t HO_active) -{ - - int i; - - LOG_I(MAC, "[MAIN] Init function start:Nb_UE_INST=%d\n", NB_UE_INST); - - if (NB_UE_INST > 0) { - UE_mac_inst = - (UE_MAC_INST *) malloc16(NB_UE_INST * sizeof(UE_MAC_INST)); - - AssertFatal(UE_mac_inst != NULL, - "[MAIN] Can't ALLOCATE %zu Bytes for %d UE_MAC_INST with size %zu \n", - NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST, - sizeof(UE_MAC_INST)); - - LOG_D(MAC, "[MAIN] ALLOCATE %zu Bytes for %d UE_MAC_INST @ %p\n", - NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST, UE_mac_inst); - - bzero(UE_mac_inst, NB_UE_INST * sizeof(UE_MAC_INST)); - - for (i = 0; i < NB_UE_INST; i++) { - ue_init_mac(i); - } - } else { - UE_mac_inst = NULL; - } - - // mutex below are used for multiple UE's L2 FAPI simulation. - if (nfapi_mode == 3){ - pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL); + uint8_t cba_group_active, uint8_t HO_active) { + int i; + LOG_I(MAC, "[MAIN] Init function start:Nb_UE_INST=%d\n", NB_UE_INST); + + if (NB_UE_INST > 0) { + UE_mac_inst = + (UE_MAC_INST *) malloc16(NB_UE_INST * sizeof(UE_MAC_INST)); + AssertFatal(UE_mac_inst != NULL, + "[MAIN] Can't ALLOCATE %zu Bytes for %d UE_MAC_INST with size %zu \n", + NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST, + sizeof(UE_MAC_INST)); + LOG_D(MAC, "[MAIN] ALLOCATE %zu Bytes for %d UE_MAC_INST @ %p\n", + NB_UE_INST * sizeof(UE_MAC_INST), NB_UE_INST, UE_mac_inst); + bzero(UE_mac_inst, NB_UE_INST * sizeof(UE_MAC_INST)); + + for (i = 0; i < NB_UE_INST; i++) { + ue_init_mac(i); } - - LOG_I(MAC, "[MAIN] calling RRC\n"); - openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, - HO_active); - - - LOG_I(MAC, "[MAIN][INIT] Init function finished\n"); - - return (0); - + } else { + UE_mac_inst = NULL; + } + + // mutex below are used for multiple UE's L2 FAPI simulation. + if (NFAPI_MODE == NFAPI_UE_STUB_PNF) { + pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL); + } + + LOG_I(MAC, "[MAIN] calling RRC\n"); + openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, + HO_active); + LOG_I(MAC, "[MAIN][INIT] Init function finished\n"); + return (0); } -int rlcmac_init_global_param_ue(void) -{ - - - LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n"); - - if (rlc_module_init() != 0) { - return (-1); - } - - pdcp_layer_init(); +int rlcmac_init_global_param_ue(void) { + LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n"); - LOG_I(MAC, "[MAIN] Init Global Param Done\n"); + if (rlc_module_init() != 0) { + return (-1); + } - return 0; + pdcp_layer_init(); + LOG_I(MAC, "[MAIN] Init Global Param Done\n"); + return 0; } int l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, - uint8_t HO_active) -{ - LOG_I(MAC, "[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n"); - // NB_NODE=2; - // NB_INST=2; - - rlcmac_init_global_param_ue(); - LOG_I(MAC, "[MAIN] init UE MAC functions \n"); - mac_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, HO_active); - return (1); + uint8_t HO_active) { + LOG_I(MAC, "[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n"); + // NB_NODE=2; + // NB_INST=2; + rlcmac_init_global_param_ue(); + LOG_I(MAC, "[MAIN] init UE MAC functions \n"); + mac_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, HO_active); + return (1); } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index e98019eff9d3e8cf4da6ac56b135722ed9a921dc..e70ed082f97eefc83b0fa59717b270c50f8a19ce 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -56,6 +56,13 @@ extern RAN_CONTEXT_t RC; //#define ICIC 0 +void +sort_ue_ul(module_id_t module_idP, + int slice_idx, + int sched_frameP, + sub_frame_t sched_subframeP, + rnti_t *rntiTable); + /* this function checks that get_eNB_UE_stats returns * a non-NULL pointer for all the active CCs of an UE */ @@ -68,12 +75,12 @@ int phy_stats_exist(module_id_t Mod_id, int rnti) UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; if (UE_id == -1) { LOG_W(MAC, "[eNB %d] UE %x not found, should be there (in phy_stats_exist)\n", - Mod_id, rnti); + Mod_id, rnti); return 0; } if (UE_list->numactiveCCs[UE_id] == 0) { LOG_W(MAC, "[eNB %d] UE %x has no active CC (in phy_stats_exist)\n", - Mod_id, rnti); + Mod_id, rnti); return 0; } for (i = 0; i < UE_list->numactiveCCs[UE_id]; i++) { @@ -91,7 +98,6 @@ store_dlsch_buffer(module_id_t Mod_id, int slice_idx, frame_t frameP, sub_frame_t subframeP) { - int UE_id, lcid; rnti_t rnti; mac_rlc_status_resp_t rlc_status; @@ -100,13 +106,12 @@ store_dlsch_buffer(module_id_t Mod_id, for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { if (UE_list->active[UE_id] != TRUE) - continue; + continue; if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; UE_template = &UE_list->UE_template[UE_PCCID(Mod_id, UE_id)][UE_id]; - // clear logical channel interface variables UE_template->dl_buffer_total = 0; UE_template->dl_pdus_total = 0; @@ -121,25 +126,23 @@ store_dlsch_buffer(module_id_t Mod_id, rnti = UE_RNTI(Mod_id, UE_id); for (lcid = 0; lcid < MAX_NUM_LCID; ++lcid) { // loop over all the logical channels - - rlc_status = mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, - ENB_FLAG_YES, MBMS_FLAG_NO, lcid, 0 -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 -#endif - ); + rlc_status = mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, + ENB_FLAG_YES, MBMS_FLAG_NO, lcid, 0 + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0, 0 + #endif + ); UE_template->dl_buffer_info[lcid] = rlc_status.bytes_in_buffer; //storing the dlsch buffer for each logical channel UE_template->dl_pdus_in_buffer[lcid] = rlc_status.pdus_in_buffer; UE_template->dl_buffer_head_sdu_creation_time[lcid] = rlc_status.head_sdu_creation_time; UE_template->dl_buffer_head_sdu_creation_time_max = - cmax(UE_template->dl_buffer_head_sdu_creation_time_max, rlc_status.head_sdu_creation_time); + cmax(UE_template->dl_buffer_head_sdu_creation_time_max, rlc_status.head_sdu_creation_time); UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid] = rlc_status.head_sdu_remaining_size_to_send; UE_template->dl_buffer_head_sdu_is_segmented[lcid] = rlc_status.head_sdu_is_segmented; UE_template->dl_buffer_total += UE_template->dl_buffer_info[lcid]; //storing the total dlsch buffer UE_template->dl_pdus_total += UE_template->dl_pdus_in_buffer[lcid]; -#ifdef DEBUG_eNB_SCHEDULER - + #ifdef DEBUG_eNB_SCHEDULER /* note for dl_buffer_head_sdu_remaining_size_to_send[lcid] : * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent */ @@ -152,9 +155,7 @@ store_dlsch_buffer(module_id_t Mod_id, UE_template->dl_buffer_head_sdu_creation_time[lcid], UE_template->dl_buffer_head_sdu_remaining_size_to_send[lcid], UE_template->dl_buffer_head_sdu_is_segmented[lcid]); - -#endif - + #endif } @@ -178,11 +179,8 @@ assign_rbs_required(module_id_t Mod_id, frame_t frameP, sub_frame_t subframe, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - int min_rb_unit[NFAPI_CC_MAX]) -{ - + int min_rb_unit[NFAPI_CC_MAX]) { uint16_t TBS = 0; - int UE_id, n, i, j, CC_id, pCCid, tmp; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; slice_info_t *sli = &RC.mac[Mod_id]->slice_info; @@ -192,25 +190,27 @@ assign_rbs_required(module_id_t Mod_id, // clear rb allocations across all CC_id for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { if (UE_list->active[UE_id] != TRUE) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; + pCCid = UE_PCCID(Mod_id, UE_id); //update CQI information across component carriers for (n = 0; n < UE_list->numactiveCCs[UE_id]; n++) { - CC_id = UE_list->ordered_CCids[n][UE_id]; eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; -// eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], sli->dl[slice_idx].maxmcs); + // eNB_UE_stats->dlsch_mcs1 = cmin(cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]], sli->dl[slice_idx].maxmcs); eNB_UE_stats->dlsch_mcs1 = cmin(cqi2mcs(UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]), sli->dl[slice_idx].maxmcs); - } // provide the list of CCs sorted according to MCS for (i = 0; i < UE_list->numactiveCCs[UE_id]; ++i) { eNB_UE_stats_i = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[i][UE_id]][UE_id]; + for (j = i + 1; j < UE_list->numactiveCCs[UE_id]; j++) { DevAssert(j < NFAPI_CC_MAX); eNB_UE_stats_j = &UE_list->eNB_UE_stats[UE_list->ordered_CCids[j][UE_id]][UE_id]; + if (eNB_UE_stats_j->dlsch_mcs1 > eNB_UE_stats_i->dlsch_mcs1) { tmp = UE_list->ordered_CCids[i][UE_id]; UE_list->ordered_CCids[i][UE_id] = UE_list->ordered_CCids[j][UE_id]; @@ -233,18 +233,15 @@ assign_rbs_required(module_id_t Mod_id, } TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]); - LOG_D(MAC, "[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n", UE_id, CC_id, UE_list->UE_template[pCCid][UE_id].dl_buffer_total, nb_rbs_required[CC_id][UE_id], eNB_UE_stats->dlsch_mcs1, TBS); - N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); - UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx] = - nb_rbs_allowed_slice(sli->dl[slice_idx].pct, N_RB_DL); + nb_rbs_allowed_slice(sli->dl[slice_idx].pct, N_RB_DL); /* calculating required number of RBs for each UE */ while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) { @@ -255,6 +252,7 @@ assign_rbs_required(module_id_t Mod_id, nb_rbs_required[CC_id][UE_id] = UE_list->UE_sched_ctrl[UE_id].max_rbs_allowed_slice[CC_id][slice_idx]; break; } + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rbs_required[CC_id][UE_id]); } // end of while @@ -263,7 +261,6 @@ assign_rbs_required(module_id_t Mod_id, Mod_id, frameP, UE_id, CC_id, min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats->dlsch_mcs1); - sli->pre_processor_results[slice_idx].mcs[CC_id][UE_id] = eNB_UE_stats->dlsch_mcs1; } } @@ -274,8 +271,7 @@ assign_rbs_required(module_id_t Mod_id, // This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes int maxround(module_id_t Mod_id, uint16_t rnti, int frame, - sub_frame_t subframe, uint8_t ul_flag) { - + sub_frame_t subframe) { uint8_t round, round_max = 0, UE_id; int CC_id, harq_pid; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; @@ -283,11 +279,32 @@ maxround(module_id_t Mod_id, uint16_t rnti, int frame, for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { cc = &RC.mac[Mod_id]->common_channels[CC_id]; + UE_id = find_UE_id(Mod_id, rnti); + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame,subframe); + round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid]; + if (round > round_max) { + round_max = round; + } + } + + return round_max; +} + +int +maxround_ul(module_id_t Mod_id, uint16_t rnti, int sched_frame, + sub_frame_t sched_subframe) { + uint8_t round, round_max = 0, UE_id; + int CC_id, harq_pid; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + COMMON_channels_t *cc; + + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { + cc = &RC.mac[Mod_id]->common_channels[CC_id]; UE_id = find_UE_id(Mod_id, rnti); - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame ,subframe); + harq_pid = subframe2harqpid(cc, sched_frame, sched_subframe); + round = UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid]; - round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid]; if (round > round_max) { round_max = round; } @@ -329,44 +346,39 @@ long min_lcgidpriority(module_id_t Mod_id, int32_t UE_id) { } struct sort_ue_dl_params { - int Mod_idP; - int frameP; - int subframeP; - int slice_idx; + int Mod_idP; + int frameP; + int subframeP; + int slice_idx; }; -static int ue_dl_compare(const void *_a, const void *_b, void *_params) -{ +static int ue_dl_compare(const void *_a, const void *_b, void *_params) { struct sort_ue_dl_params *params = _params; UE_list_t *UE_list = &RC.mac[params->Mod_idP]->UE_list; - int i; int slice_idx = params->slice_idx; int UE_id1 = *(const int *) _a; int UE_id2 = *(const int *) _b; - int rnti1 = UE_RNTI(params->Mod_idP, UE_id1); int pCC_id1 = UE_PCCID(params->Mod_idP, UE_id1); - int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP, 1); - + int round1 = maxround(params->Mod_idP, rnti1, params->frameP, params->subframeP); int rnti2 = UE_RNTI(params->Mod_idP, UE_id2); int pCC_id2 = UE_PCCID(params->Mod_idP, UE_id2); - int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP, 1); - + int round2 = maxround(params->Mod_idP, rnti2, params->frameP, params->subframeP); int cqi1 = maxcqi(params->Mod_idP, UE_id1); int cqi2 = maxcqi(params->Mod_idP, UE_id2); - long lcgid1 = min_lcgidpriority(params->Mod_idP, UE_id1); long lcgid2 = min_lcgidpriority(params->Mod_idP, UE_id2); for (i = 0; i < CR_NUM; ++i) { switch (UE_list->sorting_criteria[slice_idx][i]) { - case CR_ROUND : if (round1 > round2) return -1; + if (round1 < round2) return 1; + break; case CR_SRB12 : @@ -375,41 +387,50 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) return -1; + if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2] < UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) return 1; + break; case CR_HOL : if (UE_list-> UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max > UE_list-> UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max) return -1; + if (UE_list-> UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max < UE_list-> UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max) return 1; + break; case CR_LC : if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total > UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) return -1; + if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total < UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total) return 1; + break; case CR_CQI : if (cqi1 > cqi2) return -1; + if (cqi1 < cqi2) return 1; + break; case CR_LCP : if (lcgid1 < lcgid2) return -1; + if (lcgid1 > lcgid2) return 1; @@ -418,12 +439,11 @@ static int ue_dl_compare(const void *_a, const void *_b, void *_params) } } - return 0; + return 0; } void decode_sorting_policy(module_id_t Mod_idP, int slice_idx) { int i; - UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; uint32_t policy = RC.mac[Mod_idP]->slice_info.dl[slice_idx].sorting; uint32_t mask = 0x0000000F; @@ -431,6 +451,7 @@ void decode_sorting_policy(module_id_t Mod_idP, int slice_idx) { for (i = 0; i < CR_NUM; ++i) { criterion = (uint16_t) (policy >> 4 * (CR_NUM - 1 - i) & mask); + if (criterion >= CR_NUM) { LOG_W(MAC, "Invalid criterion in slice index %d ID %d policy, revert to default policy \n", @@ -438,14 +459,14 @@ void decode_sorting_policy(module_id_t Mod_idP, int slice_idx) { RC.mac[Mod_idP]->slice_info.dl[slice_idx].sorting = 0x12345; break; } + UE_list->sorting_criteria[slice_idx][i] = criterion; } } void decode_slice_positioning(module_id_t Mod_idP, int slice_idx, - uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]) -{ + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]) { uint8_t CC_id; int RBG, start_frequency, end_frequency; @@ -458,6 +479,7 @@ void decode_slice_positioning(module_id_t Mod_idP, start_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_idx].pos_low; end_frequency = RC.mac[Mod_idP]->slice_info.dl[slice_idx].pos_high; + for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_idP]; ++CC_id) { for (RBG = start_frequency; RBG <= end_frequency; ++RBG) { slice_allocation_mask[CC_id][RBG] = 1; @@ -465,35 +487,49 @@ void decode_slice_positioning(module_id_t Mod_idP, } } - -// This fuction sorts the UE in order their dlsch buffer and CQI -void sort_UEs(module_id_t Mod_idP, int slice_idx, int frameP, sub_frame_t subframeP) +//----------------------------------------------------------------------------- +/* + * This function sorts the UEs in order, depending on their dlsch buffer and CQI + */ +void sort_UEs(module_id_t Mod_idP, + int slice_idx, + int frameP, + sub_frame_t subframeP) +//----------------------------------------------------------------------------- { - int i; int list[MAX_MOBILES_PER_ENB]; int list_size = 0; struct sort_ue_dl_params params = {Mod_idP, frameP, subframeP, slice_idx}; + UE_list_t *UE_list = &(RC.mac[Mod_idP]->UE_list); + UE_sched_ctrl *UE_scheduling_control = NULL; - UE_list_t *UE_list = &RC.mac[Mod_idP]->UE_list; + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + UE_scheduling_control = &(UE_list->UE_sched_ctrl[i]); - if (UE_list->active[i] == FALSE) continue; - if (UE_RNTI(Mod_idP, i) == NOT_A_RNTI) continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) continue; - if (!ue_dl_slice_membership(Mod_idP, i, slice_idx)) continue; + /* Check CDRX configuration and if UE is in active time for this subframe */ + if (UE_scheduling_control->cdrx_configured == TRUE) { + if (UE_scheduling_control->in_active_time == FALSE) { + continue; + } + } - list[list_size] = i; - list_size++; + if (UE_list->active[i] == TRUE && + UE_RNTI(Mod_idP, i) != NOT_A_RNTI && + UE_list->UE_sched_ctrl[i].ul_out_of_sync != 1 && + ue_dl_slice_membership(Mod_idP, i, slice_idx)) { + list[list_size++] = i; + } } decode_sorting_policy(Mod_idP, slice_idx); - qsort_r(list, list_size, sizeof(int), ue_dl_compare, ¶ms); if (list_size) { - for (i = 0; i < list_size - 1; ++i) + for (int i = 0; i < list_size - 1; ++i) { UE_list->next[list[i]] = list[i + 1]; + } + UE_list->next[list[list_size - 1]] = -1; UE_list->head = list[0]; } else { @@ -502,18 +538,18 @@ void sort_UEs(module_id_t Mod_idP, int slice_idx, int frameP, sub_frame_t subfra } void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, - int slice_idx, - const uint8_t rbs_retx[NFAPI_CC_MAX]) -{ + int slice_idx, + const uint8_t rbs_retx[NFAPI_CC_MAX]) { int UE_id, CC_id, N_RB_DL, i; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; uint16_t available_rbs; for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; @@ -522,6 +558,7 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, CC_id = UE_list->ordered_CCids[i][UE_id]; N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); available_rbs = nb_rbs_allowed_slice(RC.mac[Mod_id]->slice_info.dl[slice_idx].pct, N_RB_DL); + if (rbs_retx[CC_id] < available_rbs) ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx] = available_rbs - rbs_retx[CC_id]; else @@ -531,16 +568,14 @@ void dlsch_scheduler_pre_processor_partitioning(module_id_t Mod_id, } void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, - int slice_idx, - frame_t frameP, - sub_frame_t subframeP, - int min_rb_unit[NFAPI_CC_MAX], - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) -{ + int slice_idx, + frame_t frameP, + sub_frame_t subframeP, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]) { int UE_id, CC_id; int i; - rnti_t rnti; uint8_t harq_pid, round; uint16_t available_rbs[NFAPI_CC_MAX]; @@ -550,7 +585,6 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, int ue_count_newtx[NFAPI_CC_MAX]; int ue_count_retx[NFAPI_CC_MAX]; //uint8_t ue_retx_flag[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; UE_sched_ctrl *ue_sched_ctl; COMMON_channels_t *cc; @@ -571,15 +605,18 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // Find total UE count, and account the RBs required for retransmissions for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id]; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); round = ue_sched_ctl->round[CC_id][harq_pid]; if (nb_rbs_required[CC_id][UE_id] > 0) { @@ -603,46 +640,53 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { if (UE_list->head < 0) continue; // no UEs in list - // max_rbs_allowed_slice is saved in every UE, so take it from the first one + + // max_rbs_allowed_slice is saved in every UE, so take it from the first one ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_list->head]; available_rbs[CC_id] = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx]; } switch (RC.mac[Mod_id]->slice_info.dl[slice_idx].accounting) { - // If greedy scheduling, try to account all the required RBs case POL_GREEDY: - for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; + if (available_rbs[CC_id] == 0) continue; + nb_rbs_accounted[CC_id][UE_id] = cmin(nb_rbs_required[CC_id][UE_id], available_rbs[CC_id]); available_rbs[CC_id] -= nb_rbs_accounted[CC_id][UE_id]; } } + break; // Use the old, fair algorithm // Loop over all active UEs and account the avg number of RBs to each UE, based on all non-retx UEs. // case POL_FAIR: default: + // FIXME: This is not ideal, why loop on UEs to find average_rbs_per_user[], that is per-CC? // TODO: Look how to loop on active CCs only without using the UE_num_active_CC() function. for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); ++i) { - CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; available_rbs[CC_id] = ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_idx]; @@ -662,8 +706,11 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, // extend nb_rbs_required to capture per LCID RB required for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { @@ -671,25 +718,26 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, nb_rbs_accounted[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); } } + break; } - - - // Check retransmissions // TODO: Do this once at the beginning for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; cc = &RC.mac[Mod_id]->common_channels[CC_id]; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); round = ue_sched_ctl->round[CC_id][harq_pid]; // control channel or retransmission @@ -702,23 +750,23 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, } void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, - int slice_idx, - int min_rb_unit[NFAPI_CC_MAX], - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) -{ + int slice_idx, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { int UE_id, CC_id; int i; -#ifdef TM5 + + #ifdef TM5 uint8_t transmission_mode; -#endif + #endif + uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; int N_RBG[NFAPI_CC_MAX]; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - decode_slice_positioning(Mod_id, slice_idx, slice_allocation_mask); for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { @@ -728,17 +776,19 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, // Try to allocate accounted RBs for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; nb_rbs_remaining[CC_id][UE_id] = nb_rbs_accounted[CC_id][UE_id]; -#ifdef TM5 + + #ifdef TM5 transmission_mode = get_tmode(Mod_id, CC_id, UE_id); -#endif + #endif if (nb_rbs_required[CC_id][UE_id] > 0) LOG_D(MAC, @@ -764,191 +814,183 @@ void dlsch_scheduler_pre_processor_positioning(module_id_t Mod_id, slice_allocation_mask, MIMO_mode_indicator); -#ifdef TM5 + #ifdef TM5 // data chanel TM5: to be revisited - if ((round == 0) && - (transmission_mode == 5) && - (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { - + if ((round == 0) && + (transmission_mode == 5) && + (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { for (j = 0; j < N_RBG[CC_id]; j += 2) { - - if ((((j == (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j] == 0) - && (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j + 1] == 0) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j + 1] == 0))) - && (nb_rbs_remaining[CC_id][UE_id] - > 0)) { - + if ((((j == (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j] == 0) + && (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j + 1] == 0) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j + 1] == 0))) + && (nb_rbs_remaining[CC_id][UE_id] + > 0)) { for (i = UE_list->next[UE_id + 1]; i >= 0; i = UE_list->next[i]) { - - UE_id2 = i; - rnti2 = UE_RNTI(Mod_id, UE_id2); - ue_sched_ctl2 = + UE_id2 = i; + rnti2 = UE_RNTI(Mod_id, UE_id2); + ue_sched_ctl2 = &UE_list->UE_sched_ctrl[UE_id2]; - round2 = ue_sched_ctl2->round[CC_id]; - if (rnti2 == NOT_A_RNTI) + round2 = ue_sched_ctl2->round[CC_id]; + + if (rnti2 == NOT_A_RNTI) continue; - if (UE_list-> - UE_sched_ctrl - [UE_id2].ul_out_of_sync == 1) + + if (UE_list-> + UE_sched_ctrl + [UE_id2].ul_out_of_sync == 1) continue; - eNB_UE_stats2 = + eNB_UE_stats2 = UE_list-> eNB_UE_stats[CC_id][UE_id2]; - //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); - - if ((mac_eNB_get_rrc_status - (Mod_id, - rnti2) >= RRC_RECONFIGURED) - && (round2 == 0) - && - (get_tmode(Mod_id, CC_id, UE_id2) - == 5) - && (ue_sched_ctl-> - dl_pow_off[CC_id] != 1)) { + //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); + if ((mac_eNB_get_rrc_status + (Mod_id, + rnti2) >= RRC_RECONFIGURED) + && (round2 == 0) + && + (get_tmode(Mod_id, CC_id, UE_id2) + == 5) + && (ue_sched_ctl-> + dl_pow_off[CC_id] != 1)) { if ((((j == (N_RBG[CC_id] - 1)) && (ue_sched_ctl->rballoc_sub_UE [CC_id][j] == 0)) || ((j < (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j + - 1] - == 0))) + && + (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j + + 1] + == 0))) && (nb_rbs_remaining [CC_id] [UE_id2] > 0)) { - - if ((((eNB_UE_stats2-> - DL_pmi_single ^ - eNB_UE_stats1-> - DL_pmi_single) - << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration - + if ((((eNB_UE_stats2-> + DL_pmi_single ^ + eNB_UE_stats1-> + DL_pmi_single) + << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration rballoc_sub[CC_id][j] = 1; ue_sched_ctl-> - rballoc_sub_UE[CC_id] - [j] = 1; + rballoc_sub_UE[CC_id] + [j] = 1; ue_sched_ctl2-> - rballoc_sub_UE[CC_id] - [j] = 1; + rballoc_sub_UE[CC_id] + [j] = 1; MIMO_mode_indicator[CC_id] - [j] = 0; + [j] = 0; if (j < N_RBG[CC_id] - 1) { - rballoc_sub[CC_id][j + - 1] = - 1; - ue_sched_ctl-> - rballoc_sub_UE - [CC_id][j + 1] = 1; - ue_sched_ctl2->rballoc_sub_UE - [CC_id][j + 1] = 1; - MIMO_mode_indicator - [CC_id][j + 1] + rballoc_sub[CC_id][j + + 1] = + 1; + ue_sched_ctl-> + rballoc_sub_UE + [CC_id][j + 1] = 1; + ue_sched_ctl2->rballoc_sub_UE + [CC_id][j + 1] = 1; + MIMO_mode_indicator + [CC_id][j + 1] = 0; } ue_sched_ctl-> - dl_pow_off[CC_id] - = 0; + dl_pow_off[CC_id] + = 0; ue_sched_ctl2-> - dl_pow_off[CC_id] - = 0; - + dl_pow_off[CC_id] + = 0; if ((j == N_RBG[CC_id] - 1) && ((N_RB_DL == 25) - || (N_RB_DL == - 50))) { - - nb_rbs_remaining - [CC_id][UE_id] = + || (N_RB_DL == + 50))) { + nb_rbs_remaining + [CC_id][UE_id] = nb_rbs_remaining [CC_id][UE_id] - min_rb_unit[CC_id] + 1; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = ue_sched_ctl->pre_nb_available_rbs [CC_id] + min_rb_unit[CC_id] - 1; - nb_rbs_remaining - [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] = nb_rbs_remaining [CC_id][UE_id2] - min_rb_unit[CC_id] + 1; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = ue_sched_ctl2->pre_nb_available_rbs [CC_id] + min_rb_unit[CC_id] - 1; } else { - - nb_rbs_remaining - [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] = nb_rbs_remaining [CC_id][UE_id] - 4; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = ue_sched_ctl->pre_nb_available_rbs [CC_id] + 4; - nb_rbs_remaining - [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] = nb_rbs_remaining [CC_id][UE_id2] - 4; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = ue_sched_ctl2->pre_nb_available_rbs [CC_id] + 4; } - break; - } + } } - } - } + } } + } } - } -#endif + } + #endif + } } } void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, - int slice_idx, - int min_rb_unit[NFAPI_CC_MAX], - uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], - uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) -{ + int slice_idx, + int min_rb_unit[NFAPI_CC_MAX], + uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_accounted[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { int UE_id, CC_id; int i; -#ifdef TM5 + + #ifdef TM5 uint8_t transmission_mode; -#endif + #endif + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; int N_RBG[NFAPI_CC_MAX]; slice_info_t *sli = &RC.mac[Mod_id]->slice_info; uint8_t (*slice_allocation_mask)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].slice_allocation_mask; - decode_slice_positioning(Mod_id, slice_idx, slice_allocation_mask); for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { @@ -958,20 +1000,23 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, // Remaining RBs are allocated to high priority UEs for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - if (UE_RNTI(Mod_id, UE_id) == NOT_A_RNTI) continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) continue; + if (!ue_dl_slice_membership(Mod_id, UE_id, slice_idx)) continue; for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; nb_rbs_remaining[CC_id][UE_id] = - nb_rbs_required[CC_id][UE_id] - nb_rbs_accounted[CC_id][UE_id] + nb_rbs_remaining[CC_id][UE_id]; + nb_rbs_required[CC_id][UE_id] - nb_rbs_accounted[CC_id][UE_id] + nb_rbs_remaining[CC_id][UE_id]; + if (nb_rbs_remaining[CC_id][UE_id] < 0) abort(); -#ifdef TM5 + + #ifdef TM5 transmission_mode = get_tmode(Mod_id, CC_id, UE_id); -#endif + #endif if (nb_rbs_required[CC_id][UE_id] > 0) LOG_D(MAC, @@ -997,168 +1042,161 @@ void dlsch_scheduler_pre_processor_intraslice_sharing(module_id_t Mod_id, slice_allocation_mask, MIMO_mode_indicator); -#ifdef TM5 + #ifdef TM5 // data chanel TM5: to be revisited - if ((round == 0) && - (transmission_mode == 5) && - (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { - - for (j = 0; j < N_RBG[CC_id]; j += 2) { - - if ((((j == (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j] == 0) - && (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j + 1] == 0) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j + 1] == 0))) - && (nb_rbs_remaining[CC_id][UE_id] - > 0)) { - - for (i = UE_list->next[UE_id + 1]; i >= 0; - i = UE_list->next[i]) { - - UE_id2 = i; - rnti2 = UE_RNTI(Mod_id, UE_id2); - ue_sched_ctl2 = - &UE_list->UE_sched_ctrl[UE_id2]; - round2 = ue_sched_ctl2->round[CC_id]; - if (rnti2 == NOT_A_RNTI) - continue; - if (UE_list-> - UE_sched_ctrl - [UE_id2].ul_out_of_sync == 1) - continue; - - eNB_UE_stats2 = - UE_list-> - eNB_UE_stats[CC_id][UE_id2]; - //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); - - if ((mac_eNB_get_rrc_status - (Mod_id, - rnti2) >= RRC_RECONFIGURED) - && (round2 == 0) - && - (get_tmode(Mod_id, CC_id, UE_id2) - == 5) - && (ue_sched_ctl-> - dl_pow_off[CC_id] != 1)) { - - if ((((j == (N_RBG[CC_id] - 1)) + if ((round == 0) && + (transmission_mode == 5) && + (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { + for (j = 0; j < N_RBG[CC_id]; j += 2) { + if ((((j == (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j] == 0) + && (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j + 1] == 0) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j + 1] == 0))) + && (nb_rbs_remaining[CC_id][UE_id] + > 0)) { + for (i = UE_list->next[UE_id + 1]; i >= 0; + i = UE_list->next[i]) { + UE_id2 = i; + rnti2 = UE_RNTI(Mod_id, UE_id2); + ue_sched_ctl2 = + &UE_list->UE_sched_ctrl[UE_id2]; + round2 = ue_sched_ctl2->round[CC_id]; + + if (rnti2 == NOT_A_RNTI) + continue; + + if (UE_list-> + UE_sched_ctrl + [UE_id2].ul_out_of_sync == 1) + continue; + + eNB_UE_stats2 = + UE_list-> + eNB_UE_stats[CC_id][UE_id2]; + //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); + + if ((mac_eNB_get_rrc_status + (Mod_id, + rnti2) >= RRC_RECONFIGURED) + && (round2 == 0) && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j + - 1] - == 0))) - && - (nb_rbs_remaining - [CC_id] - [UE_id2] > 0)) { - - if ((((eNB_UE_stats2-> - DL_pmi_single ^ - eNB_UE_stats1-> - DL_pmi_single) - << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration - - rballoc_sub[CC_id][j] = 1; - ue_sched_ctl-> + (get_tmode(Mod_id, CC_id, UE_id2) + == 5) + && (ue_sched_ctl-> + dl_pow_off[CC_id] != 1)) { + if ((((j == (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j + + 1] + == 0))) + && + (nb_rbs_remaining + [CC_id] + [UE_id2] > 0)) { + if ((((eNB_UE_stats2-> + DL_pmi_single ^ + eNB_UE_stats1-> + DL_pmi_single) + << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration + rballoc_sub[CC_id][j] = 1; + ue_sched_ctl-> rballoc_sub_UE[CC_id] [j] = 1; - ue_sched_ctl2-> + ue_sched_ctl2-> rballoc_sub_UE[CC_id] [j] = 1; - MIMO_mode_indicator[CC_id] + MIMO_mode_indicator[CC_id] [j] = 0; - if (j < N_RBG[CC_id] - 1) { - rballoc_sub[CC_id][j + - 1] = - 1; - ue_sched_ctl-> - rballoc_sub_UE - [CC_id][j + 1] = 1; - ue_sched_ctl2->rballoc_sub_UE - [CC_id][j + 1] = 1; - MIMO_mode_indicator - [CC_id][j + 1] - = 0; - } + if (j < N_RBG[CC_id] - 1) { + rballoc_sub[CC_id][j + + 1] = + 1; + ue_sched_ctl-> + rballoc_sub_UE + [CC_id][j + 1] = 1; + ue_sched_ctl2->rballoc_sub_UE + [CC_id][j + 1] = 1; + MIMO_mode_indicator + [CC_id][j + 1] + = 0; + } - ue_sched_ctl-> + ue_sched_ctl-> dl_pow_off[CC_id] - = 0; - ue_sched_ctl2-> + = 0; + ue_sched_ctl2-> dl_pow_off[CC_id] - = 0; - - - if ((j == N_RBG[CC_id] - 1) - && ((N_RB_DL == 25) - || (N_RB_DL == - 50))) { - - nb_rbs_remaining - [CC_id][UE_id] = - nb_rbs_remaining - [CC_id][UE_id] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - nb_rbs_remaining - [CC_id][UE_id2] = - nb_rbs_remaining - [CC_id][UE_id2] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - } else { - - nb_rbs_remaining - [CC_id][UE_id] = - nb_rbs_remaining - [CC_id][UE_id] - 4; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + 4; - nb_rbs_remaining - [CC_id][UE_id2] = - nb_rbs_remaining - [CC_id][UE_id2] - - 4; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + 4; - } + = 0; - break; + if ((j == N_RBG[CC_id] - 1) + && ((N_RB_DL == 25) + || (N_RB_DL == + 50))) { + nb_rbs_remaining + [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + nb_rbs_remaining + [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + } else { + nb_rbs_remaining + [CC_id][UE_id] = + nb_rbs_remaining + [CC_id][UE_id] - 4; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + 4; + nb_rbs_remaining + [CC_id][UE_id2] = + nb_rbs_remaining + [CC_id][UE_id2] - + 4; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + 4; + } + + break; + } } + } } - } - } + } } - } - } -#endif + } + #endif + } } } @@ -1170,24 +1208,22 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag, - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) -{ + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) { int UE_id; uint8_t CC_id; uint16_t i, j; - int min_rb_unit[NFAPI_CC_MAX]; - slice_info_t *sli = &RC.mac[Mod_id]->slice_info; + eNB_MAC_INST *eNB = RC.mac[Mod_id]; + slice_info_t *sli = &eNB->slice_info; uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_required; uint16_t (*nb_rbs_accounted)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_accounted; uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB] = sli->pre_processor_results[slice_idx].nb_rbs_remaining; uint8_t (*MIMO_mode_indicator)[N_RBG_MAX] = sli->pre_processor_results[slice_idx].MIMO_mode_indicator; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_list_t *UE_list = &eNB->UE_list; UE_sched_ctrl *ue_sched_ctl; -// int rrc_status = RRC_IDLE; - + // int rrc_status = RRC_IDLE; #ifdef TM5 int harq_pid1 = 0; int round1 = 0, round2 = 0; @@ -1198,36 +1234,52 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; #endif - // Initialize scheduling information for all active UEs memset(&sli->pre_processor_results[slice_idx], 0, sizeof(sli->pre_processor_results[slice_idx])); // FIXME: After the memset above, some of the resets in reset() are redundant - dlsch_scheduler_pre_processor_reset(Mod_id, slice_idx, frameP, subframeP, + dlsch_scheduler_pre_processor_reset(Mod_id, + slice_idx, + frameP, + subframeP, min_rb_unit, nb_rbs_required, rballoc_sub, MIMO_mode_indicator, mbsfn_flag); // FIXME: Not sure if useful - // STATUS // Store the DLSCH buffer for each logical channel - store_dlsch_buffer(Mod_id, slice_idx, frameP, subframeP); + store_dlsch_buffer(Mod_id, + slice_idx, + frameP, + subframeP); // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required(Mod_id, slice_idx, frameP, subframeP, nb_rbs_required, min_rb_unit); + assign_rbs_required(Mod_id, + slice_idx, + frameP, + subframeP, + nb_rbs_required, + min_rb_unit); // Sorts the user on the basis of dlsch logical channel buffer and CQI - sort_UEs(Mod_id, slice_idx, frameP, subframeP); + sort_UEs(Mod_id, + slice_idx, + frameP, + subframeP); // ACCOUNTING // This procedure decides the number of RBs to allocate - dlsch_scheduler_pre_processor_accounting(Mod_id, slice_idx, frameP, subframeP, + dlsch_scheduler_pre_processor_accounting(Mod_id, + slice_idx, + frameP, + subframeP, min_rb_unit, nb_rbs_required, nb_rbs_accounted); // POSITIONING // This procedure does the main allocation of the RBs - dlsch_scheduler_pre_processor_positioning(Mod_id, slice_idx, + dlsch_scheduler_pre_processor_positioning(Mod_id, + slice_idx, min_rb_unit, nb_rbs_required, nb_rbs_accounted, @@ -1237,8 +1289,9 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, // SHARING // If there are available RBs left in the slice, allocate them to the highest priority UEs - if (RC.mac[Mod_id]->slice_info.intraslice_share_active) { - dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, slice_idx, + if (eNB->slice_info.intraslice_share_active) { + dlsch_scheduler_pre_processor_intraslice_sharing(Mod_id, + slice_idx, min_rb_unit, nb_rbs_required, nb_rbs_accounted, @@ -1248,9 +1301,10 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, } #ifdef TM5 + // This has to be revisited!!!! for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; CC_id++) { - COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + COMMON_channels_t *cc = &eNB->common_channels[CC_id]; int N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); i1 = 0; i2 = 0; @@ -1258,61 +1312,59 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, for (j = 0; j < N_RBG; j++) { if (MIMO_mode_indicator[CC_id][j] == 2) { - i1 = i1 + 1; + i1++; } else if (MIMO_mode_indicator[CC_id][j] == 1) { - i2 = i2 + 1; + i2++; } else if (MIMO_mode_indicator[CC_id][j] == 0) { - i3 = i3 + 1; + i3++; } } - if ((i1 < N_RBG) && (i2 > 0) && (i3 == 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_SUMIMO_transmissions + 1; - } - - if (i3 == N_RBG && i1 == 0 && i2 == 0) { - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + - 1; - } - - if ((i1 < N_RBG) && (i3 > 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_MUMIMO_transmissions + 1; + if (i1 < N_RBG) { + if (i2 > 0 && i3 == 0) { + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions + 1; + } else if (i3 > 0) { + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions + 1; + } + } else if (i3 == N_RBG && i1 == 0 && i2 == 0) { + PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + 1; } - - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + - 1; + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + 1; } + #endif for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { CC_id = UE_list->ordered_CCids[i][UE_id]; //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; - COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + COMMON_channels_t *cc = &eNB->common_channels[CC_id]; int N_RBG = to_rbg(cc->mib->message.dl_Bandwidth); if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { - LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n", UE_id); - LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, ue_sched_ctl->dl_pow_off[CC_id]); - LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n", UE_id); + LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n", + UE_id); + LOG_D(MAC, "dl power offset UE%d = %d \n", + UE_id, + ue_sched_ctl->dl_pow_off[CC_id]); + LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n", + UE_id); for (j = 0; j < N_RBG; j++) { //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[UE_id] = rballoc_sub_UE[CC_id][UE_id][UE_id]; - LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", UE_id, j, ue_sched_ctl->rballoc_sub_UE[CC_id][j]); + LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", + UE_id, j, + ue_sched_ctl->rballoc_sub_UE[CC_id][j]); } //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n", - Mod_id, RC.mac[Mod_id]->slice_info.dl[slice_idx].id, UE_id, + Mod_id, + eNB->slice_info.dl[slice_idx].id, + UE_id, ue_sched_ctl->pre_nb_available_rbs[CC_id]); } } @@ -1330,9 +1382,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, uint16_t nb_rbs_required[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX], - int *mbsfn_flag) -{ - + int *mbsfn_flag) { int UE_id; uint8_t CC_id; int i, j; @@ -1340,17 +1390,15 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, UE_sched_ctrl *ue_sched_ctl; int N_RB_DL, RBGsize, RBGsize_last; int N_RBG[NFAPI_CC_MAX]; - #ifdef SF0_LIMIT int sf0_lower, sf0_upper; #endif - rnti_t rnti; uint8_t *vrb_map; COMMON_channels_t *cc; -// - for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { + // + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id,(int)(UE_RNTI(module_idP, UE_id))); // initialize harq_pid and round cc = &RC.mac[module_idP]->common_channels[CC_id]; @@ -1361,13 +1409,10 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, continue; for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { - - UE_list = &RC.mac[module_idP]->UE_list; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; rnti = UE_RNTI(module_idP, UE_id); - if (rnti == NOT_A_RNTI) continue; @@ -1378,11 +1423,11 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, continue; LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); + // initialize harq_pid and round if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--; - /* eNB_UE_stats *eNB_UE_stats; @@ -1440,7 +1485,6 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_TIMING_ADVANCE,ue_sched_ctl->ta_update); } */ - nb_rbs_required[CC_id][UE_id] = 0; ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; ue_sched_ctl->dl_pow_off[CC_id] = 2; @@ -1451,32 +1495,38 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, } N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); - #ifdef SF0_LIMIT + switch (N_RBG[CC_id]) { case 6: sf0_lower = 0; sf0_upper = 5; break; + case 8: sf0_lower = 2; sf0_upper = 5; break; + case 13: sf0_lower = 4; sf0_upper = 7; break; + case 17: sf0_lower = 7; sf0_upper = 9; break; + case 25: sf0_lower = 11; sf0_upper = 13; break; + default: AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); } + #endif switch (N_RB_DL) { @@ -1484,37 +1534,43 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, RBGsize = 1; RBGsize_last = 1; break; + case 15: RBGsize = 2; RBGsize_last = 1; break; + case 25: RBGsize = 2; RBGsize_last = 1; break; + case 50: RBGsize = 3; RBGsize_last = 2; break; + case 75: RBGsize = 4; RBGsize_last = 3; break; + case 100: RBGsize = 4; RBGsize_last = 4; break; + default: AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); } vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; + // Initialize Subbands according to VRB map for (i = 0; i < N_RBG[CC_id]; i++) { int rb_size = i == N_RBG[CC_id] - 1 ? RBGsize_last : RBGsize; - - #ifdef SF0_LIMIT + // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) /* TODO: make it proper - allocate those RBs, do not "protect" them, but * compute number of available REs and limit MCS according to the @@ -1522,6 +1578,7 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, */ if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) rballoc_sub[CC_id][i] = 1; + #endif // for SI-RNTI,RA-RNTI and P-RNTI allocations @@ -1532,8 +1589,9 @@ dlsch_scheduler_pre_processor_reset(module_id_t module_idP, break; } } + //LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", - //frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); + //frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); MIMO_mode_indicator[CC_id][i] = 2; } } @@ -1550,8 +1608,7 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, uint16_t nb_rbs_remaining[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX], uint8_t slice_allocation_mask[NFAPI_CC_MAX][N_RBG_MAX], - uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) -{ + uint8_t MIMO_mode_indicator[NFAPI_CC_MAX][N_RBG_MAX]) { int i; int tm = get_tmode(Mod_id, CC_id, UE_id); UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; @@ -1559,12 +1616,16 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, int N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); for (i = 0; i < N_RBG; i++) { - if (rballoc_sub[CC_id][i] != 0) continue; + if (ue_sched_ctl->rballoc_sub_UE[CC_id][i] != 0) continue; + if (nb_rbs_remaining[CC_id][UE_id] <= 0) continue; + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) continue; + if (ue_sched_ctl->dl_pow_off[CC_id] == 0) continue; + if (slice_allocation_mask[CC_id][i] == 0) continue; if ((i == N_RBG - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) { @@ -1573,9 +1634,11 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, rballoc_sub[CC_id][i] = 1; ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; MIMO_mode_indicator[CC_id][i] = 1; + if (tm == 5) { ue_sched_ctl->dl_pow_off[CC_id] = 1; } + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit + 1; ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; } @@ -1585,9 +1648,11 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id, rballoc_sub[CC_id][i] = 1; ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1; MIMO_mode_indicator[CC_id][i] = 1; + if (tm == 5) { ue_sched_ctl->dl_pow_off[CC_id] = 1; } + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit; ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; } @@ -1602,255 +1667,207 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, int slice_idx, int frameP, sub_frame_t subframeP, + int sched_frameP, unsigned char sched_subframeP, - uint16_t *first_rb) -{ - int16_t i; - uint16_t UE_id, n, r; - uint8_t CC_id, harq_pid; - uint16_t nb_allocated_rbs[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB], - total_allocated_rbs[NFAPI_CC_MAX], - average_rbs_per_user[NFAPI_CC_MAX]; - int16_t total_remaining_rbs[NFAPI_CC_MAX]; - uint16_t total_ue_count[NFAPI_CC_MAX]; - rnti_t rnti = -1; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - slice_info_t *sli = &RC.mac[module_idP]->slice_info; - UE_TEMPLATE *UE_template = 0; - UE_sched_ctrl *ue_sched_ctl; - int N_RB_UL = 0; - uint16_t available_rbs, first_rb_offset; - - LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n"); - // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB - assign_max_mcs_min_rb(module_idP, slice_idx, frameP, subframeP, first_rb); - - LOG_D(MAC, "In ulsch_preprocessor: sort ue \n"); - // sort ues - sort_ue_ul(module_idP, frameP, subframeP); - - - // we need to distribute RBs among UEs - // step1: reset the vars - for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { - total_allocated_rbs[CC_id] = 0; - total_remaining_rbs[CC_id] = 0; - average_rbs_per_user[CC_id] = 0; - total_ue_count[CC_id] = 0; - } + uint16_t *first_rb) { + int UE_id; + uint16_t n; + uint8_t CC_id, harq_pid; + uint16_t nb_allocated_rbs[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + uint16_t total_allocated_rbs[NFAPI_CC_MAX]; + uint16_t average_rbs_per_user[NFAPI_CC_MAX]; + int16_t total_remaining_rbs[NFAPI_CC_MAX]; + uint16_t total_ue_count[NFAPI_CC_MAX]; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + UE_list_t *UE_list = &eNB->UE_list; + slice_info_t *sli = &eNB->slice_info; + UE_TEMPLATE *UE_template = 0; + UE_sched_ctrl *ue_sched_ctl; + int N_RB_UL = 0; + uint16_t available_rbs, first_rb_offset; + rnti_t rntiTable[MAX_MOBILES_PER_ENB]; + + // sort ues + LOG_D(MAC, "In ulsch_preprocessor: sort ue \n"); + sort_ue_ul(module_idP, slice_idx, sched_frameP, sched_subframeP, rntiTable); + // maximize MCS and then allocate required RB according to the buffer occupancy with the limit of max available UL RB + LOG_D(MAC, "In ulsch_preprocessor: assign max mcs min rb\n"); + assign_max_mcs_min_rb(module_idP, slice_idx, frameP, subframeP, first_rb); + // we need to distribute RBs among UEs + // step1: reset the vars + uint8_t CC_nb = (uint8_t) RC.nb_mac_CC[module_idP]; + + for (CC_id = 0; CC_id < CC_nb; CC_id++) { + total_allocated_rbs[CC_id] = 0; + total_remaining_rbs[CC_id] = 0; + average_rbs_per_user[CC_id] = 0; + total_ue_count[CC_id] = 0; + } - // Step 1.5: Calculate total_ue_count - for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - for (n = 0; n < UE_list->numactiveULCCs[i]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][i]; - UE_template = &UE_list->UE_template[CC_id][i]; - if (!ue_ul_slice_membership(module_idP, i, slice_idx)) - continue; - if (UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0) { - total_ue_count[CC_id] += 1; - } + // Step 1.5: Calculate total_ue_count + for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { + // This is not the actual CC_id in the list + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + + if (UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0) { + total_ue_count[CC_id]++; } } + } - LOG_D(MAC, "In ulsch_preprocessor: step2 \n"); - // step 2: calculate the average rb per UE - for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - - rnti = UE_RNTI(module_idP, i); - UE_id = i; - - + // step 2: calculate the average rb per UE + LOG_D(MAC, "In ulsch_preprocessor: step2 \n"); + for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { if (UE_list->UE_template[CC_id][UE_id].rach_resource_type > 0) continue; - rnti = UE_RNTI(module_idP,i); - - if (rnti == NOT_A_RNTI) - continue; - - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; + LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", + UE_id, + rntiTable[UE_id]); - if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) - continue; + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x CCid %d\n", + UE_id, + rntiTable[UE_id], + CC_id); + /* + if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id]) > (1<<aggregation)) { + nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation); + max_num_ue_to_be_scheduled+=1; + } */ + N_RB_UL = to_prb(eNB->common_channels[CC_id].ul_Bandwidth); + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] = + nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL); + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; + available_rbs = + cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset); - LOG_D(MAC, "In ulsch_preprocessor: handling UE %d/%x\n", UE_id, - rnti); - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - LOG_D(MAC, - "In ulsch_preprocessor: handling UE %d/%x CCid %d\n", - UE_id, rnti, CC_id); + if (available_rbs < 0) + available_rbs = 0; + if (total_ue_count[CC_id] == 0) { average_rbs_per_user[CC_id] = 0; + } else if (total_ue_count[CC_id] == 1) { // increase the available RBs, special case, + average_rbs_per_user[CC_id] = (uint16_t) (available_rbs + 1); + } else if (total_ue_count[CC_id] <= available_rbs) { + average_rbs_per_user[CC_id] = (uint16_t) floor(available_rbs / total_ue_count[CC_id]); + } else { + average_rbs_per_user[CC_id] = 1; + LOG_W(MAC, "[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", + module_idP, + frameP, + subframeP, + UE_id, + CC_id); + } - /* - if((mac_xface->get_nCCE_max(module_idP,CC_id,3,subframeP) - nCCE_to_be_used[CC_id]) > (1<<aggregation)) { - nCCE_to_be_used[CC_id] = nCCE_to_be_used[CC_id] + (1<<aggregation); - max_num_ue_to_be_scheduled+=1; - } */ - - - - N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] = - nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL); - - first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; - available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], - N_RB_UL - first_rb[CC_id] - first_rb_offset); - if (available_rbs < 0) - available_rbs = 0; - - if (total_ue_count[CC_id] == 0) { - average_rbs_per_user[CC_id] = 0; - } else if (total_ue_count[CC_id] == 1) { // increase the available RBs, special case, - average_rbs_per_user[CC_id] = (uint16_t) (available_rbs + 1); - } else if (total_ue_count[CC_id] <= available_rbs) { - average_rbs_per_user[CC_id] = (uint16_t) floor(available_rbs / total_ue_count[CC_id]); - } else { - average_rbs_per_user[CC_id] = 1; - LOG_W(MAC, - "[eNB %d] frame %d subframe %d: UE %d CC %d: can't get average rb per user (should not be here)\n", - module_idP, frameP, subframeP, UE_id, CC_id); - } - if (total_ue_count[CC_id] > 0) - LOG_D(MAC, "[eNB %d] Frame %d subframe %d: total ue to be scheduled %d\n", - module_idP, frameP, subframeP, total_ue_count[CC_id]); + if (total_ue_count[CC_id] > 0) { + LOG_D(MAC, "[eNB %d] Frame %d subframe %d: total ue to be scheduled %d\n", + module_idP, + frameP, + subframeP, + total_ue_count[CC_id]); } } + } - // step 3: assigne RBS - for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - rnti = UE_RNTI(module_idP, i); - - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - if (!ue_ul_slice_membership(module_idP, i, slice_idx)) - continue; - - - UE_id = i; - - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - UE_template = &UE_list->UE_template[CC_id][UE_id]; - harq_pid = subframe2harqpid(&RC.mac[module_idP]->common_channels[CC_id], - frameP, sched_subframeP); + // step 3: assigne RBS + for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { + // if (continueTable[UE_id]) continue; - // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + harq_pid = subframe2harqpid(&RC.mac[module_idP]->common_channels[CC_id], + sched_frameP, sched_subframeP); - if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id] > 0) { - nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; - } else { - nb_allocated_rbs[CC_id][UE_id] = - cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[slice_idx], - average_rbs_per_user[CC_id]); - } + // mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL); - total_allocated_rbs[CC_id] += nb_allocated_rbs[CC_id][UE_id]; - LOG_D(MAC, - "In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n", - nb_allocated_rbs[CC_id][UE_id], UE_id, rnti, CC_id, - harq_pid); + if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid] > 0) { + nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; + } else { + nb_allocated_rbs[CC_id][UE_id] = + cmin(UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[slice_idx], average_rbs_per_user[CC_id]); } - } - - // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly - for (r = 0; r < 2; r++) { - for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { - rnti = UE_RNTI(module_idP, i); + total_allocated_rbs[CC_id] += nb_allocated_rbs[CC_id][UE_id]; + LOG_D(MAC, "In ulsch_preprocessor: assigning %d RBs for UE %d/%x CCid %d, harq_pid %d\n", + nb_allocated_rbs[CC_id][UE_id], + UE_id, + rntiTable[UE_id], + CC_id, + harq_pid); + } + } - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - if (!ue_ul_slice_membership(module_idP, i, slice_idx)) - continue; + // step 4: assigne the remaining RBs and set the pre_allocated rbs accordingly + for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { + // if (continueTable[UE_id]) continue; - UE_id = i; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { - // This is the actual CC_id in the list - CC_id = UE_list->ordered_ULCCids[n][UE_id]; - UE_template = &UE_list->UE_template[CC_id][UE_id]; - N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); - first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; - available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], - N_RB_UL - first_rb[CC_id] - first_rb_offset); - total_remaining_rbs[CC_id] = available_rbs - total_allocated_rbs[CC_id]; + for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { + // This is the actual CC_id in the list + CC_id = UE_list->ordered_ULCCids[n][UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + N_RB_UL = to_prb(eNB->common_channels[CC_id].ul_Bandwidth); + first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; + available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset); + total_remaining_rbs[CC_id] = available_rbs - total_allocated_rbs[CC_id]; - if (total_ue_count[CC_id] == 1) { - total_remaining_rbs[CC_id] += 1; - } + if (total_ue_count[CC_id] == 1) { + total_remaining_rbs[CC_id]++; + } - if (r == 0) { - while ((UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0) - && (nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul[slice_idx]) - && (total_remaining_rbs[CC_id] > 0)) { - nb_allocated_rbs[CC_id][UE_id] = - cmin(nb_allocated_rbs[CC_id][UE_id] + 1, - UE_template->pre_allocated_nb_rb_ul[slice_idx]); - total_remaining_rbs[CC_id]--; - total_allocated_rbs[CC_id]++; - } - } else { - UE_template->pre_allocated_nb_rb_ul[slice_idx] = - nb_allocated_rbs[CC_id][UE_id]; - LOG_D(MAC, - "******************UL Scheduling Information for UE%d CC_id %d ************************\n", - UE_id, CC_id); - LOG_D(MAC, - "[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", - module_idP, UE_id, CC_id, - UE_template->pre_allocated_nb_rb_ul[slice_idx]); - } + while (UE_template->pre_allocated_nb_rb_ul[slice_idx] > 0 && + nb_allocated_rbs[CC_id][UE_id] < UE_template->pre_allocated_nb_rb_ul[slice_idx] && + total_remaining_rbs[CC_id] > 0) { + nb_allocated_rbs[CC_id][UE_id] = cmin(nb_allocated_rbs[CC_id][UE_id] + 1, UE_template->pre_allocated_nb_rb_ul[slice_idx]); + total_remaining_rbs[CC_id]--; + total_allocated_rbs[CC_id]++; } + + UE_template->pre_allocated_nb_rb_ul[slice_idx] = nb_allocated_rbs[CC_id][UE_id]; + LOG_D(MAC, "******************UL Scheduling Information for UE%d CC_id %d ************************\n", + UE_id, + CC_id); + LOG_D(MAC, "[eNB %d] total RB allocated for UE%d CC_id %d = %d\n", + module_idP, + UE_id, + CC_id, + UE_template->pre_allocated_nb_rb_ul[slice_idx]); } } + + return; } void -assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, - sub_frame_t subframeP, uint16_t * first_rb) -{ - +assign_max_mcs_min_rb(module_id_t module_idP, + int slice_idx, + int frameP, + sub_frame_t subframeP, + uint16_t *first_rb) { int i; uint16_t n, UE_id; uint8_t CC_id; - rnti_t rnti = -1; int mcs; int rb_table_index = 0, tbs, tx_power; eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list = &eNB->UE_list; - slice_info_t *sli = &RC.mac[module_idP]->slice_info; - + slice_info_t *sli = &eNB->slice_info; UE_TEMPLATE *UE_template; UE_sched_ctrl *ue_sched_ctl; int Ncp; int N_RB_UL; int first_rb_offset, available_rbs; - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (UE_list->active[i] != TRUE) - continue; - - rnti = UE_RNTI(module_idP, i); - - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - if (!ue_ul_slice_membership(module_idP, i, slice_idx)) - continue; - + for (i = UE_list->head_ul; i >= 0; i = UE_list->next_ul[i]) { if (UE_list->UE_sched_ctrl[i].phr_received == 1) { /* if we've received the power headroom information the UE, we can go to * maximum mcs */ @@ -1865,22 +1882,18 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { // This is the actual CC_id in the list CC_id = UE_list->ordered_ULCCids[n][UE_id]; - - - - AssertFatal(CC_id < RC.nb_mac_CC[module_idP], - "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", - CC_id, NFAPI_CC_MAX, n, UE_id, + AssertFatal(CC_id < RC.nb_mac_CC[module_idP], "CC_id %u should be < %u, loop n=%u < numactiveULCCs[%u]=%u", + CC_id, + NFAPI_CC_MAX, + n, + UE_id, UE_list->numactiveULCCs[UE_id]); - UE_template = &UE_list->UE_template[CC_id][UE_id]; UE_template->pre_assigned_mcs_ul = mcs; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - - Ncp = RC.mac[module_idP]->common_channels[CC_id].Ncp; - N_RB_UL = to_prb(RC.mac[module_idP]->common_channels[CC_id].ul_Bandwidth); - ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] = - nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL); + Ncp = eNB->common_channels[CC_id].Ncp; + N_RB_UL = to_prb(eNB->common_channels[CC_id].ul_Bandwidth); + ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx] = nb_rbs_allowed_slice(sli->ul[slice_idx].pct, N_RB_UL); int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; if (bytes_to_schedule < 0) bytes_to_schedule = 0; @@ -1890,13 +1903,10 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, if (bits_to_schedule > 0) { tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, 3) << 3; // 1 or 2 PRB with cqi enabled does not work well! rb_table_index = 2; - // fixme: set use_srs flag tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); - while ((((UE_template->phr_info - tx_power) < 0) - || (tbs > bits_to_schedule)) - && (UE_template->pre_assigned_mcs_ul > 3)) { + while ((UE_template->phr_info - tx_power < 0 || tbs > bits_to_schedule) && UE_template->pre_assigned_mcs_ul > 3) { // LOG_I(MAC,"UE_template->phr_info %d tx_power %d mcs %d\n", UE_template->phr_info,tx_power, mcs); UE_template->pre_assigned_mcs_ul--; tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3; @@ -1904,13 +1914,13 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, } first_rb_offset = UE_list->first_rb_offset[CC_id][slice_idx]; - available_rbs = cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], - N_RB_UL - first_rb[CC_id] - first_rb_offset); + available_rbs = + cmin(ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_idx], N_RB_UL - first_rb[CC_id] - first_rb_offset); - while ((tbs < bits_to_schedule) - && (rb_table[rb_table_index] < available_rbs) - && ((UE_template->phr_info - tx_power) > 0) - && (rb_table_index < 32)) { + while (tbs < bits_to_schedule && + rb_table[rb_table_index] < available_rbs && + UE_template->phr_info - tx_power > 0 && + rb_table_index < 32) { rb_table_index++; tbs = get_TBS_UL(UE_template->pre_assigned_mcs_ul, rb_table[rb_table_index]) << 3; tx_power = estimate_ue_tx_power(tbs, rb_table[rb_table_index], 0, Ncp, 0); @@ -1919,16 +1929,20 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, if (rb_table[rb_table_index] > (available_rbs - 1)) { rb_table_index--; } + // 1 or 2 PRB with cqi enabled does not work well if (rb_table[rb_table_index] < 3) { - rb_table_index = 2; //3PRB + rb_table_index = 2; //3PRB } UE_template->pre_allocated_rb_table_index_ul = rb_table_index; UE_template->pre_allocated_nb_rb_ul[slice_idx] = rb_table[rb_table_index]; - LOG_D(MAC, - "[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", - module_idP, frameP, subframeP, UE_id, CC_id, + LOG_D(MAC, "[eNB %d] frame %d subframe %d: for UE %d CC %d: pre-assigned mcs %d, pre-allocated rb_table[%d]=%d RBs (phr %d, tx power %d)\n", + module_idP, + frameP, + subframeP, + UE_id, + CC_id, UE_template->pre_assigned_mcs_ul, UE_template->pre_allocated_rb_table_index_ul, UE_template->pre_allocated_nb_rb_ul[slice_idx], @@ -1952,91 +1966,114 @@ assign_max_mcs_min_rb(module_id_t module_idP, int slice_idx, int frameP, } struct sort_ue_ul_params { - int module_idP; - int frameP; - int subframeP; + int module_idP; + int sched_frameP; + int sched_subframeP; }; -static int ue_ul_compare(const void *_a, const void *_b, void *_params) -{ - struct sort_ue_ul_params *params = _params; - UE_list_t *UE_list = &RC.mac[params->module_idP]->UE_list; - - int UE_id1 = *(const int *) _a; - int UE_id2 = *(const int *) _b; - - int rnti1 = UE_RNTI(params->module_idP, UE_id1); - int pCCid1 = UE_PCCID(params->module_idP, UE_id1); - int round1 = maxround(params->module_idP, rnti1, params->frameP, - params->subframeP, 1); - - int rnti2 = UE_RNTI(params->module_idP, UE_id2); - int pCCid2 = UE_PCCID(params->module_idP, UE_id2); - int round2 = maxround(params->module_idP, rnti2, params->frameP, - params->subframeP, 1); - - if (round1 > round2) - return -1; - if (round1 < round2) - return 1; - - if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] > - UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) - return -1; - if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] < - UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) - return 1; - - int bytes_to_schedule1 = UE_list->UE_template[pCCid1][UE_id1].estimated_ul_buffer - UE_list->UE_template[pCCid1][UE_id1].scheduled_ul_bytes; - if (bytes_to_schedule1 < 0) bytes_to_schedule1 = 0; - int bytes_to_schedule2 = UE_list->UE_template[pCCid2][UE_id2].estimated_ul_buffer - UE_list->UE_template[pCCid2][UE_id2].scheduled_ul_bytes; - if (bytes_to_schedule2 < 0) bytes_to_schedule2 = 0; - - if (bytes_to_schedule1 > bytes_to_schedule2) - return -1; - if (bytes_to_schedule1 < bytes_to_schedule2) - return 1; - - if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul > - UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) - return -1; - if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul < - UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) - return 1; +static int ue_ul_compare(const void *_a, const void *_b, void *_params) { + struct sort_ue_ul_params *params = _params; + UE_list_t *UE_list = &RC.mac[params->module_idP]->UE_list; + int UE_id1 = *(const int *) _a; + int UE_id2 = *(const int *) _b; + int rnti1 = UE_RNTI(params->module_idP, UE_id1); + int pCCid1 = UE_PCCID(params->module_idP, UE_id1); + int round1 = maxround_ul(params->module_idP, rnti1, params->sched_frameP, + params->sched_subframeP); + int rnti2 = UE_RNTI(params->module_idP, UE_id2); + int pCCid2 = UE_PCCID(params->module_idP, UE_id2); + int round2 = maxround_ul(params->module_idP, rnti2, params->sched_frameP, + params->sched_subframeP); - return 0; + if (round1 > round2) + return -1; + + if (round1 < round2) + return 1; + + if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] > + UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) + return -1; + + if (UE_list->UE_template[pCCid1][UE_id1].ul_buffer_info[LCGID0] < + UE_list->UE_template[pCCid2][UE_id2].ul_buffer_info[LCGID0]) + return 1; + + int bytes_to_schedule1 = UE_list->UE_template[pCCid1][UE_id1].estimated_ul_buffer - UE_list->UE_template[pCCid1][UE_id1].scheduled_ul_bytes; + + if (bytes_to_schedule1 < 0) bytes_to_schedule1 = 0; + + int bytes_to_schedule2 = UE_list->UE_template[pCCid2][UE_id2].estimated_ul_buffer - UE_list->UE_template[pCCid2][UE_id2].scheduled_ul_bytes; + + if (bytes_to_schedule2 < 0) bytes_to_schedule2 = 0; + + if (bytes_to_schedule1 > bytes_to_schedule2) + return -1; + + if (bytes_to_schedule1 < bytes_to_schedule2) + return 1; + + if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul > + UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) + return -1; + + if (UE_list->UE_template[pCCid1][UE_id1].pre_assigned_mcs_ul < + UE_list->UE_template[pCCid2][UE_id2].pre_assigned_mcs_ul) + return 1; + + return 0; } -void sort_ue_ul(module_id_t module_idP, int frameP, sub_frame_t subframeP) +//----------------------------------------------------------------------------- +/* + * This function sorts the UEs in order, depending on their ulsch buffer and CQI + */ +void sort_ue_ul(module_id_t module_idP, + int slice_idx, + int sched_frameP, + sub_frame_t sched_subframeP, + rnti_t *rntiTable) +//----------------------------------------------------------------------------- { - int i; - int list[MAX_MOBILES_PER_ENB]; - int list_size = 0; - int rnti; - struct sort_ue_ul_params params = { module_idP, frameP, subframeP }; - - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (UE_list->active[i] == FALSE) - continue; - if ((rnti = UE_RNTI(module_idP, i)) == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - - list[list_size] = i; - list_size++; + int list[MAX_MOBILES_PER_ENB]; + int list_size = 0; + struct sort_ue_ul_params params = { module_idP, sched_frameP, sched_subframeP }; + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + UE_sched_ctrl *UE_scheduling_control = NULL; + + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + + UE_scheduling_control = &(UE_list->UE_sched_ctrl[i]); + + /* Check CDRX configuration and if UE is in active time for this subframe */ + if (UE_scheduling_control->cdrx_configured == TRUE) { + if (UE_scheduling_control->in_active_time == FALSE) { + continue; + } } - qsort_r(list, list_size, sizeof(int), ue_ul_compare, ¶ms); + rntiTable[i] = UE_RNTI(module_idP, i); + // Valid element and is not the actual CC_id in the list + if (UE_list->active[i] == TRUE && + rntiTable[i] != NOT_A_RNTI && + UE_list->UE_sched_ctrl[i].ul_out_of_sync != 1 && + ue_ul_slice_membership(module_idP, i, slice_idx)) { + list[list_size++] = i; // Add to list + } + } - if (list_size) { - for (i = 0; i < list_size - 1; i++) - UE_list->next_ul[list[i]] = list[i + 1]; - UE_list->next_ul[list[list_size - 1]] = -1; - UE_list->head_ul = list[0]; - } else { - UE_list->head_ul = -1; + qsort_r(list, list_size, sizeof(int), ue_ul_compare, ¶ms); + + if (list_size) { // At mimimum one list element + + for (int i = 0; i < list_size - 1; i++) { + UE_list->next_ul[list[i]] = list[i + 1]; } + + UE_list->next_ul[list[list_size - 1]] = -1; + UE_list->head_ul = list[0]; + + } else { // No element + UE_list->head_ul = -1; + } } diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c index d139c8bd472de11fe9350090f0f451c11d32db03..70cee3e24bc26f41a600f6cb0d1083ae6508e501 100644 --- a/openair2/LAYER2/MAC/ra_procedures.c +++ b/openair2/LAYER2/MAC/ra_procedures.c @@ -40,585 +40,586 @@ #include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "UTIL/OPT/opt.h" #include "OCG.h" #include "OCG_extern.h" -#include "SIMULATION/TOOLS/sim.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus #include "PHY/LTE_TRANSPORT/transport_common_proto.h" #include "PHY/LTE_ESTIMATION/lte_estimation.h" -extern uint8_t nfapi_mode; + extern UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index); /// This routine implements Section 5.1.2 (UE Random Access Resource Selection) from 36.321 void get_prach_resources(module_id_t module_idP, - int CC_id, - uint8_t eNB_index, - uint8_t t_id, - uint8_t first_Msg3, - LTE_RACH_ConfigDedicated_t * rach_ConfigDedicated) -{ - uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size; - PRACH_RESOURCES_t *prach_resources = - &UE_mac_inst[module_idP].RA_prach_resources; - LTE_RACH_ConfigCommon_t *rach_ConfigCommon = NULL; - uint8_t noGroupB = 0; - uint8_t f_id = 0, num_prach = 0; - int numberOfRA_Preambles; - int messageSizeGroupA; - int sizeOfRA_PreamblesGroupA; - int messagePowerOffsetGroupB; - int PLThreshold; - - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - AssertFatal(UE_mac_inst[module_idP].radioResourceConfigCommon != NULL, - "[UE %d] FATAL radioResourceConfigCommon is NULL !!!\n", - module_idP); - - rach_ConfigCommon = - &UE_mac_inst[module_idP].radioResourceConfigCommon-> - rach_ConfigCommon; - numberOfRA_Preambles = - (1 + rach_ConfigCommon->preambleInfo.numberOfRA_Preambles) << 2; - - if (rach_ConfigDedicated) { // This is for network controlled Mobility, later - if (rach_ConfigDedicated->ra_PRACH_MaskIndex != 0) { - prach_resources->ra_PreambleIndex = - rach_ConfigDedicated->ra_PreambleIndex; - prach_resources->ra_RACH_MaskIndex = - rach_ConfigDedicated->ra_PRACH_MaskIndex; - return; - } + int CC_id, + uint8_t eNB_index, + uint8_t t_id, + uint8_t first_Msg3, + LTE_RACH_ConfigDedicated_t *rach_ConfigDedicated) { + uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size; + PRACH_RESOURCES_t *prach_resources = + &UE_mac_inst[module_idP].RA_prach_resources; + LTE_RACH_ConfigCommon_t *rach_ConfigCommon = NULL; + uint8_t noGroupB = 0; + uint8_t f_id = 0, num_prach = 0; + int numberOfRA_Preambles; + int messageSizeGroupA; + int sizeOfRA_PreamblesGroupA; + int messagePowerOffsetGroupB; + int PLThreshold; + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); + AssertFatal(UE_mac_inst[module_idP].radioResourceConfigCommon != NULL, + "[UE %d] FATAL radioResourceConfigCommon is NULL !!!\n", + module_idP); + rach_ConfigCommon = + &UE_mac_inst[module_idP].radioResourceConfigCommon-> + rach_ConfigCommon; + numberOfRA_Preambles = + (1 + rach_ConfigCommon->preambleInfo.numberOfRA_Preambles) << 2; + + if (rach_ConfigDedicated) { // This is for network controlled Mobility, later + if (rach_ConfigDedicated->ra_PRACH_MaskIndex != 0) { + prach_resources->ra_PreambleIndex = + rach_ConfigDedicated->ra_PreambleIndex; + prach_resources->ra_RACH_MaskIndex = + rach_ConfigDedicated->ra_PRACH_MaskIndex; + return; + } + } + + /* TODO: gcc warns if this variable is not always set, let's put -1 for no more warning */ + messageSizeGroupA = -1; + + if (!rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) { + noGroupB = 1; + } else { + sizeOfRA_PreamblesGroupA = + (rach_ConfigCommon->preambleInfo. + preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + 1) << 2; + + switch (rach_ConfigCommon->preambleInfo. + preamblesGroupAConfig->messageSizeGroupA) { + case 0: + messageSizeGroupA = 56; + break; + + case 1: + messageSizeGroupA = 144; + break; + + case 2: + messageSizeGroupA = 208; + break; + + case 3: + messageSizeGroupA = 256; + break; } - /* TODO: gcc warns if this variable is not always set, let's put -1 for no more warning */ - messageSizeGroupA = -1; + /* TODO: what value to use as default? */ + messagePowerOffsetGroupB = -9999; - if (!rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) { - noGroupB = 1; - } else { - sizeOfRA_PreamblesGroupA = - (rach_ConfigCommon->preambleInfo. - preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + 1) << 2; - switch (rach_ConfigCommon->preambleInfo. - preamblesGroupAConfig->messageSizeGroupA) { - case 0: - messageSizeGroupA = 56; - break; - case 1: - messageSizeGroupA = 144; - break; - case 2: - messageSizeGroupA = 208; - break; - case 3: - messageSizeGroupA = 256; - break; - } - - /* TODO: what value to use as default? */ - messagePowerOffsetGroupB = -9999; - switch (rach_ConfigCommon->preambleInfo. - preamblesGroupAConfig->messagePowerOffsetGroupB) { - case 0: - messagePowerOffsetGroupB = -9999; - break; - case 1: - messagePowerOffsetGroupB = 0; - break; - case 2: - messagePowerOffsetGroupB = 5; - break; - case 3: - messagePowerOffsetGroupB = 8; - break; - case 4: - messagePowerOffsetGroupB = 10; - break; - case 5: - messagePowerOffsetGroupB = 12; - break; - case 6: - messagePowerOffsetGroupB = 15; - break; - case 7: - messagePowerOffsetGroupB = 18; - break; - } - - PLThreshold = - 0 - get_DELTA_PREAMBLE(module_idP, - CC_id) - - get_Po_NOMINAL_PUSCH(module_idP, - CC_id) - messagePowerOffsetGroupB; - // Note Pcmax is set to 0 here, we have to fix this - - if (sizeOfRA_PreamblesGroupA == numberOfRA_Preambles) { - noGroupB = 1; - } + switch (rach_ConfigCommon->preambleInfo. + preamblesGroupAConfig->messagePowerOffsetGroupB) { + case 0: + messagePowerOffsetGroupB = -9999; + break; + + case 1: + messagePowerOffsetGroupB = 0; + break; + + case 2: + messagePowerOffsetGroupB = 5; + break; + + case 3: + messagePowerOffsetGroupB = 8; + break; + + case 4: + messagePowerOffsetGroupB = 10; + break; + + case 5: + messagePowerOffsetGroupB = 12; + break; + + case 6: + messagePowerOffsetGroupB = 15; + break; + + case 7: + messagePowerOffsetGroupB = 18; + break; } - if (first_Msg3 == 1) { - if (noGroupB == 1) { - // use Group A procedure - UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = - (taus()) % numberOfRA_Preambles; - UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = - 0; - UE_mac_inst[module_idP].RA_usedGroupA = 1; - } else if ((Msg3_size < messageSizeGroupA) || - (get_PL(module_idP, 0, eNB_index) > PLThreshold)) { - // use Group A procedure - UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = - (taus()) % sizeOfRA_PreamblesGroupA; - UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = - 0; - UE_mac_inst[module_idP].RA_usedGroupA = 1; - } else { // use Group B - UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = - sizeOfRA_PreamblesGroupA + - (taus()) % (numberOfRA_Preambles - - sizeOfRA_PreamblesGroupA); - UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = - 0; - UE_mac_inst[module_idP].RA_usedGroupA = 0; - } - - UE_mac_inst[module_idP]. - RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = - get_Po_NOMINAL_PUSCH(module_idP, CC_id); - } else { // Msg3 is being retransmitted - if (UE_mac_inst[module_idP].RA_usedGroupA == 1) { - if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) { - UE_mac_inst[module_idP].RA_prach_resources. - ra_PreambleIndex = - (taus()) % - rach_ConfigCommon->preambleInfo. - preamblesGroupAConfig->sizeOfRA_PreamblesGroupA; - } else { - UE_mac_inst[module_idP].RA_prach_resources. - ra_PreambleIndex = (taus()) & 0x3f; - } - - UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = - 0; - } else { - // FIXME rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero - UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = - rach_ConfigCommon->preambleInfo. - preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + - (taus()) % - (rach_ConfigCommon->preambleInfo.numberOfRA_Preambles - - rach_ConfigCommon->preambleInfo. - preamblesGroupAConfig->sizeOfRA_PreamblesGroupA); - UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = - 0; - } + PLThreshold = + 0 - get_DELTA_PREAMBLE(module_idP, + CC_id) - + get_Po_NOMINAL_PUSCH(module_idP, + CC_id) - messagePowerOffsetGroupB; + // Note Pcmax is set to 0 here, we have to fix this + + if (sizeOfRA_PreamblesGroupA == numberOfRA_Preambles) { + noGroupB = 1; + } + } + + if (first_Msg3 == 1) { + if (noGroupB == 1) { + // use Group A procedure + UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = + (taus()) % numberOfRA_Preambles; + UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = + 0; + UE_mac_inst[module_idP].RA_usedGroupA = 1; + } else if ((Msg3_size < messageSizeGroupA) || + (get_PL(module_idP, 0, eNB_index) > PLThreshold)) { + // use Group A procedure + UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = + (taus()) % sizeOfRA_PreamblesGroupA; + UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = + 0; + UE_mac_inst[module_idP].RA_usedGroupA = 1; + } else { // use Group B + UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = + sizeOfRA_PreamblesGroupA + + (taus()) % (numberOfRA_Preambles - + sizeOfRA_PreamblesGroupA); + UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = + 0; + UE_mac_inst[module_idP].RA_usedGroupA = 0; } - // choose random PRACH resource in TDD - if (UE_mac_inst[module_idP].tdd_Config) { - num_prach = get_num_prach_tdd(module_idP); + UE_mac_inst[module_idP]. + RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER = + get_Po_NOMINAL_PUSCH(module_idP, CC_id); + } else { // Msg3 is being retransmitted + if (UE_mac_inst[module_idP].RA_usedGroupA == 1) { + if (rach_ConfigCommon->preambleInfo.preamblesGroupAConfig) { + UE_mac_inst[module_idP].RA_prach_resources. + ra_PreambleIndex = + (taus()) % + rach_ConfigCommon->preambleInfo. + preamblesGroupAConfig->sizeOfRA_PreamblesGroupA; + } else { + UE_mac_inst[module_idP].RA_prach_resources. + ra_PreambleIndex = (taus()) & 0x3f; + } + + UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = + 0; + } else { + // FIXME rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero + UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex = + rach_ConfigCommon->preambleInfo. + preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + + (taus()) % + (rach_ConfigCommon->preambleInfo.numberOfRA_Preambles - + rach_ConfigCommon->preambleInfo. + preamblesGroupAConfig->sizeOfRA_PreamblesGroupA); + UE_mac_inst[module_idP].RA_prach_resources.ra_RACH_MaskIndex = + 0; + } + } - if ((num_prach > 0) && (num_prach < 6)) { - UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index = - (taus() % num_prach); - } + // choose random PRACH resource in TDD + if (UE_mac_inst[module_idP].tdd_Config) { + num_prach = get_num_prach_tdd(module_idP); - f_id = get_fid_prach_tdd(module_idP, - UE_mac_inst - [module_idP].RA_prach_resources. - ra_TDD_map_index); + if ((num_prach > 0) && (num_prach < 6)) { + UE_mac_inst[module_idP].RA_prach_resources.ra_TDD_map_index = + (taus() % num_prach); } - // choose RA-RNTI - UE_mac_inst[module_idP].RA_prach_resources.ra_RNTI = - 1 + t_id + 10 * f_id; + + f_id = get_fid_prach_tdd(module_idP, + UE_mac_inst + [module_idP].RA_prach_resources. + ra_TDD_map_index); + } + + // choose RA-RNTI + UE_mac_inst[module_idP].RA_prach_resources.ra_RNTI = + 1 + t_id + 10 * f_id; } void Msg1_transmitted(module_id_t module_idP, uint8_t CC_id, - frame_t frameP, uint8_t eNB_id) -{ - - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - // start contention resolution timer - UE_mac_inst[module_idP].RA_attempt_number++; - - if (opt_enabled) { - trace_pdu(DIRECTION_UPLINK, NULL, 0, module_idP, WS_NO_RNTI, - UE_mac_inst[module_idP].RA_prach_resources. - ra_PreambleIndex, UE_mac_inst[module_idP].txFrame, - UE_mac_inst[module_idP].txSubframe, 0, - UE_mac_inst[module_idP].RA_attempt_number); - LOG_D(OPT, - "[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x with size %d\n", - module_idP, frameP, 1, UE_mac_inst[module_idP].RA_Msg3_size); - } - + frame_t frameP, uint8_t eNB_id) { + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); + // start contention resolution timer + UE_mac_inst[module_idP].RA_attempt_number++; + + if (opt_enabled) { + trace_pdu(DIRECTION_UPLINK, NULL, 0, module_idP, WS_NO_RNTI, + UE_mac_inst[module_idP].RA_prach_resources. + ra_PreambleIndex, UE_mac_inst[module_idP].txFrame, + UE_mac_inst[module_idP].txSubframe, 0, + UE_mac_inst[module_idP].RA_attempt_number); + LOG_D(OPT, + "[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x with size %d\n", + module_idP, frameP, 1, UE_mac_inst[module_idP].RA_Msg3_size); + } } void Msg3_transmitted(module_id_t module_idP, uint8_t CC_id, - frame_t frameP, uint8_t eNB_id) -{ - - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - - // start contention resolution timer - LOG_D(MAC, - "[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n", - module_idP, frameP); - UE_mac_inst[module_idP].RA_contention_resolution_cnt = 0; - UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1; - - if (opt_enabled) { // msg3 - trace_pdu(DIRECTION_UPLINK , &UE_mac_inst[module_idP].CCCH_pdu.payload[0], - UE_mac_inst[module_idP].RA_Msg3_size, module_idP, WS_C_RNTI, - UE_mac_inst[module_idP].crnti, - UE_mac_inst[module_idP].txFrame, - UE_mac_inst[module_idP].txSubframe, 0, 0); - LOG_D(OPT, - "[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n", - module_idP, frameP, UE_mac_inst[module_idP].crnti - /*UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex */ - , UE_mac_inst[module_idP].RA_Msg3_size); - } - + frame_t frameP, uint8_t eNB_id) { + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); + // start contention resolution timer + LOG_D(MAC, + "[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n", + module_idP, frameP); + UE_mac_inst[module_idP].RA_contention_resolution_cnt = 0; + UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 1; + + if (opt_enabled) { // msg3 + trace_pdu(DIRECTION_UPLINK, &UE_mac_inst[module_idP].CCCH_pdu.payload[0], + UE_mac_inst[module_idP].RA_Msg3_size, module_idP, WS_C_RNTI, + UE_mac_inst[module_idP].crnti, + UE_mac_inst[module_idP].txFrame, + UE_mac_inst[module_idP].txSubframe, 0, 0); + LOG_D(OPT, + "[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n", + module_idP, frameP, UE_mac_inst[module_idP].crnti + /*UE_mac_inst[module_idP].RA_prach_resources.ra_PreambleIndex */ + , UE_mac_inst[module_idP].RA_Msg3_size); + } } PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, - frame_t frameP, uint8_t eNB_indexP, - sub_frame_t subframeP) -{ - - uint8_t Size = 0; - UE_MODE_t UE_mode; - // Modification for phy_stub_ue operation - if(nfapi_mode == 3) { // phy_stub_ue mode - UE_mode = UE_mac_inst[module_idP].UE_mode[0]; - LOG_D(MAC, "ue_get_rach , UE_mode: %d", UE_mode); - } - else { // Full stack mode - UE_mode = get_ue_mode(module_idP,0,eNB_indexP); + frame_t frameP, uint8_t eNB_indexP, + sub_frame_t subframeP) { + uint8_t Size = 0; + UE_MODE_t UE_mode; + + // Modification for phy_stub_ue operation + if(NFAPI_MODE == NFAPI_UE_STUB_PNF) { // phy_stub_ue mode + UE_mode = UE_mac_inst[module_idP].UE_mode[0]; + LOG_D(MAC, "ue_get_rach , UE_mode: %d", UE_mode); + } else { // Full stack mode + UE_mode = get_ue_mode(module_idP,0,eNB_indexP); + } + + uint8_t lcid = CCCH; + uint16_t Size16; + struct LTE_RACH_ConfigCommon *rach_ConfigCommon = + (struct LTE_RACH_ConfigCommon *) NULL; + int32_t frame_diff = 0; + uint8_t dcch_header_len = 0; + uint16_t sdu_lengths; + uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); + + if (UE_mode == PRACH) { + LOG_D(MAC, "ue_get_rach 3, RA_active value: %d", UE_mac_inst[module_idP].RA_active); + + if (UE_mac_inst[module_idP].radioResourceConfigCommon) { + rach_ConfigCommon = + &UE_mac_inst[module_idP]. + radioResourceConfigCommon->rach_ConfigCommon; + } else { + return (NULL); } - - uint8_t lcid = CCCH; - uint16_t Size16; - struct LTE_RACH_ConfigCommon *rach_ConfigCommon = - (struct LTE_RACH_ConfigCommon *) NULL; - int32_t frame_diff = 0; - uint8_t dcch_header_len = 0; - uint16_t sdu_lengths; - uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; - - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - - if (UE_mode == PRACH) { - LOG_D(MAC, "ue_get_rach 3, RA_active value: %d", UE_mac_inst[module_idP].RA_active); - if (UE_mac_inst[module_idP].radioResourceConfigCommon) { - rach_ConfigCommon = - &UE_mac_inst[module_idP]. - radioResourceConfigCommon->rach_ConfigCommon; - } else { - return (NULL); - } - - if (UE_mac_inst[module_idP].RA_active == 0) { - LOG_I(MAC, "RA not active\n"); - // check if RRC is ready to initiate the RA procedure - Size = mac_rrc_data_req_ue(module_idP, - CC_id, - frameP, - CCCH, 1, - &UE_mac_inst[module_idP]. - CCCH_pdu.payload[sizeof - (SCH_SUBHEADER_SHORT) - + 1], eNB_indexP, - 0); - Size16 = (uint16_t) Size; - - // LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size); - LOG_I(RRC, - "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest eNB %d) --->][MAC_UE][MOD %02d][]\n", - frameP, module_idP, eNB_indexP, module_idP); - LOG_I(MAC, - "[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", - module_idP, frameP, Size); - - if (Size > 0) { - UE_mac_inst[module_idP].RA_active = 1; - UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = - 1; - UE_mac_inst[module_idP].RA_Msg3_size = - Size + sizeof(SCH_SUBHEADER_SHORT) + - sizeof(SCH_SUBHEADER_SHORT); - UE_mac_inst[module_idP].RA_prachMaskIndex = 0; - UE_mac_inst[module_idP].RA_prach_resources.Msg3 = - UE_mac_inst[module_idP].CCCH_pdu.payload; - UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) - - AssertFatal(rach_ConfigCommon != NULL, - "[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n", - module_idP, frameP); - UE_mac_inst[module_idP].RA_window_cnt = - 2 + - rach_ConfigCommon->ra_SupervisionInfo. - ra_ResponseWindowSize; - - if (UE_mac_inst[module_idP].RA_window_cnt == 9) { - UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! - } - - UE_mac_inst[module_idP].RA_tx_frame = frameP; - UE_mac_inst[module_idP].RA_tx_subframe = subframeP; - UE_mac_inst[module_idP].RA_backoff_frame = frameP; - UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; - // Fill in preamble and PRACH resource - get_prach_resources(module_idP, CC_id, eNB_indexP, - subframeP, 1, NULL); - - generate_ulsch_header((uint8_t *) & UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header - 1, // num sdus - 0, // short pading - &Size16, // sdu length - &lcid, // sdu lcid - NULL, // power headroom - NULL, // crnti - NULL, // truncated bsr - NULL, // short bsr - NULL, // long_bsr - 1); //post_padding - return (&UE_mac_inst[module_idP].RA_prach_resources); - - } else if (UE_mac_inst[module_idP]. - scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. - scheduling_info.LCGID - [DCCH]] > 0) { - // This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example) - dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element - LOG_USEDINLOG_VAR(mac_rlc_status_resp_t,rlc_status)=mac_rlc_status_ind(module_idP, - UE_mac_inst[module_idP].crnti, - eNB_indexP, frameP, subframeP, - ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6 + if (UE_mac_inst[module_idP].RA_active == 0) { + LOG_I(MAC, "RA not active\n"); + // check if RRC is ready to initiate the RA procedure + Size = mac_rrc_data_req_ue(module_idP, + CC_id, + frameP, + CCCH, 1, + &UE_mac_inst[module_idP]. + CCCH_pdu.payload[sizeof + (SCH_SUBHEADER_SHORT) + + 1], eNB_indexP, + 0); + Size16 = (uint16_t) Size; + // LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",module_idP,frameP,Size); + LOG_I(RRC, + "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest eNB %d) --->][MAC_UE][MOD %02d][]\n", + frameP, module_idP, eNB_indexP, module_idP); + LOG_I(MAC, + "[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", + module_idP, frameP, Size); + + if (Size > 0) { + UE_mac_inst[module_idP].RA_active = 1; + UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = + 1; + UE_mac_inst[module_idP].RA_Msg3_size = + Size + sizeof(SCH_SUBHEADER_SHORT) + + sizeof(SCH_SUBHEADER_SHORT); + UE_mac_inst[module_idP].RA_prachMaskIndex = 0; + UE_mac_inst[module_idP].RA_prach_resources.Msg3 = + UE_mac_inst[module_idP].CCCH_pdu.payload; + UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) + AssertFatal(rach_ConfigCommon != NULL, + "[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n", + module_idP, frameP); + UE_mac_inst[module_idP].RA_window_cnt = + 2 + + rach_ConfigCommon->ra_SupervisionInfo. + ra_ResponseWindowSize; + + if (UE_mac_inst[module_idP].RA_window_cnt == 9) { + UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! + } + + UE_mac_inst[module_idP].RA_tx_frame = frameP; + UE_mac_inst[module_idP].RA_tx_subframe = subframeP; + UE_mac_inst[module_idP].RA_backoff_frame = frameP; + UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; + // Fill in preamble and PRACH resource + get_prach_resources(module_idP, CC_id, eNB_indexP, + subframeP, 1, NULL); + generate_ulsch_header((uint8_t *) & UE_mac_inst[module_idP].CCCH_pdu.payload[0], // mac header + 1, // num sdus + 0, // short pading + &Size16, // sdu length + &lcid, // sdu lcid + NULL, // power headroom + NULL, // crnti + NULL, // truncated bsr + NULL, // short bsr + NULL, // long_bsr + 1); //post_padding + return (&UE_mac_inst[module_idP].RA_prach_resources); + } else if (UE_mac_inst[module_idP]. + scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. + scheduling_info.LCGID + [DCCH]] > 0) { + // This is for triggering a transmission on DCCH using PRACH (during handover, or sending SR for example) + dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element + LOG_USEDINLOG_VAR(mac_rlc_status_resp_t,rlc_status)=mac_rlc_status_ind(module_idP, + UE_mac_inst[module_idP].crnti, + eNB_indexP, frameP, subframeP, + ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + ,0, 0 #endif - ); - - if (UE_mac_inst[module_idP].crnti_before_ho) - LOG_D(MAC, - "[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n", - module_idP, frameP, - UE_mac_inst[module_idP].crnti, - UE_mac_inst[module_idP].crnti_before_ho, - rlc_status.bytes_in_buffer, dcch_header_len); - else - LOG_D(MAC, - "[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n", - module_idP, frameP, rlc_status.bytes_in_buffer, - dcch_header_len); - - sdu_lengths = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6, //not used - (char *) &ulsch_buff[0] + ); + + if (UE_mac_inst[module_idP].crnti_before_ho) + LOG_D(MAC, + "[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n", + module_idP, frameP, + UE_mac_inst[module_idP].crnti, + UE_mac_inst[module_idP].crnti_before_ho, + rlc_status.bytes_in_buffer, dcch_header_len); + else + LOG_D(MAC, + "[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n", + module_idP, frameP, rlc_status.bytes_in_buffer, + dcch_header_len); + + sdu_lengths = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6, //not used + (char *) &ulsch_buff[0] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, - 0 + ,0, + 0 #endif - ); - - if(sdu_lengths > 0) - LOG_D(MAC, "[UE %d] TX Got %d bytes for DCCH\n", - module_idP, sdu_lengths); - else - LOG_E(MAC, "[UE %d] TX DCCH error\n", - module_idP ); - - update_bsr(module_idP, frameP, subframeP, eNB_indexP); - UE_mac_inst[module_idP]. - scheduling_info.BSR[UE_mac_inst[module_idP]. - scheduling_info.LCGID[DCCH]] = - locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, - UE_mac_inst - [module_idP].scheduling_info.BSR_bytes - [UE_mac_inst - [module_idP].scheduling_info.LCGID - [DCCH]]); - - //TO DO: fill BSR infos in UL TBS - - //header_len +=2; - UE_mac_inst[module_idP].RA_active = 1; - UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = - 1; - UE_mac_inst[module_idP].RA_Msg3_size = - Size + dcch_header_len; - UE_mac_inst[module_idP].RA_prachMaskIndex = 0; - UE_mac_inst[module_idP].RA_prach_resources.Msg3 = - ulsch_buff; - UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) - - AssertFatal(rach_ConfigCommon != NULL, - "[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n", - module_idP, frameP); - UE_mac_inst[module_idP].RA_window_cnt = - 2 + - rach_ConfigCommon->ra_SupervisionInfo. - ra_ResponseWindowSize; - - if (UE_mac_inst[module_idP].RA_window_cnt == 9) { - UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! - } - - - UE_mac_inst[module_idP].RA_tx_frame = frameP; - UE_mac_inst[module_idP].RA_tx_subframe = subframeP; - UE_mac_inst[module_idP].RA_backoff_frame = frameP; - UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; - // Fill in preamble and PRACH resource - get_prach_resources(module_idP, CC_id, eNB_indexP, - subframeP, 1, NULL); - generate_ulsch_header((uint8_t *) ulsch_buff, // mac header - 1, // num sdus - 0, // short pading - &Size16, // sdu length - &lcid, // sdu lcid - NULL, // power headroom - &UE_mac_inst[module_idP].crnti, // crnti - NULL, // truncated bsr - NULL, // short bsr - NULL, // long_bsr - 0); //post_padding - - return (&UE_mac_inst[module_idP].RA_prach_resources); - } - } else { // RACH is active - LOG_D(MAC, - "[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n", - module_idP, frameP, subframeP, - UE_mac_inst[module_idP].RA_window_cnt, - UE_mac_inst[module_idP].RA_tx_frame, - UE_mac_inst[module_idP].RA_tx_subframe); - - // compute backoff parameters - if (UE_mac_inst[module_idP].RA_backoff_cnt > 0) { - frame_diff = - (sframe_t) frameP - - UE_mac_inst[module_idP].RA_backoff_frame; - - if (frame_diff < 0) { - frame_diff = -frame_diff; - } - - UE_mac_inst[module_idP].RA_backoff_cnt -= - ((10 * frame_diff) + - (subframeP - - UE_mac_inst[module_idP].RA_backoff_subframe)); - - UE_mac_inst[module_idP].RA_backoff_frame = frameP; - UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; - } - // compute RA window parameters - if (UE_mac_inst[module_idP].RA_window_cnt > 0) { - frame_diff = - (frame_t) frameP - UE_mac_inst[module_idP].RA_tx_frame; - - if (frame_diff < 0) { - frame_diff = -frame_diff; - } - - UE_mac_inst[module_idP].RA_window_cnt -= - ((10 * frame_diff) + - (subframeP - UE_mac_inst[module_idP].RA_tx_subframe)); - LOG_D(MAC, - "[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, adjusted window cnt %d\n", - module_idP, frameP, subframeP, - UE_mac_inst[module_idP].RA_window_cnt); - } - - if ((UE_mac_inst[module_idP].RA_window_cnt <= 0) && - (UE_mac_inst[module_idP].RA_backoff_cnt <= 0)) { - - UE_mac_inst[module_idP].RA_tx_frame = frameP; - UE_mac_inst[module_idP].RA_tx_subframe = subframeP; - UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER++; - UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER += (rach_ConfigCommon->powerRampingParameters.powerRampingStep << 1); // 2dB increments in ASN.1 definition - int preambleTransMax = -1; - switch (rach_ConfigCommon->ra_SupervisionInfo. - preambleTransMax) { - case LTE_PreambleTransMax_n3: - preambleTransMax = 3; - break; - case LTE_PreambleTransMax_n4: - preambleTransMax = 4; - break; - case LTE_PreambleTransMax_n5: - preambleTransMax = 5; - break; - case LTE_PreambleTransMax_n6: - preambleTransMax = 6; - break; - case LTE_PreambleTransMax_n7: - preambleTransMax = 7; - break; - case LTE_PreambleTransMax_n8: - preambleTransMax = 8; - break; - case LTE_PreambleTransMax_n10: - preambleTransMax = 10; - break; - case LTE_PreambleTransMax_n20: - preambleTransMax = 20; - break; - case LTE_PreambleTransMax_n50: - preambleTransMax = 50; - break; - case LTE_PreambleTransMax_n100: - preambleTransMax = 100; - break; - case LTE_PreambleTransMax_n200: - preambleTransMax = 200; - break; - } - - if (UE_mac_inst[module_idP]. - RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax) { - LOG_D(MAC, - "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", - module_idP, frameP, preambleTransMax); - // send message to RRC - UE_mac_inst[module_idP]. - RA_PREAMBLE_TRANSMISSION_COUNTER = 1; - UE_mac_inst[module_idP]. - RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - = get_Po_NOMINAL_PUSCH(module_idP, CC_id); - } - - UE_mac_inst[module_idP].RA_window_cnt = - 2 + - rach_ConfigCommon->ra_SupervisionInfo. - ra_ResponseWindowSize; - UE_mac_inst[module_idP].RA_backoff_cnt = 0; - - // Fill in preamble and PRACH resource - get_prach_resources(module_idP, CC_id, eNB_indexP, - subframeP, 0, NULL); - return (&UE_mac_inst[module_idP].RA_prach_resources); - } - } - } else if (UE_mode == PUSCH) { - LOG_D(MAC, - "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...", - module_idP); - AssertFatal(1 == 0, ""); + ); + + if(sdu_lengths > 0) + LOG_D(MAC, "[UE %d] TX Got %d bytes for DCCH\n", + module_idP, sdu_lengths); + else + LOG_E(MAC, "[UE %d] TX DCCH error\n", + module_idP ); + + update_bsr(module_idP, frameP, subframeP, eNB_indexP); + UE_mac_inst[module_idP]. + scheduling_info.BSR[UE_mac_inst[module_idP]. + scheduling_info.LCGID[DCCH]] = + locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, + UE_mac_inst + [module_idP].scheduling_info.BSR_bytes + [UE_mac_inst + [module_idP].scheduling_info.LCGID + [DCCH]]); + //TO DO: fill BSR infos in UL TBS + //header_len +=2; + UE_mac_inst[module_idP].RA_active = 1; + UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER = + 1; + UE_mac_inst[module_idP].RA_Msg3_size = + Size + dcch_header_len; + UE_mac_inst[module_idP].RA_prachMaskIndex = 0; + UE_mac_inst[module_idP].RA_prach_resources.Msg3 = + ulsch_buff; + UE_mac_inst[module_idP].RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) + AssertFatal(rach_ConfigCommon != NULL, + "[UE %d] FATAL Frame %d: rach_ConfigCommon is NULL !!!\n", + module_idP, frameP); + UE_mac_inst[module_idP].RA_window_cnt = + 2 + + rach_ConfigCommon->ra_SupervisionInfo. + ra_ResponseWindowSize; + + if (UE_mac_inst[module_idP].RA_window_cnt == 9) { + UE_mac_inst[module_idP].RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10! + } + + UE_mac_inst[module_idP].RA_tx_frame = frameP; + UE_mac_inst[module_idP].RA_tx_subframe = subframeP; + UE_mac_inst[module_idP].RA_backoff_frame = frameP; + UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; + // Fill in preamble and PRACH resource + get_prach_resources(module_idP, CC_id, eNB_indexP, + subframeP, 1, NULL); + generate_ulsch_header((uint8_t *) ulsch_buff, // mac header + 1, // num sdus + 0, // short pading + &Size16, // sdu length + &lcid, // sdu lcid + NULL, // power headroom + &UE_mac_inst[module_idP].crnti, // crnti + NULL, // truncated bsr + NULL, // short bsr + NULL, // long_bsr + 0); //post_padding + return (&UE_mac_inst[module_idP].RA_prach_resources); + } + } else { // RACH is active + LOG_D(MAC, + "[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n", + module_idP, frameP, subframeP, + UE_mac_inst[module_idP].RA_window_cnt, + UE_mac_inst[module_idP].RA_tx_frame, + UE_mac_inst[module_idP].RA_tx_subframe); + + // compute backoff parameters + if (UE_mac_inst[module_idP].RA_backoff_cnt > 0) { + frame_diff = + (sframe_t) frameP - + UE_mac_inst[module_idP].RA_backoff_frame; + + if (frame_diff < 0) { + frame_diff = -frame_diff; + } + + UE_mac_inst[module_idP].RA_backoff_cnt -= + ((10 * frame_diff) + + (subframeP - + UE_mac_inst[module_idP].RA_backoff_subframe)); + UE_mac_inst[module_idP].RA_backoff_frame = frameP; + UE_mac_inst[module_idP].RA_backoff_subframe = subframeP; + } + + // compute RA window parameters + if (UE_mac_inst[module_idP].RA_window_cnt > 0) { + frame_diff = + (frame_t) frameP - UE_mac_inst[module_idP].RA_tx_frame; + + if (frame_diff < 0) { + frame_diff = -frame_diff; + } + + UE_mac_inst[module_idP].RA_window_cnt -= + ((10 * frame_diff) + + (subframeP - UE_mac_inst[module_idP].RA_tx_subframe)); + LOG_D(MAC, + "[MAC][UE %d][RAPROC] frameP %d, subframe %d: RA Active, adjusted window cnt %d\n", + module_idP, frameP, subframeP, + UE_mac_inst[module_idP].RA_window_cnt); + } + + if ((UE_mac_inst[module_idP].RA_window_cnt <= 0) && + (UE_mac_inst[module_idP].RA_backoff_cnt <= 0)) { + UE_mac_inst[module_idP].RA_tx_frame = frameP; + UE_mac_inst[module_idP].RA_tx_subframe = subframeP; + UE_mac_inst[module_idP].RA_PREAMBLE_TRANSMISSION_COUNTER++; + UE_mac_inst[module_idP].RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER += (rach_ConfigCommon->powerRampingParameters.powerRampingStep << 1); // 2dB increments in ASN.1 definition + int preambleTransMax = -1; + + switch (rach_ConfigCommon->ra_SupervisionInfo. + preambleTransMax) { + case LTE_PreambleTransMax_n3: + preambleTransMax = 3; + break; + + case LTE_PreambleTransMax_n4: + preambleTransMax = 4; + break; + + case LTE_PreambleTransMax_n5: + preambleTransMax = 5; + break; + + case LTE_PreambleTransMax_n6: + preambleTransMax = 6; + break; + + case LTE_PreambleTransMax_n7: + preambleTransMax = 7; + break; + + case LTE_PreambleTransMax_n8: + preambleTransMax = 8; + break; + + case LTE_PreambleTransMax_n10: + preambleTransMax = 10; + break; + + case LTE_PreambleTransMax_n20: + preambleTransMax = 20; + break; + + case LTE_PreambleTransMax_n50: + preambleTransMax = 50; + break; + + case LTE_PreambleTransMax_n100: + preambleTransMax = 100; + break; + + case LTE_PreambleTransMax_n200: + preambleTransMax = 200; + break; + } + + if (UE_mac_inst[module_idP]. + RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax) { + LOG_D(MAC, + "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", + module_idP, frameP, preambleTransMax); + // send message to RRC + UE_mac_inst[module_idP]. + RA_PREAMBLE_TRANSMISSION_COUNTER = 1; + UE_mac_inst[module_idP]. + RA_prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER + = get_Po_NOMINAL_PUSCH(module_idP, CC_id); + } + + UE_mac_inst[module_idP].RA_window_cnt = + 2 + + rach_ConfigCommon->ra_SupervisionInfo. + ra_ResponseWindowSize; + UE_mac_inst[module_idP].RA_backoff_cnt = 0; + // Fill in preamble and PRACH resource + get_prach_resources(module_idP, CC_id, eNB_indexP, + subframeP, 0, NULL); + return (&UE_mac_inst[module_idP].RA_prach_resources); + } } + } else if (UE_mode == PUSCH) { + LOG_D(MAC, + "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...", + module_idP); + AssertFatal(1 == 0, ""); + } - return (NULL); + return (NULL); } diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index 2fa13fc98c2293b9ab5215ef12a5c540bbc9cc47..284c0af19e0a96c52466b821031c8eca895b8f33 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -110,98 +110,124 @@ fill_rar(const module_id_t module_idP, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //------------------------------------------------------------------------------ - +/* + * Fill the RAR buffer (header + PDU) for LTE-M devices + */ unsigned short fill_rar_br(eNB_MAC_INST *eNB, - int CC_id, - RA_t *ra, - const frame_t frameP, - const sub_frame_t subframeP, - uint8_t* const dlsch_buffer, - const uint8_t ce_level - ) + int CC_id, + RA_t *ra, + const frame_t frameP, + const sub_frame_t subframeP, + uint8_t* const dlsch_buffer, + const uint8_t ce_level) //------------------------------------------------------------------------------ { - - RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer; + RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *) dlsch_buffer; COMMON_channels_t *cc = &eNB->common_channels[CC_id]; - uint8_t *rar = (uint8_t *)(dlsch_buffer+1); - - uint32_t rballoc,reps; - uint32_t TPC,ULdelay,cqireq,mpdcch_nb_index; - int input_buffer_length; + uint8_t *rar = (uint8_t *)(dlsch_buffer + 1); + uint32_t rballoc = 0; + uint32_t reps = 0; + uint32_t ULdelay = 0; + uint32_t cqireq = 0; + uint32_t mpdcch_nb_index = 0; + uint32_t TPC = 0; + int input_buffer_length = 0; + int N_NB_index = 0; AssertFatal(ra != NULL, "RA is null \n"); - // subheader fixed + /* Subheader fixed */ rarh->E = 0; // First and last RAR rarh->T = 1; // 0 for E/T/R/R/BI subheader, 1 for E/T/RAPID subheader - rarh->RAPID = ra->preamble_index; // Respond to Preamble 0 only for the moment - ra->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps - rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs of timing advance + divide by 4 - rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4 - - int N_NB_index; + rarh->RAPID = ra->preamble_index; // Respond to Preamble + + /* RAR PDU */ + /* TA Command */ + ra->timing_offset /= 16; // T_A = N_TA/16, where N_TA should be on a 30.72Msps + rar[0] = (uint8_t) (ra->timing_offset >> 4) & 0x7f; // 7 MSBs of timing advance + rar[1] = (uint8_t) (ra->timing_offset & 0x0f) << 4; // 4 LSBs of timing advance - // Copy the Msg2 narrowband + /* Copy the Msg2 narrowband */ ra->msg34_narrowband = ra->msg2_narrowband; ra->msg3_first_rb = 0; ra->msg3_nb_rb = 2; - - if (ce_level < 2) { //CE Level 0,1, CEmodeA + if (ce_level < 2) { // CE Level 0, 1 (CEmodeA) input_buffer_length = 6; N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth); - rar[4] = (uint8_t)(ra->rnti>>8); - rar[5] = (uint8_t)(ra->rnti&0xff); - //cc->ra[ra_idx].timing_offset = 0; - + /* UL Grant */ reps = 0; ra->msg3_mcs = 7; TPC = 3; // no power increase ULdelay = 0; cqireq = 0; mpdcch_nb_index = 0; - rballoc = mac_computeRIV(6,ra->msg3_first_rb,ra->msg3_nb_rb); + rballoc = mac_computeRIV(6, ra->msg3_first_rb, ra->msg3_nb_rb); uint32_t buffer = 0; buffer |= ra->msg34_narrowband << (16 + (4 - N_NB_index)); - buffer |= ((rballoc & 0xFF) << (12 + (4 - N_NB_index))); + buffer |= ((rballoc & 0x0F) << (12 + (4 - N_NB_index))); buffer |= ((reps & 0x03) << (10 + (4 - N_NB_index))); buffer |= ((ra->msg3_mcs & 0x07) << (7 + (4 - N_NB_index))); buffer |= ((TPC & 0x07) << (4 + (4 - N_NB_index))); buffer |= ((cqireq & 0x01) << (3 + (4 - N_NB_index))); buffer |= ((ULdelay & 0x01) << (2 + (4 - N_NB_index))); buffer |= (mpdcch_nb_index << (4 - N_NB_index)); - rar[1] = (buffer>>16) & 0x0F; - rar[2] = (buffer>>8) & 0xFF; - rar[3] = buffer&0xFF; - } - else { // CE level 2,3 => CEModeB - AssertFatal(1==0,"Shouldn't get here ...\n"); - input_buffer_length =5; + rar[1] |= (uint8_t) (buffer >> 16) & 0x0F; + rar[2] = (uint8_t) (buffer >> 8) & 0xFF; + rar[3] = (uint8_t) buffer & 0xFF; + /* RA CRNTI */ + rar[4] = (uint8_t)(ra->rnti >> 8); + rar[5] = (uint8_t)(ra->rnti & 0xff); + + } else { // CE level 2, 3 (CEModeB) - rar[3] = (uint8_t)(ra->rnti>>8); - rar[4] = (uint8_t)(ra->rnti&0xff); + AssertFatal(1 == 0, "Shouldn't get here ...\n"); + + input_buffer_length = 5; + + rar[3] = (uint8_t)(ra->rnti >> 8); + rar[4] = (uint8_t)(ra->rnti & 0xff); } - LOG_I(MAC,"[RAPROC] Frame %d Subframe %d : Generating RAR BR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ce_level %d, CRNTI %x,preamble %d/%d,TIMING OFFSET %d\n", - frameP,subframeP, - *(uint8_t*)rarh,rar[0],rar[1],rar[2],rar[3],rar[4],rar[5], + + LOG_I(MAC, "[RAPROC] Frame %d Subframe %d : Generating RAR BR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for ce_level %d, CRNTI %x, preamble %d/%d, TIMING OFFSET %d\n", + frameP, + subframeP, + *(uint8_t*) rarh, + rar[0], + rar[1], + rar[2], + rar[3], + rar[4], + rar[5], ce_level, ra->rnti, - rarh->RAPID,ra->preamble_index, + rarh->RAPID, + ra->preamble_index, ra->timing_offset); if (opt_enabled) { - trace_pdu(DIRECTION_DOWNLINK , dlsch_buffer, input_buffer_length, eNB->Mod_id, WS_RA_RNTI , 1, - eNB->frame, eNB->subframe, 0, 0); - LOG_D(OPT, - "[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", - frameP, ra->rnti, rarh->RAPID, input_buffer_length); + trace_pdu(DIRECTION_DOWNLINK, + dlsch_buffer, + input_buffer_length, + eNB->Mod_id, + WS_RA_RNTI, + 1, + eNB->frame, + eNB->subframe, + 0, + 0); + + LOG_D(OPT, "[RAPROC] RAR Frame %d trace pdu for rnti %x and rapid %d size %d\n", + frameP, + ra->rnti, + rarh->RAPID, + input_buffer_length); } return (ra->rnti); diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 453bf021fe126b7f126bcfa410fc49f6a84c6ff8..de1d40e604f1ba0b97bad442d3b6729b1f13f555 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -30,7 +30,7 @@ */ #ifdef EXMIMO -#include <pthread.h> + #include <pthread.h> #endif #include "mac_extern.h" @@ -46,6 +46,7 @@ #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "RRC/LTE/rrc_extern.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" @@ -55,12 +56,12 @@ #include "pdcp.h" #if defined(ENABLE_ITTI) -#include "intertask_interface.h" + #include "intertask_interface.h" #endif #include "assertions.h" -#include "SIMULATION/TOOLS/sim.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus #define DEBUG_HEADER_PARSING 1 #define ENABLE_MAC_PAYLOAD_DEBUG 1 @@ -68,7 +69,7 @@ extern UL_IND_t *UL_INFO; -extern uint8_t nfapi_mode; + extern int next_ra_frame; extern module_id_t next_Mod_id; @@ -80,541 +81,516 @@ extern module_id_t next_Mod_id; */ mapping BSR_names[] = { - {"NONE", 0}, - {"SHORT BSR", 1}, - {"TRUNCATED BSR", 2}, - {"LONG BSR", 3}, - {"PADDING BSR", 4}, - {NULL, -1} + {"NONE", 0}, + {"SHORT BSR", 1}, + {"TRUNCATED BSR", 2}, + {"LONG BSR", 3}, + {"PADDING BSR", 4}, + {NULL, -1} }; -void ue_init_mac(module_id_t module_idP) -{ - - int i; - // default values as deined in 36.331 sec 9.2.2 - LOG_I(MAC, "[UE%d] Applying default macMainConfig\n", module_idP); - //UE_mac_inst[module_idP].scheduling_info.macConfig=NULL; - UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer = - LTE_RetxBSR_Timer_r12_sf10240; - UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer = - LTE_PeriodicBSR_Timer_r12_infinity; - UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer = - LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; - UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer = - LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; - UE_mac_inst[module_idP].scheduling_info.PathlossChange_db = - LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; - UE_mac_inst[module_idP].PHR_state = - LTE_MAC_MainConfig__phr_Config_PR_setup; - UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0; - UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer = 0; - UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running = 0; - UE_mac_inst[module_idP].scheduling_info.maxHARQ_Tx = - LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; - UE_mac_inst[module_idP].scheduling_info.ttiBundling = 0; - UE_mac_inst[module_idP].scheduling_info.extendedBSR_Sizes_r10 = 0; - UE_mac_inst[module_idP].scheduling_info.extendedPHR_r10 = 0; - UE_mac_inst[module_idP].scheduling_info.drx_config = NULL; - UE_mac_inst[module_idP].scheduling_info.phr_config = NULL; - // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value configured by the NW. - UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = - MAC_UE_BSR_TIMER_NOT_RUNNING; - UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = - MAC_UE_BSR_TIMER_NOT_RUNNING; - UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE; - - UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF = - get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP]. - scheduling_info.periodicPHR_Timer); - UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF = - get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP]. - scheduling_info.prohibitPHR_Timer); - UE_mac_inst[module_idP].scheduling_info.PathlossChange_db = - get_db_dl_PathlossChange(UE_mac_inst[module_idP]. - scheduling_info.PathlossChange); - UE_mac_inst[module_idP].PHR_reporting_active = 0; +void ue_init_mac(module_id_t module_idP) { + int i; + // default values as deined in 36.331 sec 9.2.2 + LOG_I(MAC, "[UE%d] Applying default macMainConfig\n", module_idP); + //UE_mac_inst[module_idP].scheduling_info.macConfig=NULL; + UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer = + LTE_RetxBSR_Timer_r12_sf10240; + UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer = + LTE_PeriodicBSR_Timer_r12_infinity; + UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer = + LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; + UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer = + LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; + UE_mac_inst[module_idP].scheduling_info.PathlossChange_db = + LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; + UE_mac_inst[module_idP].PHR_state = + LTE_MAC_MainConfig__phr_Config_PR_setup; + UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0; + UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer = 0; + UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running = 0; + UE_mac_inst[module_idP].scheduling_info.maxHARQ_Tx = + LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + UE_mac_inst[module_idP].scheduling_info.ttiBundling = 0; + UE_mac_inst[module_idP].scheduling_info.extendedBSR_Sizes_r10 = 0; + UE_mac_inst[module_idP].scheduling_info.extendedPHR_r10 = 0; + UE_mac_inst[module_idP].scheduling_info.drx_config = NULL; + UE_mac_inst[module_idP].scheduling_info.phr_config = NULL; + // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value configured by the NW. + UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = + MAC_UE_BSR_TIMER_NOT_RUNNING; + UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = + MAC_UE_BSR_TIMER_NOT_RUNNING; + UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE; + UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF = + get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP]. + scheduling_info.periodicPHR_Timer); + UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF = + get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP]. + scheduling_info.prohibitPHR_Timer); + UE_mac_inst[module_idP].scheduling_info.PathlossChange_db = + get_db_dl_PathlossChange(UE_mac_inst[module_idP]. + scheduling_info.PathlossChange); + UE_mac_inst[module_idP].PHR_reporting_active = 0; + + for (i = 0; i < MAX_NUM_LCID; i++) { + LOG_D(MAC, + "[UE%d] Applying default logical channel config for LCGID %d\n", + module_idP, i); + UE_mac_inst[module_idP].scheduling_info.Bj[i] = -1; + UE_mac_inst[module_idP].scheduling_info.bucket_size[i] = -1; - for (i = 0; i < MAX_NUM_LCID; i++) { - LOG_D(MAC, - "[UE%d] Applying default logical channel config for LCGID %d\n", - module_idP, i); - UE_mac_inst[module_idP].scheduling_info.Bj[i] = -1; - UE_mac_inst[module_idP].scheduling_info.bucket_size[i] = -1; - - if (i < DTCH) { // initilize all control channels lcgid to 0 - UE_mac_inst[module_idP].scheduling_info.LCGID[i] = 0; - } else { // initialize all the data channels lcgid to 1 - UE_mac_inst[module_idP].scheduling_info.LCGID[i] = 1; - } - - UE_mac_inst[module_idP].scheduling_info.LCID_status[i] = - LCID_EMPTY; - UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[i] = 0; + if (i < DTCH) { // initilize all control channels lcgid to 0 + UE_mac_inst[module_idP].scheduling_info.LCGID[i] = 0; + } else { // initialize all the data channels lcgid to 1 + UE_mac_inst[module_idP].scheduling_info.LCGID[i] = 1; } - if(nfapi_mode == 3) { - pthread_mutex_init(&UE_mac_inst[module_idP].UL_INFO_mutex,NULL); - UE_mac_inst[module_idP].UE_mode[0] = NOT_SYNCHED; //PRACH; - UE_mac_inst[module_idP].first_ULSCH_Tx =0; - UE_mac_inst[module_idP].SI_Decoded = 0; - next_ra_frame = 0; - next_Mod_id = 0; - tx_request_pdu_list = NULL; - tx_req_num_elems = 0; - + UE_mac_inst[module_idP].scheduling_info.LCID_status[i] = + LCID_EMPTY; + UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[i] = 0; + } + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { + pthread_mutex_init(&UE_mac_inst[module_idP].UL_INFO_mutex,NULL); + UE_mac_inst[module_idP].UE_mode[0] = NOT_SYNCHED; //PRACH; + UE_mac_inst[module_idP].first_ULSCH_Tx =0; + UE_mac_inst[module_idP].SI_Decoded = 0; + next_ra_frame = 0; + next_Mod_id = 0; + tx_request_pdu_list = NULL; + tx_req_num_elems = 0; } #ifdef CBA - for (i = 0; i < NUM_MAX_CBA_GROUP; i++) { - UE_mac_inst[module_idP].cba_last_access[i] = - round(uniform_rngen(1, 30)); - } + for (i = 0; i < NUM_MAX_CBA_GROUP; i++) { + UE_mac_inst[module_idP].cba_last_access[i] = + round(uniform_rngen(1, 30)); + } #endif } unsigned char *parse_header(unsigned char *mac_header, - unsigned char *num_ce, - unsigned char *num_sdu, - unsigned char *rx_ces, - unsigned char *rx_lcids, - unsigned short *rx_lengths, - unsigned short tb_length) -{ - - unsigned char not_done = 1, num_ces = 0, num_cont_res = - 0, num_padding = 0, num_sdus = 0, lcid, num_sdu_cnt; - unsigned char *mac_header_ptr = mac_header; - unsigned short length, ce_len = 0; - - while (not_done == 1) { - - if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { - // printf("E=0\n"); - not_done = 0; - } - - lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; - - if (lcid < UE_CONT_RES) { - //printf("[MAC][UE] header %x.%x.%x\n",mac_header_ptr[0],mac_header_ptr[1],mac_header_ptr[2]); - if (not_done == 0) { // last MAC SDU, length is implicit - mac_header_ptr++; - length = - tb_length - (mac_header_ptr - mac_header) - ce_len; - - for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; - num_sdu_cnt++) { - length -= rx_lengths[num_sdu_cnt]; - } - } else { - if (((SCH_SUBHEADER_LONG *) mac_header_ptr)->F == 1) { - length = - ((((SCH_SUBHEADER_LONG *) mac_header_ptr)-> - L_MSB & 0x7f) - << 8) | (((SCH_SUBHEADER_LONG *) mac_header_ptr)-> - L_LSB & 0xff); - mac_header_ptr += 3; + unsigned char *num_ce, + unsigned char *num_sdu, + unsigned char *rx_ces, + unsigned char *rx_lcids, + unsigned short *rx_lengths, + unsigned short tb_length) { + unsigned char not_done = 1, num_ces = 0, num_cont_res = + 0, num_padding = 0, num_sdus = 0, lcid, num_sdu_cnt; + unsigned char *mac_header_ptr = mac_header; + unsigned short length, ce_len = 0; + + while (not_done == 1) { + if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { + // printf("E=0\n"); + not_done = 0; + } + + lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; + + if (lcid < UE_CONT_RES) { + //printf("[MAC][UE] header %x.%x.%x\n",mac_header_ptr[0],mac_header_ptr[1],mac_header_ptr[2]); + if (not_done == 0) { // last MAC SDU, length is implicit + mac_header_ptr++; + length = + tb_length - (mac_header_ptr - mac_header) - ce_len; + + for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; + num_sdu_cnt++) { + length -= rx_lengths[num_sdu_cnt]; + } + } else { + if (((SCH_SUBHEADER_LONG *) mac_header_ptr)->F == 1) { + length = + ((((SCH_SUBHEADER_LONG *) mac_header_ptr)-> + L_MSB & 0x7f) + << 8) | (((SCH_SUBHEADER_LONG *) mac_header_ptr)-> + L_LSB & 0xff); + mac_header_ptr += 3; #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] parse long sdu, size %x \n", length); + LOG_D(MAC, "[UE] parse long sdu, size %x \n", length); #endif - - } else { //if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) { - length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; - mac_header_ptr += 2; - } - } + } else { //if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) { + length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; + mac_header_ptr += 2; + } + } #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] sdu %d lcid %d length %d (offset now %ld)\n", - num_sdus, lcid, length, mac_header_ptr - mac_header); + LOG_D(MAC, "[UE] sdu %d lcid %d length %d (offset now %ld)\n", + num_sdus, lcid, length, mac_header_ptr - mac_header); #endif - rx_lcids[num_sdus] = lcid; - rx_lengths[num_sdus] = length; - num_sdus++; - } else { // This is a control element subheader - if (lcid == SHORT_PADDING) { - num_padding++; - mac_header_ptr++; - } else { - rx_ces[num_ces] = lcid; - num_ces++; - mac_header_ptr++; - - if (lcid == TIMING_ADV_CMD) { - ce_len++; - } else if (lcid == UE_CONT_RES) { - - // FNA: check MAC Header is one of thoses defined in Annex B of 36.321 - // Check there is only 1 Contention Resolution - if (num_cont_res) { - LOG_W(MAC, - "[UE] Msg4 Wrong received format: More than 1 Contention Resolution\n"); - // exit parsing - return NULL; - - } - // UE_CONT_RES shall never be the last subheader unless this is the only MAC subheader - if ((not_done == 0) - && ((num_sdus) || (num_ces > 1) || (num_padding))) { - LOG_W(MAC, - "[UE] Msg4 Wrong received format: Contention Resolution after num_ces=%d num_sdus=%d num_padding=%d\n", - num_ces, num_sdus, num_padding); - // exit parsing - return NULL; - } - num_cont_res++; - ce_len += 6; - } - } + rx_lcids[num_sdus] = lcid; + rx_lengths[num_sdus] = length; + num_sdus++; + } else { // This is a control element subheader + if (lcid == SHORT_PADDING) { + num_padding++; + mac_header_ptr++; + } else { + rx_ces[num_ces] = lcid; + num_ces++; + mac_header_ptr++; + + if (lcid == TIMING_ADV_CMD) { + ce_len++; + } else if (lcid == UE_CONT_RES) { + // FNA: check MAC Header is one of thoses defined in Annex B of 36.321 + // Check there is only 1 Contention Resolution + if (num_cont_res) { + LOG_W(MAC, + "[UE] Msg4 Wrong received format: More than 1 Contention Resolution\n"); + // exit parsing + return NULL; + } + + // UE_CONT_RES shall never be the last subheader unless this is the only MAC subheader + if ((not_done == 0) + && ((num_sdus) || (num_ces > 1) || (num_padding))) { + LOG_W(MAC, + "[UE] Msg4 Wrong received format: Contention Resolution after num_ces=%d num_sdus=%d num_padding=%d\n", + num_ces, num_sdus, num_padding); + // exit parsing + return NULL; + } + + num_cont_res++; + ce_len += 6; + } + } #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] ce %d lcid %d (offset now %ld)\n", num_ces, - lcid, mac_header_ptr - mac_header); + LOG_D(MAC, "[UE] ce %d lcid %d (offset now %ld)\n", num_ces, + lcid, mac_header_ptr - mac_header); #endif - } } + } - *num_ce = num_ces; - *num_sdu = num_sdus; - - return (mac_header_ptr); + *num_ce = num_ces; + *num_sdu = num_sdus; + return (mac_header_ptr); } uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, - uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe) -{ + uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe) { + // no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti + // int MGL=6;// measurement gap length in ms + int MGRP = 0; // measurement gap repetition period in ms + int gapOffset = -1; + int T = 0; + DevCheck(module_idP < (int) NB_UE_INST, module_idP, NB_UE_INST, 0); + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); + + // determin the measurement gap + if (UE_mac_inst[module_idP].measGapConfig != NULL) { + if (UE_mac_inst[module_idP].measGapConfig->choice.setup. + gapOffset.present == LTE_MeasGapConfig__setup__gapOffset_PR_gp0) { + MGRP = 40; + gapOffset = + UE_mac_inst[module_idP].measGapConfig->choice. + setup.gapOffset.choice.gp0; + } else if (UE_mac_inst[module_idP].measGapConfig->choice. + setup.gapOffset.present == + LTE_MeasGapConfig__setup__gapOffset_PR_gp1) { + MGRP = 80; + gapOffset = + UE_mac_inst[module_idP].measGapConfig->choice. + setup.gapOffset.choice.gp1; + } else { + LOG_W(MAC, "Measurement GAP offset is unknown\n"); + } - // no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti - // int MGL=6;// measurement gap length in ms - int MGRP = 0; // measurement gap repetition period in ms - int gapOffset = -1; - int T = 0; - - DevCheck(module_idP < (int) NB_UE_INST, module_idP, NB_UE_INST, 0); - - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - - // determin the measurement gap - if (UE_mac_inst[module_idP].measGapConfig != NULL) { - if (UE_mac_inst[module_idP].measGapConfig->choice.setup. - gapOffset.present == LTE_MeasGapConfig__setup__gapOffset_PR_gp0) { - MGRP = 40; - gapOffset = - UE_mac_inst[module_idP].measGapConfig->choice. - setup.gapOffset.choice.gp0; - } else if (UE_mac_inst[module_idP].measGapConfig->choice. - setup.gapOffset.present == - LTE_MeasGapConfig__setup__gapOffset_PR_gp1) { - MGRP = 80; - gapOffset = - UE_mac_inst[module_idP].measGapConfig->choice. - setup.gapOffset.choice.gp1; - } else { - LOG_W(MAC, "Measurement GAP offset is unknown\n"); - } - - T = MGRP / 10; - DevAssert(T != 0); - - //check the measurement gap and sr prohibit timer - if ((subframe == gapOffset % 10) - && ((frameP % T) == (floor(gapOffset / 10))) - && (UE_mac_inst[module_idP]. - scheduling_info.sr_ProhibitTimer_Running == 0)) { - UE_mac_inst[module_idP].scheduling_info.SR_pending = 1; - return (0); - } + T = MGRP / 10; + DevAssert(T != 0); + + //check the measurement gap and sr prohibit timer + if ((subframe == gapOffset % 10) + && ((frameP % T) == (floor(gapOffset / 10))) + && (UE_mac_inst[module_idP]. + scheduling_info.sr_ProhibitTimer_Running == 0)) { + UE_mac_inst[module_idP].scheduling_info.SR_pending = 1; + return (0); } + } - if ((UE_mac_inst[module_idP].physicalConfigDedicated != NULL) && - (UE_mac_inst[module_idP].scheduling_info.SR_pending == 1) && - (UE_mac_inst[module_idP].scheduling_info.SR_COUNTER < - (1 << - (2 + - UE_mac_inst[module_idP]. - physicalConfigDedicated->schedulingRequestConfig->choice.setup. - dsr_TransMax)))) { - LOG_D(MAC, - "[UE %d][SR %x] Frame %d subframe %d PHY asks for SR (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n", - module_idP, rnti, frameP, subframe, - UE_mac_inst[module_idP].scheduling_info.SR_COUNTER, - (1 << - (2 + - UE_mac_inst[module_idP]. - physicalConfigDedicated->schedulingRequestConfig->choice. - setup.dsr_TransMax)), - UE_mac_inst[module_idP].scheduling_info.SR_pending); - - UE_mac_inst[module_idP].scheduling_info.SR_COUNTER++; - - // start the sr-prohibittimer : rel 9 and above - if (UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer > 0) { // timer configured - UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer--; - UE_mac_inst[module_idP].scheduling_info. - sr_ProhibitTimer_Running = 1; - } else { - UE_mac_inst[module_idP].scheduling_info. - sr_ProhibitTimer_Running = 0; - } - - LOG_D(MAC, - "[UE %d][SR %x] Frame %d subframe %d send SR indication (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n", - module_idP, rnti, frameP, subframe, - UE_mac_inst[module_idP].scheduling_info.SR_COUNTER, - (1 << - (2 + - UE_mac_inst[module_idP]. - physicalConfigDedicated->schedulingRequestConfig->choice. - setup.dsr_TransMax)), - UE_mac_inst[module_idP].scheduling_info.SR_pending); - - //UE_mac_inst[module_idP].ul_active =1; - return (1); //instruct phy to signal SR + if ((UE_mac_inst[module_idP].physicalConfigDedicated != NULL) && + (UE_mac_inst[module_idP].scheduling_info.SR_pending == 1) && + (UE_mac_inst[module_idP].scheduling_info.SR_COUNTER < + (1 << + (2 + + UE_mac_inst[module_idP]. + physicalConfigDedicated->schedulingRequestConfig->choice.setup. + dsr_TransMax)))) { + LOG_D(MAC, + "[UE %d][SR %x] Frame %d subframe %d PHY asks for SR (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n", + module_idP, rnti, frameP, subframe, + UE_mac_inst[module_idP].scheduling_info.SR_COUNTER, + (1 << + (2 + + UE_mac_inst[module_idP]. + physicalConfigDedicated->schedulingRequestConfig->choice. + setup.dsr_TransMax)), + UE_mac_inst[module_idP].scheduling_info.SR_pending); + UE_mac_inst[module_idP].scheduling_info.SR_COUNTER++; + + // start the sr-prohibittimer : rel 9 and above + if (UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer > 0) { // timer configured + UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer--; + UE_mac_inst[module_idP].scheduling_info. + sr_ProhibitTimer_Running = 1; } else { - // notify RRC to relase PUCCH/SRS - // clear any configured dl/ul - // initiate RA - if (UE_mac_inst[module_idP].scheduling_info.SR_pending) { - // release all pucch resource - UE_mac_inst[module_idP].physicalConfigDedicated = NULL; - UE_mac_inst[module_idP].ul_active = 0; - UE_mac_inst[module_idP].BSR_reporting_active = - BSR_TRIGGER_NONE; - - LOG_I(MAC, "[UE %d] Release all SRs \n", module_idP); - } - UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; - UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0; - return (0); + UE_mac_inst[module_idP].scheduling_info. + sr_ProhibitTimer_Running = 0; + } + + LOG_D(MAC, + "[UE %d][SR %x] Frame %d subframe %d send SR indication (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n", + module_idP, rnti, frameP, subframe, + UE_mac_inst[module_idP].scheduling_info.SR_COUNTER, + (1 << + (2 + + UE_mac_inst[module_idP]. + physicalConfigDedicated->schedulingRequestConfig->choice. + setup.dsr_TransMax)), + UE_mac_inst[module_idP].scheduling_info.SR_pending); + //UE_mac_inst[module_idP].ul_active =1; + return (1); //instruct phy to signal SR + } else { + // notify RRC to relase PUCCH/SRS + // clear any configured dl/ul + // initiate RA + if (UE_mac_inst[module_idP].scheduling_info.SR_pending) { + // release all pucch resource + UE_mac_inst[module_idP].physicalConfigDedicated = NULL; + UE_mac_inst[module_idP].ul_active = 0; + UE_mac_inst[module_idP].BSR_reporting_active = + BSR_TRIGGER_NONE; + LOG_I(MAC, "[UE %d] Release all SRs \n", module_idP); } + + UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; + UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0; + return (0); + } } //------------------------------------------------------------------------------ void ue_send_sdu(module_id_t module_idP, - uint8_t CC_id, - frame_t frameP, - sub_frame_t subframeP, - uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index) + uint8_t CC_id, + frame_t frameP, + sub_frame_t subframeP, + uint8_t *sdu, uint16_t sdu_len, uint8_t eNB_index) //------------------------------------------------------------------------------ { - - unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; - unsigned char rx_lcids[NB_RB_MAX]; - unsigned short rx_lengths[NB_RB_MAX]; - unsigned char *tx_sdu; + unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; + unsigned char rx_lcids[NB_RB_MAX]; + unsigned short rx_lengths[NB_RB_MAX]; + unsigned char *tx_sdu; #if UE_TIMING_TRACE - start_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu); + start_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); //LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]); - if (opt_enabled) { - trace_pdu(DIRECTION_DOWNLINK, sdu, sdu_len, module_idP, WS_C_RNTI, - UE_mac_inst[module_idP].crnti, frameP, subframeP, 0, 0); - LOG_D(OPT, - "[UE %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n", - module_idP, frameP, UE_mac_inst[module_idP].crnti, sdu_len); - } - - payload_ptr = - parse_header(sdu, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, - sdu_len); + if (opt_enabled) { + trace_pdu(DIRECTION_DOWNLINK, sdu, sdu_len, module_idP, WS_C_RNTI, + UE_mac_inst[module_idP].crnti, frameP, subframeP, 0, 0); + LOG_D(OPT, + "[UE %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n", + module_idP, frameP, UE_mac_inst[module_idP].crnti, sdu_len); + } + payload_ptr = + parse_header(sdu, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, + sdu_len); #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, - "[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n", - module_idP, frameP, eNB_index, num_ce, num_sdu); + LOG_D(MAC, + "[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n", + module_idP, frameP, eNB_index, num_ce, num_sdu); #endif - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); + LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); - for (i = 0; i < 32; i++) { - LOG_T(MAC, "%x.", sdu[i]); - } + for (i = 0; i < 32; i++) { + LOG_T(MAC, "%x.", sdu[i]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - if (payload_ptr != NULL) { - - for (i = 0; i < num_ce; i++) { - // printf("ce %d : %d\n",i,rx_ces[i]); - switch (rx_ces[i]) { - case UE_CONT_RES: - - LOG_I(MAC, - "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", - module_idP, frameP, payload_ptr[0], payload_ptr[1], - payload_ptr[2], payload_ptr[3], payload_ptr[4], - payload_ptr[5]); - - if (UE_mac_inst[module_idP].RA_active == 1) { - LOG_I(MAC, - "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", - module_idP, frameP); - UE_mac_inst[module_idP].RA_active = 0; - // check if RA procedure has finished completely (no contention) - tx_sdu = &UE_mac_inst[module_idP].CCCH_pdu.payload[3]; - - //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits) - // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or SCH_SUBHEADER_SHORT) - for (i = 0; i < 6; i++) - if (tx_sdu[i] != payload_ptr[i]) { - LOG_E(MAC, - "[UE %d][RAPROC] Contention detected, RA failed\n", - module_idP); - if(nfapi_mode == 3) { // phy_stub mode - // Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to - // PRACH state. - LOG_I(MAC, "nfapi_mode3: Setting UE_mode BACK to PRACH 1\n"); - UE_mac_inst[module_idP].UE_mode[eNB_index] = PRACH; - //ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; - } - else{ - ra_failed(module_idP, CC_id, eNB_index); - } - UE_mac_inst - [module_idP]. - RA_contention_resolution_timer_active = 0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, - VCD_FUNCTION_OUT); - return; - } - - LOG_I(MAC, - "[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n", - module_idP, frameP); - UE_mac_inst - [module_idP]. - RA_contention_resolution_timer_active = 0; - if(nfapi_mode == 3) // phy_stub mode - { - // Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH - UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH; - } - else { // Full stack mode - ra_succeeded(module_idP,CC_id,eNB_index); - } - } - - payload_ptr += 6; - break; - - case TIMING_ADV_CMD: + if (payload_ptr != NULL) { + for (i = 0; i < num_ce; i++) { + // printf("ce %d : %d\n",i,rx_ces[i]); + switch (rx_ces[i]) { + case UE_CONT_RES: + LOG_I(MAC, + "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", + module_idP, frameP, payload_ptr[0], payload_ptr[1], + payload_ptr[2], payload_ptr[3], payload_ptr[4], + payload_ptr[5]); + + if (UE_mac_inst[module_idP].RA_active == 1) { + LOG_I(MAC, + "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", + module_idP, frameP); + UE_mac_inst[module_idP].RA_active = 0; + // check if RA procedure has finished completely (no contention) + tx_sdu = &UE_mac_inst[module_idP].CCCH_pdu.payload[3]; + + //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits) + // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or SCH_SUBHEADER_SHORT) + for (i = 0; i < 6; i++) + if (tx_sdu[i] != payload_ptr[i]) { + LOG_E(MAC, + "[UE %d][RAPROC] Contention detected, RA failed\n", + module_idP); + + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode + // Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to + // PRACH state. + LOG_I(MAC, "nfapi_mode3: Setting UE_mode BACK to PRACH 1\n"); + UE_mac_inst[module_idP].UE_mode[eNB_index] = PRACH; + //ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; + } else { + ra_failed(module_idP, CC_id, eNB_index); + } + + UE_mac_inst + [module_idP]. + RA_contention_resolution_timer_active = 0; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, + VCD_FUNCTION_OUT); + return; + } + + LOG_I(MAC, + "[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n", + module_idP, frameP); + UE_mac_inst + [module_idP]. + RA_contention_resolution_timer_active = 0; + + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode + // Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH + UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH; + } else { // Full stack mode + ra_succeeded(module_idP,CC_id,eNB_index); + } + } + + payload_ptr += 6; + break; + + case TIMING_ADV_CMD: #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, - payload_ptr[0]); + LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, + payload_ptr[0]); #endif - // Eliminate call to process_timing_advance for the phy_stub UE operation mode. Is this correct? - if (nfapi_mode!=3) - { - process_timing_advance(module_idP,CC_id,payload_ptr[0]); - } - payload_ptr++; - break; + // Eliminate call to process_timing_advance for the phy_stub UE operation mode. Is this correct? + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + process_timing_advance(module_idP,CC_id,payload_ptr[0]); + } - case DRX_CMD: + payload_ptr++; + break; + + case DRX_CMD: #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] CE %d : UE DRX :", i); + LOG_D(MAC, "[UE] CE %d : UE DRX :", i); #endif - payload_ptr++; - break; - } - } + payload_ptr++; + break; + } + } - for (i = 0; i < num_sdu; i++) { + for (i = 0; i < num_sdu; i++) { #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] SDU %d : LCID %d, length %d\n", i, - rx_lcids[i], rx_lengths[i]); + LOG_D(MAC, "[UE] SDU %d : LCID %d, length %d\n", i, + rx_lcids[i], rx_lengths[i]); #endif - if (rx_lcids[i] == CCCH) { - - LOG_D(MAC, - "[UE %d] rnti %x Frame %d : DLSCH -> DL-CCCH, RRC message (eNB %d, %d bytes)\n", - module_idP, UE_mac_inst[module_idP].crnti, frameP, - eNB_index, rx_lengths[i]); + if (rx_lcids[i] == CCCH) { + LOG_D(MAC, + "[UE %d] rnti %x Frame %d : DLSCH -> DL-CCCH, RRC message (eNB %d, %d bytes)\n", + module_idP, UE_mac_inst[module_idP].crnti, frameP, + eNB_index, rx_lengths[i]); #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - int j; + int j; - for (j = 0; j < rx_lengths[i]; j++) { - LOG_T(MAC, "%x.", (uint8_t) payload_ptr[j]); - } + for (j = 0; j < rx_lengths[i]; j++) { + LOG_T(MAC, "%x.", (uint8_t) payload_ptr[j]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif + mac_rrc_data_ind_ue(module_idP, + CC_id, + frameP,subframeP, + UE_mac_inst[module_idP].crnti, + CCCH, + (uint8_t *)payload_ptr, + rx_lengths[i], + eNB_index, + 0 + ); + } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) { + LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-DCCH%d, RRC message (eNB %d, %d bytes)\n", module_idP, frameP, rx_lcids[i],eNB_index,rx_lengths[i]); + mac_rlc_data_ind(module_idP, + UE_mac_inst[module_idP].crnti, + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + rx_lcids[i], + (char *)payload_ptr, + rx_lengths[i], + 1, + NULL); + } else if ((rx_lcids[i] < NB_RB_MAX) && (rx_lcids[i] > DCCH1 )) { + LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-DTCH%d (eNB %d, %d bytes)\n", module_idP, frameP,rx_lcids[i], eNB_index,rx_lengths[i]); +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + int j; - mac_rrc_data_ind_ue(module_idP, - CC_id, - frameP,subframeP, - UE_mac_inst[module_idP].crnti, - CCCH, - (uint8_t*)payload_ptr, - rx_lengths[i], - eNB_index, - 0 - ); - - } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) { - LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-DCCH%d, RRC message (eNB %d, %d bytes)\n", module_idP, frameP, rx_lcids[i],eNB_index,rx_lengths[i]); - mac_rlc_data_ind(module_idP, - UE_mac_inst[module_idP].crnti, - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - rx_lcids[i], - (char *)payload_ptr, - rx_lengths[i], - 1, - NULL); - - } else if ((rx_lcids[i] < NB_RB_MAX) && (rx_lcids[i] > DCCH1 )) { - - LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-DTCH%d (eNB %d, %d bytes)\n", module_idP, frameP,rx_lcids[i], eNB_index,rx_lengths[i]); + for (j = 0; j < rx_lengths[i]; j++) + LOG_T(MAC, "%x.", (unsigned char) payload_ptr[j]); -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - int j; - for (j = 0; j < rx_lengths[i]; j++) - LOG_T(MAC, "%x.", (unsigned char) payload_ptr[j]); - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - mac_rlc_data_ind(module_idP, - UE_mac_inst[module_idP].crnti, - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - rx_lcids[i], - (char *) payload_ptr, rx_lengths[i], 1, - NULL); - } else { - LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (eNB %d)\n", - module_idP, frameP, rx_lcids[i], eNB_index); - } - payload_ptr += rx_lengths[i]; - } - } // end if (payload_ptr != NULL) + mac_rlc_data_ind(module_idP, + UE_mac_inst[module_idP].crnti, + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + rx_lcids[i], + (char *) payload_ptr, rx_lengths[i], 1, + NULL); + } else { + LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (eNB %d)\n", + module_idP, frameP, rx_lcids[i], eNB_index); + } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); + payload_ptr += rx_lengths[i]; + } + } // end if (payload_ptr != NULL) + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu); + stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu); #endif } @@ -659,314 +635,297 @@ ue_decode_si_mbms(module_id_t module_idP, int CC_id, frame_t frameP, void ue_decode_si(module_id_t module_idP, int CC_id, frame_t frameP, - uint8_t eNB_index, void *pdu, uint16_t len) -{ + uint8_t eNB_index, void *pdu, uint16_t len) { #if UE_TIMING_TRACE - start_meas(&UE_mac_inst[module_idP].rx_si); + start_meas(&UE_mac_inst[module_idP].rx_si); #endif - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN); - - LOG_D(MAC, "[UE %d] Frame %d Sending SI to RRC (LCID Id %d,len %d)\n", - module_idP, frameP, BCCH, len); - - mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe - SI_RNTI, - BCCH, (uint8_t *) pdu, len, eNB_index, - 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN); + LOG_D(MAC, "[UE %d] Frame %d Sending SI to RRC (LCID Id %d,len %d)\n", + module_idP, frameP, BCCH, len); + mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe + SI_RNTI, + BCCH, (uint8_t *) pdu, len, eNB_index, + 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].rx_si); + stop_meas(&UE_mac_inst[module_idP].rx_si); #endif - if (opt_enabled == 1) { - trace_pdu(DIRECTION_UPLINK, - (uint8_t *) pdu, - len, - module_idP, - WS_SI_RNTI, - 0xffff, - UE_mac_inst[module_idP].rxFrame, - UE_mac_inst[module_idP].rxSubframe, 0, 0); - LOG_D(OPT, - "[UE %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, len); - } + + if (opt_enabled == 1) { + trace_pdu(DIRECTION_UPLINK, + (uint8_t *) pdu, + len, + module_idP, + WS_SI_RNTI, + 0xffff, + UE_mac_inst[module_idP].rxFrame, + UE_mac_inst[module_idP].rxSubframe, 0, 0); + LOG_D(OPT, + "[UE %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", + module_idP, frameP, CC_id, 0xffff, len); + } } void ue_decode_p(module_id_t module_idP, int CC_id, frame_t frameP, - uint8_t eNB_index, void *pdu, uint16_t len) -{ + uint8_t eNB_index, void *pdu, uint16_t len) { #if UE_TIMING_TRACE - start_meas(&UE_mac_inst[module_idP].rx_p); + start_meas(&UE_mac_inst[module_idP].rx_p); #endif - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_IN); - - LOG_D(MAC, - "[UE %d] Frame %d Sending Paging message to RRC (LCID Id %d,len %d)\n", - module_idP, frameP, PCCH, len); - - mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe - P_RNTI, - PCCH, (uint8_t *) pdu, len, eNB_index, - 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_OUT); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_IN); + LOG_D(MAC, + "[UE %d] Frame %d Sending Paging message to RRC (LCID Id %d,len %d)\n", + module_idP, frameP, PCCH, len); + mac_rrc_data_ind_ue(module_idP, CC_id, frameP, 0, // unknown subframe + P_RNTI, + PCCH, (uint8_t *) pdu, len, eNB_index, + 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].rx_p); + stop_meas(&UE_mac_inst[module_idP].rx_p); #endif - if (opt_enabled == 1) { - trace_pdu(DIRECTION_UPLINK , - (uint8_t *) pdu, - len, - module_idP, - WS_SI_RNTI, - P_RNTI, - UE_mac_inst[module_idP].rxFrame, - UE_mac_inst[module_idP].rxSubframe, 0, 0); - LOG_D(OPT, - "[UE %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, P_RNTI, len); - } + + if (opt_enabled == 1) { + trace_pdu(DIRECTION_UPLINK, + (uint8_t *) pdu, + len, + module_idP, + WS_SI_RNTI, + P_RNTI, + UE_mac_inst[module_idP].rxFrame, + UE_mac_inst[module_idP].rxSubframe, 0, 0); + LOG_D(OPT, + "[UE %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", + module_idP, frameP, CC_id, P_RNTI, len); + } } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) unsigned char *parse_mch_header(unsigned char *mac_header, - unsigned char *num_sdu, - unsigned char *rx_lcids, - unsigned short *rx_lengths, - unsigned short tb_length) -{ - unsigned char not_done = 1, num_sdus = 0, lcid, i; - unsigned char *mac_header_ptr = mac_header; - unsigned short length; - - while (not_done == 1) { - if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { - not_done = 0; - } - - lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; - - if (lcid < SHORT_PADDING) { // subheader for MSI, MCCH or MTCH - if (not_done == 0) { // last MAC SDU, length is implicit - mac_header_ptr++; - length = tb_length - (mac_header_ptr - mac_header); - - for (i = 0; i < num_sdus; i++) { - length -= rx_lengths[i]; - } - } else { // not the last MAC SDU - if (((SCH_SUBHEADER_LONG *) mac_header_ptr)->F == 1) { // subheader has length of 3octets - // length = ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L; - length = - ((((SCH_SUBHEADER_LONG *) mac_header_ptr)-> - L_MSB & 0x7f) - << 8) | (((SCH_SUBHEADER_LONG *) mac_header_ptr)-> - L_LSB & 0xff); - mac_header_ptr += 3; - } else { // subheader has length of 2octets - length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; - mac_header_ptr += 2; - } - } - - rx_lcids[num_sdus] = lcid; - rx_lengths[num_sdus] = length; - num_sdus++; - } else { // subheader for padding - // if (lcid == SHORT_PADDING) - mac_header_ptr++; - } + unsigned char *num_sdu, + unsigned char *rx_lcids, + unsigned short *rx_lengths, + unsigned short tb_length) { + unsigned char not_done = 1, num_sdus = 0, lcid, i; + unsigned char *mac_header_ptr = mac_header; + unsigned short length; + + while (not_done == 1) { + if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { + not_done = 0; + } + + lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; + + if (lcid < SHORT_PADDING) { // subheader for MSI, MCCH or MTCH + if (not_done == 0) { // last MAC SDU, length is implicit + mac_header_ptr++; + length = tb_length - (mac_header_ptr - mac_header); + + for (i = 0; i < num_sdus; i++) { + length -= rx_lengths[i]; + } + } else { // not the last MAC SDU + if (((SCH_SUBHEADER_LONG *) mac_header_ptr)->F == 1) { // subheader has length of 3octets + // length = ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L; + length = + ((((SCH_SUBHEADER_LONG *) mac_header_ptr)-> + L_MSB & 0x7f) + << 8) | (((SCH_SUBHEADER_LONG *) mac_header_ptr)-> + L_LSB & 0xff); + mac_header_ptr += 3; + } else { // subheader has length of 2octets + length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; + mac_header_ptr += 2; + } + } + + rx_lcids[num_sdus] = lcid; + rx_lengths[num_sdus] = length; + num_sdus++; + } else { // subheader for padding + // if (lcid == SHORT_PADDING) + mac_header_ptr++; } + } - *num_sdu = num_sdus; - return (mac_header_ptr); + *num_sdu = num_sdus; + return (mac_header_ptr); } // this function is for sending mch_sdu from phy to mac void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, - uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index, - uint8_t sync_area) -{ - - unsigned char num_sdu, i, j, *payload_ptr; - unsigned char rx_lcids[NB_RB_MAX]; - unsigned short rx_lengths[NB_RB_MAX]; + uint8_t *sdu, uint16_t sdu_len, uint8_t eNB_index, + uint8_t sync_area) { + unsigned char num_sdu, i, j, *payload_ptr; + unsigned char rx_lcids[NB_RB_MAX]; + unsigned short rx_lengths[NB_RB_MAX]; #if UE_TIMING_TRACE - start_meas(&UE_mac_inst[module_idP].rx_mch_sdu); + start_meas(&UE_mac_inst[module_idP].rx_mch_sdu); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_IN); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_IN); + LOG_D(MAC, + "[UE %d] Frame %d : process the mch PDU for sync area %d \n", + module_idP, frameP, sync_area); + LOG_D(MAC, "[UE %d] sdu: %x.%x\n", module_idP, sdu[0], sdu[1]); + LOG_D(MAC, "[UE %d] parse_mch_header, demultiplex\n", module_idP); + payload_ptr = + parse_mch_header(sdu, &num_sdu, rx_lcids, rx_lengths, sdu_len); + LOG_D(MAC, "[UE %d] parse_mch_header, found %d sdus\n", module_idP, + num_sdu); + + for (i = 0; i < num_sdu; i++) { + if (rx_lcids[i] == MCH_SCHDL_INFO) { + if (rx_lengths[i] & 0x01) { + LOG_E(MAC,"MCH Scheduling Information MAC Control Element should have an even size\n"); + } - LOG_D(MAC, - "[UE %d] Frame %d : process the mch PDU for sync area %d \n", - module_idP, frameP, sync_area); - LOG_D(MAC, "[UE %d] sdu: %x.%x\n", module_idP, sdu[0], sdu[1]); - LOG_D(MAC, "[UE %d] parse_mch_header, demultiplex\n", module_idP); + LOG_D(MAC,"MCH Scheduling Information, len(%d)\n",rx_lengths[i]); - payload_ptr = - parse_mch_header(sdu, &num_sdu, rx_lcids, rx_lengths, sdu_len); - LOG_D(MAC, "[UE %d] parse_mch_header, found %d sdus\n", module_idP, - num_sdu); + for (j=0; j<rx_lengths[i]/2; j++) { + uint16_t stop_mtch_val = ((uint16_t)(payload_ptr[2*j] & 0x07) << 8) | (uint16_t)payload_ptr[2*j+1]; + UE_mac_inst[module_idP].pmch_lcids[j] = (payload_ptr[2*j] & 0xF8) >> 3; + UE_mac_inst[module_idP].pmch_stop_mtch[j] = stop_mtch_val; + LOG_D(MAC,"lcid(%d),stop_mtch_val %d frameP(%d)\n", UE_mac_inst[module_idP].pmch_lcids[j], stop_mtch_val, frameP); - for (i = 0; i < num_sdu; i++) { - if (rx_lcids[i] == MCH_SCHDL_INFO) { - if (rx_lengths[i] & 0x01) { - LOG_E(MAC,"MCH Scheduling Information MAC Control Element should have an even size\n"); + if ((stop_mtch_val >= 2043) && (stop_mtch_val <= 2046)) { + LOG_D(MAC,"(reserved)\n"); } - LOG_D(MAC,"MCH Scheduling Information, len(%d)\n",rx_lengths[i]); - - for (j=0; j<rx_lengths[i]/2; j++) { - uint16_t stop_mtch_val = ((uint16_t)(payload_ptr[2*j] & 0x07) << 8) | (uint16_t)payload_ptr[2*j+1]; - - UE_mac_inst[module_idP].pmch_lcids[j] = (payload_ptr[2*j] & 0xF8) >> 3; - UE_mac_inst[module_idP].pmch_stop_mtch[j] = stop_mtch_val; - LOG_D(MAC,"lcid(%d),stop_mtch_val %d frameP(%d)\n", UE_mac_inst[module_idP].pmch_lcids[j], stop_mtch_val, frameP); + UE_mac_inst[module_idP].msi_status_v[j] = 0; - if ((stop_mtch_val >= 2043) && (stop_mtch_val <= 2046)) { - LOG_D(MAC,"(reserved)\n"); - } - - UE_mac_inst[module_idP].msi_status_v[j] = 0; + if (UE_mac_inst[module_idP].mcch_status==1) { + LOG_D(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes), i(%d)\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], UE_mac_inst[module_idP].pmch_stop_mtch[j]); - if (UE_mac_inst[module_idP].mcch_status==1) { - LOG_D(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes), i(%d)\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], UE_mac_inst[module_idP].pmch_stop_mtch[j]); - if (UE_mac_inst[module_idP].pmch_stop_mtch[j] < 2043) { - UE_mac_inst[module_idP].pmch_stop_mtch[j] += UE_mac_inst[module_idP].msi_current_alloc; - UE_mac_inst[module_idP].msi_status_v[j] = 1; - } + if (UE_mac_inst[module_idP].pmch_stop_mtch[j] < 2043) { + UE_mac_inst[module_idP].pmch_stop_mtch[j] += UE_mac_inst[module_idP].msi_current_alloc; + UE_mac_inst[module_idP].msi_status_v[j] = 1; } } - } else if (rx_lcids[i] == MCCH_LCHANID) { - LOG_D(MAC,"[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, i, sync_area, eNB_index, rx_lengths[i]); - mac_rrc_data_ind_ue(module_idP, - CC_id, - frameP,0, // unknown subframe - M_RNTI, - MCCH, - payload_ptr + 1, // Skip RLC layer 1st byte - rx_lengths[i] - 1, - eNB_index, - sync_area); - } else if (rx_lcids[i] <= 28) { - for (j=0; j<28; j++) { - if (rx_lcids[i] == UE_mac_inst[module_idP].pmch_lcids[j]) - break; - } - - if (j<28 && UE_mac_inst[module_idP].msi_status_v[j]==1) { - LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j); - - mac_rlc_data_ind( - module_idP, - UE_mac_inst[module_idP].crnti, - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_YES, - rx_lcids[i], /*+ (maxDRB + 3),*/ - (char *)payload_ptr, - rx_lengths[i], - 1, - NULL); - - } - } else { - LOG_W(MAC, - "[UE %d] Frame %d : unknown sdu %d rx_lcids[%d]=%d mcch status %d eNB %d \n", - module_idP, frameP, rx_lengths[i], i, rx_lcids[i], - UE_mac_inst[module_idP].mcch_status, eNB_index); + } + } else if (rx_lcids[i] == MCCH_LCHANID) { + LOG_D(MAC,"[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, i, sync_area, eNB_index, rx_lengths[i]); + mac_rrc_data_ind_ue(module_idP, + CC_id, + frameP,0, // unknown subframe + M_RNTI, + MCCH, + payload_ptr + 1, // Skip RLC layer 1st byte + rx_lengths[i] - 1, + eNB_index, + sync_area); + } else if (rx_lcids[i] <= 28) { + for (j=0; j<28; j++) { + if (rx_lcids[i] == UE_mac_inst[module_idP].pmch_lcids[j]) + break; } - payload_ptr += rx_lengths[i]; + if (j<28 && UE_mac_inst[module_idP].msi_status_v[j]==1) { + LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j); + mac_rlc_data_ind( + module_idP, + UE_mac_inst[module_idP].crnti, + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_YES, + rx_lcids[i], /*+ (maxDRB + 3),*/ + (char *)payload_ptr, + rx_lengths[i], + 1, + NULL); + } + } else { + LOG_W(MAC, + "[UE %d] Frame %d : unknown sdu %d rx_lcids[%d]=%d mcch status %d eNB %d \n", + module_idP, frameP, rx_lengths[i], i, rx_lcids[i], + UE_mac_inst[module_idP].mcch_status, eNB_index); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_OUT); + payload_ptr += rx_lengths[i]; + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].rx_mch_sdu); + stop_meas(&UE_mac_inst[module_idP].rx_mch_sdu); #endif } void ue_send_sl_sdu(module_id_t module_idP, - uint8_t CC_id, - frame_t frameP, - sub_frame_t subframeP, - uint8_t* sdu, - uint16_t sdu_len, - uint8_t eNB_index, - sl_discovery_flag_t sl_discovery_flag - ) { - + uint8_t CC_id, + frame_t frameP, + sub_frame_t subframeP, + uint8_t *sdu, + uint16_t sdu_len, + uint8_t eNB_index, + sl_discovery_flag_t sl_discovery_flag + ) { int rlc_sdu_len; char *rlc_sdu; uint32_t destinationL2Id =0x00000000; if (sl_discovery_flag == SL_DISCOVERY_FLAG_NO) { - - // Notes: 1. no control elements are supported yet - // 2. we exit with error if LCID != 3 - // 3. we exit with error if E=1 (more than one SDU/CE) - // extract header - SLSCH_SUBHEADER_24_Bit_DST_LONG *longh = (SLSCH_SUBHEADER_24_Bit_DST_LONG *)sdu; - AssertFatal(longh->E==0,"E is non-zero\n"); - AssertFatal(((longh->LCID==3)|(longh->LCID==10)),"LCID is %d (not 3 or 10)\n",longh->LCID); - //filter incoming packet based on destination address - destinationL2Id = (longh->DST07<<16) | (longh->DST815 <<8) | (longh->DST1623); - LOG_I( MAC, "[DestinationL2Id: 0x%08x] \n", destinationL2Id ); - //in case of 1-n communication, verify that UE belongs to that group - int i=0; - for (i=0; i< MAX_NUM_DEST; i++) - if (UE_mac_inst[module_idP].destinationList[i] == destinationL2Id) break; - //match the destinationL2Id with UE L2Id or groupL2ID - if (!((destinationL2Id == UE_mac_inst[module_idP].sourceL2Id) | (i < MAX_NUM_DEST))){ - LOG_I( MAC, "[Destination Id is neither matched with Source Id nor with Group Id, drop the packet!!! \n"); - return; - } - - - if (longh->F==1) { - rlc_sdu_len = ((longh->L_MSB<<8)&0x7F00)|(longh->L_LSB&0xFF); - rlc_sdu = (char *)sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG); - } - else { - rlc_sdu_len = ((SLSCH_SUBHEADER_24_Bit_DST_SHORT *)sdu)->L; - rlc_sdu = (char *)sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_SHORT); - } - mac_rlc_data_ind( - module_idP, - 0x1234, - eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - longh->LCID, //3/10 - rlc_sdu, - rlc_sdu_len, - 1, - NULL); + // Notes: 1. no control elements are supported yet + // 2. we exit with error if LCID != 3 + // 3. we exit with error if E=1 (more than one SDU/CE) + // extract header + SLSCH_SUBHEADER_24_Bit_DST_LONG *longh = (SLSCH_SUBHEADER_24_Bit_DST_LONG *)sdu; + AssertFatal(longh->E==0,"E is non-zero\n"); + AssertFatal(((longh->LCID==3)|(longh->LCID==10)),"LCID is %d (not 3 or 10)\n",longh->LCID); + //filter incoming packet based on destination address + destinationL2Id = (longh->DST07<<16) | (longh->DST815 <<8) | (longh->DST1623); + LOG_I( MAC, "[DestinationL2Id: 0x%08x] \n", destinationL2Id ); + //in case of 1-n communication, verify that UE belongs to that group + int i=0; + + for (i=0; i< MAX_NUM_DEST; i++) + if (UE_mac_inst[module_idP].destinationList[i] == destinationL2Id) break; + + //match the destinationL2Id with UE L2Id or groupL2ID + if (!((destinationL2Id == UE_mac_inst[module_idP].sourceL2Id) | (i < MAX_NUM_DEST))) { + LOG_I( MAC, "[Destination Id is neither matched with Source Id nor with Group Id, drop the packet!!! \n"); + return; + } + + if (longh->F==1) { + rlc_sdu_len = ((longh->L_MSB<<8)&0x7F00)|(longh->L_LSB&0xFF); + rlc_sdu = (char *)sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG); + } else { + rlc_sdu_len = ((SLSCH_SUBHEADER_24_Bit_DST_SHORT *)sdu)->L; + rlc_sdu = (char *)sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_SHORT); + } + + mac_rlc_data_ind( + module_idP, + 0x1234, + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + longh->LCID, //3/10 + rlc_sdu, + rlc_sdu_len, + 1, + NULL); } else { //SL_DISCOVERY - uint16_t len = sdu_len; - LOG_I( MAC, "SL DISCOVERY \n"); - mac_rrc_data_ind_ue(module_idP, - CC_id, - frameP,subframeP, - UE_mac_inst[module_idP].crnti, - SL_DISCOVERY, - sdu, //(uint8_t*)&UE_mac_inst[Mod_id].SL_Discovery[0].Rx_buffer.Payload[0], - len, - eNB_index, - 0); - + uint16_t len = sdu_len; + LOG_I( MAC, "SL DISCOVERY \n"); + mac_rrc_data_ind_ue(module_idP, + CC_id, + frameP,subframeP, + UE_mac_inst[module_idP].crnti, + SL_DISCOVERY, + sdu, //(uint8_t*)&UE_mac_inst[Mod_id].SL_Discovery[0].Rx_buffer.Payload[0], + len, + eNB_index, + 0); } } @@ -974,26 +933,26 @@ void ue_send_sl_sdu(module_id_t module_idP, int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_area, unsigned char eNB_index) { - // currently there is one-to-one mapping between sf allocation pattern and sync area - if (mbsfn_sync_area >= MAX_MBSFN_AREA) { - LOG_W(MAC, - "[UE %" PRIu8 "] MBSFN synchronization area %" PRIu8 - " out of range for eNB %" PRIu8 "\n", module_idP, - mbsfn_sync_area, eNB_index); - return -1; - } else if (UE_mac_inst[module_idP]. - mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) { - return mbsfn_sync_area; - } else { - LOG_W(MAC, - "[UE %" PRIu8 "] MBSFN Subframe Config pattern %" PRIu8 - " not found \n", module_idP, mbsfn_sync_area); - return -1; - } + // currently there is one-to-one mapping between sf allocation pattern and sync area + if (mbsfn_sync_area >= MAX_MBSFN_AREA) { + LOG_W(MAC, + "[UE %" PRIu8 "] MBSFN synchronization area %" PRIu8 + " out of range for eNB %" PRIu8 "\n", module_idP, + mbsfn_sync_area, eNB_index); + return -1; + } else if (UE_mac_inst[module_idP]. + mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) { + return mbsfn_sync_area; + } else { + LOG_W(MAC, + "[UE %" PRIu8 "] MBSFN Subframe Config pattern %" PRIu8 + " not found \n", module_idP, mbsfn_sync_area); + return -1; + } } -int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int commonSFAlloc_period, int commonSFAlloc_offset, int num_sf_alloc, int *mtch_active, int *msi_active, uint8_t *mch_lcid) -{ +int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int commonSFAlloc_period, int commonSFAlloc_offset, int num_sf_alloc, int *mtch_active, int *msi_active, + uint8_t *mch_lcid) { int i, mtch_mcs = -1; int mtch_flag = 0; int msi_flag = 0; @@ -1015,16 +974,18 @@ int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subfra //msi and mtch are mutally excluded then the break is safe if ((num_sf_alloc == 0) && (sf_AllocEnd_r9 >= 1)) { msi_flag = 1; - LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9,UE_mac_inst[module_idP].common_num_sf_alloc); + LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9, + UE_mac_inst[module_idP].common_num_sf_alloc); UE_mac_inst[module_idP].msi_current_alloc = num_sf_alloc; UE_mac_inst[module_idP].msi_pmch = i; } } else { //more that one MCH ?? check better this condition //msi and mtch are mutally excluded then the break is safe if ((num_sf_alloc == UE_mac_inst[module_idP].pmch_Config[i-1]->sf_AllocEnd_r9 + 1) && (sf_AllocEnd_r9 >= (num_sf_alloc+1))) { - //msi should be just after + //msi should be just after msi_flag = 1; - LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9,UE_mac_inst[module_idP].common_num_sf_alloc); + LOG_D(MAC,"msi(%d) should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),sf_AllocEnd_r9(%d),common_num_sf_alloc(%d)\n",i,frameP,subframe,num_sf_alloc,sf_AllocEnd_r9, + UE_mac_inst[module_idP].common_num_sf_alloc); UE_mac_inst[module_idP].msi_current_alloc = num_sf_alloc; UE_mac_inst[module_idP].msi_pmch = i; } @@ -1036,12 +997,15 @@ int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subfra if (UE_mac_inst[module_idP].pmch_stop_mtch[i] >= num_sf_alloc) { if (UE_mac_inst[module_idP].pmch_stop_mtch[i] != 2047) { mtch_flag = 1; + if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL) mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9; else mtch_mcs = -1; + *mch_lcid = (uint8_t)i; - LOG_D(MAC,"mtch should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),mtch_mcs(%d),pmch_stop_mtch(%d),lcid(%d),msi_pmch(%d)\n",frameP,subframe,num_sf_alloc,mtch_mcs,UE_mac_inst[module_idP].pmch_stop_mtch[i],UE_mac_inst[module_idP].pmch_lcids[i],UE_mac_inst[module_idP].msi_pmch); + LOG_D(MAC,"mtch should be allocated:frame(%d),submframe(%d),num_sf_alloc(%d),mtch_mcs(%d),pmch_stop_mtch(%d),lcid(%d),msi_pmch(%d)\n",frameP,subframe,num_sf_alloc,mtch_mcs, + UE_mac_inst[module_idP].pmch_stop_mtch[i],UE_mac_inst[module_idP].pmch_lcids[i],UE_mac_inst[module_idP].msi_pmch); break; } } @@ -1049,17 +1013,15 @@ int ue_query_p_mch_info(module_id_t module_idP, uint32_t frameP, uint32_t subfra *mtch_active = mtch_flag; *msi_active = msi_flag; - return mtch_mcs; } -int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int *mtch_active, int *msi_active, uint8_t *mch_lcid) -{ +int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, int *mtch_active, int *msi_active, uint8_t *mch_lcid) { int i, j, mtch_mcs = -1; int mtch_flag = 0; - // Acount for sf_allocable in CSA int num_sf_alloc = 0; + for (i = 0; i < 8; i++) { if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL) continue; @@ -1069,8 +1031,9 @@ int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, i // four-frameP format uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[2] | - (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]<<8) | - (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]<<8) | + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); + for (j = 0; j < 24; j++) num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x800000 >> j)) == (0x800000 >> j)); } @@ -1086,84 +1049,92 @@ int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, i int common_mbsfn_alloc_offset = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationOffset; int common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->radioframeAllocationPeriod; int commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9; - uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[2] | - (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]<<8) | - (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); - + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[1]<<8) | + (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); int jj = frameP % 4; + if ((frameP % common_mbsfn_period) != (common_mbsfn_alloc_offset + jj)) continue; - if(UE_mac_inst[module_idP].tdd_Config == NULL){ + if(UE_mac_inst[module_idP].tdd_Config == NULL) { switch (subframe) { - case 1: - if ((common_mbsfn_SubframeConfig & (0x800000 >> (jj*6))) == (0x800000 >> (jj*6))) { - mtch_flag = 1; - mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); - UE_mac_inst[module_idP].common_num_sf_alloc++; - UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; - } - break; - case 2: - if ((common_mbsfn_SubframeConfig & (0x400000 >> (jj*6))) == (0x400000 >> (jj*6))) { - mtch_flag = 1; - mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); - UE_mac_inst[module_idP].common_num_sf_alloc++; - UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; - } - break; - case 3: - if ((common_mbsfn_SubframeConfig & (0x200000 >> (jj*6))) == (0x200000 >> (jj*6))) { - mtch_flag = 1; - mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); - UE_mac_inst[module_idP].common_num_sf_alloc++; - UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; - } - break; - case 6: - if ((common_mbsfn_SubframeConfig & (0x100000 >> (jj*6))) == (0x100000 >> (jj*6))) { - mtch_flag = 1; - mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); - UE_mac_inst[module_idP].common_num_sf_alloc++; - UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; - } - break; - case 7: - if ((common_mbsfn_SubframeConfig & (0x80000 >> (jj*6))) == (0x80000 >> (jj*6))) { - mtch_flag = 1; - mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); - UE_mac_inst[module_idP].common_num_sf_alloc++; - UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; - } - break; - case 8: - if ((common_mbsfn_SubframeConfig & (0x40000 >> (jj*6))) == (0x40000 >> (jj*6))) { - mtch_flag = 1; - mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); - UE_mac_inst[module_idP].common_num_sf_alloc++; - UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc% ( num_sf_alloc*commonSF_AllocPeriod/common_mbsfn_period);//48; - } - break; + case 1: + if ((common_mbsfn_SubframeConfig & (0x800000 >> (jj*6))) == (0x800000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; + } + + break; + + case 2: + if ((common_mbsfn_SubframeConfig & (0x400000 >> (jj*6))) == (0x400000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; + } + + break; + + case 3: + if ((common_mbsfn_SubframeConfig & (0x200000 >> (jj*6))) == (0x200000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; + } + + break; + + case 6: + if ((common_mbsfn_SubframeConfig & (0x100000 >> (jj*6))) == (0x100000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; + } + + break; + + case 7: + if ((common_mbsfn_SubframeConfig & (0x80000 >> (jj*6))) == (0x80000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);//48; + } + + break; + + case 8: + if ((common_mbsfn_SubframeConfig & (0x40000 >> (jj*6))) == (0x40000 >> (jj*6))) { + mtch_flag = 1; + mtch_mcs = ue_query_p_mch_info(module_idP,frameP,subframe,common_mbsfn_period,common_mbsfn_alloc_offset,UE_mac_inst[module_idP].common_num_sf_alloc,mtch_active,msi_active,mch_lcid); + UE_mac_inst[module_idP].common_num_sf_alloc++; + UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc% ( num_sf_alloc*commonSF_AllocPeriod/common_mbsfn_period);//48; + } + + break; } } else { // TODO TDD } + if (mtch_flag == 1) break; } - return mtch_mcs; + return mtch_mcs; } -int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) -{ - +int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) { int i = 0, j = 0, ii = 0, jj = 0, msi_pos = 0, mcch_mcs = -1, mtch_mcs = -1; int mcch_flag = 0, mtch_flag = 0, msi_flag = 0; long mch_scheduling_period = -1; uint8_t mch_lcid = 0; - #if UE_TIMING_TRACE start_meas(&UE_mac_inst[module_idP].ue_query_mch); #endif @@ -1174,8 +1145,7 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ for (i = 0; i < UE_mac_inst[module_idP].num_active_mbsfn_area; - i++ ) - { + i++ ) { // assume, that there is always a mapping if ((j = ue_get_mbsfn_sf_alloction(module_idP,i,eNB_index)) == -1) { return -1; // continue; @@ -1183,12 +1153,10 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ ii = 0; msi_pos = 0; - long mbsfn_period = 1 << UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationPeriod; long mbsfn_alloc_offset = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset; long mcch_period = 32 << UE_mac_inst[module_idP].mbsfn_AreaInfo[j]->mcch_Config_r9.mcch_RepetitionPeriod_r9; long mcch_offset = UE_mac_inst[module_idP].mbsfn_AreaInfo[j]->mcch_Config_r9.mcch_Offset_r9; - LOG_D(MAC, "[UE %d] Frame %d subframe %d: Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %ld, mcch period %ld,mac sched period (%ld,%ld))\n", module_idP,frameP, subframe,i,UE_mac_inst[module_idP].num_active_mbsfn_area, @@ -1197,26 +1165,25 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ // get the real MCS value switch (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) { - case 0: - mcch_mcs = 2; - break; + case 0: + mcch_mcs = 2; + break; - case 1: - mcch_mcs = 7; - break; + case 1: + mcch_mcs = 7; + break; - case 2: - mcch_mcs = 13; - break; + case 2: + mcch_mcs = 13; + break; - case 3: - mcch_mcs = 19; - break; + case 3: + mcch_mcs = 19; + break; } if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format if (frameP % mbsfn_period == mbsfn_alloc_offset) { // MBSFN frameP - if (UE_mac_inst[module_idP].pmch_Config[0]) { // Find the first subframe in this MCH to transmit MSI if (frameP % mch_scheduling_period == mbsfn_alloc_offset) { @@ -1229,192 +1196,193 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1 switch (subframe) { - case 1: - if (UE_mac_inst[module_idP].tdd_Config == NULL) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { - if (msi_pos == 1) { - msi_flag = 1; + case 1: + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) { + if (msi_pos == 1) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1)) { + mcch_flag = 1; + } + + mtch_flag = 1; } + } - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1)) { - mcch_flag = 1; - } + break; - mtch_flag = 1; + case 2: + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { + if (msi_pos == 2) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) { + mcch_flag = 1; + } + + mtch_flag = 1; + } } - } - break; + break; - case 2: - if (UE_mac_inst[module_idP].tdd_Config == NULL) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) { - if (msi_pos == 2) { - msi_flag = 1; + case 3: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { // TDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { + if (msi_pos == 1) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3)) { + mcch_flag = 1; + } + + mtch_flag = 1; } - - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2)) { - mcch_flag = 1; + } else { // FDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { + if (msi_pos == 3) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) { + mcch_flag = 1; + } + + mtch_flag = 1; } - - mtch_flag = 1; } - } - break; + break; - case 3: - if (UE_mac_inst[module_idP].tdd_Config != NULL) { // TDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) { - if (msi_pos == 1) { - msi_flag = 1; - } + case 4: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { + if (msi_pos == 2) { + msi_flag = 1; + } - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3)) { - mcch_flag = 1; - } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4)) { + mcch_flag = 1; + } - mtch_flag = 1; - } - } else { // FDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) { - if (msi_pos == 3) { - msi_flag = 1; + mtch_flag = 1; } + } - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 4: - if (UE_mac_inst[module_idP].tdd_Config != NULL) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) { - if (msi_pos == 2) { - msi_flag = 1; - } - - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4)) { - mcch_flag = 1; - } - - mtch_flag = 1; - } - } - - break; - - case 6: - if (UE_mac_inst[module_idP].tdd_Config == NULL) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { - if (msi_pos == 4) { - msi_flag = 1; - } + break; - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) { - mcch_flag = 1; + case 6: + if (UE_mac_inst[module_idP].tdd_Config == NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) { + if (msi_pos == 4) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6)) { + mcch_flag = 1; + } + + mtch_flag = 1; } - - mtch_flag = 1; } - } - break; - - case 7: - if (UE_mac_inst[module_idP].tdd_Config != NULL) { // TDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { - if (msi_pos == 3) { - msi_flag = 1; - } - - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7)) { - mcch_flag = 1; - } + break; - mtch_flag = 1; - } - } else { // FDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { - if (msi_pos == 5) { - msi_flag = 1; + case 7: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { // TDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) { + if (msi_pos == 3) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7)) { + mcch_flag = 1; + } + + mtch_flag = 1; } - - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) { - mcch_flag = 1; + } else { // FDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) { + if (msi_pos == 5) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7)) { + mcch_flag = 1; + } + + mtch_flag = 1; } - - mtch_flag = 1; } - } - break; + break; - case 8: - if (UE_mac_inst[module_idP].tdd_Config != NULL) { //TDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { - if (msi_pos == 4) { - msi_flag = 1; + case 8: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { //TDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) { + if (msi_pos == 4) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8)) { + mcch_flag = 1; + } + + mtch_flag = 1; } - - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8)) { - mcch_flag = 1; + } else { // FDD + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { + if (msi_pos == 6) { + msi_flag = 1; + } + + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) { + mcch_flag = 1; + } + + mtch_flag = 1; } - - mtch_flag = 1; } - } else { // FDD - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) { - if (msi_pos == 6) { - msi_flag = 1; - } - - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8)) { - mcch_flag = 1; - } - mtch_flag = 1; - } - } + break; - break; + case 9: + if (UE_mac_inst[module_idP].tdd_Config != NULL) { + if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { + if (msi_pos == 5) { + msi_flag = 1; + } - case 9: - if (UE_mac_inst[module_idP].tdd_Config != NULL) { - if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) { - if (msi_pos == 5) { - msi_flag = 1; - } + if ((frameP % mcch_period == mcch_offset) && + ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9)) { + mcch_flag = 1; + } - if ((frameP % mcch_period == mcch_offset) && - ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9)) { - mcch_flag = 1; + mtch_flag = 1; } - - mtch_flag = 1; } - } - break; + break; }// end switch // Acount for sf_allocable in CSA int num_sf_alloc = 0; + for (i = 0; i < 8; i++) { if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL) continue; @@ -1423,6 +1391,7 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ continue; uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]; + for (j = 0; j < 6; j++) num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j)); } @@ -1434,6 +1403,7 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9; else mtch_mcs = -1; + mch_lcid = (uint8_t)i; break; } @@ -1444,89 +1414,107 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) { LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n", module_idP, frameP, subframe,i,j,msi_flag,mcch_flag,mtch_flag); - *sync_area=i; break; } } } else { // four-frameP format uint32_t mbsfn_SubframeConfig = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[2] | - (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[1]<<8) | - (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0]<<16); + (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[1]<<8) | + (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0]<<16); uint32_t MCCH_mbsfn_SubframeConfig = /* UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[2] | (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[1]<<8) | */ - (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0]<<16); - + (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0]<<16); jj=frameP%4; + if ((frameP % mbsfn_period) == (mbsfn_alloc_offset+jj)) { if (UE_mac_inst[module_idP].tdd_Config == NULL) { switch (subframe) { - case 1: - if ((mbsfn_SubframeConfig & (0x800000>>(jj*6))) == (0x800000>>(jj*6))) { - if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x800000>>(jj*6))) == (0x800000>>(jj*6)))) { - mcch_flag=1; - LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", - frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x800000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); - if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) - UE_mac_inst[module_idP].common_num_sf_alloc++; + case 1: + if ((mbsfn_SubframeConfig & (0x800000>>(jj*6))) == (0x800000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x800000>>(jj*6))) == (0x800000>>(jj*6)))) { + mcch_flag=1; + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x800000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } } - } - break; - case 2: - if ((mbsfn_SubframeConfig & (0x400000>>(jj*6))) == (0x400000>>(jj*6))) { - if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x400000>>(jj*6))) == (0x400000>>(jj*6)))) { - mcch_flag=1; - LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", - frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x400000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); - if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) - UE_mac_inst[module_idP].common_num_sf_alloc++; + + break; + + case 2: + if ((mbsfn_SubframeConfig & (0x400000>>(jj*6))) == (0x400000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x400000>>(jj*6))) == (0x400000>>(jj*6)))) { + mcch_flag=1; + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x400000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } } - } - break; - case 3: - if ((mbsfn_SubframeConfig & (0x200000>>(jj*6))) == (0x200000>>(jj*6))) { - if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x200000>>(jj*6))) == (0x200000>>(jj*6)))) { - LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", - frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x200000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); - mcch_flag=1; - if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) - UE_mac_inst[module_idP].common_num_sf_alloc++; + + break; + + case 3: + if ((mbsfn_SubframeConfig & (0x200000>>(jj*6))) == (0x200000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x200000>>(jj*6))) == (0x200000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x200000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + mcch_flag=1; + + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } } - } - break; - case 6: - if ((mbsfn_SubframeConfig & (0x100000>>(jj*6))) == (0x100000>>(jj*6))) { - if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x100000>>(jj*6))) == (0x100000>>(jj*6)))) { - LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", - frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x100000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); - mcch_flag=1; - if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) - UE_mac_inst[module_idP].common_num_sf_alloc++; + + break; + + case 6: + if ((mbsfn_SubframeConfig & (0x100000>>(jj*6))) == (0x100000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x100000>>(jj*6))) == (0x100000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x100000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + mcch_flag=1; + + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + } } - } - break; - case 7: - if ((mbsfn_SubframeConfig & (0x80000>>(jj*6))) == (0x80000>>(jj*6))) { - if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x80000>>(jj*6))) == (0x80000>>(jj*6)))) { - LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", - frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x80000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); - if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) - UE_mac_inst[module_idP].common_num_sf_alloc++; - mcch_flag=1; + + break; + + case 7: + if ((mbsfn_SubframeConfig & (0x80000>>(jj*6))) == (0x80000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x80000>>(jj*6))) == (0x80000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x80000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + + mcch_flag=1; + } } - } - break; - case 8: - if ((mbsfn_SubframeConfig & (0x40000>>(jj*6))) == (0x40000>>(jj*6))) { - if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x40000>>(jj*6))) == (0x40000>>(jj*6)))) { - LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", - frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x40000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); - if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) - UE_mac_inst[module_idP].common_num_sf_alloc++; - mcch_flag=1; + + break; + + case 8: + if ((mbsfn_SubframeConfig & (0x40000>>(jj*6))) == (0x40000>>(jj*6))) { + if ((frameP % mcch_period == (mcch_offset+jj)) && ((MCCH_mbsfn_SubframeConfig & (0x40000>>(jj*6))) == (0x40000>>(jj*6)))) { + LOG_D(MAC,"frameP(%d),mcch_period(%ld),mbsfn_SubframeConfig(%x),MCCH_mbsfn_SubframeConfig(%x),mask(%x),jj(%d),num_sf_alloc(%d)\n", + frameP, mcch_period, mbsfn_SubframeConfig, MCCH_mbsfn_SubframeConfig, (0x40000>>(jj*6)), jj, UE_mac_inst[module_idP].common_num_sf_alloc); + + if(UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]==NULL) + UE_mac_inst[module_idP].common_num_sf_alloc++; + + mcch_flag=1; + } } - } - break; + + break; }// end switch } else { // TODO TDD @@ -1549,7 +1537,7 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ stop_meas(&UE_mac_inst[module_idP].ue_query_mch); #endif - if ((mcch_flag == 1)) { // || (msi_flag==1)) + if ((mcch_flag == 1)) { // || (msi_flag==1)) *mcch_active = 1; } @@ -1557,9 +1545,11 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ if (msi_flag!=1) { for (i=0; i<8; i++) UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] = NULL; + for (i=0; i<15; i++) UE_mac_inst[module_idP].pmch_Config[i] = NULL; - for (i=0; i<28 ;i++) { + + for (i=0; i<28 ; i++) { UE_mac_inst[module_idP].pmch_lcids[i] = -1; UE_mac_inst[module_idP].pmch_stop_mtch[i] = 2047; UE_mac_inst[module_idP].msi_status_v[i] = 0; @@ -1571,6 +1561,7 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ UE_mac_inst[module_idP].msi_status_v[i] = 0; } } + return mcch_mcs; } else if ((mtch_flag==1) && (UE_mac_inst[module_idP].msi_status_v[(mch_lcid > 27) ? 27 : mch_lcid] == 1)) { return mtch_mcs; @@ -1582,949 +1573,905 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ #endif unsigned char -generate_ulsch_header(uint8_t * mac_header, - uint8_t num_sdus, - uint8_t short_padding, - uint16_t * sdu_lengths, - uint8_t * sdu_lcids, - POWER_HEADROOM_CMD * power_headroom, - uint16_t * crnti, - BSR_SHORT * truncated_bsr, - BSR_SHORT * short_bsr, - BSR_LONG * long_bsr, unsigned short post_padding) -{ - - SCH_SUBHEADER_FIXED *mac_header_ptr = - (SCH_SUBHEADER_FIXED *) mac_header; - unsigned char first_element = 0, last_size = 0, i; - unsigned char mac_header_control_elements[16], *ce_ptr; - - LOG_D(MAC, "[UE] Generate ULSCH : num_sdus %d\n", num_sdus); +generate_ulsch_header(uint8_t *mac_header, + uint8_t num_sdus, + uint8_t short_padding, + uint16_t *sdu_lengths, + uint8_t *sdu_lcids, + POWER_HEADROOM_CMD *power_headroom, + uint16_t *crnti, + BSR_SHORT *truncated_bsr, + BSR_SHORT *short_bsr, + BSR_LONG *long_bsr, unsigned short post_padding) { + SCH_SUBHEADER_FIXED *mac_header_ptr = + (SCH_SUBHEADER_FIXED *) mac_header; + unsigned char first_element = 0, last_size = 0, i; + unsigned char mac_header_control_elements[16], *ce_ptr; + LOG_D(MAC, "[UE] Generate ULSCH : num_sdus %d\n", num_sdus); #ifdef DEBUG_HEADER_PARSING - for (i = 0; i < num_sdus; i++) { - LOG_T(MAC, "[UE] sdu %d : lcid %d length %d", i, sdu_lcids[i], - sdu_lengths[i]); - } + for (i = 0; i < num_sdus; i++) { + LOG_T(MAC, "[UE] sdu %d : lcid %d length %d", i, sdu_lcids[i], + sdu_lengths[i]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - ce_ptr = &mac_header_control_elements[0]; - - if ((short_padding == 1) || (short_padding == 2)) { - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - first_element = 1; - last_size = 1; - } + ce_ptr = &mac_header_control_elements[0]; + + if ((short_padding == 1) || (short_padding == 2)) { + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + first_element = 1; + last_size = 1; + } - if (short_padding == 2) { - mac_header_ptr->E = 1; - mac_header_ptr++; - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - last_size = 1; - } + if (short_padding == 2) { + mac_header_ptr->E = 1; + mac_header_ptr++; + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + last_size = 1; + } - if (power_headroom) { - if (first_element > 0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } else { - first_element = 1; - } - - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = POWER_HEADROOM; - last_size = 1; - *((POWER_HEADROOM_CMD *) ce_ptr) = (*power_headroom); - ce_ptr += sizeof(POWER_HEADROOM_CMD); - LOG_D(MAC, "phr header size %zu\n", sizeof(POWER_HEADROOM_CMD)); + if (power_headroom) { + if (first_element > 0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } else { + first_element = 1; } - if (crnti) { + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = POWER_HEADROOM; + last_size = 1; + *((POWER_HEADROOM_CMD *) ce_ptr) = (*power_headroom); + ce_ptr += sizeof(POWER_HEADROOM_CMD); + LOG_D(MAC, "phr header size %zu\n", sizeof(POWER_HEADROOM_CMD)); + } + + if (crnti) { #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] CRNTI : %x (first_element %d)\n", *crnti, - first_element); + LOG_D(MAC, "[UE] CRNTI : %x (first_element %d)\n", *crnti, + first_element); #endif - if (first_element > 0) { - mac_header_ptr->E = 1; - mac_header_ptr++; - } else { - first_element = 1; - } - - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = CRNTI; - last_size = 1; - *((uint16_t *) ce_ptr) = (*crnti); - ce_ptr += sizeof(uint16_t); - // printf("offset %d\n",ce_ptr-mac_header_control_elements); + if (first_element > 0) { + mac_header_ptr->E = 1; + mac_header_ptr++; + } else { + first_element = 1; } - if (truncated_bsr) { - if (first_element > 0) { - mac_header_ptr->E = 1; - /* - printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr++; - } else { - first_element = 1; - } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = CRNTI; + last_size = 1; + *((uint16_t *) ce_ptr) = (*crnti); + ce_ptr += sizeof(uint16_t); + // printf("offset %d\n",ce_ptr-mac_header_control_elements); + } + + if (truncated_bsr) { + if (first_element > 0) { + mac_header_ptr->E = 1; + /* + printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr++; + } else { + first_element = 1; + } #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] Scheduler Truncated BSR Header\n"); + LOG_D(MAC, "[UE] Scheduler Truncated BSR Header\n"); #endif - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = TRUNCATED_BSR; - last_size = 1; - *((BSR_TRUNCATED *) ce_ptr) = (*truncated_bsr); - ce_ptr += sizeof(BSR_TRUNCATED); - // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); - - } else if (short_bsr) { - if (first_element > 0) { - mac_header_ptr->E = 1; - /* - printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr++; - } else { - first_element = 1; - } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = TRUNCATED_BSR; + last_size = 1; + *((BSR_TRUNCATED *) ce_ptr) = (*truncated_bsr); + ce_ptr += sizeof(BSR_TRUNCATED); + // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + } else if (short_bsr) { + if (first_element > 0) { + mac_header_ptr->E = 1; + /* + printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr++; + } else { + first_element = 1; + } #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] Scheduler SHORT BSR Header\n"); + LOG_D(MAC, "[UE] Scheduler SHORT BSR Header\n"); #endif - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_BSR; - last_size = 1; - *((BSR_SHORT *) ce_ptr) = (*short_bsr); - ce_ptr += sizeof(BSR_SHORT); - - // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); - } else if (long_bsr) { - if (first_element > 0) { - mac_header_ptr->E = 1; - /* - printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); - */ - mac_header_ptr++; - } else { - first_element = 1; - } + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_BSR; + last_size = 1; + *((BSR_SHORT *) ce_ptr) = (*short_bsr); + ce_ptr += sizeof(BSR_SHORT); + // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + } else if (long_bsr) { + if (first_element > 0) { + mac_header_ptr->E = 1; + /* + printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + */ + mac_header_ptr++; + } else { + first_element = 1; + } #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] Scheduler Long BSR Header\n"); + LOG_D(MAC, "[UE] Scheduler Long BSR Header\n"); #endif - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = LONG_BSR; - last_size = 1; - - *(ce_ptr) = - (long_bsr-> - Buffer_size0 << 2) | ((long_bsr->Buffer_size1 & 0x30) >> 4); - *(ce_ptr + 1) = - ((long_bsr->Buffer_size1 & 0x0F) << 4) | ((long_bsr-> - Buffer_size2 & 0x3C) - >> 2); - *(ce_ptr + 2) = - ((long_bsr-> - Buffer_size2 & 0x03) << 2) | (long_bsr->Buffer_size3 & 0x3F); - ce_ptr += BSR_LONG_SIZE; - - // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); - } - // printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = LONG_BSR; + last_size = 1; + *(ce_ptr) = + (long_bsr-> + Buffer_size0 << 2) | ((long_bsr->Buffer_size1 & 0x30) >> 4); + *(ce_ptr + 1) = + ((long_bsr->Buffer_size1 & 0x0F) << 4) | ((long_bsr-> + Buffer_size2 & 0x3C) + >> 2); + *(ce_ptr + 2) = + ((long_bsr-> + Buffer_size2 & 0x03) << 2) | (long_bsr->Buffer_size3 & 0x3F); + ce_ptr += BSR_LONG_SIZE; + // printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); + } + + // printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - for (i = 0; i < num_sdus; i++) { + for (i = 0; i < num_sdus; i++) { #ifdef DEBUG_HEADER_PARSING - LOG_T(MAC, "[UE] sdu subheader %d (lcid %d, %d bytes)\n", i, - sdu_lcids[i], sdu_lengths[i]); + LOG_T(MAC, "[UE] sdu subheader %d (lcid %d, %d bytes)\n", i, + sdu_lcids[i], sdu_lengths[i]); #endif - if ((i == (num_sdus - 1)) - && ((short_padding) || (post_padding == 0))) { - if (first_element > 0) { - mac_header_ptr->E = 1; + if ((i == (num_sdus - 1)) + && ((short_padding) || (post_padding == 0))) { + if (first_element > 0) { + mac_header_ptr->E = 1; #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] last subheader : %x (R%d,E%d,LCID%d)\n", - *(unsigned char *) mac_header_ptr, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID); + LOG_D(MAC, "[UE] last subheader : %x (R%d,E%d,LCID%d)\n", + *(unsigned char *) mac_header_ptr, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID); #endif - mac_header_ptr += last_size; - } - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = sdu_lcids[i]; - } else { - if ((first_element > 0)) { - mac_header_ptr->E = 1; + mac_header_ptr += last_size; + } + + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = sdu_lcids[i]; + } else { + if ((first_element > 0)) { + mac_header_ptr->E = 1; #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] last subheader : %x (R%d,E%d,LCID%d)\n", - *(unsigned char *) mac_header_ptr, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID); + LOG_D(MAC, "[UE] last subheader : %x (R%d,E%d,LCID%d)\n", + *(unsigned char *) mac_header_ptr, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID); #endif - mac_header_ptr += last_size; - // printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); - } else { - first_element = 1; - - } - - if (sdu_lengths[i] < 128) { - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0; // 3 - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = - sdu_lcids[i]; - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = - (unsigned char) sdu_lengths[i]; - last_size = 2; + mac_header_ptr += last_size; + // printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); + } else { + first_element = 1; + } + + if (sdu_lengths[i] < 128) { + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0; // 3 + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = + sdu_lcids[i]; + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = + (unsigned char) sdu_lengths[i]; + last_size = 2; #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] short sdu\n"); - LOG_T(MAC, - "[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n", - ((uint16_t *) mac_header_ptr)[0], - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R, - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E, - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID, - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F, - ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L); + LOG_D(MAC, "[UE] short sdu\n"); + LOG_T(MAC, + "[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n", + ((uint16_t *) mac_header_ptr)[0], + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R, + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E, + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID, + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F, + ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L); #endif - } else { - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = - sdu_lcids[i]; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = - ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = - (unsigned short) sdu_lengths[i] & 0xff; - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; - last_size = 3; + } else { + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = + sdu_lcids[i]; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = + ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = + (unsigned short) sdu_lengths[i] & 0xff; + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00; + last_size = 3; #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] long sdu\n"); + LOG_D(MAC, "[UE] long sdu\n"); #endif - } - } + } } + } - if (post_padding > 0) { // we have lots of padding at the end of the packet - mac_header_ptr->E = 1; - mac_header_ptr += last_size; - // add a padding element - mac_header_ptr->R = 0; - mac_header_ptr->E = 0; - mac_header_ptr->LCID = SHORT_PADDING; - mac_header_ptr++; - } else { // no end of packet padding - // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) - mac_header_ptr++; - //mac_header_ptr=last_size; // FIXME: should be ++ - } + if (post_padding > 0) { // we have lots of padding at the end of the packet + mac_header_ptr->E = 1; + mac_header_ptr += last_size; + // add a padding element + mac_header_ptr->R = 0; + mac_header_ptr->E = 0; + mac_header_ptr->LCID = SHORT_PADDING; + mac_header_ptr++; + } else { // no end of packet padding + // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE) + mac_header_ptr++; + //mac_header_ptr=last_size; // FIXME: should be ++ + } + if ((ce_ptr - mac_header_control_elements) > 0) { + memcpy((void *) mac_header_ptr, mac_header_control_elements, + ce_ptr - mac_header_control_elements); + mac_header_ptr += + (unsigned char) (ce_ptr - mac_header_control_elements); + } - if ((ce_ptr - mac_header_control_elements) > 0) { - memcpy((void *) mac_header_ptr, mac_header_control_elements, - ce_ptr - mac_header_control_elements); - mac_header_ptr += - (unsigned char) (ce_ptr - mac_header_control_elements); - } #ifdef DEBUG_HEADER_PARSING - LOG_T(MAC, " [UE] header : "); + LOG_T(MAC, " [UE] header : "); - for (i = 0; i < ((unsigned char *) mac_header_ptr - mac_header); i++) { - LOG_T(MAC, "%2x.", mac_header[i]); - } + for (i = 0; i < ((unsigned char *) mac_header_ptr - mac_header); i++) { + LOG_T(MAC, "%2x.", mac_header[i]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - return ((unsigned char *) mac_header_ptr - mac_header); - + return ((unsigned char *) mac_header_ptr - mac_header); } void ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, - sub_frame_t subframe, uint8_t eNB_index, - uint8_t * ulsch_buffer, uint16_t buflen, uint8_t * access_mode) -{ - - uint8_t total_rlc_pdu_header_len = 0, rlc_pdu_header_len_last = 0; - uint16_t buflen_remain = 0; - uint8_t bsr_len = 0, bsr_ce_len = 0, bsr_header_len = 0; - uint8_t phr_header_len = 0, phr_ce_len = 0, phr_len = 0; - uint8_t lcid = 0, lcid_rlc_pdu_count = 0; - boolean_t is_lcid_processed = FALSE; - boolean_t is_all_lcid_processed = FALSE; - uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - uint8_t payload_offset = 0, num_sdus = 0; - uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; - uint16_t sdu_length_total = 0; - BSR_SHORT bsr_short, bsr_truncated; - BSR_LONG bsr_long; - BSR_SHORT *bsr_s = &bsr_short; - BSR_LONG *bsr_l = &bsr_long; - BSR_SHORT *bsr_t = &bsr_truncated; - POWER_HEADROOM_CMD phr; - POWER_HEADROOM_CMD *phr_p = &phr; - unsigned short short_padding = 0, post_padding = 0, padding_len = 0; - int j; // used for padding - // Compute header length - int lcg_id = 0; - int lcg_id_bsr_trunc = 0; - int highest_priority = 16; - int num_lcg_id_with_data = 0; - rlc_buffer_occupancy_t lcid_buffer_occupancy_old = - 0, lcid_buffer_occupancy_new = 0; - - LOG_D(MAC, - "[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n", - module_idP, frameP, subframe, buflen); - - - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - + sub_frame_t subframe, uint8_t eNB_index, + uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) { + uint8_t total_rlc_pdu_header_len = 0, rlc_pdu_header_len_last = 0; + uint16_t buflen_remain = 0; + uint8_t bsr_len = 0, bsr_ce_len = 0, bsr_header_len = 0; + uint8_t phr_header_len = 0, phr_ce_len = 0, phr_len = 0; + uint8_t lcid = 0, lcid_rlc_pdu_count = 0; + boolean_t is_lcid_processed = FALSE; + boolean_t is_all_lcid_processed = FALSE; + uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t payload_offset = 0, num_sdus = 0; + uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES]; + uint16_t sdu_length_total = 0; + BSR_SHORT bsr_short, bsr_truncated; + BSR_LONG bsr_long; + BSR_SHORT *bsr_s = &bsr_short; + BSR_LONG *bsr_l = &bsr_long; + BSR_SHORT *bsr_t = &bsr_truncated; + POWER_HEADROOM_CMD phr; + POWER_HEADROOM_CMD *phr_p = &phr; + unsigned short short_padding = 0, post_padding = 0, padding_len = 0; + int j; // used for padding + // Compute header length + int lcg_id = 0; + int lcg_id_bsr_trunc = 0; + int highest_priority = 16; + int num_lcg_id_with_data = 0; + rlc_buffer_occupancy_t lcid_buffer_occupancy_old = + 0, lcid_buffer_occupancy_new = 0; + LOG_D(MAC, + "[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n", + module_idP, frameP, subframe, buflen); + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); #if UE_TIMING_TRACE - start_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); + start_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_IN); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_IN); #ifdef CBA - if (*access_mode == CBA_ACCESS) { - LOG_D(MAC, "[UE %d] frameP %d subframe %d try CBA transmission\n", - module_idP, frameP, subframe); - - //if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DTCH] == LCID_EMPTY) - if (cba_access(module_idP, frameP, subframe, eNB_index, buflen) == - 0) { - *access_mode = POSTPONED_ACCESS; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT); - return; - } - - LOG_I(MAC, - "[UE %d] frameP %d subframe %d CBA transmission oppurtunity, tbs %d\n", - module_idP, frameP, subframe, buflen); + if (*access_mode == CBA_ACCESS) { + LOG_D(MAC, "[UE %d] frameP %d subframe %d try CBA transmission\n", + module_idP, frameP, subframe); + + //if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DTCH] == LCID_EMPTY) + if (cba_access(module_idP, frameP, subframe, eNB_index, buflen) == + 0) { + *access_mode = POSTPONED_ACCESS; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT); + return; } + + LOG_I(MAC, + "[UE %d] frameP %d subframe %d CBA transmission oppurtunity, tbs %d\n", + module_idP, frameP, subframe, buflen); + } + #endif - bsr_header_len = 0; - phr_header_len = 1; //sizeof(SCH_SUBHEADER_FIXED); - - while (lcg_id < MAX_NUM_LCGID) { - if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]) { - num_lcg_id_with_data++; - } - lcg_id++; + bsr_header_len = 0; + phr_header_len = 1; //sizeof(SCH_SUBHEADER_FIXED); + + while (lcg_id < MAX_NUM_LCGID) { + if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]) { + num_lcg_id_with_data++; } - if (num_lcg_id_with_data) { - LOG_D(MAC, - "[UE %d] MAC Tx data pending at frame%d subframe %d nb LCG =%d Bytes for LCG0=%d LCG1=%d LCG2=%d LCG3=%d BSR Trigger status =%d TBS=%d\n", - module_idP, frameP, subframe, num_lcg_id_with_data, - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[0], - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[1], - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[2], - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[3], - UE_mac_inst[module_idP].BSR_reporting_active, buflen); + lcg_id++; + } - } - //Restart ReTxBSR Timer at new grant indication (36.321) - if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != - MAC_UE_BSR_TIMER_NOT_RUNNING) { - UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = - get_sf_retxBSRTimer(UE_mac_inst[module_idP]. - scheduling_info.retxBSR_Timer); - } - // periodicBSR-Timer expires, trigger BSR - if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != - LTE_PeriodicBSR_Timer_r12_infinity) - && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF == 0)) { - // Trigger BSR Periodic - UE_mac_inst[module_idP].BSR_reporting_active |= - BSR_TRIGGER_PERIODIC; - - LOG_D(MAC, - "[UE %d] MAC BSR Triggered PeriodicBSR Timer expiry at frame%d subframe %d TBS=%d\n", - module_idP, frameP, subframe, buflen); + if (num_lcg_id_with_data) { + LOG_D(MAC, + "[UE %d] MAC Tx data pending at frame%d subframe %d nb LCG =%d Bytes for LCG0=%d LCG1=%d LCG2=%d LCG3=%d BSR Trigger status =%d TBS=%d\n", + module_idP, frameP, subframe, num_lcg_id_with_data, + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[0], + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[1], + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[2], + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[3], + UE_mac_inst[module_idP].BSR_reporting_active, buflen); + } - } - //Compute BSR Length if Regular or Periodic BSR is triggered - //WARNING: if BSR long is computed, it may be changed to BSR short during or after multiplexing if there remains less than 1 LCGROUP with data after Tx - if (UE_mac_inst[module_idP].BSR_reporting_active) { - - AssertFatal((UE_mac_inst[module_idP].BSR_reporting_active & - BSR_TRIGGER_PADDING) == 0, - "Inconsistent BSR Trigger=%d !\n", - UE_mac_inst[module_idP].BSR_reporting_active); - - if (buflen >= 4) { - //A Regular or Periodic BSR can only be sent if TBS >= 4 as transmitting only a BSR is not allowed if UE has data to transmit - bsr_header_len = 1; - - if (num_lcg_id_with_data <= 1) { - bsr_ce_len = sizeof(BSR_SHORT); //1 byte - } else { - bsr_ce_len = BSR_LONG_SIZE; //3 bytes - } - } - } + //Restart ReTxBSR Timer at new grant indication (36.321) + if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != + MAC_UE_BSR_TIMER_NOT_RUNNING) { + UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = + get_sf_retxBSRTimer(UE_mac_inst[module_idP]. + scheduling_info.retxBSR_Timer); + } - bsr_len = bsr_ce_len + bsr_header_len; - - phr_ce_len = - (UE_mac_inst[module_idP].PHR_reporting_active == - 1) ? 1 /* sizeof(POWER_HEADROOM_CMD) */ : 0; - if ((phr_ce_len > 0) - && ((phr_ce_len + phr_header_len + bsr_len) <= buflen)) { - phr_len = phr_ce_len + phr_header_len; - LOG_D(MAC, - "[UE %d] header size info: PHR len %d (ce%d,hdr%d) buff_len %d\n", - module_idP, phr_len, phr_ce_len, phr_header_len, buflen); - } else { - phr_len = 0; - phr_header_len = 0; - phr_ce_len = 0; + // periodicBSR-Timer expires, trigger BSR + if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != + LTE_PeriodicBSR_Timer_r12_infinity) + && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF == 0)) { + // Trigger BSR Periodic + UE_mac_inst[module_idP].BSR_reporting_active |= + BSR_TRIGGER_PERIODIC; + LOG_D(MAC, + "[UE %d] MAC BSR Triggered PeriodicBSR Timer expiry at frame%d subframe %d TBS=%d\n", + module_idP, frameP, subframe, buflen); + } + + //Compute BSR Length if Regular or Periodic BSR is triggered + //WARNING: if BSR long is computed, it may be changed to BSR short during or after multiplexing if there remains less than 1 LCGROUP with data after Tx + if (UE_mac_inst[module_idP].BSR_reporting_active) { + AssertFatal((UE_mac_inst[module_idP].BSR_reporting_active & + BSR_TRIGGER_PADDING) == 0, + "Inconsistent BSR Trigger=%d !\n", + UE_mac_inst[module_idP].BSR_reporting_active); + + if (buflen >= 4) { + //A Regular or Periodic BSR can only be sent if TBS >= 4 as transmitting only a BSR is not allowed if UE has data to transmit + bsr_header_len = 1; + + if (num_lcg_id_with_data <= 1) { + bsr_ce_len = sizeof(BSR_SHORT); //1 byte + } else { + bsr_ce_len = BSR_LONG_SIZE; //3 bytes + } } + } + + bsr_len = bsr_ce_len + bsr_header_len; + phr_ce_len = + (UE_mac_inst[module_idP].PHR_reporting_active == + 1) ? 1 /* sizeof(POWER_HEADROOM_CMD) */ : 0; + + if ((phr_ce_len > 0) + && ((phr_ce_len + phr_header_len + bsr_len) <= buflen)) { + phr_len = phr_ce_len + phr_header_len; + LOG_D(MAC, + "[UE %d] header size info: PHR len %d (ce%d,hdr%d) buff_len %d\n", + module_idP, phr_len, phr_ce_len, phr_header_len, buflen); + } else { + phr_len = 0; + phr_header_len = 0; + phr_ce_len = 0; + } - // check for UL bandwidth requests and add SR control element - - // check for UL bandwidth requests and add SR control element - - // Check for DCCH first -// TO DO: Multiplex in the order defined by the logical channel prioritization - for (lcid = DCCH; - (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE); lcid++) - { - if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == - LCID_NOT_EMPTY) { - - lcid_rlc_pdu_count = 0; - is_lcid_processed = FALSE; - lcid_buffer_occupancy_old = - mac_rlc_get_buffer_occupancy_ind(module_idP, - UE_mac_inst[module_idP]. - crnti, eNB_index, frameP, - subframe, ENB_FLAG_NO, - lcid); - - lcid_buffer_occupancy_new = lcid_buffer_occupancy_old; - - AssertFatal(lcid_buffer_occupancy_new == - UE_mac_inst[module_idP]. - scheduling_info.LCID_buffer_remain[lcid], - "LCID=%d RLC has BO %d bytes but MAC has stored %d bytes\n", - lcid, lcid_buffer_occupancy_new, - UE_mac_inst[module_idP]. - scheduling_info.LCID_buffer_remain[lcid]); - - AssertFatal(lcid_buffer_occupancy_new <= - UE_mac_inst[module_idP]. - scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. - scheduling_info.LCGID - [lcid]], - "LCID=%d RLC has more BO %d bytes than BSR = %d bytes\n", - lcid, lcid_buffer_occupancy_new, - UE_mac_inst[module_idP]. - scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. - scheduling_info.LCGID - [lcid]]); - - - //Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data - //Adjust at the end of the loop - while ((!is_lcid_processed) && (lcid_buffer_occupancy_new) - && (bsr_len + phr_len + total_rlc_pdu_header_len + - sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) - { - - // Workaround for issue in OAI eNB or EPC which are not able to process SRB2 message multiplexed with SRB1 on the same MAC PDU - if (( get_softmodem_params()->usim_test == 0) && (lcid == DCCH1) - && (lcid_rlc_pdu_count == 0) && (num_sdus)) { - - // Skip SRB2 multiplex if at least one SRB1 SDU is already multiplexed - break; - } - - buflen_remain = - buflen - (bsr_len + phr_len + - total_rlc_pdu_header_len + sdu_length_total + - 1); - - - LOG_D(MAC, - "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to " - "send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n", - module_idP, frameP, lcid, lcid_buffer_occupancy_new, - buflen, bsr_len, phr_len, sdu_length_total, - total_rlc_pdu_header_len, - UE_mac_inst[module_idP]. - scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. - scheduling_info.LCGID - [lcid]]); - - - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - UE_mac_inst - [module_idP]. - crnti, eNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - lcid, - buflen_remain, - (char *)&ulsch_buff[sdu_length_total] + // check for UL bandwidth requests and add SR control element + + // check for UL bandwidth requests and add SR control element + + // Check for DCCH first + // TO DO: Multiplex in the order defined by the logical channel prioritization + for (lcid = DCCH; + (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE); lcid++) { + if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == + LCID_NOT_EMPTY) { + lcid_rlc_pdu_count = 0; + is_lcid_processed = FALSE; + lcid_buffer_occupancy_old = + mac_rlc_get_buffer_occupancy_ind(module_idP, + UE_mac_inst[module_idP]. + crnti, eNB_index, frameP, + subframe, ENB_FLAG_NO, + lcid); + lcid_buffer_occupancy_new = lcid_buffer_occupancy_old; + AssertFatal(lcid_buffer_occupancy_new == + UE_mac_inst[module_idP]. + scheduling_info.LCID_buffer_remain[lcid], + "LCID=%d RLC has BO %d bytes but MAC has stored %d bytes\n", + lcid, lcid_buffer_occupancy_new, + UE_mac_inst[module_idP]. + scheduling_info.LCID_buffer_remain[lcid]); + AssertFatal(lcid_buffer_occupancy_new <= + UE_mac_inst[module_idP]. + scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. + scheduling_info.LCGID + [lcid]], + "LCID=%d RLC has more BO %d bytes than BSR = %d bytes\n", + lcid, lcid_buffer_occupancy_new, + UE_mac_inst[module_idP]. + scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. + scheduling_info.LCGID + [lcid]]); + + //Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data + //Adjust at the end of the loop + while ((!is_lcid_processed) && (lcid_buffer_occupancy_new) + && (bsr_len + phr_len + total_rlc_pdu_header_len + + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) { + // Workaround for issue in OAI eNB or EPC which are not able to process SRB2 message multiplexed with SRB1 on the same MAC PDU + if (( get_softmodem_params()->usim_test == 0) && (lcid == DCCH1) + && (lcid_rlc_pdu_count == 0) && (num_sdus)) { + // Skip SRB2 multiplex if at least one SRB1 SDU is already multiplexed + break; + } + + buflen_remain = + buflen - (bsr_len + phr_len + + total_rlc_pdu_header_len + sdu_length_total + + 1); + LOG_D(MAC, + "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to " + "send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n", + module_idP, frameP, lcid, lcid_buffer_occupancy_new, + buflen, bsr_len, phr_len, sdu_length_total, + total_rlc_pdu_header_len, + UE_mac_inst[module_idP]. + scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. + scheduling_info.LCGID + [lcid]]); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + UE_mac_inst + [module_idP]. + crnti, eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + lcid, + buflen_remain, + (char *)&ulsch_buff[sdu_length_total] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, - 0 + ,0, + 0 #endif - ); - - - - AssertFatal(buflen_remain >= sdu_lengths[num_sdus], - "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n", - lcid, sdu_lengths[num_sdus], buflen_remain); - - - if (sdu_lengths[num_sdus]) { - sdu_length_total += sdu_lengths[num_sdus]; - sdu_lcids[num_sdus] = lcid; - LOG_I(MAC, - "[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LcId%d\n", - module_idP, sdu_lengths[num_sdus], lcid); - - if (buflen == - (bsr_len + phr_len + total_rlc_pdu_header_len + - sdu_length_total + 1)) { - //No more remaining TBS after this PDU - //exit the function - rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - is_all_lcid_processed = TRUE; - } else { - rlc_pdu_header_len_last = - (sdu_lengths[num_sdus] > 128) ? 3 : 2; - - //Change to 1 byte if it does not fit in the TBS, ie last PDU - if (buflen <= - (bsr_len + phr_len + total_rlc_pdu_header_len + - rlc_pdu_header_len_last + sdu_length_total)) { - rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - is_all_lcid_processed = TRUE; - } - } - - //Update number of SDU - num_sdus++; - - //Update total MAC Header size for RLC PDUs and save last one - total_rlc_pdu_header_len += rlc_pdu_header_len_last; - - lcid_rlc_pdu_count++; - } else { - /* avoid infinite loop ... */ - is_lcid_processed = TRUE; - } - - /* Get updated BO after multiplexing this PDU */ - lcid_buffer_occupancy_new = - mac_rlc_get_buffer_occupancy_ind(module_idP, - UE_mac_inst - [module_idP].crnti, - eNB_index, frameP, - subframe, ENB_FLAG_NO, - lcid); - - is_lcid_processed = (is_lcid_processed) - || (lcid_buffer_occupancy_new <= 0); - } - - //Update Buffer remain and BSR bytes after transmission - - AssertFatal(lcid_buffer_occupancy_new <= - lcid_buffer_occupancy_old, - "MAC UE Tx error : Buffer Occupancy After Tx=%d greater than before=%d BO! for LCID=%d RLC PDU nb=%d Frame %d Subrame %d\n", - lcid_buffer_occupancy_new, - lcid_buffer_occupancy_old, lcid, - lcid_rlc_pdu_count, frameP, subframe); - - UE_mac_inst[module_idP].scheduling_info. - LCID_buffer_remain[lcid] = lcid_buffer_occupancy_new; - UE_mac_inst[module_idP]. - scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. - scheduling_info.LCGID[lcid]] += - (lcid_buffer_occupancy_new - lcid_buffer_occupancy_old); - - //Update the number of LCGID with data as BSR shall reflect status after BSR transmission - if ((num_lcg_id_with_data > 1) - && (UE_mac_inst[module_idP]. - scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. - scheduling_info.LCGID[lcid]] - == 0)) { - num_lcg_id_with_data--; - // Change BSR size to BSR SHORT if num_lcg_id_with_data becomes to 1 - if ((bsr_len) && (num_lcg_id_with_data == 1)) { - bsr_ce_len = sizeof(BSR_SHORT); - bsr_len = bsr_ce_len + bsr_header_len; - } - } - - - UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = - LCID_EMPTY; - } - } + ); + AssertFatal(buflen_remain >= sdu_lengths[num_sdus], + "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n", + lcid, sdu_lengths[num_sdus], buflen_remain); + + if (sdu_lengths[num_sdus]) { + sdu_length_total += sdu_lengths[num_sdus]; + sdu_lcids[num_sdus] = lcid; + LOG_I(MAC, + "[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LcId%d\n", + module_idP, sdu_lengths[num_sdus], lcid); + + if (buflen == + (bsr_len + phr_len + total_rlc_pdu_header_len + + sdu_length_total + 1)) { + //No more remaining TBS after this PDU + //exit the function + rlc_pdu_header_len_last = 1; + is_lcid_processed = TRUE; + is_all_lcid_processed = TRUE; + } else { + rlc_pdu_header_len_last = + (sdu_lengths[num_sdus] > 128) ? 3 : 2; + + //Change to 1 byte if it does not fit in the TBS, ie last PDU + if (buflen <= + (bsr_len + phr_len + total_rlc_pdu_header_len + + rlc_pdu_header_len_last + sdu_length_total)) { + rlc_pdu_header_len_last = 1; + is_lcid_processed = TRUE; + is_all_lcid_processed = TRUE; + } + } + //Update number of SDU + num_sdus++; + //Update total MAC Header size for RLC PDUs and save last one + total_rlc_pdu_header_len += rlc_pdu_header_len_last; + lcid_rlc_pdu_count++; + } else { + /* avoid infinite loop ... */ + is_lcid_processed = TRUE; + } + /* Get updated BO after multiplexing this PDU */ + lcid_buffer_occupancy_new = + mac_rlc_get_buffer_occupancy_ind(module_idP, + UE_mac_inst + [module_idP].crnti, + eNB_index, frameP, + subframe, ENB_FLAG_NO, + lcid); + is_lcid_processed = (is_lcid_processed) + || (lcid_buffer_occupancy_new <= 0); + } - // Compute BSR Values and update Nb LCGID with data after multiplexing - num_lcg_id_with_data = 0; - lcg_id_bsr_trunc = 0; - for (lcg_id = 0; lcg_id < MAX_NUM_LCGID; lcg_id++) { - UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id] = - locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, - UE_mac_inst - [module_idP].scheduling_info. - BSR_bytes[lcg_id]); + //Update Buffer remain and BSR bytes after transmission + AssertFatal(lcid_buffer_occupancy_new <= + lcid_buffer_occupancy_old, + "MAC UE Tx error : Buffer Occupancy After Tx=%d greater than before=%d BO! for LCID=%d RLC PDU nb=%d Frame %d Subrame %d\n", + lcid_buffer_occupancy_new, + lcid_buffer_occupancy_old, lcid, + lcid_rlc_pdu_count, frameP, subframe); + UE_mac_inst[module_idP].scheduling_info. + LCID_buffer_remain[lcid] = lcid_buffer_occupancy_new; + UE_mac_inst[module_idP]. + scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. + scheduling_info.LCGID[lcid]] += + (lcid_buffer_occupancy_new - lcid_buffer_occupancy_old); + + //Update the number of LCGID with data as BSR shall reflect status after BSR transmission + if ((num_lcg_id_with_data > 1) + && (UE_mac_inst[module_idP]. + scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. + scheduling_info.LCGID[lcid]] + == 0)) { + num_lcg_id_with_data--; + + // Change BSR size to BSR SHORT if num_lcg_id_with_data becomes to 1 + if ((bsr_len) && (num_lcg_id_with_data == 1)) { + bsr_ce_len = sizeof(BSR_SHORT); + bsr_len = bsr_ce_len + bsr_header_len; + } + } - if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]) { - num_lcg_id_with_data++; - lcg_id_bsr_trunc = lcg_id; - } + UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = + LCID_EMPTY; } + } + // Compute BSR Values and update Nb LCGID with data after multiplexing + num_lcg_id_with_data = 0; + lcg_id_bsr_trunc = 0; - if (bsr_ce_len) { - //Print updated BSR when sent - LOG_D(MAC, - "[UE %d] Remaining Buffer after Tx frame%d subframe %d nb LCG =%d Bytes for LCG0=%d LCG1=%d LCG2=%d LCG3=%d BSR Trigger status =%d TBS=%d\n", - module_idP, frameP, subframe, num_lcg_id_with_data, - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[0], - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[1], - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[2], - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[3], - UE_mac_inst[module_idP].BSR_reporting_active, buflen); - - LOG_D(MAC, - "[UE %d] Frame %d Subframe %d TX BSR Regular or Periodic size=%d BSR0=%d BSR1=%d BSR2=%d BSR3=%d\n", - module_idP, frameP, subframe, bsr_ce_len, - UE_mac_inst[module_idP].scheduling_info.BSR[0], - UE_mac_inst[module_idP].scheduling_info.BSR[1], - UE_mac_inst[module_idP].scheduling_info.BSR[2], - UE_mac_inst[module_idP].scheduling_info.BSR[3]); - } - // build PHR and update the timers - if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) { - if(nfapi_mode ==3){ - //Substitute with a static value for the MAC layer abstraction (phy_stub mode) - phr_p->PH = 40; - } - else{ - phr_p->PH = get_phr_mapping(module_idP, CC_id, eNB_index); - } - - - phr_p->R = 0; - LOG_D(MAC, - "[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n", - module_idP, frameP, get_PHR(module_idP, CC_id, eNB_index), - phr_p->PH, POWER_HEADROOM); - update_phr(module_idP, CC_id); - } else { - phr_p = NULL; + for (lcg_id = 0; lcg_id < MAX_NUM_LCGID; lcg_id++) { + UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id] = + locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, + UE_mac_inst + [module_idP].scheduling_info. + BSR_bytes[lcg_id]); + + if (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]) { + num_lcg_id_with_data++; + lcg_id_bsr_trunc = lcg_id; } + } - LOG_T(MAC, "[UE %d] Frame %d: bsr s %p bsr_l %p, phr_p %p\n", - module_idP, frameP, bsr_s, bsr_l, phr_p); - - // Check BSR padding: it is done after PHR according to Logical Channel Prioritization order - // Check for max padding size, ie MAC Hdr for last RLC PDU = 1 - /* For Padding BSR: - - if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader: - - if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission; - - else report Short BSR. - - else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR. - */ - if (sdu_length_total) { - padding_len = - buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - - rlc_pdu_header_len_last + sdu_length_total + 1); + if (bsr_ce_len) { + //Print updated BSR when sent + LOG_D(MAC, + "[UE %d] Remaining Buffer after Tx frame%d subframe %d nb LCG =%d Bytes for LCG0=%d LCG1=%d LCG2=%d LCG3=%d BSR Trigger status =%d TBS=%d\n", + module_idP, frameP, subframe, num_lcg_id_with_data, + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[0], + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[1], + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[2], + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[3], + UE_mac_inst[module_idP].BSR_reporting_active, buflen); + LOG_D(MAC, + "[UE %d] Frame %d Subframe %d TX BSR Regular or Periodic size=%d BSR0=%d BSR1=%d BSR2=%d BSR3=%d\n", + module_idP, frameP, subframe, bsr_ce_len, + UE_mac_inst[module_idP].scheduling_info.BSR[0], + UE_mac_inst[module_idP].scheduling_info.BSR[1], + UE_mac_inst[module_idP].scheduling_info.BSR[2], + UE_mac_inst[module_idP].scheduling_info.BSR[3]); + } + + // build PHR and update the timers + if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) { + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { + //Substitute with a static value for the MAC layer abstraction (phy_stub mode) + phr_p->PH = 40; } else { - padding_len = buflen - (bsr_len + phr_len); + phr_p->PH = get_phr_mapping(module_idP, CC_id, eNB_index); } + phr_p->R = 0; + LOG_D(MAC, + "[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n", + module_idP, frameP, get_PHR(module_idP, CC_id, eNB_index), + phr_p->PH, POWER_HEADROOM); + update_phr(module_idP, CC_id); + } else { + phr_p = NULL; + } - if ((padding_len) && (bsr_len == 0)) { - /* if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR */ - if (padding_len >= (1 + BSR_LONG_SIZE)) { - bsr_ce_len = BSR_LONG_SIZE; - bsr_header_len = 1; - // Trigger BSR Padding - UE_mac_inst[module_idP].BSR_reporting_active |= - BSR_TRIGGER_PADDING; - - - } else if (padding_len >= (1 + sizeof(BSR_SHORT))) { - bsr_ce_len = sizeof(BSR_SHORT); - bsr_header_len = 1; - - if (num_lcg_id_with_data > 1) { - // REPORT TRUNCATED BSR - //Get LCGID of highest priority LCID with data - for (lcid = DCCH; lcid < MAX_NUM_LCID; lcid++) { - if (UE_mac_inst[module_idP]. - logicalChannelConfig[lcid] != NULL) { - lcg_id = - UE_mac_inst[module_idP].scheduling_info. - LCGID[lcid]; - - if ((lcg_id < MAX_NUM_LCGID) - && (UE_mac_inst[module_idP]. - scheduling_info.BSR_bytes[lcg_id]) - && - (UE_mac_inst[module_idP].logicalChannelConfig - [lcid]->ul_SpecificParameters->priority <= - highest_priority)) { - highest_priority = - UE_mac_inst[module_idP]. - logicalChannelConfig[lcid]-> - ul_SpecificParameters->priority; - lcg_id_bsr_trunc = lcg_id; - } - } - } - } else { - //Report SHORT BSR, clear bsr_t - bsr_t = NULL; - } - - // Trigger BSR Padding - UE_mac_inst[module_idP].BSR_reporting_active |= - BSR_TRIGGER_PADDING; - } - bsr_len = bsr_header_len + bsr_ce_len; - } - //Fill BSR Infos - if (bsr_ce_len == 0) { - bsr_s = NULL; - bsr_l = NULL; - bsr_t = NULL; - } else if (bsr_ce_len == BSR_LONG_SIZE) { - bsr_s = NULL; - bsr_t = NULL; - bsr_l->Buffer_size0 = - UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0]; - bsr_l->Buffer_size1 = - UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]; - bsr_l->Buffer_size2 = - UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]; - bsr_l->Buffer_size3 = - UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]; - - LOG_D(MAC, - "[UE %d] Frame %d subframe %d BSR Trig=%d report long BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d)\n", - module_idP, frameP, subframe, - UE_mac_inst[module_idP].BSR_reporting_active, - UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0], - UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1], - UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2], - UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]); - - } else if (bsr_ce_len == sizeof(BSR_SHORT)) { - bsr_l = NULL; - if ((bsr_t != NULL) - && (UE_mac_inst[module_idP].BSR_reporting_active & - BSR_TRIGGER_PADDING)) { - //Truncated BSR - bsr_s = NULL; - bsr_t->LCGID = lcg_id_bsr_trunc; - bsr_t->Buffer_size = - UE_mac_inst[module_idP].scheduling_info. - BSR[lcg_id_bsr_trunc]; - - LOG_D(MAC, - "[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n", - module_idP, frameP, subframe, - UE_mac_inst[module_idP].BSR_reporting_active, - UE_mac_inst[module_idP]. - scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc); - - } else { - bsr_t = NULL; - bsr_s->LCGID = lcg_id_bsr_trunc; - bsr_s->Buffer_size = - UE_mac_inst[module_idP].scheduling_info. - BSR[lcg_id_bsr_trunc]; - - LOG_D(MAC, - "[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n", - module_idP, frameP, subframe, - UE_mac_inst[module_idP].BSR_reporting_active, - UE_mac_inst[module_idP]. - scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc); - } + LOG_T(MAC, "[UE %d] Frame %d: bsr s %p bsr_l %p, phr_p %p\n", + module_idP, frameP, bsr_s, bsr_l, phr_p); + + // Check BSR padding: it is done after PHR according to Logical Channel Prioritization order + // Check for max padding size, ie MAC Hdr for last RLC PDU = 1 + /* For Padding BSR: + - if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader: + - if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission; + - else report Short BSR. + - else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR. + */ + if (sdu_length_total) { + padding_len = + buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - + rlc_pdu_header_len_last + sdu_length_total + 1); + } else { + padding_len = buflen - (bsr_len + phr_len); + } + + if ((padding_len) && (bsr_len == 0)) { + /* if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR */ + if (padding_len >= (1 + BSR_LONG_SIZE)) { + bsr_ce_len = BSR_LONG_SIZE; + bsr_header_len = 1; + // Trigger BSR Padding + UE_mac_inst[module_idP].BSR_reporting_active |= + BSR_TRIGGER_PADDING; + } else if (padding_len >= (1 + sizeof(BSR_SHORT))) { + bsr_ce_len = sizeof(BSR_SHORT); + bsr_header_len = 1; + + if (num_lcg_id_with_data > 1) { + // REPORT TRUNCATED BSR + //Get LCGID of highest priority LCID with data + for (lcid = DCCH; lcid < MAX_NUM_LCID; lcid++) { + if (UE_mac_inst[module_idP]. + logicalChannelConfig[lcid] != NULL) { + lcg_id = + UE_mac_inst[module_idP].scheduling_info. + LCGID[lcid]; + + if ((lcg_id < MAX_NUM_LCGID) + && (UE_mac_inst[module_idP]. + scheduling_info.BSR_bytes[lcg_id]) + && + (UE_mac_inst[module_idP].logicalChannelConfig + [lcid]->ul_SpecificParameters->priority <= + highest_priority)) { + highest_priority = + UE_mac_inst[module_idP]. + logicalChannelConfig[lcid]-> + ul_SpecificParameters->priority; + lcg_id_bsr_trunc = lcg_id; + } + } + } + } else { + //Report SHORT BSR, clear bsr_t + bsr_t = NULL; + } + + // Trigger BSR Padding + UE_mac_inst[module_idP].BSR_reporting_active |= + BSR_TRIGGER_PADDING; } -// 1-bit padding or 2-bit padding special padding subheader -// Check for max padding size, ie MAC Hdr for last RLC PDU = 1 - if (sdu_length_total) { - padding_len = - buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - - rlc_pdu_header_len_last + sdu_length_total + 1); + + bsr_len = bsr_header_len + bsr_ce_len; + } + + //Fill BSR Infos + if (bsr_ce_len == 0) { + bsr_s = NULL; + bsr_l = NULL; + bsr_t = NULL; + } else if (bsr_ce_len == BSR_LONG_SIZE) { + bsr_s = NULL; + bsr_t = NULL; + bsr_l->Buffer_size0 = + UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0]; + bsr_l->Buffer_size1 = + UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]; + bsr_l->Buffer_size2 = + UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]; + bsr_l->Buffer_size3 = + UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]; + LOG_D(MAC, + "[UE %d] Frame %d subframe %d BSR Trig=%d report long BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d)\n", + module_idP, frameP, subframe, + UE_mac_inst[module_idP].BSR_reporting_active, + UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0], + UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1], + UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2], + UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]); + } else if (bsr_ce_len == sizeof(BSR_SHORT)) { + bsr_l = NULL; + + if ((bsr_t != NULL) + && (UE_mac_inst[module_idP].BSR_reporting_active & + BSR_TRIGGER_PADDING)) { + //Truncated BSR + bsr_s = NULL; + bsr_t->LCGID = lcg_id_bsr_trunc; + bsr_t->Buffer_size = + UE_mac_inst[module_idP].scheduling_info. + BSR[lcg_id_bsr_trunc]; + LOG_D(MAC, + "[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n", + module_idP, frameP, subframe, + UE_mac_inst[module_idP].BSR_reporting_active, + UE_mac_inst[module_idP]. + scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc); } else { - padding_len = buflen - (bsr_len + phr_len); + bsr_t = NULL; + bsr_s->LCGID = lcg_id_bsr_trunc; + bsr_s->Buffer_size = + UE_mac_inst[module_idP].scheduling_info. + BSR[lcg_id_bsr_trunc]; + LOG_D(MAC, + "[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n", + module_idP, frameP, subframe, + UE_mac_inst[module_idP].BSR_reporting_active, + UE_mac_inst[module_idP]. + scheduling_info.BSR[lcg_id_bsr_trunc], lcg_id_bsr_trunc); } + } - if (padding_len <= 2) { - short_padding = padding_len; - // only add padding header - post_padding = 0; - //update total MAC Hdr size for RLC data - if (sdu_length_total) { - total_rlc_pdu_header_len = - total_rlc_pdu_header_len - rlc_pdu_header_len_last + 1; - rlc_pdu_header_len_last = 1; - } - } else if (sdu_length_total) { - post_padding = - buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + - sdu_length_total + 1); - // If by adding MAC Hdr for last RLC PDU the padding is 0 then set MAC Hdr for last RLC PDU = 1 and compute 1 or 2 byte padding - if (post_padding == 0) { - total_rlc_pdu_header_len -= rlc_pdu_header_len_last; - padding_len = - buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + - sdu_length_total + 1); - short_padding = padding_len; - total_rlc_pdu_header_len++; - } - } else { - if (padding_len == buflen) { // nona mac pdu - *access_mode = CANCELED_ACCESS; - } + // 1-bit padding or 2-bit padding special padding subheader + // Check for max padding size, ie MAC Hdr for last RLC PDU = 1 + if (sdu_length_total) { + padding_len = + buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - + rlc_pdu_header_len_last + sdu_length_total + 1); + } else { + padding_len = buflen - (bsr_len + phr_len); + } - short_padding = 0; + if (padding_len <= 2) { + short_padding = padding_len; + // only add padding header + post_padding = 0; - post_padding = - buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + - sdu_length_total + 1); + //update total MAC Hdr size for RLC data + if (sdu_length_total) { + total_rlc_pdu_header_len = + total_rlc_pdu_header_len - rlc_pdu_header_len_last + 1; + rlc_pdu_header_len_last = 1; + } + } else if (sdu_length_total) { + post_padding = + buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + + sdu_length_total + 1); + + // If by adding MAC Hdr for last RLC PDU the padding is 0 then set MAC Hdr for last RLC PDU = 1 and compute 1 or 2 byte padding + if (post_padding == 0) { + total_rlc_pdu_header_len -= rlc_pdu_header_len_last; + padding_len = + buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + + sdu_length_total + 1); + short_padding = padding_len; + total_rlc_pdu_header_len++; + } + } else { + if (padding_len == buflen) { // nona mac pdu + *access_mode = CANCELED_ACCESS; } - // Generate header - // if (num_sdus>0) { + short_padding = 0; + post_padding = + buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + + sdu_length_total + 1); + } - payload_offset = generate_ulsch_header(ulsch_buffer, // mac header - num_sdus, // num sdus - short_padding, // short pading - sdu_lengths, // sdu length - sdu_lcids, // sdu lcid - phr_p, // power headroom - NULL, // crnti - bsr_t, // truncated bsr - bsr_s, // short bsr - bsr_l, post_padding); // long_bsr + // Generate header + // if (num_sdus>0) { + payload_offset = generate_ulsch_header(ulsch_buffer, // mac header + num_sdus, // num sdus + short_padding, // short pading + sdu_lengths, // sdu length + sdu_lcids, // sdu lcid + phr_p, // power headroom + NULL, // crnti + bsr_t, // truncated bsr + bsr_s, // short bsr + bsr_l, post_padding); // long_bsr + LOG_D(MAC, + "[UE %d] Generate header :bufflen %d sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d, total_rlc_pdu_header_len %d, padding %d,post_padding %d, bsr len %d, phr len %d, reminder %d \n", + module_idP, buflen, sdu_length_total, num_sdus, sdu_lengths[0], + sdu_lcids[0], payload_offset, total_rlc_pdu_header_len, + short_padding, post_padding, bsr_len, phr_len, + buflen - sdu_length_total - payload_offset); + + // cycle through SDUs and place in ulsch_buffer + if (sdu_length_total) { + memcpy(&ulsch_buffer[payload_offset], ulsch_buff, + sdu_length_total); + } - LOG_D(MAC, - "[UE %d] Generate header :bufflen %d sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d, total_rlc_pdu_header_len %d, padding %d,post_padding %d, bsr len %d, phr len %d, reminder %d \n", - module_idP, buflen, sdu_length_total, num_sdus, sdu_lengths[0], - sdu_lcids[0], payload_offset, total_rlc_pdu_header_len, - short_padding, post_padding, bsr_len, phr_len, - buflen - sdu_length_total - payload_offset); - // cycle through SDUs and place in ulsch_buffer - if (sdu_length_total) { - memcpy(&ulsch_buffer[payload_offset], ulsch_buff, - sdu_length_total); - } - // fill remainder of DLSCH with random data - if (post_padding) { - for (j = 0; j < (buflen - sdu_length_total - payload_offset); j++) { - ulsch_buffer[payload_offset + sdu_length_total + j] = - (char) (taus() & 0xff); - } + // fill remainder of DLSCH with random data + if (post_padding) { + for (j = 0; j < (buflen - sdu_length_total - payload_offset); j++) { + ulsch_buffer[payload_offset + sdu_length_total + j] = + (char) (taus() & 0xff); } - LOG_D(MAC, - "[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n", - module_idP); - UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; - UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0; + } + + LOG_D(MAC, + "[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n", + module_idP); + UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; + UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0; - /* Actions when a BSR is sent */ - if (bsr_ce_len) { - LOG_D(MAC, - "[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n", - module_idP, bsr_ce_len, bsr_header_len, buflen); - - // Reset ReTx BSR Timer - UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = - get_sf_retxBSRTimer(UE_mac_inst[module_idP]. - scheduling_info.retxBSR_Timer); - - LOG_D(MAC, "[UE %d] MAC ReTx BSR Timer Reset =%d\n", module_idP, - UE_mac_inst[module_idP].scheduling_info.retxBSR_SF); - - // Reset Periodic Timer except when BSR is truncated - if ((bsr_t == NULL) - && (UE_mac_inst[module_idP].scheduling_info. - periodicBSR_Timer != LTE_PeriodicBSR_Timer_r12_infinity)) { - UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = - get_sf_periodicBSRTimer(UE_mac_inst - [module_idP].scheduling_info. - periodicBSR_Timer); - - LOG_D(MAC, "[UE %d] MAC Periodic BSR Timer Reset =%d\n", - module_idP, - UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF); - - } - // Reset BSR Trigger flags - UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE; + /* Actions when a BSR is sent */ + if (bsr_ce_len) { + LOG_D(MAC, + "[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n", + module_idP, bsr_ce_len, bsr_header_len, buflen); + // Reset ReTx BSR Timer + UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = + get_sf_retxBSRTimer(UE_mac_inst[module_idP]. + scheduling_info.retxBSR_Timer); + LOG_D(MAC, "[UE %d] MAC ReTx BSR Timer Reset =%d\n", module_idP, + UE_mac_inst[module_idP].scheduling_info.retxBSR_SF); + + // Reset Periodic Timer except when BSR is truncated + if ((bsr_t == NULL) + && (UE_mac_inst[module_idP].scheduling_info. + periodicBSR_Timer != LTE_PeriodicBSR_Timer_r12_infinity)) { + UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = + get_sf_periodicBSRTimer(UE_mac_inst + [module_idP].scheduling_info. + periodicBSR_Timer); + LOG_D(MAC, "[UE %d] MAC Periodic BSR Timer Reset =%d\n", + module_idP, + UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT); + // Reset BSR Trigger flags + UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE; + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); + stop_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); #endif - if (opt_enabled) { - trace_pdu(DIRECTION_UPLINK, ulsch_buffer, buflen, module_idP, WS_C_RNTI, - UE_mac_inst[module_idP].crnti, - UE_mac_inst[module_idP].txFrame, - UE_mac_inst[module_idP].txSubframe, 0, 0); - LOG_D(OPT, - "[UE %d][ULSCH] Frame %d subframe %d trace pdu for rnti %x with size %d\n", - module_idP, frameP, subframe, UE_mac_inst[module_idP].crnti, - buflen); - } + if (opt_enabled) { + trace_pdu(DIRECTION_UPLINK, ulsch_buffer, buflen, module_idP, WS_C_RNTI, + UE_mac_inst[module_idP].crnti, + UE_mac_inst[module_idP].txFrame, + UE_mac_inst[module_idP].txSubframe, 0, 0); + LOG_D(OPT, + "[UE %d][ULSCH] Frame %d subframe %d trace pdu for rnti %x with size %d\n", + module_idP, frameP, subframe, UE_mac_inst[module_idP].crnti, + buflen); + } } @@ -2539,511 +2486,498 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, UE_L2_STATE_t ue_scheduler(const module_id_t module_idP, - const frame_t rxFrameP, - const sub_frame_t rxSubframeP, - const frame_t txFrameP, - const sub_frame_t txSubframeP, - const lte_subframe_t directionP, - const uint8_t eNB_indexP, const int CC_id) + const frame_t rxFrameP, + const sub_frame_t rxSubframeP, + const frame_t txFrameP, + const sub_frame_t txSubframeP, + const lte_subframe_t directionP, + const uint8_t eNB_indexP, const int CC_id) //------------------------------------------------------------------------------ { - int lcid; // lcid index - int TTI = 1; - int bucketsizeduration = -1; - int bucketsizeduration_max = -1; - // mac_rlc_status_resp_t rlc_status[MAX_NUM_LCGID]; // 4 - // int8_t lcg_id; - struct LTE_RACH_ConfigCommon *rach_ConfigCommon = - (struct LTE_RACH_ConfigCommon *) NULL; - protocol_ctxt_t ctxt; - + int lcid; // lcid index + int TTI = 1; + int bucketsizeduration = -1; + int bucketsizeduration_max = -1; + // mac_rlc_status_resp_t rlc_status[MAX_NUM_LCGID]; // 4 + // int8_t lcg_id; + struct LTE_RACH_ConfigCommon *rach_ConfigCommon = + (struct LTE_RACH_ConfigCommon *) NULL; + protocol_ctxt_t ctxt; #if defined(ENABLE_ITTI) - MessageDef *msg_p; - int result; + MessageDef *msg_p; + int result; #endif #if UE_TIMING_TRACE - start_meas(&UE_mac_inst[module_idP].ue_scheduler); + start_meas(&UE_mac_inst[module_idP].ue_scheduler); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_IN); - - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_NO, - UE_mac_inst[module_idP].crnti, txFrameP, - txSubframeP, eNB_indexP); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_IN); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_NO, + UE_mac_inst[module_idP].crnti, txFrameP, + txSubframeP, eNB_indexP); #if defined(ENABLE_ITTI) - if(module_idP == 0){ - do { - // Checks if a message has been sent to MAC sub-task - itti_poll_msg(TASK_MAC_UE, &msg_p); - - if (msg_p != NULL) { - - switch (ITTI_MSG_ID(msg_p)) { - case RRC_MAC_CCCH_DATA_REQ: - LOG_I(MAC, - "Received %s from %s: instance %d, frameP %d, eNB_index %d\n", - ITTI_MSG_NAME(msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), ITTI_MSG_INSTANCE(msg_p), - RRC_MAC_CCCH_DATA_REQ(msg_p).frame, - RRC_MAC_CCCH_DATA_REQ(msg_p).enb_index); - - // TODO process CCCH data req. - break; - - - default: - LOG_E(MAC, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p)); - break; - } - - result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - AssertFatal(result == EXIT_SUCCESS, - "Failed to free memory (%d)!\n", result); - } + + if(module_idP == 0) { + do { + // Checks if a message has been sent to MAC sub-task + itti_poll_msg(TASK_MAC_UE, &msg_p); + + if (msg_p != NULL) { + switch (ITTI_MSG_ID(msg_p)) { + case RRC_MAC_CCCH_DATA_REQ: + LOG_I(MAC, + "Received %s from %s: instance %d, frameP %d, eNB_index %d\n", + ITTI_MSG_NAME(msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), ITTI_MSG_INSTANCE(msg_p), + RRC_MAC_CCCH_DATA_REQ(msg_p).frame, + RRC_MAC_CCCH_DATA_REQ(msg_p).enb_index); + // TODO process CCCH data req. + break; + + default: + LOG_E(MAC, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p)); + break; + } + + result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal(result == EXIT_SUCCESS, + "Failed to free memory (%d)!\n", result); } - while (msg_p != NULL); - } + } while (msg_p != NULL); + } + #endif - //Mac_rlc_xface->frameP=frameP; - //Rrc_xface->Frame_index=Mac_rlc_xface->frameP; - //if (subframe%5 == 0) - //LG#ifdef EXMIMO + //Mac_rlc_xface->frameP=frameP; + //Rrc_xface->Frame_index=Mac_rlc_xface->frameP; + //if (subframe%5 == 0) + //LG#ifdef EXMIMO - // data to/from NETLINK is treated in pdcp_run. - // one socket is used in multiple UE's L2 FAPI simulator and - // only first UE need to do this. - if(module_idP == 0){ + // data to/from NETLINK is treated in pdcp_run. + // one socket is used in multiple UE's L2 FAPI simulator and + // only first UE need to do this. + if (UE_NAS_USE_TUN) { + pdcp_run(&ctxt); + } else { + if(module_idP == 0) { pdcp_run(&ctxt); } - //#endif - UE_mac_inst[module_idP].txFrame = txFrameP; - UE_mac_inst[module_idP].txSubframe = txSubframeP; - UE_mac_inst[module_idP].rxFrame = rxFrameP; - UE_mac_inst[module_idP].rxSubframe = rxSubframeP; + } + //#endif + UE_mac_inst[module_idP].txFrame = txFrameP; + UE_mac_inst[module_idP].txSubframe = txSubframeP; + UE_mac_inst[module_idP].rxFrame = rxFrameP; + UE_mac_inst[module_idP].rxSubframe = rxSubframeP; #ifdef CELLULAR - rrc_rx_tx_ue(module_idP, txFrameP, 0, eNB_indexP); + rrc_rx_tx_ue(module_idP, txFrameP, 0, eNB_indexP); #else - switch (rrc_rx_tx_ue(&ctxt, eNB_indexP, CC_id)) { + switch (rrc_rx_tx_ue(&ctxt, eNB_indexP, CC_id)) { case RRC_OK: - break; + break; case RRC_ConnSetup_failed: - LOG_E(MAC, "RRCConnectionSetup failed, returning to IDLE state\n"); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT); + LOG_E(MAC, "RRCConnectionSetup failed, returning to IDLE state\n"); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].ue_scheduler); + stop_meas(&UE_mac_inst[module_idP].ue_scheduler); #endif - return (CONNECTION_LOST); - break; + return (CONNECTION_LOST); + break; case RRC_PHY_RESYNCH: - LOG_E(MAC, "RRC Loss of synch, returning PHY_RESYNCH\n"); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT); + LOG_E(MAC, "RRC Loss of synch, returning PHY_RESYNCH\n"); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].ue_scheduler); + stop_meas(&UE_mac_inst[module_idP].ue_scheduler); #endif - return (PHY_RESYNCH); + return (PHY_RESYNCH); case RRC_Handover_failed: - LOG_I(MAC, "Handover failure for UE %d eNB_index %d\n", module_idP, - eNB_indexP); - //Invalid...need to add another MAC UE state for re-connection procedure - phy_config_afterHO_ue(module_idP, 0, eNB_indexP, - (LTE_MobilityControlInfo_t *) NULL, 1); - //return(3); - break; + LOG_I(MAC, "Handover failure for UE %d eNB_index %d\n", module_idP, + eNB_indexP); + //Invalid...need to add another MAC UE state for re-connection procedure + phy_config_afterHO_ue(module_idP, 0, eNB_indexP, + (LTE_MobilityControlInfo_t *) NULL, 1); + //return(3); + break; case RRC_HO_STARTED: - LOG_I(MAC, - "RRC handover, Instruct PHY to start the contention-free PRACH and synchronization\n"); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT); + LOG_I(MAC, + "RRC handover, Instruct PHY to start the contention-free PRACH and synchronization\n"); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].ue_scheduler); + stop_meas(&UE_mac_inst[module_idP].ue_scheduler); #endif - return (PHY_HO_PRACH); + return (PHY_HO_PRACH); default: - break; - } + break; + } #endif - // Check Contention resolution timer (put in a function later) - if (UE_mac_inst[module_idP].RA_contention_resolution_timer_active == 1) { - - if (UE_mac_inst[module_idP].radioResourceConfigCommon) { - rach_ConfigCommon = - &UE_mac_inst[module_idP]. - radioResourceConfigCommon->rach_ConfigCommon; - } else { - LOG_E(MAC, "FATAL: radioResourceConfigCommon is NULL!!!\n"); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, - VCD_FUNCTION_OUT); - - stop_meas(&UE_mac_inst[module_idP].ue_scheduler); - AssertFatal(1 == 0, ""); - + // Check Contention resolution timer (put in a function later) + if (UE_mac_inst[module_idP].RA_contention_resolution_timer_active == 1) { + if (UE_mac_inst[module_idP].radioResourceConfigCommon) { + rach_ConfigCommon = + &UE_mac_inst[module_idP]. + radioResourceConfigCommon->rach_ConfigCommon; + } else { + LOG_E(MAC, "FATAL: radioResourceConfigCommon is NULL!!!\n"); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, + VCD_FUNCTION_OUT); + stop_meas(&UE_mac_inst[module_idP].ue_scheduler); + AssertFatal(1 == 0, ""); #if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].ue_scheduler); + stop_meas(&UE_mac_inst[module_idP].ue_scheduler); #endif + //return(RRC_OK); + } + + LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n", + txFrameP, + UE_mac_inst[module_idP].RA_contention_resolution_cnt, + ((1 + + rach_ConfigCommon-> + ra_SupervisionInfo.mac_ContentionResolutionTimer) << 3)); + UE_mac_inst[module_idP].RA_contention_resolution_cnt++; + + if (UE_mac_inst[module_idP].RA_contention_resolution_cnt == + ((1 + + rach_ConfigCommon-> + ra_SupervisionInfo.mac_ContentionResolutionTimer) << 3)) { + UE_mac_inst[module_idP].RA_active = 0; + UE_mac_inst[module_idP].RA_contention_resolution_timer_active = + 0; + // Signal PHY to quit RA procedure + LOG_E(MAC, + "Module id %u Contention resolution timer expired, RA failed\n", + module_idP); + + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode + // Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to + // PRACH state. + LOG_I(MAC, "nfapi_mode3: Setting UE_mode to PRACH 2 \n"); + UE_mac_inst[module_idP].UE_mode[eNB_indexP] = PRACH; + //ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; + } else { + ra_failed(module_idP, CC_id, eNB_indexP); + } - //return(RRC_OK); - } - - LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n", - txFrameP, - UE_mac_inst[module_idP].RA_contention_resolution_cnt, - ((1 + - rach_ConfigCommon-> - ra_SupervisionInfo.mac_ContentionResolutionTimer) << 3)); - - UE_mac_inst[module_idP].RA_contention_resolution_cnt++; - - if (UE_mac_inst[module_idP].RA_contention_resolution_cnt == - ((1 + - rach_ConfigCommon-> - ra_SupervisionInfo.mac_ContentionResolutionTimer) << 3)) { - UE_mac_inst[module_idP].RA_active = 0; - UE_mac_inst[module_idP].RA_contention_resolution_timer_active = - 0; - // Signal PHY to quit RA procedure - LOG_E(MAC, - "Module id %u Contention resolution timer expired, RA failed\n", - module_idP); - if(nfapi_mode == 3) { // phy_stub mode - // Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to - // PRACH state. - LOG_I(MAC, "nfapi_mode3: Setting UE_mode to PRACH 2 \n"); - UE_mac_inst[module_idP].UE_mode[eNB_indexP] = PRACH; - //ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0; - } - else{ - ra_failed(module_idP, CC_id, eNB_indexP); - } - //ra_failed(module_idP, 0, eNB_indexP); - } - } - // Get RLC status info and update Bj for all lcids that are active - for (lcid = DCCH; lcid < MAX_NUM_LCID; lcid++) { - if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]) { - // meausre the Bj - if ((directionP == SF_UL) - && (UE_mac_inst[module_idP].scheduling_info.Bj[lcid] >= 0)) { - if (UE_mac_inst[module_idP]. - logicalChannelConfig[lcid]->ul_SpecificParameters) { - bucketsizeduration = - UE_mac_inst[module_idP].logicalChannelConfig - [lcid]->ul_SpecificParameters->prioritisedBitRate * - TTI; - bucketsizeduration_max = - get_ms_bucketsizeduration(UE_mac_inst - [module_idP].logicalChannelConfig - [lcid]->ul_SpecificParameters->bucketSizeDuration); - } else { - LOG_E(MAC, - "[UE %d] lcid %d, NULL ul_SpecificParameters\n", - module_idP, lcid); - AssertFatal(1 == 0, ""); - } - - if (UE_mac_inst[module_idP].scheduling_info.Bj[lcid] > - bucketsizeduration_max) { - UE_mac_inst[module_idP].scheduling_info.Bj[lcid] = - bucketsizeduration_max; - } else { - UE_mac_inst[module_idP].scheduling_info.Bj[lcid] = - bucketsizeduration; - } - } - - - /* - if (lcid == DCCH) { - LOG_D(MAC,"[UE %d][SR] Frame %d subframe %d Pending data for SRB1=%d for LCGID %d \n", - module_idP, txFrameP,txSubframeP,UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]], - // UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]); - } - */ - } + //ra_failed(module_idP, 0, eNB_indexP); } + } + + // Get RLC status info and update Bj for all lcids that are active + for (lcid = DCCH; lcid < MAX_NUM_LCID; lcid++) { + if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]) { + // meausre the Bj + if ((directionP == SF_UL) + && (UE_mac_inst[module_idP].scheduling_info.Bj[lcid] >= 0)) { + if (UE_mac_inst[module_idP]. + logicalChannelConfig[lcid]->ul_SpecificParameters) { + bucketsizeduration = + UE_mac_inst[module_idP].logicalChannelConfig + [lcid]->ul_SpecificParameters->prioritisedBitRate * + TTI; + bucketsizeduration_max = + get_ms_bucketsizeduration(UE_mac_inst + [module_idP].logicalChannelConfig + [lcid]->ul_SpecificParameters->bucketSizeDuration); + } else { + LOG_E(MAC, + "[UE %d] lcid %d, NULL ul_SpecificParameters\n", + module_idP, lcid); + AssertFatal(1 == 0, ""); + } - // Call BSR procedure as described in Section 5.4.5 in 36.321 + if (UE_mac_inst[module_idP].scheduling_info.Bj[lcid] > + bucketsizeduration_max) { + UE_mac_inst[module_idP].scheduling_info.Bj[lcid] = + bucketsizeduration_max; + } else { + UE_mac_inst[module_idP].scheduling_info.Bj[lcid] = + bucketsizeduration; + } + } - // First check ReTxBSR Timer because it is always configured - // Decrement ReTxBSR Timer if it is running and not null - if ((UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != - MAC_UE_BSR_TIMER_NOT_RUNNING) - && (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != 0)) { - UE_mac_inst[module_idP].scheduling_info.retxBSR_SF--; - } - // Decrement Periodic Timer if it is running and not null - if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF != - MAC_UE_BSR_TIMER_NOT_RUNNING) - && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF != 0)) { - UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF--; - } - //Check whether Regular BSR is triggered - if (update_bsr(module_idP, txFrameP, txSubframeP, eNB_indexP) == TRUE) { - // call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures - // outlined in Sections 5.4.4 an 5.4.5 of 36.321 - UE_mac_inst[module_idP].scheduling_info.SR_pending = 1; - // Regular BSR trigger - UE_mac_inst[module_idP].BSR_reporting_active |= - BSR_TRIGGER_REGULAR; - LOG_D(MAC, - "[UE %d][BSR] Regular BSR Triggered Frame %d subframe %d SR for PUSCH is pending\n", - module_idP, txFrameP, txSubframeP); - } - // UE has no valid phy config dedicated || no valid/released SR - if ((UE_mac_inst[module_idP].physicalConfigDedicated == NULL)) { - // cancel all pending SRs - UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; - UE_mac_inst[module_idP].ul_active = 0; - LOG_T(MAC, "[UE %d] Release all SRs \n", module_idP); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT); -#if UE_TIMING_TRACE - stop_meas(&UE_mac_inst[module_idP].ue_scheduler); -#endif - return (CONNECTION_OK); + /* + if (lcid == DCCH) { + LOG_D(MAC,"[UE %d][SR] Frame %d subframe %d Pending data for SRB1=%d for LCGID %d \n", + module_idP, txFrameP,txSubframeP,UE_mac_inst[module_idP].scheduling_info.BSR[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]], + // UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]); + } + */ } + } - if ((UE_mac_inst[module_idP]. - physicalConfigDedicated->schedulingRequestConfig == NULL) - || (UE_mac_inst[module_idP]. - physicalConfigDedicated->schedulingRequestConfig->present == - LTE_SchedulingRequestConfig_PR_release)) { + // Call BSR procedure as described in Section 5.4.5 in 36.321 - // initiate RA with CRNTI included in msg3 (no contention) as descibed in 36.321 sec 5.1.5 + // First check ReTxBSR Timer because it is always configured + // Decrement ReTxBSR Timer if it is running and not null + if ((UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != + MAC_UE_BSR_TIMER_NOT_RUNNING) + && (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != 0)) { + UE_mac_inst[module_idP].scheduling_info.retxBSR_SF--; + } - // cancel all pending SRs - UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; - UE_mac_inst[module_idP].ul_active = 0; - LOG_T(MAC, "[UE %d] Release all SRs \n", module_idP); - } - // Put this in a function - // Call PHR procedure as described in Section 5.4.6 in 36.321 - if (UE_mac_inst[module_idP].PHR_state == LTE_MAC_MainConfig__phr_Config_PR_setup) { // normal operation - - if (UE_mac_inst[module_idP].PHR_reconfigured == 1) { // upon (re)configuration of the power headroom reporting functionality by upper layers - UE_mac_inst[module_idP].PHR_reporting_active = 1; - UE_mac_inst[module_idP].PHR_reconfigured = 0; - } else { - //LOG_D(MAC,"PHR normal operation %d active %d \n", UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF, UE_mac_inst[module_idP].PHR_reporting_active); - if ((UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF <= - 0) - && - ((get_PL(module_idP, 0, eNB_indexP) < - UE_mac_inst[module_idP].scheduling_info. - PathlossChange_db) - || (UE_mac_inst[module_idP].power_backoff_db[eNB_indexP] > - UE_mac_inst[module_idP]. - scheduling_info.PathlossChange_db))) - // trigger PHR and reset the timer later when the PHR report is sent - { - UE_mac_inst[module_idP].PHR_reporting_active = 1; - } else if (UE_mac_inst[module_idP].PHR_reporting_active == 0) { - UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF--; - } - - if (UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF <= - 0) - // trigger PHR and reset the timer later when the PHR report is sent - { - UE_mac_inst[module_idP].PHR_reporting_active = 1; - } else if (UE_mac_inst[module_idP].PHR_reporting_active == 0) { - UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF--; - } - } - } else { // release / nothing - UE_mac_inst[module_idP].PHR_reporting_active = 0; // release PHR - } + // Decrement Periodic Timer if it is running and not null + if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF != + MAC_UE_BSR_TIMER_NOT_RUNNING) + && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF != 0)) { + UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF--; + } + + //Check whether Regular BSR is triggered + if (update_bsr(module_idP, txFrameP, txSubframeP, eNB_indexP) == TRUE) { + // call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures + // outlined in Sections 5.4.4 an 5.4.5 of 36.321 + UE_mac_inst[module_idP].scheduling_info.SR_pending = 1; + // Regular BSR trigger + UE_mac_inst[module_idP].BSR_reporting_active |= + BSR_TRIGGER_REGULAR; + LOG_D(MAC, + "[UE %d][BSR] Regular BSR Triggered Frame %d subframe %d SR for PUSCH is pending\n", + module_idP, txFrameP, txSubframeP); + } - //If the UE has UL resources allocated for new transmission for this TTI here: + // UE has no valid phy config dedicated || no valid/released SR + if ((UE_mac_inst[module_idP].physicalConfigDedicated == NULL)) { + // cancel all pending SRs + UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; + UE_mac_inst[module_idP].ul_active = 0; + LOG_T(MAC, "[UE %d] Release all SRs \n", module_idP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT); + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE stop_meas(&UE_mac_inst[module_idP].ue_scheduler); #endif return (CONNECTION_OK); + } + + if ((UE_mac_inst[module_idP]. + physicalConfigDedicated->schedulingRequestConfig == NULL) + || (UE_mac_inst[module_idP]. + physicalConfigDedicated->schedulingRequestConfig->present == + LTE_SchedulingRequestConfig_PR_release)) { + // initiate RA with CRNTI included in msg3 (no contention) as descibed in 36.321 sec 5.1.5 + // cancel all pending SRs + UE_mac_inst[module_idP].scheduling_info.SR_pending = 0; + UE_mac_inst[module_idP].ul_active = 0; + LOG_T(MAC, "[UE %d] Release all SRs \n", module_idP); + } + + // Put this in a function + // Call PHR procedure as described in Section 5.4.6 in 36.321 + if (UE_mac_inst[module_idP].PHR_state == LTE_MAC_MainConfig__phr_Config_PR_setup) { // normal operation + if (UE_mac_inst[module_idP].PHR_reconfigured == 1) { // upon (re)configuration of the power headroom reporting functionality by upper layers + UE_mac_inst[module_idP].PHR_reporting_active = 1; + UE_mac_inst[module_idP].PHR_reconfigured = 0; + } else { + //LOG_D(MAC,"PHR normal operation %d active %d \n", UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF, UE_mac_inst[module_idP].PHR_reporting_active); + if ((UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF <= + 0) + && + ((get_PL(module_idP, 0, eNB_indexP) < + UE_mac_inst[module_idP].scheduling_info. + PathlossChange_db) + || (UE_mac_inst[module_idP].power_backoff_db[eNB_indexP] > + UE_mac_inst[module_idP]. + scheduling_info.PathlossChange_db))) + // trigger PHR and reset the timer later when the PHR report is sent + { + UE_mac_inst[module_idP].PHR_reporting_active = 1; + } else if (UE_mac_inst[module_idP].PHR_reporting_active == 0) { + UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF--; + } + + if (UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF <= + 0) + // trigger PHR and reset the timer later when the PHR report is sent + { + UE_mac_inst[module_idP].PHR_reporting_active = 1; + } else if (UE_mac_inst[module_idP].PHR_reporting_active == 0) { + UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF--; + } + } + } else { // release / nothing + UE_mac_inst[module_idP].PHR_reporting_active = 0; // release PHR + } + + //If the UE has UL resources allocated for new transmission for this TTI here: + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT); +#if UE_TIMING_TRACE + stop_meas(&UE_mac_inst[module_idP].ue_scheduler); +#endif + return (CONNECTION_OK); } // to be improved #ifdef CBA extern int cba_backoff; -double uniform_rngen(int min, int max) -{ - double random = (double) taus() / ((double) 0xffffffff); - return (max - min) * random + min; +double uniform_rngen(int min, int max) { + double random = (double) taus() / ((double) 0xffffffff); + return (max - min) * random + min; } int cba_access(module_id_t module_idP, frame_t frameP, - sub_frame_t subframe, uint8_t eNB_index, uint16_t buflen) -{ - - mac_rlc_status_resp_t rlc_status; - int header_offset = 4; - int rv = 0; - - /* - if (( ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]<64)) || - ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]<64)) || - ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]<64)) ) - // && (UE_mac_inst[module_idP].ul_active == 0) // check if the ul is acrtive - && (UE_mac_inst[module_idP].cba_last_access[0] <= 0) ) { // backoff - // LOG_D(MAC,"[UE %d] Frame %d Subframe %d: the current CBA backoff is %d \n", module_idP, frameP, subframe, - // UE_mac_inst[module_idP].cba_last_access[0] ); - - UE_mac_inst[module_idP].cba_last_access[0]= round(uniform_rngen(1,40)); - LOG_D(MAC,"[UE %d] Frame %d Subframe %d: start a new CBA backoff %d UL active state %d \n", module_idP, frameP, subframe, - UE_mac_inst[module_idP].cba_last_access[0], UE_mac_inst[module_idP].ul_active); - - rv=1; - } else if (( ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]> 0 )) || - ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]> 0 )) || - ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]> 0 )) ) - // && (UE_mac_inst[module_idP].ul_active == 0) // check if the ul is acrtive - && (UE_mac_inst[module_idP].cba_last_access[0]> 0) ){ - - UE_mac_inst[module_idP].cba_last_access[0]-=1; - LOG_D(MAC,"[UE %d] Frame %d Subframe %d: CBA backoff is decreased by one to %d UL active state %d \n", - module_idP, frameP, subframe, - UE_mac_inst[module_idP].cba_last_access[0], UE_mac_inst[module_idP].ul_active); - - } else if (( ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1] == 0 )) && - ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2] == 0 )) && - ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3] == 0 )) ) - && (UE_mac_inst[module_idP].cba_last_access[0]> 0) ){ - UE_mac_inst[module_idP].cba_last_access[0]-=1; - } */ - - if ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0] > 0) - && (UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0] < 64)) { - return 0; - } - - if ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1] <= 0) && - (UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2] <= 0) && - (UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3] <= 0)) { - return 0; - } + sub_frame_t subframe, uint8_t eNB_index, uint16_t buflen) { + mac_rlc_status_resp_t rlc_status; + int header_offset = 4; + int rv = 0; + + /* + if (( ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]<64)) || + ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]<64)) || + ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]<64)) ) + // && (UE_mac_inst[module_idP].ul_active == 0) // check if the ul is acrtive + && (UE_mac_inst[module_idP].cba_last_access[0] <= 0) ) { // backoff + // LOG_D(MAC,"[UE %d] Frame %d Subframe %d: the current CBA backoff is %d \n", module_idP, frameP, subframe, + // UE_mac_inst[module_idP].cba_last_access[0] ); + + UE_mac_inst[module_idP].cba_last_access[0]= round(uniform_rngen(1,40)); + LOG_D(MAC,"[UE %d] Frame %d Subframe %d: start a new CBA backoff %d UL active state %d \n", module_idP, frameP, subframe, + UE_mac_inst[module_idP].cba_last_access[0], UE_mac_inst[module_idP].ul_active); + + rv=1; + } else if (( ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]> 0 )) || + ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]> 0 )) || + ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]> 0 )) ) + // && (UE_mac_inst[module_idP].ul_active == 0) // check if the ul is acrtive + && (UE_mac_inst[module_idP].cba_last_access[0]> 0) ){ + + UE_mac_inst[module_idP].cba_last_access[0]-=1; + LOG_D(MAC,"[UE %d] Frame %d Subframe %d: CBA backoff is decreased by one to %d UL active state %d \n", + module_idP, frameP, subframe, + UE_mac_inst[module_idP].cba_last_access[0], UE_mac_inst[module_idP].ul_active); + + } else if (( ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1] == 0 )) && + ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2] == 0 )) && + ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3] == 0 )) ) + && (UE_mac_inst[module_idP].cba_last_access[0]> 0) ){ + UE_mac_inst[module_idP].cba_last_access[0]-=1; + } */ + + if ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0] > 0) + && (UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0] < 64)) { + return 0; + } - if (cba_backoff == 0) { // apply probablisitc method - UE_mac_inst[module_idP].cba_last_access[0] = uniform_rngen(0, 1); + if ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1] <= 0) && + (UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2] <= 0) && + (UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3] <= 0)) { + return 0; + } - if (uniform_rngen(0, 1) > 0.6) { - LOG_I(MAC, - "[UE %d] Frame %d Subframe %d: CBA probability-based backoff (%d), UL active state %d \n", - module_idP, frameP, subframe, cba_backoff, - UE_mac_inst[module_idP].ul_active); + if (cba_backoff == 0) { // apply probablisitc method + UE_mac_inst[module_idP].cba_last_access[0] = uniform_rngen(0, 1); - rv = 1; - } + if (uniform_rngen(0, 1) > 0.6) { + LOG_I(MAC, + "[UE %d] Frame %d Subframe %d: CBA probability-based backoff (%d), UL active state %d \n", + module_idP, frameP, subframe, cba_backoff, + UE_mac_inst[module_idP].ul_active); + rv = 1; + } + } else { + if (UE_mac_inst[module_idP].cba_last_access[0] <= 0) { + UE_mac_inst[module_idP].cba_last_access[0] = + round(uniform_rngen(1, cba_backoff)); + LOG_I(MAC, + "[UE %d] Frame %d Subframe %d: start a new CBA backoff %d/%d UL active state %d \n", + module_idP, frameP, subframe, + UE_mac_inst[module_idP].cba_last_access[0], cba_backoff, + UE_mac_inst[module_idP].ul_active); + rv = 1; + /* + rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, // eNB_index + DTCH, + 0); + + if (( + // (rlc_status.pdus_in_buffer > 0 ) && + // (UE_mac_inst[module_idP].ul_active == 0) && // check if the ul is acrtive + (rlc_status.head_sdu_is_segmented == 0 ) && + ((rlc_status.head_sdu_remaining_size_to_send + header_offset ) <= buflen ) + )){ + rv = 1; + + UE_mac_inst[module_idP].cba_last_access[0]= round(uniform_rngen(1,30)); + LOG_D(MAC,"[UE %d] Frame %d Subframe %d: start a new CBA backoff %d UL active state %d \n", module_idP, frameP, subframe, + UE_mac_inst[module_idP].cba_last_access[0], UE_mac_inst[module_idP].ul_active); + */ } else { - - if (UE_mac_inst[module_idP].cba_last_access[0] <= 0) { - UE_mac_inst[module_idP].cba_last_access[0] = - round(uniform_rngen(1, cba_backoff)); - - LOG_I(MAC, - "[UE %d] Frame %d Subframe %d: start a new CBA backoff %d/%d UL active state %d \n", - module_idP, frameP, subframe, - UE_mac_inst[module_idP].cba_last_access[0], cba_backoff, - UE_mac_inst[module_idP].ul_active); - - rv = 1; - /* - rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, // eNB_index - DTCH, - 0); - - if (( - // (rlc_status.pdus_in_buffer > 0 ) && - // (UE_mac_inst[module_idP].ul_active == 0) && // check if the ul is acrtive - (rlc_status.head_sdu_is_segmented == 0 ) && - ((rlc_status.head_sdu_remaining_size_to_send + header_offset ) <= buflen ) - )){ - rv = 1; - - UE_mac_inst[module_idP].cba_last_access[0]= round(uniform_rngen(1,30)); - LOG_D(MAC,"[UE %d] Frame %d Subframe %d: start a new CBA backoff %d UL active state %d \n", module_idP, frameP, subframe, - UE_mac_inst[module_idP].cba_last_access[0], UE_mac_inst[module_idP].ul_active); - */ - } else { - UE_mac_inst[module_idP].cba_last_access[0] -= 1; - LOG_D(MAC, - "[UE %d] Frame %d Subframe %d: wait for backoff to expire (%d) CBA UL active state %d \n", - module_idP, frameP, subframe, - UE_mac_inst[module_idP].cba_last_access[0], - UE_mac_inst[module_idP].ul_active); - } + UE_mac_inst[module_idP].cba_last_access[0] -= 1; + LOG_D(MAC, + "[UE %d] Frame %d Subframe %d: wait for backoff to expire (%d) CBA UL active state %d \n", + module_idP, frameP, subframe, + UE_mac_inst[module_idP].cba_last_access[0], + UE_mac_inst[module_idP].ul_active); } + } - return rv; - /* - if (( ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]<64)) || - ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]<64)) || - ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]<64)) ) - // && (UE_mac_inst[module_idP].ul_active == 0) // check if the ul is acrtive - && (UE_mac_inst[module_idP].cba_last_access[0] <= 0) ) { - - UE_mac_inst[module_idP].cba_last_access[0]= round(uniform_rngen(1,cba_backoff)); - - LOG_I(MAC,"[UE %d] Frame %d Subframe %d: start a new CBA backoff %d/%d UL active state %d \n", module_idP, frameP, subframe, - UE_mac_inst[module_idP].cba_last_access[0], cba_backoff,UE_mac_inst[module_idP].ul_active); - - rv = 1; - - rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, // eNB_index - DTCH, - 0); - - if (( - // (rlc_status.pdus_in_buffer > 0 ) && - // (UE_mac_inst[module_idP].ul_active == 0) && // check if the ul is acrtive - (rlc_status.head_sdu_is_segmented == 0 ) && - ((rlc_status.head_sdu_remaining_size_to_send + header_offset ) <= buflen ) - )){ - rv = 1; - - UE_mac_inst[module_idP].cba_last_access[0]= round(uniform_rngen(1,30)); - LOG_D(MAC,"[UE %d] Frame %d Subframe %d: start a new CBA backoff %d UL active state %d \n", module_idP, frameP, subframe, - UE_mac_inst[module_idP].cba_last_access[0], UE_mac_inst[module_idP].ul_active); - } else - UE_mac_inst[module_idP].cba_last_access[0]= round(uniform_rngen(1,5)); - - - } else if (( ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]> 0 )) || - ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]> 0 )) || - ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]> 0 )) ) - // && (UE_mac_inst[module_idP].ul_active == 0) // check if the ul is acrtive - && (UE_mac_inst[module_idP].cba_last_access[0]> 0) ) - { - - UE_mac_inst[module_idP].cba_last_access[0]-=1; - LOG_D(MAC,"[UE %d] Frame %d Subframe %d: wait for backoff to expire (%d) CBA UL active state %d \n", - module_idP, frameP, subframe, - UE_mac_inst[module_idP].cba_last_access[0], UE_mac_inst[module_idP].ul_active); - } - } - */ - + return rv; + /* + if (( ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]<64)) || + ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]<64)) || + ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]>0)&&(UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]<64)) ) + // && (UE_mac_inst[module_idP].ul_active == 0) // check if the ul is acrtive + && (UE_mac_inst[module_idP].cba_last_access[0] <= 0) ) { + + UE_mac_inst[module_idP].cba_last_access[0]= round(uniform_rngen(1,cba_backoff)); + + LOG_I(MAC,"[UE %d] Frame %d Subframe %d: start a new CBA backoff %d/%d UL active state %d \n", module_idP, frameP, subframe, + UE_mac_inst[module_idP].cba_last_access[0], cba_backoff,UE_mac_inst[module_idP].ul_active); + + rv = 1; + + rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, // eNB_index + DTCH, + 0); + + if (( + // (rlc_status.pdus_in_buffer > 0 ) && + // (UE_mac_inst[module_idP].ul_active == 0) && // check if the ul is acrtive + (rlc_status.head_sdu_is_segmented == 0 ) && + ((rlc_status.head_sdu_remaining_size_to_send + header_offset ) <= buflen ) + )){ + rv = 1; + + UE_mac_inst[module_idP].cba_last_access[0]= round(uniform_rngen(1,30)); + LOG_D(MAC,"[UE %d] Frame %d Subframe %d: start a new CBA backoff %d UL active state %d \n", module_idP, frameP, subframe, + UE_mac_inst[module_idP].cba_last_access[0], UE_mac_inst[module_idP].ul_active); + } else + UE_mac_inst[module_idP].cba_last_access[0]= round(uniform_rngen(1,5)); + + + } else if (( ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1]> 0 )) || + ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2]> 0 )) || + ((UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]> 0 )) ) + // && (UE_mac_inst[module_idP].ul_active == 0) // check if the ul is acrtive + && (UE_mac_inst[module_idP].cba_last_access[0]> 0) ) + { + + UE_mac_inst[module_idP].cba_last_access[0]-=1; + LOG_D(MAC,"[UE %d] Frame %d Subframe %d: wait for backoff to expire (%d) CBA UL active state %d \n", + module_idP, frameP, subframe, + UE_mac_inst[module_idP].cba_last_access[0], UE_mac_inst[module_idP].ul_active); + } + } + */ } #endif boolean_t update_bsr(module_id_t module_idP, frame_t frameP, - sub_frame_t subframeP, eNB_index_t eNB_index) -{ - + sub_frame_t subframeP, eNB_index_t eNB_index) { mac_rlc_status_resp_t rlc_status; boolean_t bsr_regular_triggered = FALSE; uint8_t lcid; @@ -3057,537 +2991,493 @@ update_bsr(module_id_t module_idP, frame_t frameP, uint8_t pos_next = 0; uint8_t highest_priority = 16; uint8_t array_index = 0; - // Reset All BSR Infos lcid_bytes_in_buffer[0] = 0; - for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++) - { - // Reset transmission status - lcid_bytes_in_buffer[lcid] = 0; - UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid]=LCID_EMPTY; + + for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++) { + // Reset transmission status + lcid_bytes_in_buffer[lcid] = 0; + UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid]=LCID_EMPTY; } - for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++) - { - // Reset Buffer Info - UE_mac_inst[module_idP].scheduling_info.BSR[lcgid]=0; - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid]=0; + for (lcgid=0; lcgid < MAX_NUM_LCGID; lcgid++) { + // Reset Buffer Info + UE_mac_inst[module_idP].scheduling_info.BSR[lcgid]=0; + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid]=0; } //Get Buffer Occupancy and fill lcid_reordered_array - for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++) - { - if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]) - { - lcgid = UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]; - - // Store already available data to transmit per Group - if (lcgid < MAX_NUM_LCGID) - { - lcgid_buffer_remain[lcgid] += UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]; - } - - rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, - lcid, - 0xFFFF //TBS is not used in RLC at this step, set a special value for debug + for (lcid=DCCH; lcid < MAX_NUM_LCID; lcid++) { + if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]) { + lcgid = UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]; + + // Store already available data to transmit per Group + if (lcgid < MAX_NUM_LCGID) { + lcgid_buffer_remain[lcgid] += UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]; + } + + rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, + lcid, + 0xFFFF //TBS is not used in RLC at this step, set a special value for debug #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + ,0, 0 #endif - ); - - lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer; - - if (rlc_status.bytes_in_buffer > 0) - { - LOG_D(MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d subframe %d\n", - module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,subframeP); - - UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY; - //Update BSR_bytes and position in lcid_reordered_array only if Group is defined - if (lcgid < MAX_NUM_LCGID) - { - num_lcid_with_data ++; - // sum lcid buffer which has same lcgid - UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer; - - //Fill in the array - array_index = 0; - do - { - if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority) - { - //Insert if priority is higher or equal (lower or equal in value) - for (pos_next=num_lcid_with_data-1; pos_next > array_index; pos_next--) - { - lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1]; - - } - lcid_reordered_array[array_index] = lcid; - break; - - } - array_index ++; - } - while ((array_index < num_lcid_with_data) && (array_index < MAX_NUM_LCID)); - } - } - } + ); + lcid_bytes_in_buffer[lcid] = rlc_status.bytes_in_buffer; + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC,"[UE %d] PDCCH Tick : LCID%d LCGID%d has data to transmit =%d bytes at frame %d subframe %d\n", + module_idP, lcid,lcgid,rlc_status.bytes_in_buffer,frameP,subframeP); + UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_NOT_EMPTY; + + //Update BSR_bytes and position in lcid_reordered_array only if Group is defined + if (lcgid < MAX_NUM_LCGID) { + num_lcid_with_data ++; + // sum lcid buffer which has same lcgid + UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcgid] += rlc_status.bytes_in_buffer; + //Fill in the array + array_index = 0; + + do { + if (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority) { + //Insert if priority is higher or equal (lower or equal in value) + for (pos_next=num_lcid_with_data-1; pos_next > array_index; pos_next--) { + lcid_reordered_array[pos_next] = lcid_reordered_array[pos_next - 1]; + } - } + lcid_reordered_array[array_index] = lcid; + break; + } - // Check whether a regular BSR can be triggered according to the first cases in 36.321 - if (num_lcid_with_data) { - LOG_D(MAC, - "[UE %d] PDCCH Tick at frame %d subframe %d: NumLCID with data=%d Reordered LCID0=%d LCID1=%d LCID2=%d\n", - module_idP, frameP, subframeP, num_lcid_with_data, - lcid_reordered_array[0], lcid_reordered_array[1], - lcid_reordered_array[2]); - - for (array_index = 0; array_index < num_lcid_with_data; - array_index++) { - lcid = lcid_reordered_array[array_index]; - /* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity - either the data belongs to a logical channel with higher priority than the priorities of the logical channels - which belong to any LCG and for which data is already available for transmission - */ - if ((UE_mac_inst[module_idP]. - scheduling_info.LCID_buffer_remain[lcid] == 0) - /* or there is no data available for any of the logical channels which belong to a LCG */ - || - (lcgid_buffer_remain - [UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == - 0)) { - bsr_regular_triggered = TRUE; - - LOG_D(MAC, - "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d subframe %d\n", - module_idP, lcid, - UE_mac_inst[module_idP].scheduling_info.LCGID[lcid], - frameP, subframeP); - - break; - } - } - - // Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission - if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF == 0) { - bsr_regular_triggered = TRUE; - - if ((UE_mac_inst[module_idP].BSR_reporting_active & - BSR_TRIGGER_REGULAR) == 0) { - LOG_I(MAC, - "[UE %d] PDCCH Tick : MAC BSR Triggered ReTxBSR Timer expiry at frame %d subframe %d\n", - module_idP, frameP, subframeP); - } - - } - } - //Store Buffer Occupancy in remain buffers for next TTI - for (lcid = DCCH; lcid < MAX_NUM_LCID; lcid++) { - UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] = - lcid_bytes_in_buffer[lcid]; + array_index ++; + } while ((array_index < num_lcid_with_data) && (array_index < MAX_NUM_LCID)); + } + } } + } - return bsr_regular_triggered; -} - -uint8_t -locate_BsrIndexByBufferSize(const uint32_t * table, int size, int value) -{ - - uint8_t ju, jm, jl; - int ascend; + // Check whether a regular BSR can be triggered according to the first cases in 36.321 + if (num_lcid_with_data) { + LOG_D(MAC, + "[UE %d] PDCCH Tick at frame %d subframe %d: NumLCID with data=%d Reordered LCID0=%d LCID1=%d LCID2=%d\n", + module_idP, frameP, subframeP, num_lcid_with_data, + lcid_reordered_array[0], lcid_reordered_array[1], + lcid_reordered_array[2]); + + for (array_index = 0; array_index < num_lcid_with_data; + array_index++) { + lcid = lcid_reordered_array[array_index]; + + /* UL data, for a logical channel which belongs to a LCG, becomes available for transmission in the RLC entity + either the data belongs to a logical channel with higher priority than the priorities of the logical channels + which belong to any LCG and for which data is already available for transmission + */ + if ((UE_mac_inst[module_idP]. + scheduling_info.LCID_buffer_remain[lcid] == 0) + /* or there is no data available for any of the logical channels which belong to a LCG */ + || + (lcgid_buffer_remain + [UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == + 0)) { + bsr_regular_triggered = TRUE; + LOG_D(MAC, + "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d subframe %d\n", + module_idP, lcid, + UE_mac_inst[module_idP].scheduling_info.LCGID[lcid], + frameP, subframeP); + break; + } + } - DevAssert(size > 0); - DevAssert(size <= 256); + // Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission + if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF == 0) { + bsr_regular_triggered = TRUE; - if (value == 0) { - return 0; //elseif (value > 150000) return 63; + if ((UE_mac_inst[module_idP].BSR_reporting_active & + BSR_TRIGGER_REGULAR) == 0) { + LOG_I(MAC, + "[UE %d] PDCCH Tick : MAC BSR Triggered ReTxBSR Timer expiry at frame %d subframe %d\n", + module_idP, frameP, subframeP); + } } + } + + //Store Buffer Occupancy in remain buffers for next TTI + for (lcid = DCCH; lcid < MAX_NUM_LCID; lcid++) { + UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] = + lcid_bytes_in_buffer[lcid]; + } - jl = 0; // lower bound - ju = size - 1; // upper bound - ascend = (table[ju] >= table[jl]) ? 1 : 0; // determine the order of the the table: 1 if ascending order of table, 0 otherwise + return bsr_regular_triggered; +} - while (ju - jl > 1) { //If we are not yet done, - jm = (ju + jl) >> 1; //compute a midpoint, +uint8_t +locate_BsrIndexByBufferSize(const uint32_t *table, int size, int value) { + uint8_t ju, jm, jl; + int ascend; + DevAssert(size > 0); + DevAssert(size <= 256); + + if (value == 0) { + return 0; //elseif (value > 150000) return 63; + } - if ((value >= table[jm]) == ascend) { - jl = jm; // replace the lower limit - } else { - ju = jm; //replace the upper limit - } + jl = 0; // lower bound + ju = size - 1; // upper bound + ascend = (table[ju] >= table[jl]) ? 1 : 0; // determine the order of the the table: 1 if ascending order of table, 0 otherwise - LOG_T(MAC, - "[UE] searching BSR index %d for (BSR TABLE %d < value %d)\n", - jm, table[jm], value); - } + while (ju - jl > 1) { //If we are not yet done, + jm = (ju + jl) >> 1; //compute a midpoint, - if (value == table[jl]) { - return jl; + if ((value >= table[jm]) == ascend) { + jl = jm; // replace the lower limit } else { - return jl + 1; //equally ju + ju = jm; //replace the upper limit } -} + LOG_T(MAC, + "[UE] searching BSR index %d for (BSR TABLE %d < value %d)\n", + jm, table[jm], value); + } -int get_sf_periodicBSRTimer(uint8_t sf_offset) -{ + if (value == table[jl]) { + return jl; + } else { + return jl + 1; //equally ju + } +} - switch (sf_offset) { +int get_sf_periodicBSRTimer(uint8_t sf_offset) { + switch (sf_offset) { case LTE_PeriodicBSR_Timer_r12_sf5: - return 5; - break; + return 5; + break; case LTE_PeriodicBSR_Timer_r12_sf10: - return 10; - break; + return 10; + break; case LTE_PeriodicBSR_Timer_r12_sf16: - return 16; - break; + return 16; + break; case LTE_PeriodicBSR_Timer_r12_sf20: - return 20; - break; + return 20; + break; case LTE_PeriodicBSR_Timer_r12_sf32: - return 32; - break; + return 32; + break; case LTE_PeriodicBSR_Timer_r12_sf40: - return 40; - break; + return 40; + break; case LTE_PeriodicBSR_Timer_r12_sf64: - return 64; - break; + return 64; + break; case LTE_PeriodicBSR_Timer_r12_sf80: - return 80; - break; + return 80; + break; case LTE_PeriodicBSR_Timer_r12_sf128: - return 128; - break; + return 128; + break; case LTE_PeriodicBSR_Timer_r12_sf160: - return 160; - break; + return 160; + break; case LTE_PeriodicBSR_Timer_r12_sf320: - return 320; - break; + return 320; + break; case LTE_PeriodicBSR_Timer_r12_sf640: - return 640; - break; + return 640; + break; case LTE_PeriodicBSR_Timer_r12_sf1280: - return 1280; - break; + return 1280; + break; case LTE_PeriodicBSR_Timer_r12_sf2560: - return 2560; - break; + return 2560; + break; case LTE_PeriodicBSR_Timer_r12_infinity: default: - return 0xFFFF; - break; - } + return 0xFFFF; + break; + } } -int get_sf_retxBSRTimer(uint8_t sf_offset) -{ - - switch (sf_offset) { +int get_sf_retxBSRTimer(uint8_t sf_offset) { + switch (sf_offset) { case LTE_RetxBSR_Timer_r12_sf320: - return 320; - break; + return 320; + break; case LTE_RetxBSR_Timer_r12_sf640: - return 640; - break; + return 640; + break; case LTE_RetxBSR_Timer_r12_sf1280: - return 1280; - break; + return 1280; + break; case LTE_RetxBSR_Timer_r12_sf2560: - return 2560; - break; + return 2560; + break; case LTE_RetxBSR_Timer_r12_sf5120: - return 5120; - break; + return 5120; + break; case LTE_RetxBSR_Timer_r12_sf10240: - return 10240; - break; + return 10240; + break; default: - return -1; - break; - } + return -1; + break; + } } -int get_ms_bucketsizeduration(uint8_t bucketsizeduration) -{ - - switch (bucketsizeduration) { +int get_ms_bucketsizeduration(uint8_t bucketsizeduration) { + switch (bucketsizeduration) { case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50: - return - 50; - break; + return + 50; + break; case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100: - return - 100; - break; + return + 100; + break; case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms150: - return - 150; - break; + return + 150; + break; case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms300: - return - 300; - break; + return + 300; + break; case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms500: - return - 500; - break; + return + 500; + break; case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms1000: - return - 1000; - break; + return + 1000; + break; default: - return 0; - break; - } + return 0; + break; + } } -void update_phr(module_id_t module_idP, int CC_id) -{ - - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - - UE_mac_inst[module_idP].PHR_reporting_active = 0; - UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF = - get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP]. - scheduling_info.periodicPHR_Timer); - UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF = - get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP]. - scheduling_info.prohibitPHR_Timer); - // LOG_D(MAC,"phr %d %d\n ",UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF, UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF); +void update_phr(module_id_t module_idP, int CC_id) { + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); + UE_mac_inst[module_idP].PHR_reporting_active = 0; + UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF = + get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP]. + scheduling_info.periodicPHR_Timer); + UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF = + get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP]. + scheduling_info.prohibitPHR_Timer); + // LOG_D(MAC,"phr %d %d\n ",UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF, UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF); } uint8_t -get_phr_mapping(module_id_t module_idP, int CC_id, uint8_t eNB_index) -{ - - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); - - //power headroom reporting range is from -23 ...+40 dB, as described in 36313 - //note: mac_xface->get_Po_NOMINAL_PUSCH(module_idP) is float - if (get_PHR(module_idP, CC_id, eNB_index) < -23) { - return 0; - } else if (get_PHR(module_idP, CC_id, eNB_index) >= 40) { - return 63; - } else { // -23 to 40 - return (uint8_t) get_PHR(module_idP, CC_id, - eNB_index) + PHR_MAPPING_OFFSET; - - } +get_phr_mapping(module_id_t module_idP, int CC_id, uint8_t eNB_index) { + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); + + //power headroom reporting range is from -23 ...+40 dB, as described in 36313 + //note: mac_xface->get_Po_NOMINAL_PUSCH(module_idP) is float + if (get_PHR(module_idP, CC_id, eNB_index) < -23) { + return 0; + } else if (get_PHR(module_idP, CC_id, eNB_index) >= 40) { + return 63; + } else { // -23 to 40 + return (uint8_t) get_PHR(module_idP, CC_id, + eNB_index) + PHR_MAPPING_OFFSET; + } } -int get_sf_perioidicPHR_Timer(uint8_t perioidicPHR_Timer) -{ - return (perioidicPHR_Timer + 1) * 10; +int get_sf_perioidicPHR_Timer(uint8_t perioidicPHR_Timer) { + return (perioidicPHR_Timer + 1) * 10; } -int get_sf_prohibitPHR_Timer(uint8_t prohibitPHR_Timer) -{ - return (prohibitPHR_Timer) * 10; +int get_sf_prohibitPHR_Timer(uint8_t prohibitPHR_Timer) { + return (prohibitPHR_Timer) * 10; } -int get_db_dl_PathlossChange(uint8_t dl_PathlossChange) -{ - switch (dl_PathlossChange) { +int get_db_dl_PathlossChange(uint8_t dl_PathlossChange) { + switch (dl_PathlossChange) { case LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1: - return 1; - break; + return 1; + break; case LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3: - return 3; - break; + return 3; + break; case LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB6: - return 6; - break; + return 6; + break; case LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_infinity: default: - return -1; - break; - } + return -1; + break; + } } SLSS_t *ue_get_slss(module_id_t Mod_id,int CC_id,frame_t frame_tx,sub_frame_t subframe_tx) { - - return((SLSS_t*)NULL); + return((SLSS_t *)NULL); } SLDCH_t *ue_get_sldch(module_id_t Mod_id,int CC_id,frame_t frame_tx,sub_frame_t subframe_tx) { - - //UE_MAC_INST *ue = &UE_mac_inst[Mod_id]; - SLDCH_t *sldch = &UE_mac_inst[Mod_id].sldch; - - sldch->payload_length = mac_rrc_data_req_ue(Mod_id, - CC_id, - frame_tx, - SL_DISCOVERY, - 1, - (uint8_t*)(sldch->payload), //&UE_mac_inst[Mod_id].SL_Discovery[0].Tx_buffer.Payload[0], - 0, //eNB_indexP - 0); - - - - if (sldch->payload_length >0 ) { - LOG_I(MAC,"Got %d bytes from RRC for SLDCH @ %p\n",sldch->payload_length,sldch); - return (sldch); - } - else - - return((SLDCH_t*)NULL); + //UE_MAC_INST *ue = &UE_mac_inst[Mod_id]; + SLDCH_t *sldch = &UE_mac_inst[Mod_id].sldch; + sldch->payload_length = mac_rrc_data_req_ue(Mod_id, + CC_id, + frame_tx, + SL_DISCOVERY, + 1, + (uint8_t *)(sldch->payload), //&UE_mac_inst[Mod_id].SL_Discovery[0].Tx_buffer.Payload[0], + 0, //eNB_indexP + 0); + + if (sldch->payload_length >0 ) { + LOG_I(MAC,"Got %d bytes from RRC for SLDCH @ %p\n",sldch->payload_length,sldch); + return (sldch); + } else + return((SLDCH_t *)NULL); } SLSCH_t *ue_get_slsch(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframeP) { + mac_rlc_status_resp_t rlc_status; //, rlc_status_data; + uint32_t absSF = (frameP*10)+subframeP; + UE_MAC_INST *ue = &UE_mac_inst[module_idP]; + int rvtab[4] = {0,2,3,1}; + int sdu_length; + //uint8_t sl_lcids[2] = {3, 10}; //list of lcids for SL - hardcoded + int i = 0; + // Note: this is hard-coded for now for the default SL configuration (4 SF PSCCH, 36 SF PSSCH) + SLSCH_t *slsch = &UE_mac_inst[module_idP].slsch; + LOG_D(MAC,"Checking SLSCH for absSF %d\n",absSF); + + if ((absSF%40) == 0) { // fill PSCCH data later in first subframe of SL period + ue->sltx_active = 0; - mac_rlc_status_resp_t rlc_status; //, rlc_status_data; - uint32_t absSF = (frameP*10)+subframeP; - UE_MAC_INST *ue = &UE_mac_inst[module_idP]; - int rvtab[4] = {0,2,3,1}; - int sdu_length; - //uint8_t sl_lcids[2] = {3, 10}; //list of lcids for SL - hardcoded - int i = 0; - - // Note: this is hard-coded for now for the default SL configuration (4 SF PSCCH, 36 SF PSSCH) - SLSCH_t *slsch = &UE_mac_inst[module_idP].slsch; - - LOG_D(MAC,"Checking SLSCH for absSF %d\n",absSF); - if ((absSF%40) == 0) { // fill PSCCH data later in first subframe of SL period - ue->sltx_active = 0; - - for (i = 0; i < MAX_NUM_LCID; i++){ - if (ue->SL_LCID[i] > 0) { - for (int j = 0; j < ue->numCommFlows; j++){ - if ((ue->sourceL2Id > 0) && (ue->destinationList[j] >0) ){ - rlc_status = mac_rlc_status_ind(module_idP, 0x1234,0,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, - ue->SL_LCID[i], 0xFFFF, ue->sourceL2Id, ue->destinationList[j]); - if (rlc_status.bytes_in_buffer > 2){ - LOG_I(MAC,"SFN.SF %d.%d: Scheduling for %d bytes in Sidelink buffer\n",frameP,subframeP,rlc_status.bytes_in_buffer); - // Fill in group id for off-network communications - ue->sltx_active = 1; - //store LCID, destinationL2Id - ue->slsch_lcid = ue->SL_LCID[i]; - ue->destinationL2Id = ue->destinationList[j]; - break; - } - } + for (i = 0; i < MAX_NUM_LCID; i++) { + if (ue->SL_LCID[i] > 0) { + for (int j = 0; j < ue->numCommFlows; j++) { + if ((ue->sourceL2Id > 0) && (ue->destinationList[j] >0) ) { + rlc_status = mac_rlc_status_ind(module_idP, 0x1234,0,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, + ue->SL_LCID[i], 0xFFFF, ue->sourceL2Id, ue->destinationList[j]); + + if (rlc_status.bytes_in_buffer > 2) { + LOG_I(MAC,"SFN.SF %d.%d: Scheduling for %d bytes in Sidelink buffer\n",frameP,subframeP,rlc_status.bytes_in_buffer); + // Fill in group id for off-network communications + ue->sltx_active = 1; + //store LCID, destinationL2Id + ue->slsch_lcid = ue->SL_LCID[i]; + ue->destinationL2Id = ue->destinationList[j]; + break; } - } - if ( ue->sltx_active == 1) break; + } + } } - } // we're not in the SCCH period - else if (((absSF & 3) == 0 ) && - (ue->sltx_active == 1)) { // every 4th subframe, check for new data from RLC - // 10 PRBs, mcs 19 - int TBS = 4584/8; - int req; - - - if (TBS <= rlc_status.bytes_in_buffer) req = TBS; - else req = rlc_status.bytes_in_buffer; - - if (req>0) { - sdu_length = mac_rlc_data_req(module_idP, - 0x1234, - 0, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - ue->slsch_lcid, - req, - (char*)(ue->slsch_pdu.payload + sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG)) + + if ( ue->sltx_active == 1) break; + } + } // we're not in the SCCH period + else if (((absSF & 3) == 0 ) && + (ue->sltx_active == 1)) { // every 4th subframe, check for new data from RLC + // 10 PRBs, mcs 19 + int TBS = 4584/8; + int req; + + if (TBS <= rlc_status.bytes_in_buffer) req = TBS; + else req = rlc_status.bytes_in_buffer; + + if (req>0) { + sdu_length = mac_rlc_data_req(module_idP, + 0x1234, + 0, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + ue->slsch_lcid, + req, + (char *)(ue->slsch_pdu.payload + sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG)) #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,ue->sourceL2Id, - ue->destinationL2Id + ,ue->sourceL2Id, + ue->destinationL2Id #endif - ); - - // Notes: 1. hard-coded to 24-bit destination format for now - if (sdu_length > 0) { - - LOG_I(MAC,"SFN.SF %d.%d : got %d bytes from Sidelink buffer (%d requested)\n",frameP,subframeP,sdu_length,req); - LOG_I(MAC,"sourceL2Id: 0x%08x \n",ue->sourceL2Id); - LOG_I(MAC,"groupL2Id/destinationL2Id: 0x%08x \n",ue->destinationL2Id); - - slsch->payload = (unsigned char*)ue->slsch_pdu.payload; - if (sdu_length < 128) { - slsch->payload++; - SLSCH_SUBHEADER_24_Bit_DST_SHORT *shorth= (SLSCH_SUBHEADER_24_Bit_DST_SHORT *)slsch->payload; - shorth->F = 0; - shorth->L = sdu_length; - shorth->E = 0; - shorth->LCID = ue->slsch_lcid; - shorth->SRC07 = (ue->sourceL2Id>>16) & 0x000000ff; - shorth->SRC815 = (ue->sourceL2Id>>8) & 0x000000ff; - shorth->SRC1623 = ue->sourceL2Id & 0x000000ff; - shorth->DST07 = (ue->destinationL2Id >>16) & 0x000000ff; - shorth->DST815 = (ue->destinationL2Id >>8) & 0x000000ff; - shorth->DST1623 = ue->destinationL2Id & 0x000000ff; - shorth->V = 0x1; - } - else { - SLSCH_SUBHEADER_24_Bit_DST_LONG *longh= (SLSCH_SUBHEADER_24_Bit_DST_LONG *)slsch->payload; - longh->F = 1; - longh->L_LSB = sdu_length&0xff; - longh->L_MSB = (sdu_length>>8)&0x7f; - longh->E = 0; - longh->LCID = ue->slsch_lcid; - longh->SRC07 = (ue->sourceL2Id >>16) & 0x000000ff; - longh->SRC815 = (ue->sourceL2Id>>8) & 0x000000ff; - longh->SRC1623 = ue->sourceL2Id & 0x000000ff; - longh->DST07 = (ue->destinationL2Id >>16) & 0x000000ff; - longh->DST815 = (ue->destinationL2Id>>8) & 0x000000ff; - longh->DST1623 = ue->destinationL2Id & 0x000000ff; - longh->V = 0x1; - } - slsch->rvidx = 0; - slsch->payload_length = TBS; - // fill in SLSCH configuration - return(&ue->slsch); - } - else ue->sltx_active = 0; - } + ); + + // Notes: 1. hard-coded to 24-bit destination format for now + if (sdu_length > 0) { + LOG_I(MAC,"SFN.SF %d.%d : got %d bytes from Sidelink buffer (%d requested)\n",frameP,subframeP,sdu_length,req); + LOG_I(MAC,"sourceL2Id: 0x%08x \n",ue->sourceL2Id); + LOG_I(MAC,"groupL2Id/destinationL2Id: 0x%08x \n",ue->destinationL2Id); + slsch->payload = (unsigned char *)ue->slsch_pdu.payload; + + if (sdu_length < 128) { + slsch->payload++; + SLSCH_SUBHEADER_24_Bit_DST_SHORT *shorth= (SLSCH_SUBHEADER_24_Bit_DST_SHORT *)slsch->payload; + shorth->F = 0; + shorth->L = sdu_length; + shorth->E = 0; + shorth->LCID = ue->slsch_lcid; + shorth->SRC07 = (ue->sourceL2Id>>16) & 0x000000ff; + shorth->SRC815 = (ue->sourceL2Id>>8) & 0x000000ff; + shorth->SRC1623 = ue->sourceL2Id & 0x000000ff; + shorth->DST07 = (ue->destinationL2Id >>16) & 0x000000ff; + shorth->DST815 = (ue->destinationL2Id >>8) & 0x000000ff; + shorth->DST1623 = ue->destinationL2Id & 0x000000ff; + shorth->V = 0x1; + } else { + SLSCH_SUBHEADER_24_Bit_DST_LONG *longh= (SLSCH_SUBHEADER_24_Bit_DST_LONG *)slsch->payload; + longh->F = 1; + longh->L_LSB = sdu_length&0xff; + longh->L_MSB = (sdu_length>>8)&0x7f; + longh->E = 0; + longh->LCID = ue->slsch_lcid; + longh->SRC07 = (ue->sourceL2Id >>16) & 0x000000ff; + longh->SRC815 = (ue->sourceL2Id>>8) & 0x000000ff; + longh->SRC1623 = ue->sourceL2Id & 0x000000ff; + longh->DST07 = (ue->destinationL2Id >>16) & 0x000000ff; + longh->DST815 = (ue->destinationL2Id>>8) & 0x000000ff; + longh->DST1623 = ue->destinationL2Id & 0x000000ff; + longh->V = 0x1; + } - } else if ((absSF%40)>3 && ue->sltx_active == 1) { // handle retransmission of SDU - LOG_I(MAC,"SFN.SF %d.%d : retransmission\n",frameP,subframeP); - slsch->rvidx = rvtab[absSF&3]; - return(&ue->slsch); - } + slsch->rvidx = 0; + slsch->payload_length = TBS; + // fill in SLSCH configuration + return(&ue->slsch); + } else ue->sltx_active = 0; + } + } else if ((absSF%40)>3 && ue->sltx_active == 1) { // handle retransmission of SDU + LOG_I(MAC,"SFN.SF %d.%d : retransmission\n",frameP,subframeP); + slsch->rvidx = rvtab[absSF&3]; + return(&ue->slsch); + } return(NULL); } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 1a552510907026741b9a18cfd978452860700da6..41688a62cfd5e1f1f71d83eb2b0e59e69c018010 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -28,7 +28,6 @@ */ #define PDCP_C -//#define DEBUG_PDCP_FIFO_FLUSH_SDU #define MBMS_MULTICAST_OUT @@ -47,41 +46,49 @@ #include "common/utils/LOG/log.h" #include <inttypes.h> #include "platform_constants.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "msc.h" +#include "common/ngran_types.h" #include "targets/COMMON/openairinterface5g_limits.h" -#if defined(ENABLE_SECURITY) -# include "UTIL/OSA/osa_defs.h" -#endif - -#if defined(ENABLE_ITTI) +#include "targets/RT/USER/lte-softmodem.h" +#include "SIMULATION/ETH_TRANSPORT/proto.h" +#include "UTIL/OSA/osa_defs.h" +#include "openair2/RRC/NAS/nas_config.h" # include "intertask_interface.h" -#endif -#if defined(LINK_ENB_PDCP_TO_GTPV1U) + # include "gtpv1u_eNB_task.h" # include "gtpv1u.h" -#endif + +#include "ENB_APP/enb_config.h" + + extern int otg_enabled; -#if defined(ENABLE_USE_MME) extern uint8_t nfapi_mode; -#endif #include "common/ran_context.h" extern RAN_CONTEXT_t RC; hash_table_t *pdcp_coll_p = NULL; #ifdef MBMS_MULTICAST_OUT -# include <sys/types.h> -# include <sys/socket.h> -# include <netinet/in.h> -# include <netinet/ip.h> -# include <netinet/udp.h> -# include <unistd.h> - -static int mbms_socket = -1; + #include <sys/types.h> + #include <sys/socket.h> + #include <netinet/in.h> + #include <netinet/ip.h> + #include <netinet/udp.h> + #include <unistd.h> + + static int mbms_socket = -1; #endif + +/* pdcp module parameters and related functions*/ +static pdcp_params_t pdcp_params= {0,NULL}; + +uint64_t get_pdcp_optmask(void) { + return pdcp_params.optmask; +} //----------------------------------------------------------------------------- /* * If PDCP_UNIT_TEST is set here then data flow between PDCP and RLC is broken @@ -91,22 +98,19 @@ static int mbms_socket = -1; * code at targets/TEST/PDCP/test_pdcp.c:test_pdcp_data_req() */ boolean_t pdcp_data_req( - protocol_ctxt_t* ctxt_pP, + protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, const rb_id_t rb_idP, const mui_t muiP, const confirm_t confirmP, const sdu_size_t sdu_buffer_sizeP, unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,const uint32_t * const sourceL2Id - ,const uint32_t * const destinationL2Id -#endif + const pdcp_transmission_mode_t modeP, + const uint32_t *const sourceL2Id, + const uint32_t *const destinationL2Id ) //----------------------------------------------------------------------------- { - pdcp_t *pdcp_p = NULL; uint8_t i = 0; uint8_t pdcp_header_len = 0; @@ -116,17 +120,17 @@ boolean_t pdcp_data_req( mem_block_t *pdcp_pdu_p = NULL; rlc_op_status_t rlc_status; boolean_t ret = TRUE; - hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 : 0; uint16_t pdcp_uid=0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_IN); CHECK_CTXT_ARGS(ctxt_pP); - #if T_TRACER + if (ctxt_pP->enb_flag != ENB_FLAG_NO) T(T_ENB_PDCP_DL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_buffer_sizeP)); + #endif if (sdu_buffer_sizeP == 0) { @@ -138,8 +142,8 @@ boolean_t pdcp_data_req( * XXX MAX_IP_PACKET_SIZE is 4096, shouldn't this be MAX SDU size, which is 8188 bytes? */ AssertFatal(sdu_buffer_sizeP<= MAX_IP_PACKET_SIZE,"Requested SDU size (%d) is bigger than that can be handled by PDCP (%u)!\n", - sdu_buffer_sizeP, MAX_IP_PACKET_SIZE); - + sdu_buffer_sizeP, MAX_IP_PACKET_SIZE); + if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) { AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti); } else { @@ -151,21 +155,21 @@ boolean_t pdcp_data_req( } key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); if (h_rc != HASH_TABLE_OK) { if (modeP != PDCP_TRANSMISSION_MODE_TRANSPARENT) { LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %d Ignoring SDU...\n", - PROTOCOL_CTXT_ARGS(ctxt_pP), - rb_idP); + PROTOCOL_CTXT_ARGS(ctxt_pP), + rb_idP); ctxt_pP->configured=FALSE; return FALSE; } - }else{ + } else { // instance for a given RB is configured ctxt_pP->configured=TRUE; } - + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { @@ -180,26 +184,20 @@ boolean_t pdcp_data_req( if (pdcp_pdu_p != NULL) { memcpy(&pdcp_pdu_p->data[0], sdu_buffer_pP, sdu_buffer_sizeP); -#if defined(DEBUG_PDCP_PAYLOAD) - rlc_util_print_hex_octets(PDCP, - (unsigned char*)&pdcp_pdu_p->data[0], - sdu_buffer_sizeP); -#endif - LOG_D(PDCP, "Before rlc_data_req 1, srb_flagP: %d, rb_idP: %d \n", srb_flagP, rb_idP); - rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP, confirmP, sdu_buffer_sizeP, pdcp_pdu_p -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL -#endif - ); + + if( LOG_DEBUGFLAG(DEBUG_PDCP) ) { + rlc_util_print_hex_octets(PDCP, + (unsigned char *)&pdcp_pdu_p->data[0], + sdu_buffer_sizeP); + LOG_UI(PDCP, "Before rlc_data_req 1, srb_flagP: %d, rb_idP: %d \n", srb_flagP, rb_idP); + } + + rlc_status = pdcp_params.send_rlc_data_req_func(ctxt_pP, srb_flagP, NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)?MBMS_FLAG_NO:MBMS_FLAG_YES, rb_idP, muiP, + confirmP, sdu_buffer_sizeP, pdcp_pdu_p,NULL,NULL); } else { rlc_status = RLC_OP_STATUS_OUT_OF_RESSOURCES; - LOG_W(PDCP,PROTOCOL_CTXT_FMT" PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n", + LOG_E(PDCP,PROTOCOL_CTXT_FMT" PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n", PROTOCOL_CTXT_ARGS(ctxt_pP)); -#if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) - AssertFatal(0, PROTOCOL_CTXT_FMT"[RB %u] PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n", - PROTOCOL_CTXT_ARGS(ctxt_pP), - rb_idP); -#endif } } else { // calculate the pdcp header and trailer size @@ -212,13 +210,11 @@ boolean_t pdcp_data_req( } pdcp_pdu_size = sdu_buffer_sizeP + pdcp_header_len + pdcp_tailer_len; - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT"Data request notification pdu size %d (header%d, trailer%d)\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), pdcp_pdu_size, pdcp_header_len, pdcp_tailer_len); - /* * Allocate a new block for the new PDU (i.e. PDU header and SDU payload) */ @@ -230,7 +226,6 @@ boolean_t pdcp_data_req( * * Place User Plane PDCP Data PDU header first */ - if (srb_flagP) { // this Control plane PDCP Data PDU pdcp_control_plane_data_pdu_header pdu_header; pdu_header.sn = pdcp_get_next_tx_seq_number(pdcp_p); @@ -238,7 +233,7 @@ boolean_t pdcp_data_req( memset(&pdu_header.mac_i[0],0,PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE); memset(&pdcp_pdu_p->data[sdu_buffer_sizeP + pdcp_header_len],0,PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE); - if (pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer((unsigned char*)pdcp_pdu_p->data, &pdu_header) == FALSE) { + if (pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer((unsigned char *)pdcp_pdu_p->data, &pdu_header) == FALSE) { LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" Cannot fill PDU buffer with relevant header fields!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p)); @@ -257,12 +252,11 @@ boolean_t pdcp_data_req( pdu_header.sn = pdcp_get_next_tx_seq_number(pdcp_p); current_sn = pdu_header.sn ; - if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char*)pdcp_pdu_p->data, &pdu_header) == FALSE) { + if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char *)pdcp_pdu_p->data, &pdu_header) == FALSE) { LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" Cannot fill PDU buffer with relevant header fields!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p)); - - if (ctxt_pP->enb_flag == ENB_FLAG_YES) { + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].data_req); } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); @@ -281,7 +275,6 @@ boolean_t pdcp_data_req( "There must be a problem with PDCP initialization, ignoring this PDU...\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), current_sn); - free_mem_block(pdcp_pdu_p, __func__); if (ctxt_pP->enb_flag == ENB_FLAG_YES) { @@ -295,7 +288,6 @@ boolean_t pdcp_data_req( } LOG_D(PDCP, "Sequence number %d is assigned to current PDU\n", current_sn); - /* Then append data... */ memcpy(&pdcp_pdu_p->data[pdcp_header_len], sdu_buffer_pP, sdu_buffer_sizeP); @@ -306,12 +298,9 @@ boolean_t pdcp_data_req( pdcp_pdu_p->data[pdcp_header_len + sdu_buffer_sizeP + i] = 0x00;// pdu_header.mac_i[i]; } -#if defined(ENABLE_SECURITY) - if ((pdcp_p->security_activated != 0) && (((pdcp_p->cipheringAlgorithm) != 0) || ((pdcp_p->integrityProtAlgorithm) != 0))) { - if (ctxt_pP->enb_flag == ENB_FLAG_YES) { start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].apply_security); } else { @@ -334,8 +323,6 @@ boolean_t pdcp_data_req( } } -#endif - /* Print octets of outgoing data in hexadecimal form */ LOG_D(PDCP, "Following content with size %d will be sent over RLC (PDCP PDU header is the first two bytes)\n", pdcp_pdu_size); @@ -350,14 +337,11 @@ boolean_t pdcp_data_req( stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); } -#if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) - AssertFatal(0, "[FRAME %5u][%s][PDCP][MOD %u/%u][RB %u] PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n", - ctxt_pP->frame, - (ctxt_pP->enb_flag) ? "eNB" : "UE", - ctxt_pP->enb_module_id, - ctxt_pP->ue_module_id, - rb_idP); -#endif + LOG_E(PDCP, "[FRAME %5u][%s][PDCP][MOD %u][RB %u] PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n", + ctxt_pP->frame, + (ctxt_pP->enb_flag) ? "eNB" : "UE", + ctxt_pP->module_id, + rb_idP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); return FALSE; } @@ -366,45 +350,108 @@ boolean_t pdcp_data_req( * Ask sublayer to transmit data and check return value * to see if RLC succeeded */ - LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)pdcp_pdu_p->data,pdcp_pdu_size, "[MSG] PDCP DL %s PDU on rb_id %d\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP); - LOG_D(PDCP, "Before rlc_data_req 2, srb_flagP: %d, rb_idP: %d \n", srb_flagP, rb_idP); - rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,sourceL2Id - ,destinationL2Id -#endif - ); + if ((pdcp_pdu_p!=NULL) && (srb_flagP == 0) && (ctxt_pP->enb_flag == 1)) { + LOG_D(PDCP, "pdcp data req on drb %d, size %d, rnti %x, node_type %d \n", + rb_idP, pdcp_pdu_size, ctxt_pP->rnti, RC.rrc[ctxt_pP->module_id]->node_type); - } + if (ctxt_pP->enb_flag == ENB_FLAG_YES && NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) { + LOG_E(PDCP, "Can't be DU, bad node type %d \n", RC.rrc[ctxt_pP->module_id]->node_type); + ret=FALSE; + } else { + rlc_status = pdcp_params.send_rlc_data_req_func(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, + confirmP, pdcp_pdu_size, pdcp_pdu_p,sourceL2Id, + destinationL2Id); + + switch (rlc_status) { + case RLC_OP_STATUS_OK: + LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); + ret=TRUE; + break; + + case RLC_OP_STATUS_BAD_PARAMETER: + LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); + ret= FALSE; + break; + + case RLC_OP_STATUS_INTERNAL_ERROR: + LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); + ret= FALSE; + break; + + case RLC_OP_STATUS_OUT_OF_RESSOURCES: + LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); + ret= FALSE; + break; + + default: + LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); + ret= FALSE; + break; + } // switch case + } /* end if node_type is not DU */ + } else { // SRB + if (ctxt_pP->enb_flag == ENB_FLAG_YES && NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + // DL transfer + MessageDef *message_p; + // Note: the acyual task must be TASK_PDCP_ENB, but this task is not created + message_p = itti_alloc_new_message (TASK_PDCP_ENB, F1AP_DL_RRC_MESSAGE); + F1AP_DL_RRC_MESSAGE (message_p).rrc_container = &pdcp_pdu_p->data[0] ; + F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = pdcp_pdu_size; + F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id = 0; + F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id = 0; + F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id = 0xFFFFFFFF; // unknown + F1AP_DL_RRC_MESSAGE (message_p).rnti = ctxt_pP->rnti; + F1AP_DL_RRC_MESSAGE (message_p).srb_id = rb_idP; + F1AP_DL_RRC_MESSAGE (message_p).execute_duplication = 1; + F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc = 0; + itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); + //CU_send_DL_RRC_MESSAGE_TRANSFER(ctxt_pP->module_id, message_p); + LOG_I(PDCP, "Send F1AP_DL_RRC_MESSAGE with ITTI\n"); + ret=TRUE; + } else { + rlc_status = rlc_data_req(ctxt_pP + , srb_flagP + , MBMS_FLAG_NO + , rb_idP + , muiP + , confirmP + , pdcp_pdu_size + , pdcp_pdu_p + ,NULL + ,NULL + ); + + switch (rlc_status) { + case RLC_OP_STATUS_OK: + LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); + ret=TRUE; + break; + + case RLC_OP_STATUS_BAD_PARAMETER: + LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); + ret= FALSE; + break; + + case RLC_OP_STATUS_INTERNAL_ERROR: + LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); + ret= FALSE; + break; - switch (rlc_status) { - case RLC_OP_STATUS_OK: - LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); - ret=TRUE; - break; - - case RLC_OP_STATUS_BAD_PARAMETER: - LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - ret= FALSE; - break; - - case RLC_OP_STATUS_INTERNAL_ERROR: - LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - ret= FALSE; - break; - - case RLC_OP_STATUS_OUT_OF_RESSOURCES: - LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); - ret= FALSE; - break; - - default: - LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); - ret= FALSE; - break; + case RLC_OP_STATUS_OUT_OF_RESSOURCES: + LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); + ret= FALSE; + break; + + default: + LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); + ret= FALSE; + break; + } // switch case + } + } } if (ctxt_pP->enb_flag == ENB_FLAG_YES) { @@ -418,7 +465,7 @@ boolean_t pdcp_data_req( * so we return TRUE afterwards */ - for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB;pdcp_uid++){ + for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB; pdcp_uid++) { if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ) break; } @@ -429,26 +476,23 @@ boolean_t pdcp_data_req( Pdcp_stats_tx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=sdu_buffer_sizeP; Pdcp_stats_tx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=current_sn; - Pdcp_stats_tx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); - Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); + Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); Pdcp_stats_tx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_enb[ctxt_pP->module_id].sfn; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); return ret; - } //----------------------------------------------------------------------------- boolean_t pdcp_data_ind( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, const sdu_size_t sdu_buffer_sizeP, - mem_block_t* const sdu_buffer_pP + mem_block_t *const sdu_buffer_pP ) //----------------------------------------------------------------------------- { @@ -464,22 +508,20 @@ pdcp_data_ind( hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 :0; - uint16_t pdcp_uid=0; - uint8_t oo_flag=0; -#if defined(LINK_ENB_PDCP_TO_GTPV1U) + uint16_t pdcp_uid=0; MessageDef *message_p = NULL; uint8_t *gtpu_buffer_p = NULL; -#endif - - + uint32_t rx_hfn_for_count; + int pdcp_sn_for_count; + int security_ok; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_IN); LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)sdu_buffer_pP->data,sdu_buffer_sizeP, "[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); - - #if T_TRACER + if (ctxt_pP->enb_flag != ENB_FLAG_NO) T(T_ENB_PDCP_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_buffer_sizeP)); + #endif if (MBMS_flagP) { @@ -498,17 +540,15 @@ pdcp_data_ind( rb_idP, sdu_buffer_sizeP, ctxt_pP->enb_flag); - } else { LOG_D(PDCP, "Data indication notification for PDCP entity from UE %x to eNB %u " "and radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d\n", ctxt_pP->rnti, - ctxt_pP->module_id , + ctxt_pP->module_id, rb_idP, sdu_buffer_sizeP, ctxt_pP->enb_flag); } - } else { rb_id = rb_idP % LTE_maxDRB; AssertError (rb_id < LTE_maxDRB, return FALSE, "RB id is too high (%u/%d) %u UE %x!\n", @@ -522,7 +562,7 @@ pdcp_data_ind( ctxt_pP->module_id, ctxt_pP->rnti); key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_id, srb_flagP); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); if (h_rc != HASH_TABLE_OK) { LOG_W(PDCP, @@ -557,22 +597,23 @@ pdcp_data_ind( if (srb_flagP) { //SRB1/2 pdcp_header_len = PDCP_CONTROL_PLANE_DATA_PDU_SN_SIZE; pdcp_tailer_len = PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE; - sequence_number = pdcp_get_sequence_number_of_pdu_with_SRB_sn((unsigned char*)sdu_buffer_pP->data); + sequence_number = pdcp_get_sequence_number_of_pdu_with_SRB_sn((unsigned char *)sdu_buffer_pP->data); } else { // DRB pdcp_tailer_len = 0; - if (pdcp_p->seq_num_size == PDCP_SN_7BIT) { + if (pdcp_p->seq_num_size == 7) { pdcp_header_len = PDCP_USER_PLANE_DATA_PDU_SHORT_SN_HEADER_SIZE; - sequence_number = pdcp_get_sequence_number_of_pdu_with_short_sn((unsigned char*)sdu_buffer_pP->data); - } else if (pdcp_p->seq_num_size == PDCP_SN_12BIT) { + sequence_number = pdcp_get_sequence_number_of_pdu_with_short_sn((unsigned char *)sdu_buffer_pP->data); + } else if (pdcp_p->seq_num_size == 12) { pdcp_header_len = PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE; - sequence_number = pdcp_get_sequence_number_of_pdu_with_long_sn((unsigned char*)sdu_buffer_pP->data); + sequence_number = pdcp_get_sequence_number_of_pdu_with_long_sn((unsigned char *)sdu_buffer_pP->data); } else { //sequence_number = 4095; LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT"wrong sequence number (%d) for this pdcp entity \n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), pdcp_p->seq_num_size); + exit(1); } //uint8_t dc = pdcp_get_dc_filed((unsigned char*)sdu_buffer_pP->data); @@ -598,6 +639,9 @@ pdcp_data_ind( return FALSE; } +#if 0 + + /* Removed by Cedric */ if (pdcp_is_rx_seq_number_valid(sequence_number, pdcp_p, srb_flagP) == TRUE) { LOG_T(PDCP, "Incoming PDU has a sequence number (%d) in accordance with RX window\n", sequence_number); /* if (dc == PDCP_DATA_PDU ) @@ -605,8 +649,8 @@ pdcp_data_ind( else LOG_D(PDCP, "Passing piggybacked SDU to RRC ...\n");*/ } else { - oo_flag=1; - LOG_W(PDCP, + Pdcp_stats_rx_outoforder[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; + LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT"Incoming PDU has an unexpected sequence number (%d), RX window synchronisation have probably been lost!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), sequence_number); @@ -619,9 +663,18 @@ pdcp_data_ind( return FALSE; } +#endif + // SRB1/2: control-plane data if (srb_flagP) { -#if defined(ENABLE_SECURITY) + /* process as described in 36.323 5.1.2.2 */ + if (sequence_number < pdcp_p->next_pdcp_rx_sn) { + rx_hfn_for_count = pdcp_p->rx_hfn + 1; + pdcp_sn_for_count = sequence_number; + } else { + rx_hfn_for_count = pdcp_p->rx_hfn; + pdcp_sn_for_count = sequence_number; + } if (pdcp_p->security_activated == 1) { if (ctxt_pP->enb_flag == ENB_FLAG_NO) { @@ -630,37 +683,58 @@ pdcp_data_ind( start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); } - pdcp_validate_security(ctxt_pP, - pdcp_p, - srb_flagP, - rb_idP, - pdcp_header_len, - sequence_number, - sdu_buffer_pP->data, - sdu_buffer_sizeP - pdcp_tailer_len); + security_ok = pdcp_validate_security(ctxt_pP, + pdcp_p, + srb_flagP, + rb_idP, + pdcp_header_len, + rx_hfn_for_count, + pdcp_sn_for_count, + sdu_buffer_pP->data, + sdu_buffer_sizeP - pdcp_tailer_len) == 0; if (ctxt_pP->enb_flag == ENB_FLAG_NO) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); } + } else { + security_ok = 1; + } + + if (security_ok == 0) { + LOG_W(PDCP, + PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDCP SRB PDU\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); + LOG_W(PDCP, "Ignoring PDU...\n"); + free_mem_block(sdu_buffer_pP, __func__); + /* TODO: indicate integrity verification failure to upper layer */ + return FALSE; + } + + if (sequence_number < pdcp_p->next_pdcp_rx_sn) + pdcp_p->rx_hfn++; + + pdcp_p->next_pdcp_rx_sn = sequence_number + 1; + + if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) { + pdcp_p->next_pdcp_rx_sn = 0; + pdcp_p->rx_hfn++; } -#endif //rrc_lite_data_ind(module_id, //Modified MW - L2 Interface - MSC_LOG_TX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_NO)? MSC_PDCP_UE:MSC_PDCP_ENB, + MSC_LOG_TX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_NO)? MSC_PDCP_UE:MSC_PDCP_ENB, (ctxt_pP->enb_flag == ENB_FLAG_NO)? MSC_RRC_UE:MSC_RRC_ENB, NULL,0, PROTOCOL_PDCP_CTXT_FMT" DATA-IND len %u", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len); - rrc_data_ind(ctxt_pP, - rb_id, - sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len, - (uint8_t*)&sdu_buffer_pP->data[pdcp_header_len]); - free_mem_block(sdu_buffer_pP, __func__); - + rrc_data_ind(ctxt_pP, + rb_id, + sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len, + (uint8_t *)&sdu_buffer_pP->data[pdcp_header_len]); + free_mem_block(sdu_buffer_pP, __func__); // free_mem_block(new_sdu, __func__); if (ctxt_pP->enb_flag) { @@ -671,41 +745,166 @@ pdcp_data_ind( VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); return TRUE; - } + } /* if (srb_flagP) */ /* * DRBs */ payload_offset=pdcp_header_len;// PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE; -#if defined(ENABLE_SECURITY) - if (pdcp_p->security_activated == 1) { - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); - } else { - start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); - } + switch (pdcp_p->rlc_mode) { + case RLC_MODE_AM: { + /* process as described in 36.323 5.1.2.1.2 */ + int reordering_window; - pdcp_validate_security( - ctxt_pP, - pdcp_p, - srb_flagP, - rb_idP, - pdcp_header_len, - sequence_number, - sdu_buffer_pP->data, - sdu_buffer_sizeP - pdcp_tailer_len); + if (pdcp_p->seq_num_size == 7) + reordering_window = REORDERING_WINDOW_SN_7BIT; + else + reordering_window = REORDERING_WINDOW_SN_12BIT; + + if (sequence_number - pdcp_p->last_submitted_pdcp_rx_sn > reordering_window || + (pdcp_p->last_submitted_pdcp_rx_sn - sequence_number >= 0 && + pdcp_p->last_submitted_pdcp_rx_sn - sequence_number < reordering_window)) { + /* TODO: specs say to decipher and do header decompression */ + LOG_W(PDCP, + PROTOCOL_PDCP_CTXT_FMT"discard PDU, out of\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); + LOG_W(PDCP, "Ignoring PDU...\n"); + free_mem_block(sdu_buffer_pP, __func__); + /* TODO: indicate integrity verification failure to upper layer */ + return FALSE; + } else if (pdcp_p->next_pdcp_rx_sn - sequence_number > reordering_window) { + pdcp_p->rx_hfn++; + rx_hfn_for_count = pdcp_p->rx_hfn; + pdcp_sn_for_count = sequence_number; + pdcp_p->next_pdcp_rx_sn = sequence_number + 1; + } else if (sequence_number - pdcp_p->next_pdcp_rx_sn >= reordering_window) { + rx_hfn_for_count = pdcp_p->rx_hfn - 1; + pdcp_sn_for_count = sequence_number; + } else if (sequence_number >= pdcp_p->next_pdcp_rx_sn) { + rx_hfn_for_count = pdcp_p->rx_hfn; + pdcp_sn_for_count = sequence_number; + pdcp_p->next_pdcp_rx_sn = sequence_number + 1; + + if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) { + pdcp_p->next_pdcp_rx_sn = 0; + pdcp_p->rx_hfn++; + } + } else { /* sequence_number < pdcp_p->next_pdcp_rx_sn */ + rx_hfn_for_count = pdcp_p->rx_hfn; + pdcp_sn_for_count = sequence_number; + } - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); - } else { - stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); - } + if (pdcp_p->security_activated == 1) { + if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); + } else { + start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); + } - } + security_ok = pdcp_validate_security(ctxt_pP, + pdcp_p, + srb_flagP, + rb_idP, + pdcp_header_len, + rx_hfn_for_count, + pdcp_sn_for_count, + sdu_buffer_pP->data, + sdu_buffer_sizeP - pdcp_tailer_len) == 0; + + if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); + } else { + stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); + } + } else { + security_ok = 1; + } -#endif - } else { + if (security_ok == 0) { + LOG_W(PDCP, + PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDPC DRB RLC/AM PDU\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); + LOG_W(PDCP, "Ignoring PDU...\n"); + free_mem_block(sdu_buffer_pP, __func__); + /* TODO: indicate integrity verification failure to upper layer */ + return FALSE; + } + + /* TODO: specs say we have to store this PDU in a list and then deliver + * stored packets to upper layers according to a well defined + * procedure. The code below that deals with delivery is today + * too complex to do this properly, so we only send the current + * received packet. This is not correct and has to be fixed + * some day. + * In the meantime, let's pretend the last submitted PDCP SDU + * is the current one. + * TODO: we also have to deal with re-establishment PDU (control PDUs) + * that contain no SDU. + */ + pdcp_p->last_submitted_pdcp_rx_sn = sequence_number; + break; + } /* case RLC_MODE_AM */ + + case RLC_MODE_UM: + + /* process as described in 36.323 5.1.2.1.3 */ + if (sequence_number < pdcp_p->next_pdcp_rx_sn) { + pdcp_p->rx_hfn++; + } + + rx_hfn_for_count = pdcp_p->rx_hfn; + pdcp_sn_for_count = sequence_number; + pdcp_p->next_pdcp_rx_sn = sequence_number + 1; + + if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) { + pdcp_p->next_pdcp_rx_sn = 0; + pdcp_p->rx_hfn++; + } + + if (pdcp_p->security_activated == 1) { + if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); + } else { + start_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); + } + + security_ok = pdcp_validate_security(ctxt_pP, + pdcp_p, + srb_flagP, + rb_idP, + pdcp_header_len, + rx_hfn_for_count, + pdcp_sn_for_count, + sdu_buffer_pP->data, + sdu_buffer_sizeP - pdcp_tailer_len) == 0; + + if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].validate_security); + } else { + stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].validate_security); + } + } else { + security_ok = 1; + } + + if (security_ok == 0) { + LOG_W(PDCP, + PROTOCOL_PDCP_CTXT_FMT"security not validated for incoming PDPC DRB RLC/UM PDU\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); + LOG_W(PDCP, "Ignoring PDU...\n"); + free_mem_block(sdu_buffer_pP, __func__); + /* TODO: indicate integrity verification failure to upper layer */ + return FALSE; + } + + break; + + default: + LOG_E(PDCP, "bad RLC mode, cannot happen.\n"); + exit(1); + } /* switch (pdcp_p->rlc_mode) */ + } else { /* MBMS_flagP == 0 */ payload_offset=0; } @@ -724,50 +923,52 @@ pdcp_data_ind( } // XXX Decompression would be done at this point - /* * After checking incoming sequence number PDCP header * has to be stripped off so here we copy SDU buffer starting * from its second byte (skipping 0th and 1st octets, i.e. * PDCP header) */ -#if defined(LINK_ENB_PDCP_TO_GTPV1U) - - if ((TRUE == ctxt_pP->enb_flag) && (FALSE == srb_flagP)) { - MSC_LOG_TX_MESSAGE( - MSC_PDCP_ENB, - MSC_GTPU_ENB, - NULL,0, - "0 GTPV1U_ENB_TUNNEL_DATA_REQ ue %x rab %u len %u", - ctxt_pP->rnti, - rb_id + 4, - sdu_buffer_sizeP - payload_offset); - //LOG_T(PDCP,"Sending to GTPV1U %d bytes\n", sdu_buffer_sizeP - payload_offset); - gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U, - sdu_buffer_sizeP - payload_offset + GTPU_HEADER_OVERHEAD_MAX); - AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY"); - memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset); - message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_ENB_TUNNEL_DATA_REQ); - AssertFatal(message_p != NULL, "OUT OF MEMORY"); - GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p; - GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length = sdu_buffer_sizeP - payload_offset; - GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; - GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti; - GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; - itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); - packet_forwarded = TRUE; + + if (LINK_ENB_PDCP_TO_GTPV1U) { + if ((TRUE == ctxt_pP->enb_flag) && (FALSE == srb_flagP)) { + LOG_D(PDCP, "Sending packet to GTP, Calling GTPV1U_ENB_TUNNEL_DATA_REQ ue %x rab %u len %u\n", + ctxt_pP->rnti, + rb_id + 4, + sdu_buffer_sizeP - payload_offset ); + MSC_LOG_TX_MESSAGE( + MSC_PDCP_ENB, + MSC_GTPU_ENB, + NULL,0, + "0 GTPV1U_ENB_TUNNEL_DATA_REQ ue %x rab %u len %u", + ctxt_pP->rnti, + rb_id + 4, + sdu_buffer_sizeP - payload_offset); + //LOG_T(PDCP,"Sending to GTPV1U %d bytes\n", sdu_buffer_sizeP - payload_offset); + gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U, + sdu_buffer_sizeP - payload_offset + GTPU_HEADER_OVERHEAD_MAX); + AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY"); + memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset); + message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_ENB_TUNNEL_DATA_REQ); + AssertFatal(message_p != NULL, "OUT OF MEMORY"); + GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p; + GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length = sdu_buffer_sizeP - payload_offset; + GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; + GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti; + GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; + itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); + packet_forwarded = TRUE; + } + } else { + packet_forwarded = FALSE; } - -#else - packet_forwarded = FALSE; -#endif #ifdef MBMS_MULTICAST_OUT + if ((MBMS_flagP != 0) && (mbms_socket != -1)) { - struct iphdr *ip_header = (struct iphdr*)&sdu_buffer_pP->data[payload_offset]; - struct udphdr *udp_header = (struct udphdr*)&sdu_buffer_pP->data[payload_offset + sizeof(struct iphdr)]; + struct iphdr *ip_header = (struct iphdr *)&sdu_buffer_pP->data[payload_offset]; + struct udphdr *udp_header = (struct udphdr *)&sdu_buffer_pP->data[payload_offset + sizeof(struct iphdr)]; struct sockaddr_in dest_addr; - dest_addr.sin_family = AF_INET; dest_addr.sin_port = udp_header->dest; dest_addr.sin_addr.s_addr = ip_header->daddr; @@ -776,6 +977,7 @@ pdcp_data_ind( //packet_forwarded = TRUE; } + #endif if (FALSE == packet_forwarded) { @@ -797,87 +999,72 @@ pdcp_data_ind( // set ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst for IP layer here if (ctxt_pP->enb_flag == ENB_FLAG_NO) { ((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id; -#if defined(ENABLE_USE_MME) - /* for the UE compiled in S1 mode, we need 1 here - * for the UE compiled in noS1 mode, we need 0 - * TODO: be sure of this - */ - if (nfapi_mode == 3) { + + if (EPC_MODE_ENABLED) { + /* for the UE compiled in S1 mode, we need 1 here + * for the UE compiled in noS1 mode, we need 0 + * TODO: be sure of this + */ + if (NFAPI_MODE == NFAPI_UE_STUB_PNF ) { #ifdef UESIM_EXPANSION - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 0; + + if (UE_NAS_USE_TUN) { + ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id; + } else { + ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = 0; + } + #else - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; + ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id; #endif - } else { - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; + } else { // nfapi_mode + if (UE_NAS_USE_TUN) { + ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id; + } else { + ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = 1; + } + } // nfapi_mode } -#endif } else { - ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * LTE_maxDRB); - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; + ((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * LTE_maxDRB); + ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = ctxt_pP->module_id; } - // new_sdu_p->data->inst is set again in UE case so move to above. - //Panos: Commented this out because it cancels the assignment in #if defined(ENABLE_USE_MME) case - //((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; - -#ifdef DEBUG_PDCP_FIFO_FLUSH_SDU - static uint32_t pdcp_inst = 0; - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = pdcp_inst++; - LOG_D(PDCP, "inst=%d size=%d\n", ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst, ((pdcp_data_ind_header_t *) new_sdu_p->data)->data_size); -#endif - //((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; //pdcp_inst++; - memcpy(&new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], \ - &sdu_buffer_pP->data[payload_offset], \ + if( LOG_DEBUGFLAG(DEBUG_PDCP) ) { + static uint32_t pdcp_inst = 0; + ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst = pdcp_inst++; + LOG_D(PDCP, "inst=%d size=%d\n", ((pdcp_data_ind_header_t *) new_sdu_p->data)->inst, ((pdcp_data_ind_header_t *) new_sdu_p->data)->data_size); + } + + memcpy(&new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], + &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset); list_add_tail_eurecom (new_sdu_p, sdu_list_p); - - - } - /* Print octets of incoming data in hexadecimal form */ - LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", - sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), - sdu_buffer_sizeP - payload_offset); - //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); - //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); - - /* - * Update PDCP statistics - * XXX Following two actions are identical, is there a merge error? - */ - - for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB;pdcp_uid++){ - if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ){ + /* Print octets of incoming data in hexadecimal form */ + LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", + sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), + sdu_buffer_sizeP - payload_offset); + //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); + //util_flush_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); + } + + /* Update PDCP statistics */ + for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB; pdcp_uid++) { + if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti ) { break; } - } - + } + Pdcp_stats_rx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; Pdcp_stats_rx_bytes[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(sdu_buffer_sizeP - payload_offset); - Pdcp_stats_rx_sn[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=sequence_number; - - if (oo_flag == 1 ) - Pdcp_stats_rx_outoforder[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; - Pdcp_stats_rx_aiat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+= (pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]+=(pdcp_enb[ctxt_pP->module_id].sfn - Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]); Pdcp_stats_rx_iat[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]=pdcp_enb[ctxt_pP->module_id].sfn; - - -#if defined(STOP_ON_IP_TRAFFIC_OVERLOAD) - else { - AssertFatal(0, PROTOCOL_PDCP_CTXT_FMT" PDCP_DATA_IND SDU DROPPED, OUT OF MEMORY \n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); - } -#endif - - } - free_mem_block(sdu_buffer_pP, __func__); if (ctxt_pP->enb_flag) { @@ -890,63 +1077,64 @@ pdcp_data_ind( return TRUE; } -void pdcp_update_stats(const protocol_ctxt_t* const ctxt_pP){ - +void pdcp_update_stats(const protocol_ctxt_t *const ctxt_pP) { uint16_t pdcp_uid = 0; uint8_t rb_id = 0; - - // these stats are measured for both eNB and UE on per seond basis - for (rb_id =0; rb_id < NB_RB_MAX; rb_id ++){ - for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB;pdcp_uid++){ + + // these stats are measured for both eNB and UE on per seond basis + for (rb_id =0; rb_id < NB_RB_MAX; rb_id ++) { + for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB; pdcp_uid++) { //printf("frame %d and subframe %d \n", pdcp_enb[ctxt_pP->module_id].frame, pdcp_enb[ctxt_pP->module_id].subframe); // tx stats if (Pdcp_stats_tx_window_ms[ctxt_pP->module_id][pdcp_uid] > 0 && - pdcp_enb[ctxt_pP->module_id].sfn % Pdcp_stats_tx_window_ms[ctxt_pP->module_id][pdcp_uid] == 0){ - // unit: bit/s - Pdcp_stats_tx_throughput_w[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]*8; - Pdcp_stats_tx_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; - Pdcp_stats_tx_bytes_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; - if (Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id] > 0){ - Pdcp_stats_tx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=(Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]); - }else { - Pdcp_stats_tx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - } - // reset the tmp vars - Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - + pdcp_enb[ctxt_pP->module_id].sfn % Pdcp_stats_tx_window_ms[ctxt_pP->module_id][pdcp_uid] == 0) { + // unit: bit/s + Pdcp_stats_tx_throughput_w[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]*8; + Pdcp_stats_tx_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + Pdcp_stats_tx_bytes_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + + if (Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id] > 0) { + Pdcp_stats_tx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=(Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]); + } else { + Pdcp_stats_tx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + } + + // reset the tmp vars + Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_tx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_tx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; } + if (Pdcp_stats_rx_window_ms[ctxt_pP->module_id][pdcp_uid] > 0 && - pdcp_enb[ctxt_pP->module_id].sfn % Pdcp_stats_rx_window_ms[ctxt_pP->module_id][pdcp_uid] == 0){ - // rx stats - Pdcp_stats_rx_goodput_w[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]*8; - Pdcp_stats_rx_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; - Pdcp_stats_rx_bytes_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; - - if(Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id] > 0){ - Pdcp_stats_rx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]= (Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]); - } else { - Pdcp_stats_rx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - } - - // reset the tmp vars - Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; - } + pdcp_enb[ctxt_pP->module_id].sfn % Pdcp_stats_rx_window_ms[ctxt_pP->module_id][pdcp_uid] == 0) { + // rx stats + Pdcp_stats_rx_goodput_w[ctxt_pP->module_id][pdcp_uid][rb_id]=Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]*8; + Pdcp_stats_rx_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + Pdcp_stats_rx_bytes_w[ctxt_pP->module_id][pdcp_uid][rb_id]= Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]; + + if(Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id] > 0) { + Pdcp_stats_rx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]= (Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]/Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]); + } else { + Pdcp_stats_rx_aiat_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + } + + // reset the tmp vars + Pdcp_stats_rx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_rx_bytes_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + Pdcp_stats_rx_aiat_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_id]=0; + } } - } } + + //----------------------------------------------------------------------------- void pdcp_run ( - const protocol_ctxt_t* const ctxt_pP + const protocol_ctxt_t *const ctxt_pP ) //----------------------------------------------------------------------------- { - if (ctxt_pP->enb_flag) { start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_run); } else { @@ -954,13 +1142,10 @@ pdcp_run ( } pdcp_enb[ctxt_pP->module_id].sfn++; // range: 0 to 18,446,744,073,709,551,615 - pdcp_enb[ctxt_pP->module_id].frame=ctxt_pP->frame; // 1023 + pdcp_enb[ctxt_pP->module_id].frame=ctxt_pP->frame; // 1023 pdcp_enb[ctxt_pP->module_id].subframe= ctxt_pP->subframe; pdcp_update_stats(ctxt_pP); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN); - -#if defined(ENABLE_ITTI) MessageDef *msg_p; int result; protocol_ctxt_t ctxt; @@ -970,66 +1155,64 @@ pdcp_run ( itti_poll_msg (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, &msg_p); if (msg_p != NULL) { - switch (ITTI_MSG_ID(msg_p)) { - case RRC_DCCH_DATA_REQ: - PROTOCOL_CTXT_SET_BY_MODULE_ID( - &ctxt, - RRC_DCCH_DATA_REQ (msg_p).module_id, - RRC_DCCH_DATA_REQ (msg_p).enb_flag, - RRC_DCCH_DATA_REQ (msg_p).rnti, - RRC_DCCH_DATA_REQ (msg_p).frame, - 0, - RRC_DCCH_DATA_REQ (msg_p).eNB_index); - LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", - PROTOCOL_CTXT_ARGS(&ctxt), - ITTI_MSG_NAME (msg_p), - ITTI_MSG_ORIGIN_NAME(msg_p), - ITTI_MSG_INSTANCE (msg_p), - RRC_DCCH_DATA_REQ (msg_p).rb_id, - RRC_DCCH_DATA_REQ (msg_p).muip, - RRC_DCCH_DATA_REQ (msg_p).confirmp, - RRC_DCCH_DATA_REQ (msg_p).mode); - - LOG_D(PDCP, "Before calling pdcp_data_req from pdcp_run! RRC_DCCH_DATA_REQ (msg_p).rb_id: %d \n", RRC_DCCH_DATA_REQ (msg_p).rb_id); - result = pdcp_data_req (&ctxt, - SRB_FLAG_YES, - RRC_DCCH_DATA_REQ (msg_p).rb_id, - RRC_DCCH_DATA_REQ (msg_p).muip, - RRC_DCCH_DATA_REQ (msg_p).confirmp, - RRC_DCCH_DATA_REQ (msg_p).sdu_size, - RRC_DCCH_DATA_REQ (msg_p).sdu_p, - RRC_DCCH_DATA_REQ (msg_p).mode -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , NULL, NULL -#endif - ); - if (result != TRUE) - LOG_E(PDCP, "PDCP data request failed!\n"); + case RRC_DCCH_DATA_REQ: + PROTOCOL_CTXT_SET_BY_MODULE_ID( + &ctxt, + RRC_DCCH_DATA_REQ (msg_p).module_id, + RRC_DCCH_DATA_REQ (msg_p).enb_flag, + RRC_DCCH_DATA_REQ (msg_p).rnti, + RRC_DCCH_DATA_REQ (msg_p).frame, + 0, + RRC_DCCH_DATA_REQ (msg_p).eNB_index); + LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", + PROTOCOL_CTXT_ARGS(&ctxt), + ITTI_MSG_NAME (msg_p), + ITTI_MSG_ORIGIN_NAME(msg_p), + ITTI_MSG_INSTANCE (msg_p), + RRC_DCCH_DATA_REQ (msg_p).rb_id, + RRC_DCCH_DATA_REQ (msg_p).muip, + RRC_DCCH_DATA_REQ (msg_p).confirmp, + RRC_DCCH_DATA_REQ (msg_p).mode); + LOG_D(PDCP, "Before calling pdcp_data_req from pdcp_run! RRC_DCCH_DATA_REQ (msg_p).rb_id: %d \n", RRC_DCCH_DATA_REQ (msg_p).rb_id); + result = pdcp_data_req (&ctxt, + SRB_FLAG_YES, + RRC_DCCH_DATA_REQ (msg_p).rb_id, + RRC_DCCH_DATA_REQ (msg_p).muip, + RRC_DCCH_DATA_REQ (msg_p).confirmp, + RRC_DCCH_DATA_REQ (msg_p).sdu_size, + RRC_DCCH_DATA_REQ (msg_p).sdu_p, + RRC_DCCH_DATA_REQ (msg_p).mode, + NULL, NULL + ); + + if (result != TRUE) + LOG_E(PDCP, "PDCP data request failed!\n"); + + // Message buffer has been processed, free it now. + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ (msg_p).sdu_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + break; - // Message buffer has been processed, free it now. - result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ (msg_p).sdu_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - break; + case RRC_PCCH_DATA_REQ: { + sdu_size_t sdu_buffer_sizeP; + sdu_buffer_sizeP = RRC_PCCH_DATA_REQ(msg_p).sdu_size; + uint8_t CC_id = RRC_PCCH_DATA_REQ(msg_p).CC_id; + uint8_t ue_index = RRC_PCCH_DATA_REQ(msg_p).ue_index; + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_paging[ue_index] = sdu_buffer_sizeP; - case RRC_PCCH_DATA_REQ: - { - sdu_size_t sdu_buffer_sizeP; - sdu_buffer_sizeP = RRC_PCCH_DATA_REQ(msg_p).sdu_size; - uint8_t CC_id = RRC_PCCH_DATA_REQ(msg_p).CC_id; - uint8_t ue_index = RRC_PCCH_DATA_REQ(msg_p).ue_index; - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_paging[ue_index] = sdu_buffer_sizeP; - if (sdu_buffer_sizeP > 0) { - memcpy(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].paging[ue_index], RRC_PCCH_DATA_REQ(msg_p).sdu_p, sdu_buffer_sizeP); - } - //paging pdcp log - LOG_D(PDCP, "PDCP Received RRC_PCCH_DATA_REQ CC_id %d length %d \n", CC_id, sdu_buffer_sizeP); - } - break; + if (sdu_buffer_sizeP > 0) { + memcpy(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].paging[ue_index], RRC_PCCH_DATA_REQ(msg_p).sdu_p, sdu_buffer_sizeP); + } - default: - LOG_E(PDCP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); + //paging pdcp log + LOG_D(PDCP, "PDCP Received RRC_PCCH_DATA_REQ CC_id %d length %d \n", CC_id, sdu_buffer_sizeP); + } break; + + default: + LOG_E(PDCP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p)); + break; } result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); @@ -1037,23 +1220,16 @@ pdcp_run ( } } while(msg_p != NULL); -#endif - // IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer -#if defined(LINK_ENB_PDCP_TO_GTPV1U) - - if (ctxt_pP->enb_flag == ENB_FLAG_NO) -#endif - { + // if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) { + if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) { pdcp_fifo_read_input_sdus(ctxt_pP); } // PDCP -> NAS/IP traffic: RX if (ctxt_pP->enb_flag) { start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_ip); - } - - else { + } else { start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_ip); } @@ -1070,36 +1246,74 @@ pdcp_run ( } else { stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT); } -void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP){ +void pdcp_init_stats_UE(module_id_t mod, uint16_t uid) { + Pdcp_stats_tx_window_ms[mod][uid] = 100; + Pdcp_stats_rx_window_ms[mod][uid] = 100; + + for (int i = 0; i < NB_RB_MAX; ++i) { + Pdcp_stats_tx_bytes[mod][uid][i] = 0; + Pdcp_stats_tx_bytes_w[mod][uid][i] = 0; + Pdcp_stats_tx_bytes_tmp_w[mod][uid][i] = 0; + Pdcp_stats_tx[mod][uid][i] = 0; + Pdcp_stats_tx_w[mod][uid][i] = 0; + Pdcp_stats_tx_tmp_w[mod][uid][i] = 0; + Pdcp_stats_tx_sn[mod][uid][i] = 0; + Pdcp_stats_tx_throughput_w[mod][uid][i] = 0; + Pdcp_stats_tx_aiat[mod][uid][i] = 0; + Pdcp_stats_tx_aiat_w[mod][uid][i] = 0; + Pdcp_stats_tx_aiat_tmp_w[mod][uid][i] = 0; + Pdcp_stats_tx_iat[mod][uid][i] = 0; + Pdcp_stats_rx[mod][uid][i] = 0; + Pdcp_stats_rx_w[mod][uid][i] = 0; + Pdcp_stats_rx_tmp_w[mod][uid][i] = 0; + Pdcp_stats_rx_bytes[mod][uid][i] = 0; + Pdcp_stats_rx_bytes_w[mod][uid][i] = 0; + Pdcp_stats_rx_bytes_tmp_w[mod][uid][i] = 0; + Pdcp_stats_rx_sn[mod][uid][i] = 0; + Pdcp_stats_rx_goodput_w[mod][uid][i] = 0; + Pdcp_stats_rx_aiat[mod][uid][i] = 0; + Pdcp_stats_rx_aiat_w[mod][uid][i] = 0; + Pdcp_stats_rx_aiat_tmp_w[mod][uid][i] = 0; + Pdcp_stats_rx_iat[mod][uid][i] = 0; + Pdcp_stats_rx_outoforder[mod][uid][i] = 0; + } +} + +void pdcp_add_UE(const protocol_ctxt_t *const ctxt_pP) { int i, ue_flag=1; //, ret=-1; to be decied later - for (i=0; i < MAX_MOBILES_PER_ENB; i++){ + + for (i=0; i < MAX_MOBILES_PER_ENB; i++) { if (pdcp_enb[ctxt_pP->module_id].rnti[i] == ctxt_pP->rnti) { ue_flag=-1; break; } } - if (ue_flag == 1 ){ - for (i=0; i < MAX_MOBILES_PER_ENB ; i++){ - if (pdcp_enb[ctxt_pP->module_id].rnti[i] == 0 ){ - pdcp_enb[ctxt_pP->module_id].rnti[i]=ctxt_pP->rnti; - pdcp_enb[ctxt_pP->module_id].uid[i]=i; - pdcp_enb[ctxt_pP->module_id].num_ues++; - printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti); - // ret=1; - break; + + if (ue_flag == 1 ) { + for (i=0; i < MAX_MOBILES_PER_ENB ; i++) { + if (pdcp_enb[ctxt_pP->module_id].rnti[i] == 0 ) { + pdcp_enb[ctxt_pP->module_id].rnti[i]=ctxt_pP->rnti; + pdcp_enb[ctxt_pP->module_id].uid[i]=i; + pdcp_enb[ctxt_pP->module_id].num_ues++; + printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti); + pdcp_init_stats_UE(ctxt_pP->module_id, i); + // ret=1; + break; } } } + //return ret; } //----------------------------------------------------------------------------- boolean_t pdcp_remove_UE( - const protocol_ctxt_t* const ctxt_pP + const protocol_ctxt_t *const ctxt_pP ) //----------------------------------------------------------------------------- { @@ -1107,11 +1321,11 @@ pdcp_remove_UE( LTE_DRB_Identity_t drb_id = 0; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; - int i; - // check and remove SRBs first + int i; + // check and remove SRBs first - for(int i = 0;i<MAX_MOBILES_PER_ENB;i++){ - if(pdcp_eNB_UE_instance_to_rnti[i] == ctxt_pP->rnti){ + for(int i = 0; i<MAX_MOBILES_PER_ENB; i++) { + if(pdcp_eNB_UE_instance_to_rnti[i] == ctxt_pP->rnti) { pdcp_eNB_UE_instance_to_rnti[i] = NOT_A_RNTI; break; } @@ -1125,24 +1339,23 @@ pdcp_remove_UE( for (drb_id=0; drb_id<LTE_maxDRB; drb_id++) { key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO); h_rc = hashtable_remove(pdcp_coll_p, key); - } (void)h_rc; /* remove gcc warning "set but not used" */ // remove ue for pdcp enb inst - for (i=0; i < MAX_MOBILES_PER_ENB; i++) { + for (i=0; i < MAX_MOBILES_PER_ENB; i++) { if (pdcp_enb[ctxt_pP->module_id].rnti[i] == ctxt_pP->rnti ) { LOG_I(PDCP, "remove uid is %d/%d %x\n", i, - pdcp_enb[ctxt_pP->module_id].uid[i], - pdcp_enb[ctxt_pP->module_id].rnti[i]); + pdcp_enb[ctxt_pP->module_id].uid[i], + pdcp_enb[ctxt_pP->module_id].rnti[i]); pdcp_enb[ctxt_pP->module_id].uid[i]=0; pdcp_enb[ctxt_pP->module_id].rnti[i]=0; pdcp_enb[ctxt_pP->module_id].num_ues--; break; } } - + return 1; } @@ -1150,18 +1363,16 @@ pdcp_remove_UE( //----------------------------------------------------------------------------- boolean_t rrc_pdcp_config_asn1_req ( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, LTE_SRB_ToAddModList_t *const srb2add_list_pP, LTE_DRB_ToAddModList_t *const drb2add_list_pP, LTE_DRB_ToReleaseList_t *const drb2release_list_pP, const uint8_t security_modeP, uint8_t *const kRRCenc_pP, uint8_t *const kRRCint_pP, - uint8_t *const kUPenc_pP -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - ,LTE_PMCH_InfoList_r9_t* const pmch_InfoList_r9_pP -#endif - ,rb_id_t *const defaultDRB + uint8_t *const kUPenc_pP, + LTE_PMCH_InfoList_r9_t *const pmch_InfoList_r9_pP, + rb_id_t *const defaultDRB ) //----------------------------------------------------------------------------- { @@ -1180,17 +1391,13 @@ rrc_pdcp_config_asn1_req ( LTE_SRB_ToAddMod_t *srb_toaddmod_p = NULL; LTE_DRB_ToAddMod_t *drb_toaddmod_p = NULL; pdcp_t *pdcp_p = NULL; - hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; hash_key_t key_defaultDRB = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_defaultDRB_rc; -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) int i,j; LTE_MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL; LTE_MBMS_SessionInfo_r9_t *MBMS_SessionInfo_p = NULL; -#endif - LOG_T(PDCP, PROTOCOL_CTXT_FMT" %s() SRB2ADD %p DRB2ADD %p DRB2RELEASE %p\n", PROTOCOL_CTXT_ARGS(ctxt_pP), __FUNCTION__, @@ -1207,7 +1414,7 @@ rrc_pdcp_config_asn1_req ( rlc_type = RLC_MODE_AM; lc_id = srb_id; key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_YES); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); if (h_rc == HASH_TABLE_OK) { action = CONFIG_ACTION_MODIFY; @@ -1225,9 +1432,8 @@ rrc_pdcp_config_asn1_req ( key); free(pdcp_p); return TRUE; - - } else { - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64"\n", + } else { + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key); } @@ -1235,15 +1441,37 @@ rrc_pdcp_config_asn1_req ( if (srb_toaddmod_p->rlc_Config) { switch (srb_toaddmod_p->rlc_Config->present) { - case LTE_SRB_ToAddMod__rlc_Config_PR_NOTHING: - break; + case LTE_SRB_ToAddMod__rlc_Config_PR_NOTHING: + break; + + case LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue: + switch (srb_toaddmod_p->rlc_Config->choice.explicitValue.present) { + case LTE_RLC_Config_PR_NOTHING: + break; + + default: + pdcp_config_req_asn1 ( + ctxt_pP, + pdcp_p, + SRB_FLAG_YES, + rlc_type, + action, + lc_id, + mch_id, + srb_id, + srb_sn, + 0, // drb_report + 0, // header compression + security_modeP, + kRRCenc_pP, + kRRCint_pP, + kUPenc_pP); + break; + } - case LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue: - switch (srb_toaddmod_p->rlc_Config->choice.explicitValue.present) { - case LTE_RLC_Config_PR_NOTHING: break; - default: + case LTE_SRB_ToAddMod__rlc_Config_PR_defaultValue: pdcp_config_req_asn1 ( ctxt_pP, pdcp_p, @@ -1260,34 +1488,12 @@ rrc_pdcp_config_asn1_req ( kRRCenc_pP, kRRCint_pP, kUPenc_pP); + // already the default values break; - } - - break; - - case LTE_SRB_ToAddMod__rlc_Config_PR_defaultValue: - pdcp_config_req_asn1 ( - ctxt_pP, - pdcp_p, - SRB_FLAG_YES, - rlc_type, - action, - lc_id, - mch_id, - srb_id, - srb_sn, - 0, // drb_report - 0, // header compression - security_modeP, - kRRCenc_pP, - kRRCint_pP, - kUPenc_pP); - // already the default values - break; - default: - DevParam(srb_toaddmod_p->rlc_Config->present, ctxt_pP->module_id, ctxt_pP->rnti); - break; + default: + DevParam(srb_toaddmod_p->rlc_Config->present, ctxt_pP->module_id, ctxt_pP->rnti); + break; } } } @@ -1297,10 +1503,9 @@ rrc_pdcp_config_asn1_req ( if (drb2add_list_pP != NULL) { for (cnt=0; cnt<drb2add_list_pP->list.count; cnt++) { - drb_toaddmod_p = drb2add_list_pP->list.array[cnt]; - drb_id = drb_toaddmod_p->drb_Identity;// + drb_id_offset; + if (drb_toaddmod_p->logicalChannelIdentity) { lc_id = *(drb_toaddmod_p->logicalChannelIdentity); } else { @@ -1316,14 +1521,13 @@ rrc_pdcp_config_asn1_req ( DevCheck4(drb_id < LTE_maxDRB, drb_id, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); if (h_rc == HASH_TABLE_OK) { action = CONFIG_ACTION_MODIFY; LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_MODIFY key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key); - } else { action = CONFIG_ACTION_ADD; pdcp_p = calloc(1, sizeof(pdcp_t)); @@ -1353,7 +1557,7 @@ rrc_pdcp_config_asn1_req ( LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD ADD key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key); - } + } } if (drb_toaddmod_p->pdcp_Config) { @@ -1373,44 +1577,44 @@ rrc_pdcp_config_asn1_req ( } switch (drb_toaddmod_p->pdcp_Config->headerCompression.present) { - case LTE_PDCP_Config__headerCompression_PR_NOTHING: - case LTE_PDCP_Config__headerCompression_PR_notUsed: - header_compression_profile=0x0; - break; - - case LTE_PDCP_Config__headerCompression_PR_rohc: - - // parse the struc and get the rohc profile - if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0001) { - header_compression_profile=0x0001; - } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0002) { - header_compression_profile=0x0002; - } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0003) { - header_compression_profile=0x0003; - } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0004) { - header_compression_profile=0x0004; - } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0006) { - header_compression_profile=0x0006; - } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0101) { - header_compression_profile=0x0101; - } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0102) { - header_compression_profile=0x0102; - } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0103) { - header_compression_profile=0x0103; - } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0104) { - header_compression_profile=0x0104; - } else { + case LTE_PDCP_Config__headerCompression_PR_NOTHING: + case LTE_PDCP_Config__headerCompression_PR_notUsed: header_compression_profile=0x0; - LOG_W(PDCP,"unknown header compresion profile\n"); - } + break; - // set the applicable profile - break; + case LTE_PDCP_Config__headerCompression_PR_rohc: + + // parse the struc and get the rohc profile + if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0001) { + header_compression_profile=0x0001; + } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0002) { + header_compression_profile=0x0002; + } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0003) { + header_compression_profile=0x0003; + } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0004) { + header_compression_profile=0x0004; + } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0006) { + header_compression_profile=0x0006; + } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0101) { + header_compression_profile=0x0101; + } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0102) { + header_compression_profile=0x0102; + } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0103) { + header_compression_profile=0x0103; + } else if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0104) { + header_compression_profile=0x0104; + } else { + header_compression_profile=0x0; + LOG_W(PDCP,"unknown header compresion profile\n"); + } + + // set the applicable profile + break; - default: - LOG_W(PDCP,PROTOCOL_PDCP_CTXT_FMT"[RB %ld] unknown drb_toaddmod->PDCP_Config->headerCompression->present \n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), drb_id); - break; + default: + LOG_W(PDCP,PROTOCOL_PDCP_CTXT_FMT"[RB %ld] unknown drb_toaddmod->PDCP_Config->headerCompression->present \n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), drb_id); + break; } pdcp_config_req_asn1 ( @@ -1438,7 +1642,7 @@ rrc_pdcp_config_asn1_req ( pdrb_id_p = drb2release_list_pP->list.array[cnt]; drb_id = *pdrb_id_p; key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); if (h_rc != HASH_TABLE_OK) { LOG_E(PDCP, PROTOCOL_CTXT_FMT" PDCP REMOVE FAILED drb_id %ld\n", @@ -1446,8 +1650,8 @@ rrc_pdcp_config_asn1_req ( drb_id); continue; } - lc_id = pdcp_p->lcid; + lc_id = pdcp_p->lcid; action = CONFIG_ACTION_REMOVE; pdcp_config_req_asn1 ( ctxt_pP, @@ -1470,7 +1674,7 @@ rrc_pdcp_config_asn1_req ( if ((defaultDRB != NULL) && (*defaultDRB == drb_id)) { // default DRB being removed. nevertheless this shouldn't happen as removing default DRB is not allowed in standard key_defaultDRB = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag); - h_defaultDRB_rc = hashtable_get(pdcp_coll_p, key_defaultDRB, (void**)&pdcp_p); + h_defaultDRB_rc = hashtable_get(pdcp_coll_p, key_defaultDRB, (void **)&pdcp_p); if (h_defaultDRB_rc == HASH_TABLE_OK) { h_defaultDRB_rc = hashtable_remove(pdcp_coll_p, key_defaultDRB); @@ -1483,20 +1687,20 @@ rrc_pdcp_config_asn1_req ( } } -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - if (pmch_InfoList_r9_pP != NULL) { for (i=0; i<pmch_InfoList_r9_pP->list.count; i++) { mbms_SessionInfoList_r9_p = &(pmch_InfoList_r9_pP->list.array[i]->mbms_SessionInfoList_r9); for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) { MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j]; + if (MBMS_SessionInfo_p->sessionId_r9) lc_id = MBMS_SessionInfo_p->sessionId_r9->buf[0]; else lc_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9; + mch_id = MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2]; //serviceId is 3-octet string -// mch_id = j; + // mch_id = j; // can set the mch_id = i if (ctxt_pP->enb_flag) { @@ -1518,13 +1722,12 @@ rrc_pdcp_config_asn1_req ( } LOG_D(PDCP, "lc_id (%02ld) mch_id(%02x,%02x,%02x) drb_id(%ld) action(%d)\n", - lc_id, - MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[0], - MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[1], - MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2], - drb_id, - action); - + lc_id, + MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[0], + MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[1], + MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[2], + drb_id, + action); pdcp_config_req_asn1 ( ctxt_pP, NULL, // unused for MBMS @@ -1545,15 +1748,14 @@ rrc_pdcp_config_asn1_req ( } } -#endif return 0; } //----------------------------------------------------------------------------- boolean_t pdcp_config_req_asn1 ( - const protocol_ctxt_t* const ctxt_pP, - pdcp_t * const pdcp_pP, + const protocol_ctxt_t *const ctxt_pP, + pdcp_t *const pdcp_pP, const srb_flag_t srb_flagP, const rlc_mode_t rlc_modeP, const config_action_t actionP, @@ -1569,179 +1771,182 @@ pdcp_config_req_asn1 ( uint8_t *const kUPenc_pP) //----------------------------------------------------------------------------- { - switch (actionP) { - case CONFIG_ACTION_ADD: - DevAssert(pdcp_pP != NULL); - if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - pdcp_pP->is_ue = FALSE; - pdcp_add_UE(ctxt_pP); - - //pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti; -// pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti; - if( srb_flagP == SRB_FLAG_NO ) { - for(int i = 0;i<MAX_MOBILES_PER_ENB;i++){ - if(pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] == NOT_A_RNTI){ - break; - } - pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB; + case CONFIG_ACTION_ADD: + DevAssert(pdcp_pP != NULL); + + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { + pdcp_pP->is_ue = FALSE; + pdcp_add_UE(ctxt_pP); + + //pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti; + // pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti; + if( srb_flagP == SRB_FLAG_NO ) { + for(int i = 0; i<MAX_MOBILES_PER_ENB; i++) { + if(pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] == NOT_A_RNTI) { + break; + } + + pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB; } + pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti; pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB; - } - //pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB; - } else { - pdcp_pP->is_ue = TRUE; - pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; - } - pdcp_pP->is_srb = (srb_flagP == SRB_FLAG_YES) ? TRUE : FALSE; - pdcp_pP->lcid = lc_idP; - pdcp_pP->rb_id = rb_idP; - pdcp_pP->header_compression_profile = header_compression_profileP; - pdcp_pP->status_report = rb_reportP; - - if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits) { - pdcp_pP->seq_num_size = PDCP_SN_12BIT; - } else if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { - pdcp_pP->seq_num_size = PDCP_SN_7BIT; - } else { - pdcp_pP->seq_num_size = PDCP_SN_5BIT; - } + } + //pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB; + } else { + pdcp_pP->is_ue = TRUE; + pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; + } - pdcp_pP->rlc_mode = rlc_modeP; - pdcp_pP->next_pdcp_tx_sn = 0; - pdcp_pP->next_pdcp_rx_sn = 0; - pdcp_pP->next_pdcp_rx_sn_before_integrity = 0; - pdcp_pP->tx_hfn = 0; - pdcp_pP->rx_hfn = 0; - pdcp_pP->last_submitted_pdcp_rx_sn = 4095; - pdcp_pP->first_missing_pdu = -1; - pdcp_pP->rx_hfn_offset = 0; + pdcp_pP->is_srb = (srb_flagP == SRB_FLAG_YES) ? TRUE : FALSE; + pdcp_pP->lcid = lc_idP; + pdcp_pP->rb_id = rb_idP; + pdcp_pP->header_compression_profile = header_compression_profileP; + pdcp_pP->status_report = rb_reportP; + + if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits) { + pdcp_pP->seq_num_size = 12; + pdcp_pP->maximum_pdcp_rx_sn = (1 << 12) - 1; + } else if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { + pdcp_pP->seq_num_size = 7; + pdcp_pP->maximum_pdcp_rx_sn = (1 << 7) - 1; + } else { + pdcp_pP->seq_num_size = 5; + pdcp_pP->maximum_pdcp_rx_sn = (1 << 5) - 1; + } - LOG_I(PDCP, PROTOCOL_PDCP_CTXT_FMT" Action ADD LCID %d (%s id %d) " + pdcp_pP->rlc_mode = rlc_modeP; + pdcp_pP->next_pdcp_tx_sn = 0; + pdcp_pP->next_pdcp_rx_sn = 0; + pdcp_pP->tx_hfn = 0; + pdcp_pP->rx_hfn = 0; + pdcp_pP->last_submitted_pdcp_rx_sn = 4095; + pdcp_pP->first_missing_pdu = -1; + LOG_I(PDCP, PROTOCOL_PDCP_CTXT_FMT" Action ADD LCID %d (%s id %d) " "configured with SN size %d bits and RLC %s\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), - lc_idP, - (srb_flagP == SRB_FLAG_YES) ? "SRB" : "DRB", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), + lc_idP, + (srb_flagP == SRB_FLAG_YES) ? "SRB" : "DRB", + rb_idP, + pdcp_pP->seq_num_size, + (rlc_modeP == RLC_MODE_AM ) ? "AM" : (rlc_modeP == RLC_MODE_TM) ? "TM" : "UM"); + + /* Setup security */ + if (security_modeP != 0xff) { + pdcp_config_set_security( + ctxt_pP, + pdcp_pP, rb_idP, - pdcp_pP->seq_num_size, - (rlc_modeP == RLC_MODE_AM ) ? "AM" : (rlc_modeP == RLC_MODE_TM) ? "TM" : "UM"); - /* Setup security */ - if (security_modeP != 0xff) { - pdcp_config_set_security( - ctxt_pP, - pdcp_pP, - rb_idP, - lc_idP, - security_modeP, - kRRCenc_pP, - kRRCint_pP, - kUPenc_pP); - } - break; + lc_idP, + security_modeP, + kRRCenc_pP, + kRRCint_pP, + kUPenc_pP); + } - case CONFIG_ACTION_MODIFY: - DevAssert(pdcp_pP != NULL); - pdcp_pP->header_compression_profile=header_compression_profileP; - pdcp_pP->status_report = rb_reportP; - pdcp_pP->rlc_mode = rlc_modeP; + break; - /* Setup security */ - if (security_modeP != 0xff) { - pdcp_config_set_security( - ctxt_pP, - pdcp_pP, - rb_idP, - lc_idP, - security_modeP, - kRRCenc_pP, - kRRCint_pP, - kUPenc_pP); - } + case CONFIG_ACTION_MODIFY: + DevAssert(pdcp_pP != NULL); + pdcp_pP->header_compression_profile=header_compression_profileP; + pdcp_pP->status_report = rb_reportP; + pdcp_pP->rlc_mode = rlc_modeP; - if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { - pdcp_pP->seq_num_size = 7; - } else if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits) { - pdcp_pP->seq_num_size = 12; - } else { - pdcp_pP->seq_num_size=5; - } + /* Setup security */ + if (security_modeP != 0xff) { + pdcp_config_set_security( + ctxt_pP, + pdcp_pP, + rb_idP, + lc_idP, + security_modeP, + kRRCenc_pP, + kRRCint_pP, + kUPenc_pP); + } + + if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { + pdcp_pP->seq_num_size = 7; + } else if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits) { + pdcp_pP->seq_num_size = 12; + } else { + pdcp_pP->seq_num_size=5; + } - LOG_I(PDCP,PROTOCOL_PDCP_CTXT_FMT" Action MODIFY LCID %d " + LOG_I(PDCP,PROTOCOL_PDCP_CTXT_FMT" Action MODIFY LCID %d " "RB id %d reconfigured with SN size %d and RLC %s \n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), - lc_idP, - rb_idP, - rb_snP, + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), + lc_idP, + rb_idP, + rb_snP, (rlc_modeP == RLC_MODE_AM) ? "AM" : (rlc_modeP == RLC_MODE_TM) ? "TM" : "UM"); - break; + break; - case CONFIG_ACTION_REMOVE: - DevAssert(pdcp_pP != NULL); -//#warning "TODO pdcp_module_id_to_rnti" - //pdcp_module_id_to_rnti[ctxt_pP.module_id ][dst_id] = NOT_A_RNTI; - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE LCID %d RBID %d configured\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), - lc_idP, - rb_idP); + case CONFIG_ACTION_REMOVE: + DevAssert(pdcp_pP != NULL); + //#warning "TODO pdcp_module_id_to_rnti" + //pdcp_module_id_to_rnti[ctxt_pP.module_id ][dst_id] = NOT_A_RNTI; + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE LCID %d RBID %d configured\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), + lc_idP, + rb_idP); - if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - // pdcp_remove_UE(ctxt_pP); - } + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { + // pdcp_remove_UE(ctxt_pP); + } - /* Security keys */ - if (pdcp_pP->kUPenc != NULL) { - free(pdcp_pP->kUPenc); - } + /* Security keys */ + if (pdcp_pP->kUPenc != NULL) { + free(pdcp_pP->kUPenc); + } - if (pdcp_pP->kRRCint != NULL) { - free(pdcp_pP->kRRCint); - } + if (pdcp_pP->kRRCint != NULL) { + free(pdcp_pP->kRRCint); + } - if (pdcp_pP->kRRCenc != NULL) { - free(pdcp_pP->kRRCenc); - } + if (pdcp_pP->kRRCenc != NULL) { + free(pdcp_pP->kRRCenc); + } - memset(pdcp_pP, 0, sizeof(pdcp_t)); - break; -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - - case CONFIG_ACTION_MBMS_ADD: - case CONFIG_ACTION_MBMS_MODIFY: - LOG_D(PDCP," %s service_id/mch index %d, session_id/lcid %d, rbid %d configured\n", - //PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), - actionP == CONFIG_ACTION_MBMS_ADD ? "CONFIG_ACTION_MBMS_ADD" : "CONFIG_ACTION_MBMS_MODIFY", - mch_idP, - lc_idP, - rb_idP); + memset(pdcp_pP, 0, sizeof(pdcp_t)); + break; - if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = TRUE ; - pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_idP][lc_idP].rb_id = rb_idP; - } else { - pdcp_mbms_array_ue[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = TRUE ; - pdcp_mbms_array_ue[ctxt_pP->module_id][mch_idP][lc_idP].rb_id = rb_idP; - } + case CONFIG_ACTION_MBMS_ADD: + case CONFIG_ACTION_MBMS_MODIFY: + LOG_D(PDCP," %s service_id/mch index %d, session_id/lcid %d, rbid %d configured\n", + //PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), + actionP == CONFIG_ACTION_MBMS_ADD ? "CONFIG_ACTION_MBMS_ADD" : "CONFIG_ACTION_MBMS_MODIFY", + mch_idP, + lc_idP, + rb_idP); - break; -#endif + if (ctxt_pP->enb_flag == ENB_FLAG_YES) { + pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = TRUE ; + pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_idP][lc_idP].rb_id = rb_idP; + } else { + pdcp_mbms_array_ue[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = TRUE ; + pdcp_mbms_array_ue[ctxt_pP->module_id][mch_idP][lc_idP].rb_id = rb_idP; + } + + break; - case CONFIG_ACTION_SET_SECURITY_MODE: - pdcp_config_set_security( - ctxt_pP, - pdcp_pP, - rb_idP, - lc_idP, - security_modeP, - kRRCenc_pP, - kRRCint_pP, - kUPenc_pP); - break; - - default: - DevParam(actionP, ctxt_pP->module_id, ctxt_pP->rnti); - break; + case CONFIG_ACTION_SET_SECURITY_MODE: + pdcp_config_set_security( + ctxt_pP, + pdcp_pP, + rb_idP, + lc_idP, + security_modeP, + kRRCenc_pP, + kRRCint_pP, + kUPenc_pP); + break; + + default: + DevParam(actionP, ctxt_pP->module_id, ctxt_pP->rnti); + break; } return 0; @@ -1750,14 +1955,14 @@ pdcp_config_req_asn1 ( //----------------------------------------------------------------------------- void pdcp_config_set_security( - const protocol_ctxt_t* const ctxt_pP, - pdcp_t * const pdcp_pP, + const protocol_ctxt_t *const ctxt_pP, + pdcp_t *const pdcp_pP, const rb_id_t rb_idP, const uint16_t lc_idP, const uint8_t security_modeP, - uint8_t * const kRRCenc, - uint8_t * const kRRCint, - uint8_t * const kUPenc) + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc) //----------------------------------------------------------------------------- { DevAssert(pdcp_pP != NULL); @@ -1765,30 +1970,27 @@ pdcp_config_set_security( if ((security_modeP >= 0) && (security_modeP <= 0x77)) { pdcp_pP->cipheringAlgorithm = security_modeP & 0x0f; pdcp_pP->integrityProtAlgorithm = (security_modeP>>4) & 0xf; - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_SET_SECURITY_MODE: cipheringAlgorithm %d integrityProtAlgorithm %d\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), - pdcp_pP->cipheringAlgorithm, - pdcp_pP->integrityProtAlgorithm); - + pdcp_pP->cipheringAlgorithm, + pdcp_pP->integrityProtAlgorithm); pdcp_pP->kRRCenc = kRRCenc; pdcp_pP->kRRCint = kRRCint; pdcp_pP->kUPenc = kUPenc; - /* Activate security */ pdcp_pP->security_activated = 1; - MSC_LOG_EVENT( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - "0 Set security ciph %X integ %x UE %"PRIx16" ", - pdcp_pP->cipheringAlgorithm, - pdcp_pP->integrityProtAlgorithm, - ctxt_pP->rnti); + MSC_LOG_EVENT( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + "0 Set security ciph %X integ %x UE %"PRIx16" ", + pdcp_pP->cipheringAlgorithm, + pdcp_pP->integrityProtAlgorithm, + ctxt_pP->rnti); } else { - MSC_LOG_EVENT( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - "0 Set security failed UE %"PRIx16" ", - ctxt_pP->rnti); - LOG_E(PDCP,PROTOCOL_PDCP_CTXT_FMT" bad security mode %d", + MSC_LOG_EVENT( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + "0 Set security failed UE %"PRIx16" ", + ctxt_pP->rnti); + LOG_E(PDCP,PROTOCOL_PDCP_CTXT_FMT" bad security mode %d", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), security_modeP); } @@ -1797,7 +1999,7 @@ pdcp_config_set_security( //----------------------------------------------------------------------------- void rrc_pdcp_config_req ( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, const uint32_t actionP, const rb_id_t rb_idP, @@ -1807,102 +2009,23 @@ rrc_pdcp_config_req ( pdcp_t *pdcp_p = NULL; hash_key_t key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); hashtable_rc_t h_rc; - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); if (h_rc == HASH_TABLE_OK) { - - /* - * Initialize sequence number state variables of relevant PDCP entity - */ - switch (actionP) { - case CONFIG_ACTION_ADD: - pdcp_p->is_srb = srb_flagP; - pdcp_p->rb_id = rb_idP; - - if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - pdcp_p->is_ue = TRUE; - pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; - } else { - pdcp_p->is_ue = FALSE; - } - - pdcp_p->next_pdcp_tx_sn = 0; - pdcp_p->next_pdcp_rx_sn = 0; - pdcp_p->tx_hfn = 0; - pdcp_p->rx_hfn = 0; - /* SN of the last PDCP SDU delivered to upper layers */ - pdcp_p->last_submitted_pdcp_rx_sn = 4095; - - if (rb_idP < DTCH) { // SRB - pdcp_p->seq_num_size = 5; - } else { // DRB - pdcp_p->seq_num_size = 12; - } - - pdcp_p->first_missing_pdu = -1; - LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %d (already added) configured\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), - rb_idP); - break; - - case CONFIG_ACTION_MODIFY: - break; - - case CONFIG_ACTION_REMOVE: - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE: radio bearer id %d configured\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), - rb_idP); - pdcp_p->next_pdcp_tx_sn = 0; - pdcp_p->next_pdcp_rx_sn = 0; - pdcp_p->tx_hfn = 0; - pdcp_p->rx_hfn = 0; - pdcp_p->last_submitted_pdcp_rx_sn = 4095; - pdcp_p->seq_num_size = 0; - pdcp_p->first_missing_pdu = -1; - pdcp_p->security_activated = 0; - h_rc = hashtable_remove(pdcp_coll_p, key); - - break; - - case CONFIG_ACTION_SET_SECURITY_MODE: - if ((security_modeP >= 0) && (security_modeP <= 0x77)) { - pdcp_p->cipheringAlgorithm= security_modeP & 0x0f; - pdcp_p->integrityProtAlgorithm = (security_modeP>>4) & 0xf; - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_SET_SECURITY_MODE: cipheringAlgorithm %d integrityProtAlgorithm %d\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), - pdcp_p->cipheringAlgorithm, - pdcp_p->integrityProtAlgorithm ); - } else { - LOG_W(PDCP,PROTOCOL_PDCP_CTXT_FMT" bad security mode %d", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), security_modeP); - } - - break; - - default: - DevParam(actionP, ctxt_pP->module_id, ctxt_pP->rnti); - break; - } - } else { + /* + * Initialize sequence number state variables of relevant PDCP entity + */ switch (actionP) { - case CONFIG_ACTION_ADD: - pdcp_p = calloc(1, sizeof(pdcp_t)); - h_rc = hashtable_insert(pdcp_coll_p, key, pdcp_p); - - if (h_rc != HASH_TABLE_OK) { - LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" PDCP ADD FAILED\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); - free(pdcp_p); - - } else { + case CONFIG_ACTION_ADD: pdcp_p->is_srb = srb_flagP; pdcp_p->rb_id = rb_idP; if (ctxt_pP->enb_flag == ENB_FLAG_NO) { pdcp_p->is_ue = TRUE; - pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; + pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; } else { pdcp_p->is_ue = FALSE; - } + } pdcp_p->next_pdcp_tx_sn = 0; pdcp_p->next_pdcp_rx_sn = 0; @@ -1913,83 +2036,161 @@ rrc_pdcp_config_req ( if (rb_idP < DTCH) { // SRB pdcp_p->seq_num_size = 5; - } else { // DRB pdcp_p->seq_num_size = 12; } pdcp_p->first_missing_pdu = -1; - LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Inserting PDCP instance in collection key 0x%"PRIx64"\n", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), key); - LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %d configured\n", + LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %d (already added) configured\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), rb_idP); - } + break; - break; + case CONFIG_ACTION_MODIFY: + break; - case CONFIG_ACTION_REMOVE: - LOG_D(PDCP, PROTOCOL_CTXT_FMT" CONFIG_REQ PDCP CONFIG_ACTION_REMOVE PDCP instance not found\n", - PROTOCOL_CTXT_ARGS(ctxt_pP)); - break; + case CONFIG_ACTION_REMOVE: + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE: radio bearer id %d configured\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), + rb_idP); + pdcp_p->next_pdcp_tx_sn = 0; + pdcp_p->next_pdcp_rx_sn = 0; + pdcp_p->tx_hfn = 0; + pdcp_p->rx_hfn = 0; + pdcp_p->last_submitted_pdcp_rx_sn = 4095; + pdcp_p->seq_num_size = 0; + pdcp_p->first_missing_pdu = -1; + pdcp_p->security_activated = 0; + h_rc = hashtable_remove(pdcp_coll_p, key); + break; - default: - LOG_E(PDCP, PROTOCOL_CTXT_FMT" CONFIG_REQ PDCP NOT FOUND\n", - PROTOCOL_CTXT_ARGS(ctxt_pP)); + case CONFIG_ACTION_SET_SECURITY_MODE: + if ((security_modeP >= 0) && (security_modeP <= 0x77)) { + pdcp_p->cipheringAlgorithm= security_modeP & 0x0f; + pdcp_p->integrityProtAlgorithm = (security_modeP>>4) & 0xf; + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_SET_SECURITY_MODE: cipheringAlgorithm %d integrityProtAlgorithm %d\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), + pdcp_p->cipheringAlgorithm, + pdcp_p->integrityProtAlgorithm ); + } else { + LOG_W(PDCP,PROTOCOL_PDCP_CTXT_FMT" bad security mode %d", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), security_modeP); + } + + break; + + default: + DevParam(actionP, ctxt_pP->module_id, ctxt_pP->rnti); + break; } - } -} + } else { + switch (actionP) { + case CONFIG_ACTION_ADD: + pdcp_p = calloc(1, sizeof(pdcp_t)); + h_rc = hashtable_insert(pdcp_coll_p, key, pdcp_p); + if (h_rc != HASH_TABLE_OK) { + LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" PDCP ADD FAILED\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p)); + free(pdcp_p); + } else { + pdcp_p->is_srb = srb_flagP; + pdcp_p->rb_id = rb_idP; -//----------------------------------------------------------------------------- - -int -pdcp_module_init ( - void -) -//----------------------------------------------------------------------------- -{ - -#ifdef PDCP_USE_RT_FIFO - int ret; + if (ctxt_pP->enb_flag == ENB_FLAG_NO) { + pdcp_p->is_ue = TRUE; + pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; + } else { + pdcp_p->is_ue = FALSE; + } - ret=rtf_create(PDCP2NW_DRIVER_FIFO,32768); + pdcp_p->next_pdcp_tx_sn = 0; + pdcp_p->next_pdcp_rx_sn = 0; + pdcp_p->tx_hfn = 0; + pdcp_p->rx_hfn = 0; + /* SN of the last PDCP SDU delivered to upper layers */ + pdcp_p->last_submitted_pdcp_rx_sn = 4095; + + if (rb_idP < DTCH) { // SRB + pdcp_p->seq_num_size = 5; + } else { // DRB + pdcp_p->seq_num_size = 12; + } - if (ret < 0) { - LOG_E(PDCP, "Cannot create PDCP2NW_DRIVER_FIFO fifo %d (ERROR %d)\n", PDCP2NW_DRIVER_FIFO, ret); - return -1; - } else { - LOG_D(PDCP, "Created PDCP2NAS fifo %d\n", PDCP2NW_DRIVER_FIFO); - rtf_reset(PDCP2NW_DRIVER_FIFO); - } + pdcp_p->first_missing_pdu = -1; + LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Inserting PDCP instance in collection key 0x%"PRIx64"\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), key); + LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %d configured\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), + rb_idP); + } - ret=rtf_create(NW_DRIVER2PDCP_FIFO,32768); + break; - if (ret < 0) { - LOG_E(PDCP, "Cannot create NW_DRIVER2PDCP_FIFO fifo %d (ERROR %d)\n", NW_DRIVER2PDCP_FIFO, ret); + case CONFIG_ACTION_REMOVE: + LOG_D(PDCP, PROTOCOL_CTXT_FMT" CONFIG_REQ PDCP CONFIG_ACTION_REMOVE PDCP instance not found\n", + PROTOCOL_CTXT_ARGS(ctxt_pP)); + break; - return -1; - } else { - LOG_D(PDCP, "Created NW_DRIVER2PDCP_FIFO fifo %d\n", NW_DRIVER2PDCP_FIFO); - rtf_reset(NW_DRIVER2PDCP_FIFO); + default: + LOG_E(PDCP, PROTOCOL_CTXT_FMT" CONFIG_REQ PDCP NOT FOUND\n", + PROTOCOL_CTXT_ARGS(ctxt_pP)); + } } +} - pdcp_2_nas_irq = 0; - pdcp_input_sdu_remaining_size_to_read=0; - pdcp_input_sdu_size_read=0; -#endif +pdcp_data_ind_func_t get_pdcp_data_ind_func() { + return pdcp_params.pdcp_data_ind_func; +} - return 0; +void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req) { + pdcp_params.send_rlc_data_req_func = send_rlc_data_req; +} + +void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind) { + pdcp_params.pdcp_data_ind_func = pdcp_data_ind; +} + +uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { + /* temporary enforce netlink when UE_NAS_USE_TUN is set, + this is while switching from noS1 as build option + to noS1 as config option */ + if ( pdcp_optmask & UE_NAS_USE_TUN_BIT) { + pdcp_params.optmask = pdcp_params.optmask | PDCP_USE_NETLINK_BIT ; + } + + pdcp_params.optmask = pdcp_params.optmask | pdcp_optmask ; + LOG_I(PDCP, "pdcp init,%s %s\n", + ((LINK_ENB_PDCP_TO_GTPV1U)?"usegtp":""), + ((PDCP_USE_NETLINK)?"usenetlink":"")); + + if (PDCP_USE_NETLINK) { + nas_getparams(); + + if(UE_NAS_USE_TUN) { + int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1; + netlink_init_tun("ue",num_if); + LOG_I(PDCP, "UE pdcp will use tun interface\n"); + } else if(ENB_NAS_USE_TUN) { + netlink_init_tun("enb",1); + nas_config(1, 1, 1, "enb"); + LOG_I(PDCP, "ENB pdcp will use tun interface\n"); + } else { + LOG_I(PDCP, "pdcp will use kernel modules\n"); + netlink_init(); + } + } + return pdcp_params.optmask ; } + //----------------------------------------------------------------------------- void pdcp_free ( - void* pdcp_pP + void *pdcp_pP ) //----------------------------------------------------------------------------- { - pdcp_t* pdcp_p = (pdcp_t*)pdcp_pP; + pdcp_t *pdcp_p = (pdcp_t *)pdcp_pP; if (pdcp_p != NULL) { if (pdcp_p->kUPenc != NULL) { @@ -2013,23 +2214,16 @@ pdcp_free ( void pdcp_module_cleanup (void) //----------------------------------------------------------------------------- { -#ifdef PDCP_USE_RT_FIFO - rtf_destroy(NW_DRIVER2PDCP_FIFO); - rtf_destroy(PDCP2NW_DRIVER_FIFO); -#endif } //----------------------------------------------------------------------------- void pdcp_layer_init(void) //----------------------------------------------------------------------------- { - module_id_t instance; int i,j; -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) mbms_session_id_t session_id; mbms_service_id_t service_id; -#endif /* * Initialize SDU list */ @@ -2038,55 +2232,47 @@ void pdcp_layer_init(void) AssertFatal(pdcp_coll_p != NULL, "UNRECOVERABLE error, PDCP hashtable_create failed"); for (instance = 0; instance < MAX_MOBILES_PER_ENB; instance++) { -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - for (service_id = 0; service_id < LTE_maxServiceCount; service_id++) { for (session_id = 0; session_id < LTE_maxSessionPerPMCH; session_id++) { memset(&pdcp_mbms_array_ue[instance][service_id][session_id], 0, sizeof(pdcp_mbms_t)); } } -#endif + pdcp_eNB_UE_instance_to_rnti[instance] = NOT_A_RNTI; } - pdcp_eNB_UE_instance_to_rnti_index = 0; - - for (instance = 0; instance < NUMBER_OF_eNB_MAX; instance++) { -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + pdcp_eNB_UE_instance_to_rnti_index = 0; + for (instance = 0; instance < NUMBER_OF_eNB_MAX; instance++) { for (service_id = 0; service_id < LTE_maxServiceCount; service_id++) { for (session_id = 0; session_id < LTE_maxSessionPerPMCH; session_id++) { memset(&pdcp_mbms_array_eNB[instance][service_id][session_id], 0, sizeof(pdcp_mbms_t)); } } - -#endif } #ifdef MBMS_MULTICAST_OUT mbms_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + if (mbms_socket == -1) LOG_W(PDCP, "Could not create RAW socket, MBMS packets will not be put to the network\n"); -#endif +#endif LOG_I(PDCP, "PDCP layer has been initialized\n"); - pdcp_output_sdu_bytes_to_write=0; pdcp_output_header_bytes_to_write=0; pdcp_input_sdu_remaining_size_to_read=0; - memset(pdcp_enb, 0, sizeof(pdcp_enb_t)); - - memset(Pdcp_stats_tx_window_ms, 0, sizeof(Pdcp_stats_tx_window_ms)); memset(Pdcp_stats_rx_window_ms, 0, sizeof(Pdcp_stats_rx_window_ms)); - for (i =0; i< MAX_NUM_CCs ; i ++){ - for (j=0; j< MAX_MOBILES_PER_ENB;j++){ + + for (i = 0; i < MAX_eNB; i++) { + for (j = 0; j < MAX_MOBILES_PER_ENB; j++) { Pdcp_stats_tx_window_ms[i][j]=100; Pdcp_stats_rx_window_ms[i][j]=100; } } - + memset(Pdcp_stats_tx, 0, sizeof(Pdcp_stats_tx)); memset(Pdcp_stats_tx_w, 0, sizeof(Pdcp_stats_tx_w)); memset(Pdcp_stats_tx_tmp_w, 0, sizeof(Pdcp_stats_tx_tmp_w)); @@ -2097,8 +2283,6 @@ void pdcp_layer_init(void) memset(Pdcp_stats_tx_throughput_w, 0, sizeof(Pdcp_stats_tx_throughput_w)); memset(Pdcp_stats_tx_aiat, 0, sizeof(Pdcp_stats_tx_aiat)); memset(Pdcp_stats_tx_iat, 0, sizeof(Pdcp_stats_tx_iat)); - - memset(Pdcp_stats_rx, 0, sizeof(Pdcp_stats_rx)); memset(Pdcp_stats_rx_w, 0, sizeof(Pdcp_stats_rx_w)); memset(Pdcp_stats_rx_tmp_w, 0, sizeof(Pdcp_stats_rx_tmp_w)); @@ -2110,7 +2294,6 @@ void pdcp_layer_init(void) memset(Pdcp_stats_rx_aiat, 0, sizeof(Pdcp_stats_rx_aiat)); memset(Pdcp_stats_rx_iat, 0, sizeof(Pdcp_stats_rx_iat)); memset(Pdcp_stats_rx_outoforder, 0, sizeof(Pdcp_stats_rx_outoforder)); - } //----------------------------------------------------------------------------- @@ -2118,15 +2301,13 @@ void pdcp_layer_cleanup (void) //----------------------------------------------------------------------------- { list_free (&pdcp_sdu_list); - hashtable_destroy(pdcp_coll_p); + hashtable_destroy(&pdcp_coll_p); #ifdef MBMS_MULTICAST_OUT + if(mbms_socket != -1) { close(mbms_socket); mbms_socket = -1; } + #endif } - -#ifdef PDCP_USE_RT_FIFO -EXPORT_SYMBOL(pdcp_2_nas_irq); -#endif //PDCP_USE_RT_FIFO diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 69157b639837bf146ef29b8306f997597314809b..860f90bf34e85f4511a2bc3cd4b23673225f8b50 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -26,7 +26,7 @@ * \version 1.0 */ -/** @defgroup _pdcp PDCP +/** @defgroup _pdcp PDCP * @ingroup _oai2 * @{ */ @@ -35,8 +35,8 @@ # define __PDCP_H__ //----------------------------------------------------------------------------- #ifndef NON_ACCESS_STRATUM -#include "UTIL/MEM/mem_block.h" -#include "UTIL/LISTS/list.h" + #include "UTIL/MEM/mem_block.h" + #include "UTIL/LISTS/list.h" #endif //NON_ACCESS_STRATUM //----------------------------------------------------------------------------- #include "RRC/LTE/rrc_defs.h" @@ -47,10 +47,40 @@ #include "LTE_SRB-ToAddMod.h" #include "LTE_SRB-ToAddModList.h" #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "LTE_MBMS-SessionInfoList-r9.h" -#include "LTE_PMCH-InfoList-r9.h" + #include "LTE_MBMS-SessionInfoList-r9.h" + #include "LTE_PMCH-InfoList-r9.h" #endif +typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *const, + const srb_flag_t, const MBMS_flag_t, + const rb_id_t, const mui_t, + confirm_t, sdu_size_t, mem_block_t *,const uint32_t *const, const uint32_t *const); +typedef boolean_t (*pdcp_data_ind_func_t)( const protocol_ctxt_t *, const srb_flag_t, + const MBMS_flag_t, const rb_id_t, const sdu_size_t, + mem_block_t *,const uint32_t *const, const uint32_t *const); +/* maximum number of tun interfaces that will be created to emulates UEs */ +/* UEs beyond that will be multiplexed on the same tun */ +#define MAX_NUMBER_NETIF 16 + +#define PDCP_USE_NETLINK_BIT (1<< 11) +#define LINK_ENB_PDCP_TO_IP_DRIVER_BIT (1<< 13) +#define LINK_ENB_PDCP_TO_GTPV1U_BIT (1<< 14) +#define UE_NAS_USE_TUN_BIT (1<< 15) +#define ENB_NAS_USE_TUN_BIT (1<< 16) +typedef struct { + uint64_t optmask; + send_rlc_data_req_func_t send_rlc_data_req_func; + pdcp_data_ind_func_t pdcp_data_ind_func; +} pdcp_params_t; + + + +#define PDCP_USE_NETLINK ( get_pdcp_optmask() & PDCP_USE_NETLINK_BIT) +#define LINK_ENB_PDCP_TO_IP_DRIVER ( get_pdcp_optmask() & LINK_ENB_PDCP_TO_IP_DRIVER_BIT) +#define LINK_ENB_PDCP_TO_GTPV1U ( get_pdcp_optmask() & LINK_ENB_PDCP_TO_GTPV1U_BIT) +#define UE_NAS_USE_TUN ( get_pdcp_optmask() & UE_NAS_USE_TUN_BIT) +#define ENB_NAS_USE_TUN ( get_pdcp_optmask() & ENB_NAS_USE_TUN_BIT) +uint64_t get_pdcp_optmask(void); extern pthread_t pdcp_thread; extern pthread_attr_t pdcp_thread_attr; @@ -61,41 +91,41 @@ extern int pdcp_instance_cnt; #define PROTOCOL_PDCP_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u] " #define PROTOCOL_PDCP_CTXT_ARGS(CTXT_Pp, pDCP_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ - (pDCP_Pp->is_srb) ? "SRB" : "DRB",\ - pDCP_Pp->rb_id + (pDCP_Pp->is_srb) ? "SRB" : "DRB",\ + pDCP_Pp->rb_id int init_pdcp_thread(void); void cleanup_pdcp_thread(void); -uint32_t Pdcp_stats_tx_window_ms[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; -uint32_t Pdcp_stats_tx_bytes[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_bytes_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_sn[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_throughput_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_aiat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_aiat_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_tx_iat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; - -uint32_t Pdcp_stats_rx_window_ms[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; -uint32_t Pdcp_stats_rx[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_bytes[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_bytes_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_sn[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_goodput_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_aiat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_aiat_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_iat[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; -uint32_t Pdcp_stats_rx_outoforder[MAX_NUM_CCs][MAX_MOBILES_PER_ENB][NB_RB_MAX]; - -void pdcp_update_perioidical_stats(const protocol_ctxt_t* const ctxt_pP); +uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB]; +uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; + +uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB]; +uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; +uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX]; + +void pdcp_update_perioidical_stats(const protocol_ctxt_t *const ctxt_pP); /*Packet Probing for agent PDCP*/ @@ -106,12 +136,12 @@ typedef struct pdcp_enb_s { uint16_t uid[MAX_MOBILES_PER_ENB]; rnti_t rnti[MAX_MOBILES_PER_ENB]; uint16_t num_ues; - + uint64_t sfn; frame_t frame; sub_frame_t subframe; - -} pdcp_enb_t; + +} pdcp_enb_t; pdcp_enb_t pdcp_enb[MAX_NUM_CCs]; @@ -136,7 +166,7 @@ typedef struct pdcp_s { boolean_t is_ue; boolean_t is_srb; - /* Configured security algorithms */ + /* Configured security algorithms */ uint8_t cipheringAlgorithm; uint8_t integrityProtAlgorithm; @@ -164,13 +194,12 @@ typedef struct pdcp_s { */ pdcp_sn_t next_pdcp_tx_sn; pdcp_sn_t next_pdcp_rx_sn; - pdcp_sn_t next_pdcp_rx_sn_before_integrity; + pdcp_sn_t maximum_pdcp_rx_sn; /* * TX and RX Hyper Frame Numbers */ pdcp_hfn_t tx_hfn; pdcp_hfn_t rx_hfn; - pdcp_hfn_offset_t rx_hfn_offset; // related to sn mismatch /* * SN of the last PDCP SDU delivered to upper layers @@ -188,10 +217,6 @@ typedef struct pdcp_s { * which is not also a valid sequence number */ short int first_missing_pdu; - /* - * decipher using a different rx_hfn - */ - } pdcp_t; @@ -224,19 +249,19 @@ typedef struct pdcp_mbms_s { * @ingroup _pdcp */ boolean_t pdcp_data_req( - protocol_ctxt_t* ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, \ - const sdu_size_t sdu_buffer_size, - unsigned char* const sdu_buffer, - const pdcp_transmission_mode_t mode + protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, \ + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,const uint32_t * const sourceL2Id - ,const uint32_t * const destinationL2Id + ,const uint32_t *const sourceL2Id + ,const uint32_t *const destinationL2Id #endif - ); +); /*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t) * \brief This functions handles data transfer indications coming from RLC @@ -252,12 +277,12 @@ boolean_t pdcp_data_req( * @ingroup _pdcp */ boolean_t pdcp_data_ind( - const protocol_ctxt_t* const ctxt_pP, - const srb_flag_t srb_flagP, - const MBMS_flag_t MBMS_flagP, - const rb_id_t rb_id, - const sdu_size_t sdu_buffer_size, - mem_block_t* const sdu_buffer); + const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_id, + const sdu_size_t sdu_buffer_size, + mem_block_t *const sdu_buffer); /*! \fn void rrc_pdcp_config_req(const protocol_ctxt_t* const ,uint32_t,rb_id_t,uint8_t) * \brief This functions initializes relevant PDCP entity @@ -270,11 +295,11 @@ boolean_t pdcp_data_ind( * @ingroup _pdcp */ void rrc_pdcp_config_req ( - const protocol_ctxt_t* const ctxt_pP, - const srb_flag_t srb_flagP, - const uint32_t actionP, - const rb_id_t rb_idP, - const uint8_t security_modeP); + const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const uint32_t actionP, + const rb_id_t rb_idP, + const uint8_t security_modeP); /*! \fn bool rrc_pdcp_config_asn1_req (const protocol_ctxt_t* const , SRB_ToAddModList_t* srb2add_list, DRB_ToAddModList_t* drb2add_list, DRB_ToReleaseList_t* drb2release_list) * \brief Function for RRC to configure a Radio Bearer. @@ -291,19 +316,19 @@ void rrc_pdcp_config_req ( * \return A status about the processing, OK or error code. */ boolean_t rrc_pdcp_config_asn1_req ( - const protocol_ctxt_t* const ctxt_pP, - LTE_SRB_ToAddModList_t *const srb2add_list, - LTE_DRB_ToAddModList_t *const drb2add_list, - LTE_DRB_ToReleaseList_t *const drb2release_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc + const protocol_ctxt_t *const ctxt_pP, + LTE_SRB_ToAddModList_t *const srb2add_list, + LTE_DRB_ToAddModList_t *const drb2add_list, + LTE_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 + ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif - ,rb_id_t *const defaultDRB - ); + ,rb_id_t *const defaultDRB +); /*! \fn boolean_t pdcp_config_req_asn1 (const protocol_ctxt_t* const ctxt_pP, srb_flag_t srb_flagP, uint32_t action, rb_id_t rb_id, uint8_t rb_sn, uint8_t rb_report, uint16_t header_compression_profile, uint8_t security_mode) * \brief Function for RRC to configure a Radio Bearer. @@ -326,36 +351,36 @@ boolean_t rrc_pdcp_config_asn1_req ( * \return A status about the processing, OK or error code. */ boolean_t pdcp_config_req_asn1 ( - const protocol_ctxt_t* const ctxt_pP, - pdcp_t *const pdcp_pP, - const srb_flag_t srb_flagP, - const rlc_mode_t rlc_mode, - const uint32_t action, - const uint16_t lc_id, - const uint16_t mch_id, - const rb_id_t rb_id, - const uint8_t rb_sn, - const uint8_t rb_report, - const uint16_t header_compression_profile, - const uint8_t security_mode, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc); + const protocol_ctxt_t *const ctxt_pP, + pdcp_t *const pdcp_pP, + const srb_flag_t srb_flagP, + const rlc_mode_t rlc_mode, + const uint32_t action, + const uint16_t lc_id, + const uint16_t mch_id, + const rb_id_t rb_id, + const uint8_t rb_sn, + const uint8_t rb_report, + const uint16_t header_compression_profile, + const uint8_t security_mode, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc); /*! \fn void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP) * \brief Function (for RRC) to add a new UE in PDCP module * \param[in] ctxt_pP Running context. * \return A status about the processing, OK or error code. */ -void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP); - +void pdcp_add_UE(const protocol_ctxt_t *const ctxt_pP); + /*! \fn boolean_t pdcp_remove_UE(const protocol_ctxt_t* const ctxt_pP) -* \brief Function for RRC to remove UE from PDCP module hashtable +* \brief Function for RRC to remove UE from PDCP module hashtable * \param[in] ctxt_pP Running context. * \return A status about the processing, OK or error code. */ boolean_t pdcp_remove_UE( - const protocol_ctxt_t* const ctxt_pP); + const protocol_ctxt_t *const ctxt_pP); /*! \fn void rrc_pdcp_config_release( const protocol_ctxt_t* const, rb_id_t) * \brief This functions is unused @@ -375,23 +400,21 @@ boolean_t pdcp_remove_UE( * @ingroup _pdcp */ void pdcp_run ( - const protocol_ctxt_t* const ctxt_pP); -int pdcp_module_init (void); + const protocol_ctxt_t *const ctxt_pP); +uint64_t pdcp_module_init (uint64_t pdcp_optmask); void pdcp_module_cleanup (void); void pdcp_layer_init (void); void pdcp_layer_cleanup (void); -#if defined(PDCP_USE_NETLINK_QUEUES) -int pdcp_netlink_init (void); - -#endif #define PDCP2NW_DRIVER_FIFO 21 #define NW_DRIVER2PDCP_FIFO 22 -int pdcp_fifo_flush_sdus ( const protocol_ctxt_t* const ctxt_pP); -int pdcp_fifo_read_input_sdus_remaining_bytes ( const protocol_ctxt_t* const ctxt_pP); -int pdcp_fifo_read_input_sdus ( const protocol_ctxt_t* const ctxt_pP); -void pdcp_fifo_read_input_sdus_from_otg ( const protocol_ctxt_t* const ctxt_pP); - +int pdcp_fifo_flush_sdus ( const protocol_ctxt_t *const ctxt_pP); +int pdcp_fifo_read_input_sdus_remaining_bytes ( const protocol_ctxt_t *const ctxt_pP); +int pdcp_fifo_read_input_sdus ( const protocol_ctxt_t *const ctxt_pP); +void pdcp_fifo_read_input_sdus_from_otg ( const protocol_ctxt_t *const ctxt_pP); +void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req); +void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind); +pdcp_data_ind_func_t get_pdcp_data_ind_func(void); //----------------------------------------------------------------------------- /* @@ -439,26 +462,26 @@ struct sockaddr_in pdcp_sin; void pdcp_pc5_socket_init(void); typedef struct { - rb_id_t rb_id; - sdu_size_t data_size; - signed int inst; - ip_traffic_type_t traffic_type; - uint32_t sourceL2Id; - uint32_t destinationL2Id; + rb_id_t rb_id; + sdu_size_t data_size; + signed int inst; + ip_traffic_type_t traffic_type; + uint32_t sourceL2Id; + uint32_t destinationL2Id; } __attribute__((__packed__)) pc5s_header_t; //new PC5S-message typedef struct { - unsigned char bytes[PC5_SIGNALLING_PAYLOAD_SIZE]; + unsigned char bytes[PC5_SIGNALLING_PAYLOAD_SIZE]; } __attribute__((__packed__)) PC5SignallingMessage ; //example of PC5-S messages typedef struct { - pc5s_header_t pc5s_header; - union { - uint8_t status; - PC5SignallingMessage pc5_signalling_message; - } pc5sPrimitive; + pc5s_header_t pc5s_header; + union { + uint8_t status; + PC5SignallingMessage pc5_signalling_message; + } pc5sPrimitive; } __attribute__((__packed__)) sidelink_pc5s_element; @@ -479,29 +502,18 @@ typedef struct { #define REORDERING_WINDOW_SN_7BIT 64 #define REORDERING_WINDOW_SN_12BIT 2048 -/* - * SN size - */ -#define PDCP_SN_5BIT 5 -#define PDCP_SN_7BIT 7 -#define PDCP_SN_12BIT 12 - - signed int pdcp_2_nas_irq; pdcp_stats_t UE_pdcp_stats[MAX_MOBILES_PER_ENB]; pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX]; -//pdcp_t pdcp_array_srb_ue[MAX_MOBILES_PER_ENB][2]; -//pdcp_t pdcp_array_drb_ue[MAX_MOBILES_PER_ENB][maxDRB]; -//pdcp_t pdcp_array_srb_eNB[NUMBER_OF_eNB_MAX][MAX_MOBILES_PER_ENB][2]; -//pdcp_t pdcp_array_drb_eNB[NUMBER_OF_eNB_MAX][MAX_MOBILES_PER_ENB][maxDRB]; + // for UE code conly rnti_t pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB]; rnti_t pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode unsigned int pdcp_eNB_UE_instance_to_rnti_index; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -pdcp_mbms_t pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h -pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h + pdcp_mbms_t pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h + pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h #endif sdu_size_t pdcp_output_sdu_bytes_to_write; sdu_size_t pdcp_output_header_bytes_to_write; @@ -514,33 +526,33 @@ sdu_size_t pdcp_input_sdu_size_read; sdu_size_t pdcp_input_sdu_remaining_size_to_read; #define PDCP_COLL_KEY_VALUE(mODULE_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \ - ((hash_key_t)mODULE_iD | \ - (((hash_key_t)(rNTI)) << 8) | \ - (((hash_key_t)(iS_eNB)) << 24) | \ - (((hash_key_t)(rB_iD)) << 25) | \ - (((hash_key_t)(iS_sRB)) << 33) | \ - (((hash_key_t)(0x55)) << 34)) + ((hash_key_t)mODULE_iD | \ + (((hash_key_t)(rNTI)) << 8) | \ + (((hash_key_t)(iS_eNB)) << 24) | \ + (((hash_key_t)(rB_iD)) << 25) | \ + (((hash_key_t)(iS_sRB)) << 33) | \ + (((hash_key_t)(0x55)) << 34)) // hash key to the same PDCP as indexed by PDCP_COLL_KEY_VALUE(... rB_iD, iS_sRB=0) where rB_iD // is the default DRB ID. The hidden code 0x55 indicates the key is indexed by (rB_iD,is_sRB) // whereas the hidden code 0xaa indicates the key is for default DRB only #define PDCP_COLL_KEY_DEFAULT_DRB_VALUE(mODULE_iD, rNTI, iS_eNB) \ - ((hash_key_t)mODULE_iD | \ - (((hash_key_t)(rNTI)) << 8) | \ - (((hash_key_t)(iS_eNB)) << 24) | \ - (((hash_key_t)(0xff)) << 25) | \ - (((hash_key_t)(0x00)) << 33) | \ - (((hash_key_t)(0xaa)) << 34)) + ((hash_key_t)mODULE_iD | \ + (((hash_key_t)(rNTI)) << 8) | \ + (((hash_key_t)(iS_eNB)) << 24) | \ + (((hash_key_t)(0xff)) << 25) | \ + (((hash_key_t)(0x00)) << 33) | \ + (((hash_key_t)(0xaa)) << 34)) // service id max val is maxServiceCount = 16 (asn1_constants.h) #define PDCP_COLL_KEY_MBMS_VALUE(mODULE_iD, rNTI, iS_eNB, sERVICE_ID, sESSION_ID) \ - ((hash_key_t)mODULE_iD | \ - (((hash_key_t)(rNTI)) << 8) | \ - (((hash_key_t)(iS_eNB)) << 24) | \ - (((hash_key_t)(sERVICE_ID)) << 32) | \ - (((hash_key_t)(sESSION_ID)) << 37) | \ - (((hash_key_t)(0x0000000000000001)) << 63)) + ((hash_key_t)mODULE_iD | \ + (((hash_key_t)(rNTI)) << 8) | \ + (((hash_key_t)(iS_eNB)) << 24) | \ + (((hash_key_t)(sERVICE_ID)) << 32) | \ + (((hash_key_t)(sESSION_ID)) << 37) | \ + (((hash_key_t)(0x0000000000000001)) << 63)) extern hash_table_t *pdcp_coll_p; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 906fbaba5a4f626cb2457c89f9687138f88b36b0..17d386343b9c0d499f21268f33566b6e41b8c956 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -30,8 +30,8 @@ */ #define PDCP_FIFO_C -#define PDCP_DEBUG 1 -//#define DEBUG_PDCP_FIFO_FLUSH_SDU + + extern int otg_enabled; @@ -54,6 +54,7 @@ extern int otg_enabled; #include "UTIL/OCG/OCG_extern.h" #include "common/utils/LOG/log.h" #include "UTIL/OTG/otg_tx.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "UTIL/FIFO/pad_list.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "platform_constants.h" @@ -62,7 +63,7 @@ extern int otg_enabled; #include "assertions.h" -#ifdef PDCP_USE_NETLINK + #include <sys/socket.h> #include <linux/netlink.h> #include "NETWORK_DRIVER/UE_IP/constant.h" @@ -73,381 +74,109 @@ extern struct nlmsghdr *nas_nlh_tx; extern struct nlmsghdr *nas_nlh_rx; extern struct iovec nas_iov_tx; extern struct iovec nas_iov_rx; -#ifdef UE_NAS_USE_TUN + extern int nas_sock_fd[MAX_MOBILES_PER_ENB]; -#else -extern int nas_sock_fd; -#endif + extern struct msghdr nas_msg_tx; extern struct msghdr nas_msg_rx; -unsigned char pdcp_read_state_g = 0; -extern uint8_t nfapi_mode; + + #ifdef UESIM_EXPANSION -extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; -#endif + extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; #endif extern Packet_OTG_List_t *otg_pdcp_buffer; -#if defined(LINK_ENB_PDCP_TO_GTPV1U) + + # include "gtpv1u_eNB_task.h" # include "gtpv1u_eNB_defs.h" -#endif -extern int gtpv1u_new_data_req( uint8_t enb_module_idP, rnti_t ue_rntiP, uint8_t rab_idP, uint8_t *buffer_pP, uint32_t buf_lenP, uint32_t buf_offsetP); - -/* Prevent de-queueing the same PDCP SDU from the queue twice - * by multiple threads. This has happened in TDD when thread-odd - * is flushing a PDCP SDU after UE_RX() processing; whereas - * thread-even is at a special-subframe, skips the UE_RX() process - * and goes straight to the PDCP SDU flushing. The 2nd flushing - * dequeues the same SDU again causing unexpected behavior. - * - * comment out the MACRO below to disable this protection - */ -#define PDCP_SDU_FLUSH_LOCK -#ifdef PDCP_SDU_FLUSH_LOCK -static pthread_mutex_t mtex = PTHREAD_MUTEX_INITIALIZER; -#endif +extern int gtpv1u_new_data_req( uint8_t enb_module_idP, rnti_t ue_rntiP, uint8_t rab_idP, uint8_t *buffer_pP, uint32_t buf_lenP, uint32_t buf_offsetP); -pdcp_data_req_header_t pdcp_read_header_g; +void debug_pdcp_pc5s_sdu(sidelink_pc5s_element *sl_pc5s_msg, char *title) { + LOG_I(PDCP,"%s: \nPC5S message, header traffic_type: %d)\n", title, sl_pc5s_msg->pc5s_header.traffic_type); + LOG_I(PDCP,"PC5S message, header rb_id: %d)\n", sl_pc5s_msg->pc5s_header.rb_id); + LOG_I(PDCP,"PC5S message, header data_size: %d)\n", sl_pc5s_msg->pc5s_header.data_size); + LOG_I(PDCP,"PC5S message, header inst: %d)\n", sl_pc5s_msg->pc5s_header.inst); + LOG_I(PDCP,"PC5-S message, sourceL2Id: 0x%08x\n)\n", sl_pc5s_msg->pc5s_header.sourceL2Id); + LOG_I(PDCP,"PC5-S message, destinationL1Id: 0x%08x\n)\n", sl_pc5s_msg->pc5s_header.destinationL2Id); +} //----------------------------------------------------------------------------- -int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) -{ - //----------------------------------------------------------------------------- - - //#if defined(PDCP_USE_NETLINK) && defined(LINUX) - int ret = 0; - //#endif - -#ifdef DEBUG_PDCP_FIFO_FLUSH_SDU -#define THREAD_NAME_LEN 16 - static char threadname[THREAD_NAME_LEN]; - ret = pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN); - if (ret != 0) - { - perror("pthread_getname_np : "); - exit_fun("Error getting thread name"); - } -#undef THREAD_NAME_LEN -#endif - -#ifdef PDCP_SDU_FLUSH_LOCK - ret = pthread_mutex_trylock(&mtex); - if (ret == EBUSY) { -#ifdef DEBUG_PDCP_FIFO_FLUSH_SDU - LOG_W(PDCP, "[%s] at SFN/SF=%d/%d wait for PDCP FIFO to be unlocked\n", - threadname, ctxt_pP->frame, ctxt_pP->subframe); -#endif - if (pthread_mutex_lock(&mtex)) { - exit_fun("PDCP_SDU_FLUSH_LOCK lock error!"); - } -#ifdef DEBUG_PDCP_FIFO_FLUSH_SDU - LOG_I(PDCP, "[%s] at SFN/SF=%d/%d PDCP FIFO is unlocked\n", - threadname, ctxt_pP->frame, ctxt_pP->subframe); -#endif - } else if (ret != 0) { - exit_fun("PDCP_SDU_FLUSH_LOCK trylock error!"); - } - -#endif - - mem_block_t *sdu_p = list_get_head (&pdcp_sdu_list); - int bytes_wrote = 0; - int pdcp_nb_sdu_sent = 0; - uint8_t cont = 1; -#if defined(LINK_ENB_PDCP_TO_GTPV1U) - //MessageDef *message_p = NULL; -#endif - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH, 1 ); - while (sdu_p && cont) { - -#ifdef DEBUG_PDCP_FIFO_FLUSH_SDU - LOG_D(PDCP, "[%s] SFN/SF=%d/%d inst=%d size=%d\n", - threadname, ctxt_pP->frame, ctxt_pP->subframe, - ((pdcp_data_ind_header_t*) sdu_p->data)->inst, - ((pdcp_data_ind_header_t *) sdu_p->data)->data_size); -#else - // Raphael: was suppressed by Raymond --> should be suppressed? - // value of sdu_p->data->inst is set in pdcp_data_ind - // it's necessary to set 1 in case of UE with S1. - //if (ctxt_pP->enb_flag){ - // ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; - //} -#endif - -#if defined(LINK_ENB_PDCP_TO_GTPV1U) - - if (ctxt_pP->enb_flag) { - AssertFatal(0, "Now execution should not go here"); - LOG_D(PDCP,"Sending to GTPV1U %d bytes\n", ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); - gtpv1u_new_data_req( - ctxt_pP->module_id, //gtpv1u_data_t *gtpv1u_data_p, - ctxt_pP->rnti,//rb_id/LTE_maxDRB, TO DO UE ID - ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id + 4, - &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t)]), - ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, - 0); - - list_remove_head (&pdcp_sdu_list); - free_mem_block (sdu_p, __func__); - cont = 1; - pdcp_nb_sdu_sent += 1; - sdu_p = list_get_head (&pdcp_sdu_list); - LOG_D(OTG,"After GTPV1U\n"); - continue; // loop again - } - -#endif /* defined(ENABLE_USE_MME) */ -#ifdef PDCP_DEBUG - LOG_I(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n", - ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, - ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); -#endif //PDCP_DEBUG - cont = 0; - -//TTN - for D2D (PC5S) -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - sidelink_pc5s_element *sl_pc5s_msg_recv = NULL; - char send_buf[BUFSIZE]; - int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id; - - if (rb_id == 10) { //hardcoded for PC5-Signaling - //if ((rb_id == 28) | (rb_id == 29) | (rb_id == 30)) - -#ifdef PDCP_DEBUG - sl_pc5s_msg_recv = calloc(1, sizeof(sidelink_pc5s_element)); - memcpy((void*)sl_pc5s_msg_recv, (void*)(sdu_p->data+sizeof(pdcp_data_ind_header_t)), sizeof(sidelink_pc5s_element)); - LOG_D(PDCP,"Received PC5S message, header traffic_type: %d)\n", sl_pc5s_msg_recv->pc5s_header.traffic_type); - LOG_D(PDCP,"Received PC5S message, header rb_id: %d)\n", sl_pc5s_msg_recv->pc5s_header.rb_id); - LOG_D(PDCP,"Received PC5S message, header data_size: %d)\n", sl_pc5s_msg_recv->pc5s_header.data_size); - LOG_D(PDCP,"Received PC5S message, header inst: %d)\n", sl_pc5s_msg_recv->pc5s_header.inst); - LOG_D(PDCP,"Received PC5-S message, sourceL2Id: 0x%08x\n)\n", sl_pc5s_msg_recv->pc5s_header.sourceL2Id); - LOG_D(PDCP,"Received PC5-S message, destinationL1Id: 0x%08x\n)\n", sl_pc5s_msg_recv->pc5s_header.destinationL2Id); - free(sl_pc5s_msg_recv); -#endif - memset(send_buf, 0, BUFSIZE); - memcpy((void *)send_buf, (void*)(sdu_p->data+sizeof(pdcp_data_ind_header_t)), sizeof(sidelink_pc5s_element)); - - int prose_addr_len = sizeof(prose_pdcp_addr); - int n = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len); - if (n < 0) { - LOG_E(PDCP, "ERROR: Failed to send to ProSe App\n"); - exit(EXIT_FAILURE); - } - } -#endif - - if (!pdcp_output_sdu_bytes_to_write) { - if (!pdcp_output_header_bytes_to_write) { - pdcp_output_header_bytes_to_write = sizeof (pdcp_data_ind_header_t); - } - -#ifdef PDCP_USE_RT_FIFO - bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, - &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), - pdcp_output_header_bytes_to_write); - -#else -#ifdef PDCP_USE_NETLINK -#ifdef LINUX - memcpy(NLMSG_DATA(nas_nlh_tx), &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), - pdcp_output_header_bytes_to_write); - nas_nlh_tx->nlmsg_len = pdcp_output_header_bytes_to_write; -#endif //LINUX -#endif //PDCP_USE_NETLINK - - bytes_wrote = pdcp_output_header_bytes_to_write; -#endif //PDCP_USE_RT_FIFO - -#ifdef PDCP_DEBUG - LOG_D(PDCP, "Frame %d Sent %d Bytes of header to Nas_mesh\n", - ctxt_pP->frame, - bytes_wrote); -#endif //PDCP_DEBUG - - if (bytes_wrote > 0) { - pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote; - - if (!pdcp_output_header_bytes_to_write) { // continue with sdu - pdcp_output_sdu_bytes_to_write = ((pdcp_data_ind_header_t *) sdu_p->data)->data_size; - AssertFatal(pdcp_output_sdu_bytes_to_write >= 0, "invalid data_size!"); - -#ifdef PDCP_USE_RT_FIFO - bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); -#else - -#ifdef PDCP_USE_NETLINK -#ifdef LINUX - memcpy(NLMSG_DATA(nas_nlh_tx)+sizeof(pdcp_data_ind_header_t), &(sdu_p->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); - nas_nlh_tx->nlmsg_len += pdcp_output_sdu_bytes_to_write; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE_PDCP_FLUSH_SIZE, pdcp_output_sdu_bytes_to_write); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH_BUFFER, 1 ); -#ifdef UE_NAS_USE_TUN - ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); -#else - ret = sendmsg(nas_sock_fd,&nas_msg_tx,0); -#endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH_BUFFER, 0 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_UE_PDCP_FLUSH_ERR, ret ); - - if (ret<0) { - LOG_E(PDCP, "[PDCP_FIFOS] sendmsg returns %d (errno: %d)\n", ret, errno); - MSC_LOG_TX_MESSAGE_FAILED( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-IND RNTI %"PRIx16" rb %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, - ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); - AssertFatal(1==0,"sendmsg failed for nas_sock_fd\n"); - break; - } else { - MSC_LOG_TX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-IND RNTI %"PRIx16" rb %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, - ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); - } - -#endif // LINUX -#endif //PDCP_USE_NETLINK - bytes_wrote= pdcp_output_sdu_bytes_to_write; -#endif // PDCP_USE_RT_FIFO - -#ifdef PDCP_DEBUG - LOG_D(PDCP, "PDCP->IP Frame %d INST %d: Sent %d Bytes of data from rab %d to higher layers\n", - ctxt_pP->frame, - ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, - bytes_wrote, - ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); -#endif //PDCP_DEBUG - - if (bytes_wrote > 0) { - pdcp_output_sdu_bytes_to_write -= bytes_wrote; - - if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU - // LOG_D(PDCP, "rb sent a sdu qos_sap %d\n", sapiP); - LOG_D(PDCP, - "[FRAME %05d][xxx][PDCP][MOD xx/xx][RB %u][--- PDCP_DATA_IND / %d Bytes --->][IP][INSTANCE %u][RB %u]\n", - ctxt_pP->frame, - ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, - ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, - ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, - ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); - - list_remove_head (&pdcp_sdu_list); - free_mem_block (sdu_p, __func__); - cont = 1; - pdcp_nb_sdu_sent += 1; - sdu_p = list_get_head (&pdcp_sdu_list); - } else { - LOG_D(PDCP, "1 skip free_mem_block: pdcp_output_sdu_bytes_to_write = %d\n", pdcp_output_sdu_bytes_to_write); - AssertFatal(pdcp_output_sdu_bytes_to_write > 0, "pdcp_output_sdu_bytes_to_write cannot be negative!"); - } - } else { - LOG_W(PDCP, "2: RADIO->IP SEND SDU CONGESTION!\n"); - } - } else { - LOG_W(PDCP, "3: RADIO->IP SEND SDU CONGESTION!\n"); - } - } else { - LOG_D(PDCP, "4 skip free_mem_block: bytes_wrote = %d\n", bytes_wrote); - } - } else { - // continue writing sdu -#ifdef PDCP_USE_RT_FIFO - bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, - (uint8_t *) (&(sdu_p->data[sizeof (pdcp_data_ind_header_t) + ((pdcp_data_ind_header_t *) sdu_p->data)->data_size - pdcp_output_sdu_bytes_to_write])), - pdcp_output_sdu_bytes_to_write); -#else // PDCP_USE_RT_FIFO - bytes_wrote = pdcp_output_sdu_bytes_to_write; -#endif // PDCP_USE_RT_FIFO - LOG_D(PDCP, "THINH 2 bytes_wrote = %d\n", bytes_wrote); - - if (bytes_wrote > 0) { - pdcp_output_sdu_bytes_to_write -= bytes_wrote; - - if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU - //PRINT_RB_SEND_OUTPUT_SDU ("[PDCP] RADIO->IP SEND SDU\n"); - list_remove_head (&pdcp_sdu_list); - free_mem_block (sdu_p, __func__); - cont = 1; - pdcp_nb_sdu_sent += 1; - sdu_p = list_get_head (&pdcp_sdu_list); - // LOG_D(PDCP, "rb sent a sdu from rab\n"); - } else { - LOG_D(PDCP, "5 skip free_mem_block: pdcp_output_sdu_bytes_to_write = %d\n", pdcp_output_sdu_bytes_to_write); - } - } else { - LOG_D(PDCP, "6 skip free_mem_block: bytes_wrote = %d\n", bytes_wrote); - } - } - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH, 0 ); - -#ifdef PDCP_USE_RT_FIFO - - if ((pdcp_nb_sdu_sent)) { - if ((pdcp_2_nas_irq > 0)) { -#ifdef PDCP_DEBUG - LOG_D(PDCP, "Frame %d : Trigger NAS RX interrupt\n", - ctxt_pP->frame); -#endif //PDCP_DEBUG - rt_pend_linux_srq (pdcp_2_nas_irq); - - } else { - LOG_E(PDCP, "Frame %d: ERROR IF IP STACK WANTED : NOTIF PACKET(S) pdcp_2_nas_irq not initialized : %d\n", - ctxt_pP->frame, - pdcp_2_nas_irq); +int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { + mem_block_t *sdu_p; + int pdcp_nb_sdu_sent = 0; + int ret=0; + + while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) { + ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; + int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id; + int sizeToWrite= sizeof (pdcp_data_ind_header_t) + + ((pdcp_data_ind_header_t *) sdu_p->data)->data_size; + + if (rb_id == 10) { //hardcoded for PC5-Signaling + if( LOG_DEBUGFLAG(DEBUG_PDCP) ) { + debug_pdcp_pc5s_sdu((sidelink_pc5s_element *)&(sdu_p->data[sizeof(pdcp_data_ind_header_t)]), + "pdcp_fifo_flush_sdus sends a aPC5S message"); } - } - -#endif //PDCP_USE_RT_FIFO -#ifdef PDCP_SDU_FLUSH_LOCK - if (pthread_mutex_unlock(&mtex)) exit_fun("PDCP_SDU_FLUSH_LOCK unlock error!"); -#endif + ret = sendto(pdcp_pc5_sockfd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]), + sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) ); + } else if (UE_NAS_USE_TUN) { + ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + } else if (ENB_NAS_USE_TUN) { + ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + } else if (PDCP_USE_NETLINK) { + memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) sdu_p->data, sizeToWrite); + nas_nlh_tx->nlmsg_len = sizeToWrite; + ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0); + } // PDCP_USE_NETLINK + + AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno)); + list_remove_head (&pdcp_sdu_list); + free_mem_block (sdu_p, __func__); + pdcp_nb_sdu_sent ++; + } - return pdcp_nb_sdu_sent; + return pdcp_nb_sdu_sent; } -//----------------------------------------------------------------------------- -int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) -{ -#ifdef UE_NAS_USE_TUN +int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { protocol_ctxt_t ctxt = *ctxt_pP; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; - pdcp_t* pdcp_p = NULL; + pdcp_t *pdcp_p = NULL; int len; rb_id_t rab_id = DEFAULT_RAB_ID; do { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 ); - len = read(nas_sock_fd[ctxt_pP->module_id], &nl_rx_buf, NL_MAX_PAYLOAD); + len = read(UE_NAS_USE_TUN?nas_sock_fd[ctxt_pP->module_id]:nas_sock_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 ); if (len<=0) continue; + + if (UE_NAS_USE_TUN) { + key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + } else { // => ENB_NAS_USE_TUN + ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0]; + ctxt.enb_flag=ENB_FLAG_YES; + ctxt.module_id=0; + key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_YES); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + } + LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); + if (h_rc == HASH_TABLE_OK) { LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", ctxt.frame, ctxt.instance, len, rab_id); - - LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %u]\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id); MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, @@ -456,486 +185,172 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), ctxt.instance, rab_id, rab_id, len); - pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf, PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , NULL, NULL -#endif ); } else { MSC_LOG_RX_DISCARDED_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ctxt.instance, rab_id, rab_id, len); + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt.instance, rab_id, rab_id, len); LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id, key); } } while (len > 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 ); return len; +} -#else /* UE_NAS_USE_TUN */ - -#ifdef PDCP_USE_NETLINK - protocol_ctxt_t ctxt_cpy = *ctxt_pP; - protocol_ctxt_t ctxt; - hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; - hashtable_rc_t h_rc; - struct pdcp_netlink_element_s* data_p = NULL; - /* avoid gcc warnings */ - (void)data_p; - module_id_t ue_id = 0; - pdcp_t* pdcp_p = NULL; - -//TTN for D2D (PC5S) -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - int prose_addr_len; - char send_buf[BUFSIZE], receive_buf[BUFSIZE]; - //int optval; - int bytes_received; - sidelink_pc5s_element *sl_pc5s_msg_recv = NULL; - sidelink_pc5s_element *sl_pc5s_msg_send = NULL; - //uint32_t sourceL2Id; - //uint32_t groupL2Id; - //module_id_t module_id = 0; - pc5s_header_t *pc5s_header; -#endif - -# if defined(PDCP_USE_NETLINK_QUEUES) - rb_id_t rab_id = 0; - - pdcp_transmission_mode_t pdcp_mode = PDCP_TRANSMISSION_MODE_UNKNOWN; - - - while (pdcp_netlink_dequeue_element(ctxt_pP, &data_p) != 0) { - DevAssert(data_p != NULL); - rab_id = data_p->pdcp_read_header.rb_id % LTE_maxDRB; - // ctxt_pP->rnti is NOT_A_RNTI - ctxt_cpy.rnti = pdcp_module_id_to_rnti[ctxt_cpy.module_id][data_p->pdcp_read_header.inst]; - key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_cpy.rnti, ctxt_pP->enb_flag, rab_id, SRB_FLAG_NO); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - - if (h_rc != HASH_TABLE_OK) { - LOG_W(PDCP, PROTOCOL_CTXT_FMT" Dropped IP PACKET cause no PDCP instanciated\n", - PROTOCOL_CTXT_ARGS(ctxt_pP)); - free(data_p->data); - free(data_p); - data_p = NULL; - continue; - } - - CHECK_CTXT_ARGS(&ctxt_cpy); - - AssertFatal (rab_id < LTE_maxDRB, "RB id is too high (%u/%d)!\n", rab_id, LTE_maxDRB); - - if (rab_id != 0) { - LOG_D(PDCP, "[FRAME %05d][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ " - "/ %d Bytes --->][PDCP][MOD %u][RB %u]\n", - ctxt_cpy.frame, - (ctxt_cpy.enb_flag) ? "eNB" : "UE", - data_p->pdcp_read_header.inst, - data_p->pdcp_read_header.rb_id, - data_p->pdcp_read_header.data_size, - ctxt_cpy.module_id, - rab_id); -#ifdef OAI_NW_DRIVER_TYPE_ETHERNET - - if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_MULTICAST) /*TRAFFIC_IPV6_TYPE_MULTICAST */ || - (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_MULTICAST) /*TRAFFIC_IPV4_TYPE_MULTICAST */ || - (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_BROADCAST) /*TRAFFIC_IPV4_TYPE_BROADCAST */ ) { -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - PDCP_TRANSMISSION_MODE_TRANSPARENT; -#else - pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; -#endif - } else if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_UNICAST) /* TRAFFIC_IPV6_TYPE_UNICAST */ || - (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_UNICAST) /*TRAFFIC_IPV4_TYPE_UNICAST*/ ) { - pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; - } else { - pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; - LOG_W(PDCP,"unknown IP traffic type \n"); - } - -#else // OAI_NW_DRIVER_TYPE_ETHERNET NASMESH driver does not curreenlty support multicast traffic - pdcp_mode = PDCP_TRANSMISSION_MODE_DATA; -#endif - pdcp_data_req(&ctxt_cpy, - SRB_FLAG_NO, - rab_id % LTE_maxDRB, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - data_p->pdcp_read_header.data_size, - data_p->data, - pdcp_mode -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL -#endif - ); - } else if (ctxt_cpy.enb_flag) { - /* rb_id = 0, thus interpreated as broadcast and transported as - * multiple unicast is a broadcast packet, we have to send this - * packet on all default RABS of all connected UEs - */ - LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID first_ue_local %u nb_ue_local %u\n", oai_emulation.info.first_ue_local, oai_emulation.info.nb_ue_local); - - for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { - if (pdcp_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { - LOG_D(PDCP, "eNB Try Forcing send on DEFAULT_RAB_ID UE %d\n", ue_id); - ctxt.module_id = ctxt_cpy.module_id; - ctxt.rnti = ctxt_cpy.pdcp_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; - ctxt.frame = ctxt_cpy.frame; - ctxt.enb_flag = ctxt_cpy.enb_flag; - - pdcp_data_req( - &ctxt, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - data_p->pdcp_read_header.data_size, - data_p->data, - PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL -#endif - ); - } - } - } else { - LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); - pdcp_data_req( - &ctxt_cpy, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - data_p->pdcp_read_header.data_size, - data_p->data, - PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL -#endif - ); - } - - free(data_p->data); - free(data_p); - data_p = NULL; - } - - return 0; -# else /* PDCP_USE_NETLINK_QUEUES*/ - int len = 1; - int msg_len; - rb_id_t rab_id = 0; - int rlc_data_req_flag = 3; - - -//TTN for D2D (PC5S) -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - prose_addr_len = sizeof(prose_pdcp_addr); - // receive a message from ProSe App - memset(receive_buf, 0, BUFSIZE); - bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, BUFSIZE, 0, - (struct sockaddr *) &prose_pdcp_addr, (socklen_t *)&prose_addr_len); - // if (bytes_received < 0){ - // LOG_E(RRC, "ERROR: Failed to receive from ProSe App\n"); - // exit(EXIT_FAILURE); - // } - if (bytes_received > 0) { - pc5s_header = calloc(1, sizeof(pc5s_header_t)); - memcpy((void *)pc5s_header, (void *)receive_buf, sizeof(pc5s_header_t)); - - if (pc5s_header->traffic_type == TRAFFIC_PC5S_SESSION_INIT){ - //send reply to ProSe app - LOG_D(PDCP,"Received a request to open PDCP socket and establish a new PDCP session ... send response to ProSe App \n"); - memset(send_buf, 0, BUFSIZE); - sl_pc5s_msg_send = calloc(1, sizeof(sidelink_pc5s_element)); - sl_pc5s_msg_send->pc5s_header.traffic_type = TRAFFIC_PC5S_SESSION_INIT; - sl_pc5s_msg_send->pc5sPrimitive.status = 1; - - memcpy((void *)send_buf, (void *)sl_pc5s_msg_send, sizeof(sidelink_pc5s_element)); - int prose_addr_len = sizeof(prose_pdcp_addr); - int bytes_sent = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len); - if (bytes_sent < 0) { - LOG_E(PDCP, "ERROR: Failed to send to ProSe App\n"); - exit(EXIT_FAILURE); - } - } else if (pc5s_header->traffic_type == TRAFFIC_PC5S_SIGNALLING) { //if containing PC5-S message -> send to other UE - LOG_D(PDCP,"Received PC5-S message ... send to the other UE\n"); -#ifdef PDCP_DEBUG - LOG_D(PDCP,"Received PC5-S message, traffic_type: %d)\n", pc5s_header->traffic_type); - LOG_D(PDCP,"Received PC5-S message, rbid: %d)\n", pc5s_header->rb_id); - LOG_D(PDCP,"Received PC5-S message, data_size: %d)\n", pc5s_header->data_size); - LOG_D(PDCP,"Received PC5-S message, inst: %d)\n", pc5s_header->inst); - LOG_D(PDCP,"Received PC5-S message,sourceL2Id: 0x%08x\n)\n", pc5s_header->sourceL2Id); - LOG_D(PDCP,"Received PC5-S message,destinationL1Id: 0x%08x\n)\n", pc5s_header->destinationL2Id); +int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctxt_pP) { + int len = 1; + int rlc_data_req_flag = 3; + + while ((len > 0) && (rlc_data_req_flag !=0)) { + pdcp_data_req_header_t pdcp_read_header_g; + protocol_ctxt_t ctxt_cpy = *ctxt_pP; + protocol_ctxt_t ctxt; + hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; + hashtable_rc_t h_rc; + module_id_t ue_id = 0; + pdcp_t *pdcp_p = NULL; + static unsigned char pdcp_read_state_g =0; + rb_id_t rab_id = 0; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 ); + len = recvmsg(nas_sock_fd[0], &nas_msg_rx, 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 ); -#endif + if (len > 0) { + for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf; + NLMSG_OK (nas_nlh_rx, len); + nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, len)) { + if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) { + LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n"); + //return; + } + + if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) { + LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n"); + } + + if (pdcp_read_state_g == 0) { + if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) { + pdcp_read_state_g = 1; //get + memcpy((void *)&pdcp_read_header_g, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t)); + LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d, source L2Id 0x%08x, destination L2Id 0x%08x\n", + pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size,pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id ); + } else { + LOG_E(PDCP, "[PDCP][NETLINK] WRONG size %d should be sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n", + nas_nlh_rx->nlmsg_len); + } + } else { + pdcp_read_state_g = 0; + // print_active_requests() + LOG_D(PDCP, "[PDCP][NETLINK] Something in socket, length %zu\n", + nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr)); + /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ + // pdcp_read_header_g.inst = 0; + //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" + ctxt.frame = ctxt_cpy.frame; + ctxt.enb_flag = ctxt_cpy.enb_flag; + LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %d, source L2Id = 0x%08x, destination L2Id = 0x%08x \n", pdcp_read_header_g.rb_id, pdcp_read_header_g.sourceL2Id, + pdcp_read_header_g.destinationL2Id); -#ifdef OAI_EMU - - // overwrite function input parameters, because only one netlink socket for all instances - if (pc5s_header->inst < oai_emulation.info.nb_enb_local) { - ctxt.frame = ctxt_cpy.frame; - ctxt.enb_flag = ENB_FLAG_YES; - ctxt.module_id = pc5s_header.inst + oai_emulation.info.first_enb_local; - ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pc5s_header->rb_id / LTE_maxDRB + oai_emulation.info.first_ue_local]; - rab_id = pc5s_header->rb_id % LTE_maxDRB; - } else { - ctxt.frame = ctxt_cpy.frame; - ctxt.enb_flag = ENB_FLAG_NO; - ctxt.module_id = pc5s_header->inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local; - ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; - rab_id = pc5s_header->rb_id % LTE_maxDRB; - } - - CHECK_CTXT_ARGS(&ctxt); - AssertFatal (rab_id < LTE_maxDRB, "RB id is too high (%u/%d)!\n", rab_id, LTE_maxDRB); - /*LGpdcp_read_header.inst = (pc5s_header.inst >= oai_emulation.info.nb_enb_local) ? \ - pc5s_header.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : - pc5s_header.inst + oai_emulation.info.first_enb_local;*/ -#else // OAI_EMU - /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ - // pc5s_header.inst = 0; - //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" - ctxt.frame = ctxt_cpy.frame; - ctxt.enb_flag = ctxt_cpy.enb_flag; - - LOG_I(PDCP, "[PDCP] pc5s_header->rb_id = %d\n", pc5s_header->rb_id); - - if (ctxt_cpy.enb_flag) { - ctxt.module_id = 0; - rab_id = pc5s_header->rb_id % LTE_maxDRB; - ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index]; - } else { + if (ctxt.enb_flag) { ctxt.module_id = 0; - rab_id = pc5s_header->rb_id % LTE_maxDRB; - ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; - } -#endif + rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB; + ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / LTE_maxDRB]; - //UE - if (!ctxt.enb_flag) { if (rab_id != 0) { - if (rab_id == UE_IP_DEFAULT_RAB_ID) { - LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", - ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", - (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); - } else { - rab_id = rab_id % LTE_maxDRB; - LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", - ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); - key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n", - (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); - } - - if (h_rc == HASH_TABLE_OK) { - rab_id = pdcp_p->rb_id; -#ifdef PDCP_DEBUG - LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", - ctxt.frame, - pc5s_header->inst, - bytes_received, - pc5s_header->rb_id); - - LOG_I(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", - ctxt.frame, - pc5s_header->inst, - pc5s_header->rb_id, - pc5s_header->data_size, - ctxt.module_id, - ctxt.rnti, - rab_id); -#endif - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pc5s_header->inst, - pc5s_header->rb_id, - rab_id, - pc5s_header->data_size); - - pdcp_data_req( - &ctxt, - SRB_FLAG_NO, - rab_id, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pc5s_header->data_size, - (unsigned char *)receive_buf, - PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,&pc5s_header->sourceL2Id - ,&pc5s_header->destinationL2Id -#endif - ); - } else { - MSC_LOG_RX_DISCARDED_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pc5s_header->inst, - pc5s_header->rb_id, - rab_id, - pc5s_header->data_size); - LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + rab_id = rab_id % LTE_maxDRB; + key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + + if (h_rc == HASH_TABLE_OK) { + LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", + ctxt.frame, + pdcp_read_header_g.inst, + len, + nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), + pdcp_read_header_g.rb_id); + MSC_LOG_RX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + rab_id, + pdcp_read_header_g.data_size); + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %u]\n", + ctxt_cpy.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + rab_id); + pdcp_data_req(&ctxt, + SRB_FLAG_NO, + rab_id, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pdcp_read_header_g.data_size, + (unsigned char *)NLMSG_DATA(nas_nlh_rx), + PDCP_TRANSMISSION_MODE_DATA + ,NULL, NULL + ); + } else { + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n", + ctxt.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + rab_id); + } + } else { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast + // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs + //#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES + for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { + if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { + ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", ctxt.frame, - pc5s_header->inst, - pc5s_header->rb_id, - pc5s_header->data_size, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, ctxt.module_id, ctxt.rnti, - rab_id, - key); - } - } else { //if (rab_id == 0) - LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", - ctxt.frame, - pc5s_header->inst, - pc5s_header->rb_id, - pc5s_header->data_size, - ctxt.module_id, - ctxt.rnti, - DEFAULT_RAB_ID); - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL,0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pc5s_header->inst, - pc5s_header->rb_id, - DEFAULT_RAB_ID, - pc5s_header->data_size); - - pdcp_data_req ( - &ctxt, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pc5s_header->data_size, - (unsigned char *)receive_buf, - PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,&pc5s_header->sourceL2Id - ,&pc5s_header->destinationL2Id -#endif - ); - } - } - free (sl_pc5s_msg_recv); - free (sl_pc5s_msg_send); - } - } - -#endif - - while ((len > 0) && (rlc_data_req_flag !=0)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 ); - len = recvmsg(nas_sock_fd, &nas_msg_rx, 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 ); - - if (len<=0) { - // nothing in pdcp NAS socket - //LOG_D(PDCP, "[PDCP][NETLINK] Nothing in socket, length %d \n", len); - } else { - - msg_len = len; - for (nas_nlh_rx = (struct nlmsghdr *) nl_rx_buf; - NLMSG_OK (nas_nlh_rx, msg_len); - nas_nlh_rx = NLMSG_NEXT (nas_nlh_rx, msg_len)) { - - if (nas_nlh_rx->nlmsg_type == NLMSG_DONE) { - LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_DONE\n"); - //return; - } - - if (nas_nlh_rx->nlmsg_type == NLMSG_ERROR) { - LOG_D(PDCP, "[PDCP][NETLINK] RX NLMSG_ERROR\n"); + DEFAULT_RAB_ID); + pdcp_data_req ( + &ctxt, + SRB_FLAG_NO, + DEFAULT_RAB_ID, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pdcp_read_header_g.data_size, + (unsigned char *)NLMSG_DATA(nas_nlh_rx), + PDCP_TRANSMISSION_MODE_DATA + ,NULL, NULL + ); + } + } } - - if (pdcp_read_state_g == 0) { - if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) { - pdcp_read_state_g = 1; //get - memcpy((void *)&pdcp_read_header_g, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t)); - LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d, source L2Id 0x%08x, destination L2Id 0x%08x\n", - pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size,pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id ); - } else { - LOG_E(PDCP, "[PDCP][NETLINK] WRONG size %d should be sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n", - nas_nlh_rx->nlmsg_len); - } - } else { - pdcp_read_state_g = 0; - // print_active_requests() -#ifdef PDCP_DEBUG - LOG_D(PDCP, "[PDCP][NETLINK] Something in socket, length %zu\n", - nas_nlh_rx->nlmsg_len - sizeof(struct nlmsghdr)); -#endif - -#ifdef OAI_EMU - - - // overwrite function input parameters, because only one netlink socket for all instances - if (pdcp_read_header_g.inst < oai_emulation.info.nb_enb_local) { - ctxt.frame = ctxt_cpy.frame; - ctxt.enb_flag = ENB_FLAG_YES; - ctxt.module_id = pdcp_read_header_g.inst + oai_emulation.info.first_enb_local; - ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_read_header_g.rb_id / LTE_maxDRB + oai_emulation.info.first_ue_local]; - rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB; - } else { - ctxt.frame = ctxt_cpy.frame; - ctxt.enb_flag = ENB_FLAG_NO; - ctxt.module_id = pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local; - ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; - rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB; - } - - CHECK_CTXT_ARGS(&ctxt); - AssertFatal (rab_id < LTE_maxDRB, "RB id is too high (%u/%d)!\n", rab_id, LTE_maxDRB); - /*LGpdcp_read_header.inst = (pdcp_read_header_g.inst >= oai_emulation.info.nb_enb_local) ? \ - pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : - pdcp_read_header_g.inst + oai_emulation.info.first_enb_local;*/ -#else // OAI_EMU - /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ - // pdcp_read_header_g.inst = 0; - //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" - ctxt.frame = ctxt_cpy.frame; - ctxt.enb_flag = ctxt_cpy.enb_flag; - -#ifdef PDCP_DEBUG - LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %d, source L2Id = 0x%08x, destination L2Id = 0x%08x \n", pdcp_read_header_g.rb_id, pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id); -#endif - if (ctxt_cpy.enb_flag) { - ctxt.module_id = 0; - rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB; - ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / LTE_maxDRB]; - } else { - if (nfapi_mode == 3) { + } else { // ctxt.enb_flag => UE + if (NFAPI_MODE == NFAPI_UE_STUB_PNF) { #ifdef UESIM_EXPANSION ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst]; #else @@ -944,282 +359,348 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) } else { ctxt.module_id = 0; } + rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB; ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; - } - -#endif - if (ctxt.enb_flag) { if (rab_id != 0) { + if (rab_id == UE_IP_DEFAULT_RAB_ID) { + LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", + ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); + } else { + rab_id = rab_id % LTE_maxDRB; + LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", + ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); + key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); + } + + if (h_rc == HASH_TABLE_OK) { + rab_id = pdcp_p->rb_id; + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", + ctxt.frame, + pdcp_read_header_g.inst, + len, + nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), + pdcp_read_header_g.rb_id); + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + ctxt.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + rab_id); + MSC_LOG_RX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + rab_id, + pdcp_read_header_g.data_size); + pdcp_data_req( + &ctxt, + SRB_FLAG_NO, + rab_id, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pdcp_read_header_g.data_size, + (unsigned char *)NLMSG_DATA(nas_nlh_rx), + PDCP_TRANSMISSION_MODE_DATA, + (NFAPI_MODE == NFAPI_UE_STUB_PNF)?NULL:&pdcp_read_header_g.sourceL2Id, + (NFAPI_MODE == NFAPI_UE_STUB_PNF)?NULL:&pdcp_read_header_g.destinationL2Id + ); + } else { /* else of h_rc == HASH_TABLE_OK */ + MSC_LOG_RX_DISCARDED_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + rab_id, + pdcp_read_header_g.data_size); + LOG_D(PDCP, + "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + ctxt.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + rab_id, + key); + } /* h_rc != HASH_TABLE_OK */ + } else {/* else of rab_id != 0 */ + LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + ctxt.frame, + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + pdcp_read_header_g.data_size, + ctxt.module_id, + ctxt.rnti, + DEFAULT_RAB_ID); + MSC_LOG_RX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL,0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pdcp_read_header_g.inst, + pdcp_read_header_g.rb_id, + DEFAULT_RAB_ID, + pdcp_read_header_g.data_size); + pdcp_data_req ( + &ctxt, + SRB_FLAG_NO, + DEFAULT_RAB_ID, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pdcp_read_header_g.data_size, + (unsigned char *)NLMSG_DATA(nas_nlh_rx), + PDCP_TRANSMISSION_MODE_DATA, + (NFAPI_MODE == NFAPI_UE_STUB_PNF) ? NULL :&pdcp_read_header_g.sourceL2Id, + (NFAPI_MODE == NFAPI_UE_STUB_PNF) ? NULL :&pdcp_read_header_g.destinationL2Id + ); + } /* rab_id == 0 */ + } /*pdcp_read_state_g != 0 */ + } /* UE */ + } /* for loop on netlink buffers */ + + return len; + } /* len > 0 */ + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 ); + } /* while loop on reading from netlink socket */ + + return 0; +} /* pdcp_fifo_read_input_sdus_fromnetlinksock */ + +void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) { + protocol_ctxt_t ctxt_cpy = *ctxt_pP; + protocol_ctxt_t ctxt; + hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; + hashtable_rc_t h_rc; + struct pdcp_netlink_element_s *data_p = NULL; + /* avoid gcc warnings */ + (void)data_p; + pdcp_t *pdcp_p = NULL; + //TTN for D2D (PC5S) + int prose_addr_len; + char send_buf[BUFSIZE], receive_buf[BUFSIZE]; + //int optval; + int bytes_received; + sidelink_pc5s_element *sl_pc5s_msg_send = NULL; + pc5s_header_t *pc5s_header; + rb_id_t rab_id = 0; + //TTN for D2D (PC5S) + // receive a message from ProSe App + memset(receive_buf, 0, BUFSIZE); + bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, BUFSIZE, 0, + (struct sockaddr *) &prose_pdcp_addr, (socklen_t *)&prose_addr_len); + + if (bytes_received > 0) { + pc5s_header = calloc(1, sizeof(pc5s_header_t)); + memcpy((void *)pc5s_header, (void *)receive_buf, sizeof(pc5s_header_t)); + + switch(pc5s_header->traffic_type) { + case TRAFFIC_PC5S_SESSION_INIT : + //send reply to ProSe app + LOG_D(PDCP,"Received a request to open PDCP socket and establish a new PDCP session ... send response to ProSe App \n"); + memset(send_buf, 0, BUFSIZE); + sl_pc5s_msg_send = calloc(1, sizeof(sidelink_pc5s_element)); + sl_pc5s_msg_send->pc5s_header.traffic_type = TRAFFIC_PC5S_SESSION_INIT; + sl_pc5s_msg_send->pc5sPrimitive.status = 1; + memcpy((void *)send_buf, (void *)sl_pc5s_msg_send, sizeof(sidelink_pc5s_element)); + int prose_addr_len = sizeof(prose_pdcp_addr); + int bytes_sent = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len); + free (sl_pc5s_msg_send); + + if (bytes_sent < 0) { + LOG_E(PDCP, "ERROR: Failed to send to ProSe App\n"); + exit(EXIT_FAILURE); + } + + break; + + case TRAFFIC_PC5S_SIGNALLING: /* PC5-S message -> send to other UE */ + if( LOG_DEBUGFLAG(DEBUG_PDCP) ) { + debug_pdcp_pc5s_sdu((sidelink_pc5s_element *)send_buf, + "pdcp_fifo_read_input_sdus received aPC5S message"); + } + + /* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */ + // pc5s_header.inst = 0; + //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" + ctxt.frame = ctxt_cpy.frame; + ctxt.enb_flag = ctxt_cpy.enb_flag; + LOG_I(PDCP, "[PDCP] pc5s_header->rb_id = %d\n", pc5s_header->rb_id); + + if (ctxt_cpy.enb_flag) { + ctxt.module_id = 0; + rab_id = pc5s_header->rb_id % LTE_maxDRB; + ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index]; + } else { + ctxt.module_id = 0; + rab_id = pc5s_header->rb_id % LTE_maxDRB; + ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; + } + + //UE + if (!ctxt.enb_flag) { + if (rab_id != 0) { + if (rab_id == UE_IP_DEFAULT_RAB_ID) { + LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", + ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); + } else { rab_id = rab_id % LTE_maxDRB; + LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", + ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - - - if (h_rc == HASH_TABLE_OK) { -#ifdef PDCP_DEBUG - LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", - ctxt.frame, - pdcp_read_header_g.inst, - len, - nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), - pdcp_read_header_g.rb_id); -#endif - - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - rab_id, - pdcp_read_header_g.data_size); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %u]\n", - ctxt_cpy.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - rab_id); - - pdcp_data_req(&ctxt, - SRB_FLAG_NO, - rab_id, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pdcp_read_header_g.data_size, - (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL -#endif - ); - } else { - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - rab_id); - } - } else { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast - // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs - //#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES - for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { - if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { - ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - DEFAULT_RAB_ID); - pdcp_data_req ( - &ctxt, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pdcp_read_header_g.data_size, - (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL -#endif - ); - } - } - } - } else { // enb_flag - if (rab_id != 0) { - if (rab_id == UE_IP_DEFAULT_RAB_ID) { - LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", - ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", - (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); - } else { - rab_id = rab_id % LTE_maxDRB; - LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", - ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); - key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", - (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); - } - - if (h_rc == HASH_TABLE_OK) { - rab_id = pdcp_p->rb_id; -#ifdef PDCP_DEBUG - LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", - ctxt.frame, - pdcp_read_header_g.inst, - len, - nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), - pdcp_read_header_g.rb_id); - - LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - rab_id); -#endif - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - rab_id, - pdcp_read_header_g.data_size); - if(nfapi_mode == 3){ - pdcp_data_req( - &ctxt, - SRB_FLAG_NO, - rab_id, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pdcp_read_header_g.data_size, - (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL - ,NULL -#endif - ); - }else{ - pdcp_data_req( - &ctxt, - SRB_FLAG_NO, - rab_id, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pdcp_read_header_g.data_size, - (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,&pdcp_read_header_g.sourceL2Id - ,&pdcp_read_header_g.destinationL2Id -#endif - ); - } - } else { - MSC_LOG_RX_DISCARDED_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - rab_id, - pdcp_read_header_g.data_size); - LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - rab_id, - key); - } - } else { - LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", - ctxt.frame, - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - pdcp_read_header_g.data_size, - ctxt.module_id, - ctxt.rnti, - DEFAULT_RAB_ID); - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL,0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - DEFAULT_RAB_ID, - pdcp_read_header_g.data_size); - if(nfapi_mode == 3){ - pdcp_data_req ( - &ctxt, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pdcp_read_header_g.data_size, - (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL - ,NULL -#endif - ); - }else{ - pdcp_data_req ( - &ctxt, - SRB_FLAG_NO, - DEFAULT_RAB_ID, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pdcp_read_header_g.data_size, - (unsigned char *)NLMSG_DATA(nas_nlh_rx), - PDCP_TRANSMISSION_MODE_DATA -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,&pdcp_read_header_g.sourceL2Id - ,&pdcp_read_header_g.destinationL2Id -#endif - ); - } - } - } + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n", + (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); + } + if (h_rc == HASH_TABLE_OK) { + rab_id = pdcp_p->rb_id; + LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", + ctxt.frame, + pc5s_header->inst, + bytes_received, + pc5s_header->rb_id); + LOG_I(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + ctxt.frame, + pc5s_header->inst, + pc5s_header->rb_id, + pc5s_header->data_size, + ctxt.module_id, + ctxt.rnti, + rab_id); + MSC_LOG_RX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pc5s_header->inst, + pc5s_header->rb_id, + rab_id, + pc5s_header->data_size); + pdcp_data_req( + &ctxt, + SRB_FLAG_NO, + rab_id, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pc5s_header->data_size, + (unsigned char *)receive_buf, + PDCP_TRANSMISSION_MODE_DATA, + &pc5s_header->sourceL2Id, + &pc5s_header->destinationL2Id + ); + } else { /* else of h_rc == HASH_TABLE_OK */ + MSC_LOG_RX_DISCARDED_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pc5s_header->inst, + pc5s_header->rb_id, + rab_id, + pc5s_header->data_size); + LOG_D(PDCP, + "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + ctxt.frame, + pc5s_header->inst, + pc5s_header->rb_id, + pc5s_header->data_size, + ctxt.module_id, + ctxt.rnti, + rab_id, + key); } - } - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 ); - } + } else { /* else of if (rab_id == 0) */ + LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + ctxt.frame, + pc5s_header->inst, + pc5s_header->rb_id, + pc5s_header->data_size, + ctxt.module_id, + ctxt.rnti, + DEFAULT_RAB_ID); + MSC_LOG_RX_MESSAGE( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, + NULL,0, + MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + pc5s_header->inst, + pc5s_header->rb_id, + DEFAULT_RAB_ID, + pc5s_header->data_size); + pdcp_data_req ( + &ctxt, + SRB_FLAG_NO, + DEFAULT_RAB_ID, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pc5s_header->data_size, + (unsigned char *)receive_buf, + PDCP_TRANSMISSION_MODE_DATA, + &pc5s_header->sourceL2Id, + &pc5s_header->destinationL2Id + ); + } + } /* end of !ctxt.enb_flag */ + default: + LOG_D(PDCP, "pc5s message type %d, unknown...\n", pc5s_header->traffic_type); + break; + } /* end of switch */ + }/* end of bytes_received > 0 */ +} /* pdcp_fifo_read_input_sdus_frompc5s */ - return len; -# endif -#else // neither PDCP_USE_NETLINK nor PDCP_USE_RT_FIFO - return 0; -#endif // PDCP_USE_NETLINK -#endif /* #else UE_NAS_USE_TUN */ +//----------------------------------------------------------------------------- +int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) { + if (UE_NAS_USE_TUN || ENB_NAS_USE_TUN) { + return pdcp_fifo_read_input_sdus_fromtun (ctxt_pP); + } else if (PDCP_USE_NETLINK) { + pdcp_fifo_read_input_sdus_frompc5s (ctxt_pP); + return pdcp_fifo_read_input_sdus_fromnetlinksock(ctxt_pP); + } /* PDCP_USE_NETLINK */ + + return 0; } -void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) { - - +void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t *const ctxt_pP) { module_id_t dst_id; // dst for otg protocol_ctxt_t ctxt; + // we need to add conditions to avoid transmitting data when the UE is not RRC connected. if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic - PROTOCOL_CTXT_SET_BY_MODULE_ID( &ctxt, ctxt_pP->module_id, @@ -1236,39 +717,35 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) } //TTN for D2D (PC5S) -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void pdcp_pc5_socket_init() { - //pthread_attr_t attr; - //struct sched_param sched_param; - int optval; // flag value for setsockopt - //int n; // message byte size - - //create PDCP socket - pdcp_pc5_sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (pdcp_pc5_sockfd < 0){ - LOG_E(PDCP,"[pdcp_pc5_socket_init] Error opening socket %d (%d:%s)\n",pdcp_pc5_sockfd,errno, strerror(errno)); - exit(EXIT_FAILURE); - } - - optval = 1; - setsockopt(pdcp_pc5_sockfd, SOL_SOCKET, SO_REUSEADDR, - (const void *)&optval , sizeof(int)); - - fcntl(pdcp_pc5_sockfd,F_SETFL,O_NONBLOCK); - - bzero((char *) &pdcp_sin, sizeof(pdcp_sin)); - pdcp_sin.sin_family = AF_INET; - pdcp_sin.sin_addr.s_addr = htonl(INADDR_ANY); - pdcp_sin.sin_port = htons(PDCP_SOCKET_PORT_NO); - // associate the parent socket with a port - if (bind(pdcp_pc5_sockfd, (struct sockaddr *) &pdcp_sin, - sizeof(pdcp_sin)) < 0) { - LOG_E(PDCP,"[pdcp_pc5_socket_init] ERROR: Failed on binding the socket\n"); - exit(1); - } + //pthread_attr_t attr; + //struct sched_param sched_param; + int optval; // flag value for setsockopt + //int n; // message byte size + //create PDCP socket + pdcp_pc5_sockfd = socket(AF_INET, SOCK_DGRAM, 0); + + if (pdcp_pc5_sockfd < 0) { + LOG_E(PDCP,"[pdcp_pc5_socket_init] Error opening socket %d (%d:%s)\n",pdcp_pc5_sockfd,errno, strerror(errno)); + exit(EXIT_FAILURE); + } + optval = 1; + setsockopt(pdcp_pc5_sockfd, SOL_SOCKET, SO_REUSEADDR, + (const void *)&optval, sizeof(int)); + fcntl(pdcp_pc5_sockfd,F_SETFL,O_NONBLOCK); + bzero((char *) &pdcp_sin, sizeof(pdcp_sin)); + pdcp_sin.sin_family = AF_INET; + pdcp_sin.sin_addr.s_addr = htonl(INADDR_ANY); + pdcp_sin.sin_port = htons(PDCP_SOCKET_PORT_NO); + + // associate the parent socket with a port + if (bind(pdcp_pc5_sockfd, (struct sockaddr *) &pdcp_sin, + sizeof(pdcp_sin)) < 0) { + LOG_E(PDCP,"[pdcp_pc5_socket_init] ERROR: Failed on binding the socket\n"); + exit(1); + } } -#endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c index 472c46c94a46d6825eefb7d4ca1ef831a1abdf55..f47694c2e31a8928f74b7266052022d8482d15cf 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c @@ -43,7 +43,7 @@ /* Bugfix for version of GCC = 4.4.3 (Ubuntu 10.04) */ #if GCC_VERSION <= 40403 -# include <sys/socket.h> + #include <sys/socket.h> #endif #include <linux/netlink.h> @@ -70,7 +70,7 @@ extern struct iovec nas_iov_rx; extern int nas_sock_fd; extern struct msghdr nas_msg_rx; -#if defined(PDCP_USE_NETLINK_QUEUES) + static pthread_t pdcp_netlink_thread; /* We use lock-free queues between the User-plane driver running in kernel-space @@ -93,41 +93,37 @@ pdcp_netlink_init( ) //----------------------------------------------------------------------------- { - int i; int nb_inst_enb; int nb_inst_ue; pthread_attr_t attr; struct sched_param sched_param; - reset_meas(&ip_pdcp_stats_tmp); nb_inst_enb = 1; nb_inst_ue = 1; -#if defined(LINK_ENB_PDCP_TO_GTPV1U) - nb_inst_enb = 0; - LOG_I(PDCP, "[NETLINK] Creating 0 queues for eNB Netlink -> PDCP communication\n"); -#else -#warning " LG: When there will be handover in, there will problems because dim is based on local nums of ues" - pdcp_netlink_queue_enb = calloc(nb_inst_enb, sizeof(struct lfds611_queue_state*)); - pdcp_netlink_nb_element_enb = malloc(nb_inst_enb * sizeof(uint32_t)); - LOG_I(PDCP, "[NETLINK] Creating %d queues for eNB Netlink -> PDCP communication\n", nb_inst_enb); + if (LINK_ENB_PDCP_TO_GTPV1U) { + nb_inst_enb = 0; + LOG_I(PDCP, "[NETLINK] Creating 0 queues for eNB Netlink -> PDCP communication\n"); + } else { + /* #warning " LG: When there will be handover in, there will problems because dim is based on local nums of ues" */ + pdcp_netlink_queue_enb = calloc(nb_inst_enb, sizeof(struct lfds611_queue_state *)); + pdcp_netlink_nb_element_enb = malloc(nb_inst_enb * sizeof(uint32_t)); + LOG_I(PDCP, "[NETLINK] Creating %d queues for eNB Netlink -> PDCP communication\n", nb_inst_enb); - for (i = 0; i < nb_inst_enb; i++) { - pdcp_netlink_nb_element_enb[i] = 0; + for (i = 0; i < nb_inst_enb; i++) { + pdcp_netlink_nb_element_enb[i] = 0; - if (lfds611_queue_new(&pdcp_netlink_queue_enb[i], PDCP_QUEUE_NB_ELEMENTS) < 0) { - LOG_E(PDCP, "Failed to create new FIFO for eNB Netlink -> PDCP communcation instance %d\n", i); - exit(EXIT_FAILURE); + if (lfds611_queue_new(&pdcp_netlink_queue_enb[i], PDCP_QUEUE_NB_ELEMENTS) < 0) { + LOG_E(PDCP, "Failed to create new FIFO for eNB Netlink -> PDCP communcation instance %d\n", i); + exit(EXIT_FAILURE); + } } } -#endif - if (nb_inst_ue > 0) { - pdcp_netlink_queue_ue = calloc(nb_inst_ue, sizeof(struct lfds611_queue_state*)); + pdcp_netlink_queue_ue = calloc(nb_inst_ue, sizeof(struct lfds611_queue_state *)); pdcp_netlink_nb_element_ue = malloc(nb_inst_ue * sizeof(uint32_t)); - LOG_I(PDCP, "[NETLINK] Creating %d queues for UE Netlink -> PDCP communication\n", nb_inst_ue); for (i = 0; i < nb_inst_ue; i++) { @@ -148,7 +144,6 @@ pdcp_netlink_init( } sched_param.sched_priority = 10; - pthread_attr_setschedpolicy(&attr, SCHED_RR); pthread_attr_setschedparam(&attr, &sched_param); @@ -171,21 +166,21 @@ pdcp_netlink_init( //----------------------------------------------------------------------------- int pdcp_netlink_dequeue_element( - const protocol_ctxt_t* const ctxt_pP, - struct pdcp_netlink_element_s** data_ppP + const protocol_ctxt_t *const ctxt_pP, + struct pdcp_netlink_element_s **data_ppP ) //----------------------------------------------------------------------------- { int ret = 0; if (ctxt_pP->enb_flag) { - ret = lfds611_queue_dequeue(pdcp_netlink_queue_enb[ctxt_pP->module_id], (void**)data_ppP); + ret = lfds611_queue_dequeue(pdcp_netlink_queue_enb[ctxt_pP->module_id], (void **)data_ppP); if (ret != 0) { LOG_D(PDCP,"[NETLINK]De-queueing packet for eNB instance %d\n", ctxt_pP->module_id); } } else { - ret = lfds611_queue_dequeue(pdcp_netlink_queue_ue[ctxt_pP->module_id], (void**)data_ppP); + ret = lfds611_queue_dequeue(pdcp_netlink_queue_ue[ctxt_pP->module_id], (void **)data_ppP); if (ret != 0) { LOG_D(PDCP, "[NETLINK]De-queueing packet for UE instance %d\n", ctxt_pP->module_id); @@ -209,8 +204,8 @@ void *pdcp_netlink_thread_fct(void *arg) memset(nl_rx_buf, 0, NL_MAX_PAYLOAD); LOG_I(PDCP, "[NETLINK_THREAD] binding to fd %d\n",nas_sock_fd); MSC_START_USE(); - while (1) { + while (1) { len = recvmsg(nas_sock_fd, &nas_msg_rx, 0); if (len == 0) { @@ -248,7 +243,7 @@ void *pdcp_netlink_thread_fct(void *arg) new_data_p->pdcp_read_header.data_size); } else { LOG_E(PDCP, "[NETLINK_THREAD] WRONG size %d should be sizeof " - "%d ((pdcp_data_req_header_t) + sizeof(struct nlmsghdr))\n", + "%lu ((pdcp_data_req_header_t) + sizeof(struct nlmsghdr))\n", nas_nlh_rx->nlmsg_len, sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)); } @@ -262,12 +257,11 @@ void *pdcp_netlink_thread_fct(void *arg) if (eNB_flag) { if (pdcp_netlink_nb_element_enb[module_id] > PDCP_QUEUE_NB_ELEMENTS) { - LOG_E(PDCP, "[NETLINK_THREAD][Mod %02x] We reached maximum number of elements in eNB pdcp queue (%d)\n", - module_id, pdcp_netlink_nb_element_enb); + LOG_E(PDCP, "[NETLINK_THREAD][Mod %02x] We reached maximum number of elements in eNB pdcp queue (%lu)\n", + module_id, (intptr_t)pdcp_netlink_nb_element_enb); } LOG_I(PDCP,"[NETLINK_THREAD] IP->PDCP : En-queueing packet for eNB module id %d\n", module_id); - /* Enqueue the element in the right queue */ lfds611_queue_guaranteed_enqueue(pdcp_netlink_queue_enb[module_id], new_data_p); stop_meas(&ip_pdcp_stats_tmp); @@ -275,12 +269,11 @@ void *pdcp_netlink_thread_fct(void *arg) } else { if (pdcp_netlink_nb_element_ue[module_id] > PDCP_QUEUE_NB_ELEMENTS) { - LOG_E(PDCP, "[NETLINK_THREAD][Mod %02x] We reached maximum number of elements in UE pdcp queue (%d)\n", - module_id, pdcp_netlink_nb_element_ue); + LOG_E(PDCP, "[NETLINK_THREAD][Mod %02x] We reached maximum number of elements in UE pdcp queue (%lu)\n", + module_id, (intptr_t)pdcp_netlink_nb_element_ue); } LOG_I(PDCP,"[NETLINK_THREAD] IP->PDCP : En-queueing packet for UE module id %d\n", module_id); - /* Enqueue the element in the right queue */ lfds611_queue_guaranteed_enqueue(pdcp_netlink_queue_ue[module_id], new_data_p); stop_meas(&ip_pdcp_stats_tmp); @@ -293,4 +286,4 @@ void *pdcp_netlink_thread_fct(void *arg) return NULL; } -#endif + diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h index 8e57f84b0a9e9fa86ec72144b219a2b9714304f3..8b5ebe7287c52ddbb15409edceec218569127b0d 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h @@ -173,7 +173,6 @@ int pdcp_netlink_dequeue_element(const protocol_ctxt_t* const ctxt_pP, void pdcp_config_set_security(const protocol_ctxt_t* const ctxt_pP, pdcp_t *pdcp_pP, rb_id_t rb_idP, uint16_t lc_idP, uint8_t security_modeP, uint8_t *kRRCenc_pP, uint8_t *kRRCint_pP, uint8_t *kUPenc_pP); -#if defined(ENABLE_SECURITY) int pdcp_apply_security(const protocol_ctxt_t* const ctxt_pP, pdcp_t *pdcp_entity, srb_flag_t srb_flagP, @@ -188,10 +187,10 @@ int pdcp_validate_security(const protocol_ctxt_t* const ctxt_pP, srb_flag_t srb_flagP, rb_id_t rb_id, uint8_t pdcp_header_len, - uint16_t current_sn, + uint32_t hfn, + int sn, uint8_t *pdcp_pdu_buffer, uint16_t sdu_buffer_size); -#endif /* defined(ENABLE_SECURITY) */ #endif /** @}*/ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c index 83293a709de2b7e60b13c02f8cd97821d8fe4dc6..a18713fbb67a32c94a91a922e47f7e7f67657310 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c @@ -40,13 +40,6 @@ #include "msc.h" #include "pdcp_primitives.h" -#if defined(ENABLE_SECURITY) - -static -uint32_t pdcp_get_next_count_tx(pdcp_t *const pdcp_pP, const srb_flag_t srb_flagP, const uint16_t pdcp_sn); -static -uint32_t pdcp_get_next_count_rx(pdcp_t *const pdcp_pP, const srb_flag_t srb_flagP, const uint16_t pdcp_sn); - //----------------------------------------------------------------------------- static uint32_t pdcp_get_next_count_tx( @@ -79,26 +72,25 @@ static uint32_t pdcp_get_next_count_rx( pdcp_t * const pdcp_pP, const srb_flag_t srb_flagP, - const uint16_t pdcp_sn) + const uint32_t hfn, + const int sn) { uint32_t count; /* For RX COUNT = RX_HFN << length of SN | pdcp SN of received PDU */ if (srb_flagP) { /* 5 bits length SN */ - count = (((pdcp_pP->rx_hfn + pdcp_pP->rx_hfn_offset) << 5) | (pdcp_sn & 0x001F)); + count = (hfn << 5) | (sn & 0x001F); } else { - if (pdcp_pP->seq_num_size == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { + if (pdcp_pP->seq_num_size == 7) { /* 7 bits length SN */ - count = (((pdcp_pP->rx_hfn + pdcp_pP->rx_hfn_offset) << 7) | (pdcp_sn & 0x007F)); + count = (hfn << 7) | (sn & 0x007F); } else { // default /* 12 bits length SN */ - count = (((pdcp_pP->rx_hfn + pdcp_pP->rx_hfn_offset) << 12) | (pdcp_sn & 0x0FFF)); + count = (hfn << 12) | (sn & 0x0FFF); } } - // reset the hfn offset - pdcp_pP->rx_hfn_offset =0; LOG_D(PDCP, "[OSA] RX COUNT = 0x%08x\n", count); return count; @@ -182,7 +174,8 @@ pdcp_validate_security( const srb_flag_t srb_flagP, const rb_id_t rb_id, const uint8_t pdcp_header_len, - const uint16_t current_sn, + const uint32_t hfn, + const int sn, uint8_t *const pdcp_pdu_buffer, const uint16_t sdu_buffer_size ) @@ -201,7 +194,7 @@ pdcp_validate_security( decrypt_params.direction = (pdcp_pP->is_ue == 1) ? SECU_DIRECTION_DOWNLINK : SECU_DIRECTION_UPLINK ; decrypt_params.bearer = rb_id - 1; - decrypt_params.count = pdcp_get_next_count_rx(pdcp_pP, srb_flagP, current_sn); + decrypt_params.count = pdcp_get_next_count_rx(pdcp_pP, srb_flagP, hfn, sn); decrypt_params.message = &pdcp_pdu_buffer[pdcp_header_len]; decrypt_params.blength = (sdu_buffer_size - pdcp_header_len) << 3; decrypt_params.key_length = 16; @@ -235,8 +228,8 @@ pdcp_validate_security( " Security: failed MAC-I Algo %X UE %"PRIx16" ", pdcp_pP->integrityProtAlgorithm, ctxt_pP->rnti); - LOG_E(PDCP, "[OSA][RB %d] %s failed to validate MAC-I of incoming PDU\n", - rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB"); + LOG_E(PDCP, "[OSA][RB %d] %s failed to validate MAC-I (key %llx) of incoming PDU\n", + rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB",((long long unsigned int*)decrypt_params.key)[0]); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT); return -1; } @@ -246,5 +239,3 @@ pdcp_validate_security( return 0; } - -#endif /* ENABLE_SECURITY */ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c index c6deb4944172b214c69d5f16df7025eb3a717dde..cdc583ef217873df5f794f6f9359136d1c2a1a33 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c @@ -140,152 +140,6 @@ boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity) return TRUE; } -/** - * Checks if incoming PDU has a sequence number in accordance with the RX window - * @return 1 if SN is okay, 0 otherwise - * XXX Reordering window should also be handled here - */ -boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity,srb_flag_t srb_flagP) -{ - - uint16_t reordering_window = 0; - - LOG_D(PDCP, "Incoming RX Sequence number is %04d\n", seq_num); - - if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE || pdcp_is_seq_num_valid(seq_num, pdcp_entity->seq_num_size) == FALSE) { - return FALSE; - } - - /* - * Mark received sequence numbers to keep track of missing ones - * (and to build PDCP Control PDU for PDCP status report) - */ - if (pdcp_mark_current_pdu_as_received(seq_num, pdcp_entity) == TRUE) { - LOG_D(PDCP, "Received sequence number successfuly marked\n"); - } else { - LOG_W(PDCP, "Cannot mark received sequence number on the bitmap!\n"); - } - - /* - * RX Procedures for SRB and DRBs as described in sec 5.1.2 of 36.323 - */ - - if (srb_flagP) { // SRB - - if (seq_num < pdcp_entity->next_pdcp_rx_sn) { - // decipher and verify the integrity of the PDU (if applicable) using COUNT based on RX_HFN + 1 and the received PDCP SN - pdcp_entity->rx_hfn++; - pdcp_entity->rx_hfn_offset = 0; - } else { - // decipher and verify the integrity of the PDU (if applicable) using COUNT based using COUNT based on RX_HFN and the received PDCP SN - pdcp_entity->rx_hfn_offset = 0; - } - - // Assume that integrity verification is applicable and the integrity verification is passed successfully; - // or assume that integrity verification is not applicable: - - // same the old next_pdcp_rx_sn to revert otherwise - pdcp_entity->next_pdcp_rx_sn_before_integrity = pdcp_entity->next_pdcp_rx_sn; - - if (seq_num != pdcp_entity->next_pdcp_rx_sn) { - LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num); - } - - //set Next_PDCP_RX_SN to the received PDCP SN +1 ; - pdcp_entity->next_pdcp_rx_sn = seq_num; - pdcp_advance_rx_window(pdcp_entity); // + 1, and check if it is larger than Maximum_PDCP_SN: - - } else { // DRB - - if (pdcp_entity->seq_num_size == PDCP_SN_7BIT) { - reordering_window = REORDERING_WINDOW_SN_7BIT; - } else { - reordering_window = REORDERING_WINDOW_SN_12BIT; - } - - switch (pdcp_entity->rlc_mode) { - case RLC_MODE_AM: - if ((seq_num - pdcp_entity->last_submitted_pdcp_rx_sn > reordering_window) || - ((0 <= pdcp_entity->last_submitted_pdcp_rx_sn - seq_num) && - (pdcp_entity->last_submitted_pdcp_rx_sn - seq_num < reordering_window) )) { - - if (seq_num > pdcp_entity->next_pdcp_rx_sn) { - /* - * decipher the PDCP PDU as specified in the subclause 5.6, using COUNT based on RX_HFN - 1 and the received PDCP SN; - */ - pdcp_entity->rx_hfn_offset = -1; - } else { - /* - * decipher the PDCP PDU as specified in the subclause 5.6, using COUNT based on RX_HFN and the received PDCP SN; - */ - pdcp_entity->rx_hfn_offset = 0; - } - - // discard this PDCP SDU; - LOG_W(PDCP, "Out of the reordering window (Incoming SN:%d, Expected SN:%d): discard this PDCP SDU\n", - seq_num, pdcp_entity->next_pdcp_rx_sn); - return FALSE; - } else if (pdcp_entity->next_pdcp_rx_sn - seq_num > reordering_window) { - pdcp_entity->rx_hfn++; - // use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU; - pdcp_entity->rx_hfn_offset = 0; - pdcp_entity->next_pdcp_rx_sn++; - } else if (seq_num - pdcp_entity->next_pdcp_rx_sn >= reordering_window ) { - // use COUNT based on RX_HFN – 1 and the received PDCP SN for deciphering the PDCP PDU; - pdcp_entity->rx_hfn_offset = -1; - } else if (seq_num >= pdcp_entity->next_pdcp_rx_sn ) { - // use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU; - pdcp_entity->rx_hfn_offset = 0; - //set Next_PDCP_RX_SN to the received PDCP SN +1 ; - pdcp_entity->next_pdcp_rx_sn = seq_num; - pdcp_advance_rx_window(pdcp_entity); // + 1, anc check if it is larger than Maximum_PDCP_SN: - LOG_D(PDCP,"Re-adjusting the sequence number to %d\n", seq_num); - } else if (seq_num < pdcp_entity->next_pdcp_rx_sn) { - // use COUNT based on RX_HFN and the received PDCP SN for deciphering the PDCP PDU; - pdcp_entity->rx_hfn_offset = 0; - } - - break; - - case RLC_MODE_UM : - if (seq_num < pdcp_entity->next_pdcp_rx_sn) { - pdcp_entity->rx_hfn++; - } - - // decipher the PDCP Data PDU using COUNT based on RX_HFN and the received PDCP SN as specified in the subclause 5.6; - //set Next_PDCP_RX_SN to the received PDCP SN +1 ; - pdcp_entity->next_pdcp_rx_sn = seq_num; - pdcp_advance_rx_window(pdcp_entity); // + 1, and check if it is larger than Maximum_PDCP_SN: - - break; - - case RLC_MODE_TM : - default: - LOG_W(PDCP,"RLC mode %d not supported\n",pdcp_entity->rlc_mode); - return FALSE; - } - } - - /* - if (seq_num == pdcp_entity->next_pdcp_rx_sn) { - LOG_I(PDCP, "Next expected SN (%d) arrived, advancing RX window\n", seq_num); - - return pdcp_advance_rx_window(pdcp_entity); - } else { - LOG_E(PDCP, "Incoming SN is not the one we expected to receive! (Incoming:%d, Expected:%d)\n", \ - seq_num, pdcp_entity->next_pdcp_rx_sn); - - - // Update first missing PDU (used in PDCP Control PDU for PDCP status report, see 6.2.6) - if (pdcp_entity->first_missing_pdu != -1) - pdcp_entity->first_missing_pdu = pdcp_entity->next_pdcp_rx_sn; - - return FALSE; - } - */ - return TRUE; -} - boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity) { /* diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h index ec59a4b4fe8dca5190bd26118b0e0209af2f8b8e..172c9810e69c29ad81f911f6b61a72759cf9812e 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h @@ -59,11 +59,6 @@ uint16_t pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity); * Advances the RX window state of given PDCP entity upon successfull receipt of a SDU */ boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity); -/** - * Checks if incoming PDU has a sequence number in accordance with the RX window - * @return TRUE if it is valid, FALSE otherwise - */ -boolean_t pdcp_is_rx_seq_number_valid(uint16_t seq_num, pdcp_t* pdcp_entity,srb_flag_t srb_flagP); /** * Updates missing PDU bitmap with incoming sequence number * @return TRUE if successful, FALSE otherwise diff --git a/openair2/LAYER2/PROTO_AGENT/cu_test.c b/openair2/LAYER2/PROTO_AGENT/cu_test.c new file mode 100644 index 0000000000000000000000000000000000000000..78467d68f0a88b38c7d9d4f0df247931146b2ecb --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/cu_test.c @@ -0,0 +1,177 @@ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <sys/time.h> + +#include "ENB_APP/enb_paramdef.h" +#include "LAYER2/PROTO_AGENT/proto_agent.h" +#define BUF_MAX 1400 + +int recv_client = 0; +FILE *output; + +void usage(char *prg_name) +{ + fprintf(stderr, "usage: %s <file or ->\n", prg_name); + fprintf(stderr, " - is stdin\n"); + fprintf(stderr, " received packets are written to stdout\n"); +} + +long uelapsed(struct timeval *s, struct timeval *e) +{ + return e->tv_sec * 1000000 + e->tv_usec - (s->tv_sec * 1000000 + s->tv_usec); +} + +boolean_t +pdcp_data_ind( + const protocol_ctxt_t* const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, + const sdu_size_t sdu_buffer_sizeP, + mem_block_t* const sdu_buffer_pP +) +{ + fwrite(sdu_buffer_pP->data, sdu_buffer_sizeP, 1, stdout); + fflush(stdout); + free_mem_block(sdu_buffer_pP, __func__); + /* cannot free because of const */ + //free(ctxt_pP); + recv_client = 1; + return 0; +} + +void close_proto_agent(void) +{ + proto_agent_stop(0); +} + +int main(int argc, char *argv[]) +{ + const cudu_params_t params = { + .local_ipv4_address = "192.168.12.45", + .local_port = 6464, + .remote_ipv4_address = "192.168.12.45", + .remote_port = 6465 + }; + + protocol_ctxt_t p; + memset(&p, 0, sizeof p); + mem_block_t mem; + char s[BUF_MAX]; + size_t size, totsize = 0; + struct timeval t_start, t_end; + FILE *f; + + if (argc != 2) { + usage(argv[0]); + return 1; + } + + if (strcmp(argv[1], "-") == 0) { + f = stdin; + } else { + f = fopen(argv[1], "r"); + } + if (!f) { + fprintf(stderr, "cannot open %s: %s\n", argv[1], strerror(errno)); + return 2; + } + + pool_buffer_init(); + if (proto_agent_start(0, ¶ms) != 0) { + fprintf(stderr, "error on proto_agent_start()\n"); + fclose(f); + return 3; + } + atexit(close_proto_agent); + + /* wait for first packet of client */ + while (!recv_client) sleep(1); + fprintf(stderr, "reading file\n"); + + /* now send back at the same time */ + gettimeofday(&t_start, NULL); + while ((size = fread(s, 1, BUF_MAX, f)) > 0) { + usleep(10); + totsize += size; + mem.data = &s[0]; + proto_agent_send_rlc_data_req(&p, 0, 0, 0, 0, 0, size, &mem); + } + gettimeofday(&t_end, NULL); + fclose(f); + long us = uelapsed(&t_start, &t_end); + fprintf(stderr, "read %zu bytes in %ld ms -> %.3fMB/s, %.3fMbps\n", + totsize, us / 1000, ((float) totsize ) / us, + ((float) totsize) / us * 8); + fprintf(stderr, "check files using 'diff afile bfile'\n"); + + /* give some time in case the other direction is slower */ + sleep(5); + return 0; +} + +/* + ********************************************************* + * arbitrary functions, needed for linking (used or not) * + ********************************************************* + */ + +rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + confirm_t confirmP, + sdu_size_t sdu_sizeP, + mem_block_t *sdu_pP +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t * const sourceL2Id + ,const uint32_t * const destinationL2Id +#endif + ) +{ + fprintf(stderr, "This should never be called on the CU\n"); + exit(1); +} + +pthread_t new_thread(void *(*f)(void *), void *b) { + pthread_t t; + pthread_attr_t att; + + if (pthread_attr_init(&att)){ + fprintf(stderr, "pthread_attr_init err\n"); + exit(1); + } + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) { + fprintf(stderr, "pthread_attr_setdetachstate err\n"); + exit(1); + } + if (pthread_create(&t, &att, f, b)) { + fprintf(stderr, "pthread_create err\n"); + exit(1); + } + if (pthread_attr_destroy(&att)) { + fprintf(stderr, "pthread_attr_destroy err\n"); + exit(1); + } + + return t; +} + +int log_header(char *log_buffer, int buffsize, int comp, int level,const char *format) +{ + return 0; +} + +int config_get(paramdef_t *params,int numparams, char *prefix) +{ + return 0; +} + +int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) +{ + return 0; +} diff --git a/openair2/LAYER2/PROTO_AGENT/du_test.c b/openair2/LAYER2/PROTO_AGENT/du_test.c new file mode 100644 index 0000000000000000000000000000000000000000..9ff7662ab1884c8df1f8266cf3304a3877da7c8f --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/du_test.c @@ -0,0 +1,169 @@ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <sys/time.h> + +#include "ENB_APP/enb_paramdef.h" +#include "LAYER2/PROTO_AGENT/proto_agent.h" + +#define BUF_MAX 1400 + +void usage(char *prg_name) +{ + fprintf(stderr, "usage: %s <file or ->\n", prg_name); + fprintf(stderr, " - is stdin\n"); + fprintf(stderr, " received packets are written to stdout\n"); +} + +long uelapsed(struct timeval *s, struct timeval *e) +{ + return e->tv_sec * 1000000 + e->tv_usec - (s->tv_sec * 1000000 + s->tv_usec); +} + + +rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + confirm_t confirmP, + sdu_size_t sdu_sizeP, + mem_block_t *sdu_pP +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t * const sourceL2Id + ,const uint32_t * const destinationL2Id +#endif + ) +{ + fwrite(sdu_pP->data, sdu_sizeP, 1, stdout); + fflush(stdout); + free_mem_block(sdu_pP, __func__); + //free(ctxt_pP); + return 0; +} + +void close_proto_agent(void) +{ + proto_agent_stop(0); +} + +int main(int argc, char *argv[]) +{ + const cudu_params_t params = { + .local_ipv4_address = "192.168.12.45", + .local_port = 6465, + .remote_ipv4_address = "192.168.12.45", + .remote_port = 6464 + }; + + protocol_ctxt_t p; + memset(&p, 0, sizeof p); + mem_block_t mem; + char s[BUF_MAX]; + size_t size, totsize = 0; + struct timeval t_start, t_end; + FILE *f; + + if (argc != 2) { + usage(argv[0]); + return 1; + } + + if (strcmp(argv[1], "-") == 0) { + f = stdin; + } else { + f = fopen(argv[1], "r"); + } + if (!f) { + fprintf(stderr, "cannot open %s: %s\n", argv[1], strerror(errno)); + return 2; + } + + pool_buffer_init(); + if (proto_agent_start(0, ¶ms) != 0) { + fprintf(stderr, "error on proto_agent_start()\n"); + fclose(f); + return 3; + } + atexit(close_proto_agent); + + gettimeofday(&t_start, NULL); + while ((size = fread(s, 1, BUF_MAX, f)) > 0) { + usleep(10); + totsize += size; + mem.data = &s[0]; + proto_agent_send_pdcp_data_ind(&p, 0, 0, 0, size, &mem); + } + gettimeofday(&t_end, NULL); + fclose(f); + long us = uelapsed(&t_start, &t_end); + fprintf(stderr, "read %zu bytes in %ld ms -> %.3fMB/s, %.3fMbps\n", + totsize, us / 1000, ((float) totsize ) / us, + ((float) totsize) / us * 8); + fprintf(stderr, "check files using 'diff afile bfile'\n"); + + /* wait, we are possibly receiving data */ + sleep(5); + return 0; +} + +/* + ********************************************************* + * arbitrary functions, needed for linking (used or not) * + ********************************************************* + */ + +boolean_t +pdcp_data_ind( + const protocol_ctxt_t* const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, + const sdu_size_t sdu_buffer_sizeP, + mem_block_t* const sdu_buffer_pP +) +{ + fprintf(stderr, "This should never be called on the DU\n"); + exit(1); +} + +pthread_t new_thread(void *(*f)(void *), void *b) { + pthread_t t; + pthread_attr_t att; + + if (pthread_attr_init(&att)){ + fprintf(stderr, "pthread_attr_init err\n"); + exit(1); + } + if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) { + fprintf(stderr, "pthread_attr_setdetachstate err\n"); + exit(1); + } + if (pthread_create(&t, &att, f, b)) { + fprintf(stderr, "pthread_create err\n"); + exit(1); + } + if (pthread_attr_destroy(&att)) { + fprintf(stderr, "pthread_attr_destroy err\n"); + exit(1); + } + + return t; +} + +int log_header(char *log_buffer, int buffsize, int comp, int level,const char *format) +{ + return 0; +} + +int config_get(paramdef_t *params,int numparams, char *prefix) +{ + return 0; +} + +int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) +{ + return 0; +} diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.c b/openair2/LAYER2/PROTO_AGENT/proto_agent.c new file mode 100644 index 0000000000000000000000000000000000000000..a39ebc6c84c44a17643a510ac587691db091f77d --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.c @@ -0,0 +1,284 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file enb_agent.h + * \brief top level enb agent receive thread and itti task + * \author Navid Nikaein and Xenofon Foukas + * \date 2016 + * \version 0.1 + */ +#define _GNU_SOURCE +#include "proto_agent_common.h" +#include "common/utils/LOG/log.h" +#include "proto_agent.h" +#include "assertions.h" +#include "proto_agent_net_comm.h" +#include "proto_agent_async.h" + +#include <pthread.h> + +#define ENB_AGENT_MAX 9 + +proto_agent_instance_t proto_agent[MAX_DU]; + +pthread_t new_thread(void *(*f)(void *), void *b); + +Protocol__FlexsplitMessage *proto_agent_timeout_fsp(void *args); + +#define TEST_MOD 0 + +#define ECHO + +/* Server side function; upon a new connection + reception, sends the hello packets +*/ +int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p) { + int channel_id; + // RS: CUDU does not work! + //DevAssert(p->local_interface); + //DevAssert(p->local_ipv4_address); + //DevAssert(p->local_port > 1024); // "unprivileged" port + //DevAssert(p->remote_ipv4_address); + //DevAssert(p->remote_port > 1024); // "unprivileged" port + proto_agent[mod_id].mod_id = mod_id; + proto_agent[mod_id].exit = 0; + /* Initialize the channel container */ + /* TODO only initialize the first time */ + proto_agent_init_channel_container(); + /*Create the async channel info*/ + proto_agent_async_channel_t *channel_info; + channel_info = proto_agent_async_channel_info(mod_id, p->local_ipv4_address, p->local_port, + p->remote_ipv4_address, p->remote_port); + + if (!channel_info) goto error; + + /* Create a channel using the async channel info */ + channel_id = proto_agent_create_channel((void *) channel_info, + proto_agent_async_msg_send, + proto_agent_async_msg_recv, + proto_agent_async_release); + + if (channel_id <= 0) goto error; + + proto_agent_channel_t *channel = proto_agent_get_channel(channel_id); + + if (!channel) goto error; + + proto_agent[mod_id].channel = channel; + /* Register the channel for all underlying agents (use ENB_AGENT_MAX) */ + proto_agent_register_channel(mod_id, channel, ENB_AGENT_MAX); + // Code for sending the HELLO/ECHO_REQ message once a connection is established + //uint8_t *msg = NULL; + //Protocol__FlexsplitMessage *init_msg=NULL; + //if (udp == 0) + //{ + // // If the comm is not UDP, allow the server to send the first packet over the channel + // //printf( "Proto agent Server: Calling the echo_request packet constructor\n"); + // msg_flag = proto_agent_echo_request(mod_id, NULL, &init_msg); + // if (msg_flag != 0) + // goto error; + // + // int msgsize = 0; + // if (init_msg != NULL) + // msg = proto_agent_pack_message(init_msg, &msgsize); + // if (msg!= NULL) + // { + // LOG_D(PROTO_AGENT, "Server sending the message over the async channel\n"); + // proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, (void *) channel_info); + // } + // /* After sending the message, wait for any replies; + // the server thread blocks until it reads any data + // over the channel + // */ + //} + proto_agent[mod_id].recv_thread = new_thread(proto_agent_receive, &proto_agent[mod_id]); + fprintf(stderr, "[PROTO_AGENT] server started at port %s:%d\n", p->local_ipv4_address, p->local_port); + return 0; +error: + LOG_E(PROTO_AGENT, "there was an error\n"); + return 1; +} + +void proto_agent_stop(mod_id_t mod_id) { + if (!proto_agent[mod_id].channel) return; + + /* unlock the independent read thread proto_agent_receive() */ + proto_agent[mod_id].exit = 1; + proto_agent_async_msg_recv_unlock(proto_agent[mod_id].channel->channel_info); + proto_agent_async_release(proto_agent[mod_id].channel); + proto_agent_destroy_channel(proto_agent[mod_id].channel->channel_id); + free(proto_agent[mod_id].channel); + proto_agent[mod_id].channel = NULL; + LOG_W(PROTO_AGENT, "server stopped\n"); +} + +//void +//proto_agent_send_hello(void) +//{ +// uint8_t *msg = NULL; +// Protocol__FlexsplitMessage *init_msg=NULL; +// int msg_flag = 0; +// +// +// //printf( "PDCP agent: Calling the HELLO packet constructor\n"); +// msg_flag = proto_agent_hello(proto_agent[TEST_MOD].mod_id, NULL, &init_msg); +// +// int msgsize = 0; +// if (msg_flag == 0) +// { +// proto_agent_serialize_message(init_msg, &msg, &msgsize); +// } +// +// LOG_D(PROTO_AGENT, "Agent sending the message over the async channel\n"); +// proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, (void *) client_channel[TEST_MOD]); +//} + + + +rlc_op_status_t proto_agent_send_rlc_data_req(const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, const mui_t muiP, + confirm_t confirmP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP) { + uint8_t *msg = NULL; + Protocol__FlexsplitMessage *init_msg=NULL; + int msg_flag = 0; + int msgsize = 0; + mod_id_t mod_id = ctxt_pP->module_id; + data_req_args args; + DevAssert(proto_agent[mod_id].channel); + DevAssert(proto_agent[mod_id].channel->channel_info); + args.ctxt = ctxt_pP; + args.srb_flag = srb_flagP; + args.MBMS_flag = MBMS_flagP; + args.rb_id = rb_idP; + args.mui = muiP; + args.confirm = confirmP; + args.sdu_size = sdu_sizeP; + args.sdu_p = sdu_pP; + msg_flag = proto_agent_pdcp_data_req(mod_id, (void *) &args, &init_msg); + + if (msg_flag != 0 || !init_msg) goto error; + + msg = proto_agent_pack_message(init_msg, &msgsize); + + if (!msg) goto error; + + proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, proto_agent[mod_id].channel->channel_info); + free_mem_block(sdu_pP, __func__); + return RLC_OP_STATUS_OK; +error: + LOG_E(PROTO_AGENT, "PROTO_AGENT there was an error\n"); + return RLC_OP_STATUS_INTERNAL_ERROR; +} + + +boolean_t +proto_agent_send_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, const rb_id_t rb_idP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP) { + uint8_t *msg = NULL; + Protocol__FlexsplitMessage *init_msg = NULL; + int msg_flag = 0; + int msgsize = 0; + mod_id_t mod_id = ctxt_pP->module_id; + data_req_args args; + DevAssert(proto_agent[mod_id].channel); + DevAssert(proto_agent[mod_id].channel->channel_info); + args.ctxt = ctxt_pP; + args.srb_flag = srb_flagP; + args.MBMS_flag = MBMS_flagP; + args.rb_id = rb_idP; + args.sdu_size = sdu_sizeP; + args.sdu_p = sdu_pP; + msg_flag = proto_agent_pdcp_data_ind(mod_id, (void *) &args, &init_msg); + + if (msg_flag != 0 || !init_msg) goto error; + + msg = proto_agent_pack_message(init_msg, &msgsize); + + if (!msg) goto error; + + proto_agent_async_msg_send((void *)msg, (int) msgsize, 1, proto_agent[mod_id].channel->channel_info); + free_mem_block(sdu_pP, __func__); + return TRUE; +error: + LOG_E(PROTO_AGENT, "there was an error in %s\n", __func__); + return FALSE; +} + +void * +proto_agent_receive(void *args) { + proto_agent_instance_t *inst = args; + void *data = NULL; + int size; + int priority; + err_code_t err_code; + pthread_setname_np(pthread_self(), "proto_rx"); + Protocol__FlexsplitMessage *msg; + uint8_t *ser_msg; + + while (1) { + msg = NULL; + ser_msg = NULL; + + if ((size = proto_agent_async_msg_recv(&data, &priority, inst->channel->channel_info)) < 0) { + err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING; + goto error; + } + + if (inst->exit) break; + + LOG_D(PROTO_AGENT, "Server side Received message with size %d and priority %d, calling message handle\n", size, priority); + msg = proto_agent_handle_message(inst->mod_id, data, size); + + if (!msg) { + LOG_D(PROTO_AGENT, "msg to send back is NULL\n"); + continue; + } + + ser_msg = proto_agent_pack_message(msg, &size); + + if (!ser_msg) { + continue; + } + + LOG_D(PROTO_AGENT, "Server sending the reply message over the async channel\n"); + + if (proto_agent_async_msg_send((void *)ser_msg, (int) size, 1, inst->channel->channel_info)) { + err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING; + goto error; + } + + LOG_D(PROTO_AGENT, "sent message with size %d\n", size); + } + + return NULL; +error: + LOG_E(PROTO_AGENT, "proto_agent_receive(): error %d occured\n",err_code); + return NULL; +} diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.h b/openair2/LAYER2/PROTO_AGENT/proto_agent.h new file mode 100644 index 0000000000000000000000000000000000000000..927b714b2c41f1ec4875d8d0a52335c3cb430b0c --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.h @@ -0,0 +1,58 @@ + +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file proto_agent.h + * \brief top level protocol agent + * \author Navid Nikaein and Xenofon Foukas + * \date 2016 + * \version 0.1 + */ + +#ifndef PROTO_AGENT_H_ +#define PROTO_AGENT_H_ +#include "ENB_APP/enb_config.h" // for enb properties +#include "proto_agent_common.h" + + +void *proto_agent_receive(void *args); + +int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p); +void proto_agent_stop(mod_id_t mod_id); + +rlc_op_status_t proto_agent_send_rlc_data_req( const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, const mui_t muiP, confirm_t confirmP, + sdu_size_t sdu_sizeP, mem_block_t *sdu_pP); + +boolean_t proto_agent_send_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP); + +#endif diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c new file mode 100644 index 0000000000000000000000000000000000000000..eef697c5bbe05c4e5e34875493a52fa0005a48d8 --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c @@ -0,0 +1,102 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + + +#include "proto_agent_async.h" +#include "proto_agent_defs.h" + + +#include "common/utils/LOG/log.h" + +proto_agent_async_channel_t * +proto_agent_async_channel_info(mod_id_t mod_id, const char *bind_ip, uint16_t bind_port, + const char* peer_ip, uint16_t peer_port) +{ + proto_agent_async_channel_t *channel; + channel = malloc(sizeof(proto_agent_async_channel_t)); + + if (channel == NULL) + goto error; + + channel->enb_id = mod_id; + channel->link = new_link_udp_server(bind_ip, bind_port); + + if (channel->link == NULL) goto error; + + channel->send_queue = new_message_queue(); + if (channel->send_queue == NULL) goto error; + channel->receive_queue = new_message_queue(); + if (channel->receive_queue == NULL) goto error; + + channel->manager = create_link_manager(channel->send_queue, + channel->receive_queue, + channel->link); + /* manually set remote IP&port for UDP server remote end */ + channel->manager->peer_port = peer_port; + channel->manager->peer_addr = peer_ip; + + if (channel->manager == NULL) goto error; + + return channel; + + error: + if (channel) + free(channel); + LOG_E(PROTO_AGENT, "error creating proto_agent_async_channel_t\n"); + return NULL; +} + +int proto_agent_async_msg_send(void *data, int size, int priority, void *channel_info) +{ + proto_agent_async_channel_t *channel = channel_info; + return message_put(channel->send_queue, data, size, priority); +} + +int proto_agent_async_msg_recv(void **data, int *priority, void *channel_info) +{ + proto_agent_async_channel_t *channel = channel_info; + return message_get(channel->receive_queue, data, priority); +} + +void proto_agent_async_msg_recv_unlock(proto_agent_async_channel_t *channel) { + message_get_unlock(channel->receive_queue); +} + +void proto_agent_async_release(proto_agent_channel_t *channel) +{ + proto_agent_async_channel_t *channel_info = channel->channel_info; + + destroy_link_manager(channel_info->manager); + + destroy_message_queue(channel_info->send_queue); + destroy_message_queue(channel_info->receive_queue); + + close_link(channel_info->link); + free(channel_info); +} diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h new file mode 100644 index 0000000000000000000000000000000000000000..27030924cdff888a221d42646db970c7b085b5b2 --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h @@ -0,0 +1,64 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file enb_agent_async.h + * \brief channel implementation for async interface + * \author Xenofon Foukas + * \date 2016 + * \version 0.1 + */ + +#ifndef PROTO_AGENT_ASYNC_H_ +#define PROTO_AGENT_ASYNC_H_ + +#include "proto_agent_net_comm.h" + +typedef struct proto_agent_async_channel_s { + mod_id_t enb_id; + socket_link_t *link; + message_queue_t *send_queue; + message_queue_t *receive_queue; + link_manager_t *manager; +} proto_agent_async_channel_t; + +proto_agent_async_channel_t * +proto_agent_async_channel_info(mod_id_t mod_id, const char *bind_ip, uint16_t bind_port, + const char *peer_ip, uint16_t peer_port); + +int proto_agent_async_msg_send(void *data, int size, int priority, void *channel_info); + +int proto_agent_async_msg_recv(void **data, int *priority, void *channel_info); + +/* unlocks a running proto_agent_async_msg_recv() */ +void proto_agent_async_msg_recv_unlock(proto_agent_async_channel_t *channel); + +void proto_agent_async_release(proto_agent_channel_t *channel); + + +#endif /*PROTO_AGENT_ASYNC_H_*/ diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c new file mode 100644 index 0000000000000000000000000000000000000000..1eca32b162d27bf98238dbde8d9d37dc63b0508b --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c @@ -0,0 +1,792 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file proto_agent_common.c + * \brief common primitives for all agents + * \author Navid Nikaein and Xenofon Foukas + * \date 2016 + * \version 0.1 + */ + +#include<stdio.h> +#include <dlfcn.h> +#include <time.h> + +#include "PHY/phy_extern.h" +#include "proto_agent_common.h" +#include "common/utils/LOG/log.h" + +#include "RRC/LTE/rrc_extern.h" +#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "rrc_eNB_UE_context.h" + +/* + * message primitives + */ + +// Function to fill in the dl_data header (32bits) with the appropriate fields (doing bitwise operations) +void fill_dl_data_header(int pdu_type, int spare, int seq_no, uint32_t *header) +{ + uint32_t type = pdu_type; + uint32_t spare_ = spare; + uint32_t seq = seq_no; + type = type << 28; + spare_ = spare_ << 24; + *header = (type | spare_); + *header = (*header | seq); + return; +} + + +// Function to retrieve data from the dl_data header (32bits) (doing bitwise operations) +void read_dl_data_header(int *pdu_type, int *spare, int *seqno, uint32_t header) +{ + *pdu_type = header; + *spare = header; + *seqno = header; + *pdu_type = *pdu_type >> 28; + *spare = *spare << 4; + *spare = *spare >> 28; + *seqno = *seqno << 8; + *seqno = *seqno >> 8; + return; +} + +int f1u_serialize_message(Protocol__F1uMessage *msg, void **buf,int *size) +{ + *size = protocol__f1u_message__get_packed_size(msg); + + *buf = malloc(*size); + if (!(*buf)) + goto error; + + protocol__f1u_message__pack(msg, *buf); + + return 0; + + error: + LOG_E(F1U, "an error occured\n"); + return -1; + +} + +int f1u_deserialize_message(void *data, int size, Protocol__F1uMessage **msg) +{ + *msg = protocol__f1u_message__unpack(NULL, size, data); + if (*msg == NULL) + goto error; + + return 0; + + error: + LOG_E(F1U, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int f1u_dl_data_create_header(uint32_t pdu_type, uint32_t f1u_sn, Protocol__DlDataHeader **header) +{ + *header = malloc(sizeof(Protocol__DlDataHeader)); + if(*header == NULL) + goto error; + + protocol__dl_data_header__init(*header); + LOG_D(F1U, "Initialized the DL Data User header\n"); + + fill_dl_data_header(pdu_type, 0, f1u_sn, &(*header)->fields); + return 0; + + error: + LOG_E(F1U, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int f1u_dl_data(const void *params, Protocol__F1uMessage **msg) +{ + // Initialize the PDCP params + dl_data_args *args = (dl_data_args *)params; + + Protocol__DlDataHeader *header; + + if (f1u_dl_data_create_header(args->pdu_type, args->sn, &header) != 0) + goto error; + + + Protocol__DlUserData *dl_data = NULL; + + *msg = malloc(sizeof(Protocol__DlUserData)); + + if(*msg == NULL) + goto error; + + + // FIXME: Is the following used? It seems to be overwritten by the function + // protocol__dl_user_data__init() anyway + //dl_data = *msg; + + protocol__dl_user_data__init(dl_data); + + + // Copy data to the bytes structure + dl_data->pdu.data = malloc(args->sdu_size); + dl_data->pdu.len = args->sdu_size; + memcpy(dl_data->pdu.data, args->sdu_p, args->sdu_size); + + dl_data->frame = args->frame; + dl_data->subframe = args->subframe; + dl_data->rnti = args->rnti; + + dl_data->header = header; + + return 0; + + error: + if(header != NULL) + free(header); + if(*msg != NULL) + free(*msg); + LOG_E(F1U, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int proto_agent_serialize_message(Protocol__FlexsplitMessage *msg, uint8_t **buf, int *size) +{ + *size = protocol__flexsplit_message__get_packed_size(msg); + + *buf = malloc(*size); + if (!(*buf)) + goto error; + + protocol__flexsplit_message__pack(msg, *buf); + + return 0; + + error: + LOG_E(MAC, "an error occured\n"); + return -1; +} + +/* We assume that the buffer size is equal to the message size. + Should be chekced durint Tx/Rx */ +int proto_agent_deserialize_message(void *data, int size, Protocol__FlexsplitMessage **msg) +{ + *msg = protocol__flexsplit_message__unpack(NULL, size, data); + if (*msg == NULL) + goto error; + + return 0; + + error: + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int fsp_create_header(xid_t xid, Protocol__FspType type, Protocol__FspHeader **header) +{ + *header = malloc(sizeof(Protocol__FspHeader)); + if(*header == NULL) + goto error; + + protocol__fsp_header__init(*header); + LOG_D(PROTO_AGENT, "Initialized the PROTOBUF message header\n"); + (*header)->version = FLEXSPLIT_VERSION; + LOG_D(PROTO_AGENT, "Set the vversion to FLEXSPLIT_VERSION\n"); + + (*header)->has_version = 1; + (*header)->type = type; + (*header)->has_type = 1; + (*header)->xid = xid; + (*header)->has_xid = 1; + return 0; + + error: + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int just_print(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) +{ + return 1; +} + +int proto_agent_pdcp_data_req(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) +{ + Protocol__FspCtxt *ctxt = NULL; + Protocol__FspRlcPdu *pdu = NULL; + Protocol__FspRlcData *rlc_data = NULL; + Protocol__FspRlcDataReq *data_req = NULL; + + // Initialize the PDCP params + data_req_args *args = (data_req_args *)params; + + // Create the protobuf header + Protocol__FspHeader *header; + xid_t xid = mod_id; + LOG_D(PROTO_AGENT, "creating the data_req message\n"); + + if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_RLC_DATA_REQ, &header) != 0) + goto error; + + /* Begin constructing the messages. They are defined as follows: + * 1) fspRlcPdu is storing the bytes of the packet + * 2) Message fspRlcData is packing the packet + the context of the PDCP (separate message) + * 3) Messge fspRlcDataReq is packing the header, enb_id and fspRlcData + */ + + ctxt = malloc(sizeof(Protocol__FspCtxt)); + pdu = malloc(sizeof(Protocol__FspRlcPdu)); + rlc_data = malloc(sizeof(Protocol__FspRlcData)); + data_req = malloc(sizeof(Protocol__FspRlcDataReq)); + + protocol__fsp_ctxt__init(ctxt); + protocol__fsp_rlc_pdu__init(pdu); + protocol__fsp_rlc_data__init(rlc_data); + protocol__fsp_rlc_data_req__init(data_req); + + // Copy data to the RlcPdu structure + pdu->fsp_pdu_data.data = malloc(args->sdu_size); + pdu->fsp_pdu_data.len = args->sdu_size; + + memcpy(pdu->fsp_pdu_data.data, args->sdu_p->data, args->sdu_size); + pdu->has_fsp_pdu_data = 1; + + // Copy data to the ctxt structure + ctxt->fsp_mod_id = args->ctxt->module_id; + ctxt->fsp_enb_flag = args->ctxt->enb_flag; + ctxt->fsp_instance = args->ctxt->instance; + ctxt->fsp_rnti = args->ctxt->rnti; + ctxt->fsp_frame = args->ctxt->frame; + ctxt->fsp_subframe = args->ctxt->subframe; + ctxt->fsp_enb_index = args->ctxt->eNB_index; + + ctxt->has_fsp_mod_id = 1; + ctxt->has_fsp_enb_flag = 1; + ctxt->has_fsp_instance = 1; + ctxt->has_fsp_rnti = 1; + ctxt->has_fsp_frame = 1; + ctxt->has_fsp_subframe = 1; + ctxt->has_fsp_enb_index = 1; + + rlc_data->fsp_ctxt = ctxt; + rlc_data->fsp_srb_flag = args->srb_flag; + rlc_data->fsp_mbms_flag = args->MBMS_flag; + rlc_data->fsp_rb_id = args->rb_id; + rlc_data->fsp_muip = args->mui; + rlc_data->fsp_confirm = args->confirm; + rlc_data->fsp_sdu_buffer_size = args->sdu_size; + rlc_data->fsp_pdu = pdu; + + rlc_data->has_fsp_srb_flag = 1; + rlc_data->has_fsp_mbms_flag = 1; + rlc_data->has_fsp_rb_id = 1; + rlc_data->has_fsp_muip = 1; + rlc_data->has_fsp_confirm = 1; + rlc_data->has_fsp_sdu_buffer_size = 1; + + // Up to here, everything is a signle message that is packed inside another. The final data_req + // will be created later, after the setting of all variables + + data_req->header = header; + data_req->enb_id = mod_id; + data_req->has_enb_id = 1; + data_req->pdcp_data = rlc_data; + + *msg = malloc(sizeof(Protocol__FlexsplitMessage)); + + if(*msg == NULL) + goto error; + + protocol__flexsplit_message__init(*msg); + + (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_REQ_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__INITIATING_MESSAGE; //we will be waiting for the ACK + (*msg)->has_msg_dir = 1; + (*msg)->data_req_msg = data_req; + + return 0; + + error: + if(header != NULL) + free(header); + if(pdu!=NULL) + free(pdu); + if(rlc_data!=NULL) + free(rlc_data); + if(data_req!= NULL) + free(data_req); + if(*msg != NULL) + free(*msg); + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int proto_agent_destroy_pdcp_data_req(Protocol__FlexsplitMessage *msg) { + if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_REQ_MSG) + goto error; + + free(msg->data_req_msg->header); + free(msg->data_req_msg->pdcp_data->fsp_pdu->fsp_pdu_data.data); + free(msg->data_req_msg->pdcp_data->fsp_pdu); + free(msg->data_req_msg->pdcp_data->fsp_ctxt); + free(msg->data_req_msg->pdcp_data); + free(msg->data_req_msg); + free(msg); + return 0; + + error: + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int proto_agent_get_ack_result(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) +{ + rlc_op_status_t result = 0; + //printf("PROTO_AGENT: handling the data_req_ack message\n"); + Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params; + Protocol__FspRlcDataReqAck *data_ack = input->data_req_ack; + result = data_ack->result; + //printf("PROTO_AGENT: ACK RESULT IS %u\n", result); + ack_result = result; + return 0; + +} + + +int proto_agent_pdcp_data_req_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) +{ + rlc_op_status_t result = 0; + + Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params; + Protocol__FspRlcDataReq *data_req = input->data_req_msg; + + Protocol__FspCtxt *ctxt = NULL; + Protocol__FspRlcData *rlc_data = NULL; + + rlc_data = data_req->pdcp_data; + ctxt = rlc_data->fsp_ctxt; + + protocol_ctxt_t ctxt_pP; + srb_flag_t srb_flagP = 0; + rb_id_t rb_idP = 0; + mui_t muiP = 0; + confirm_t confirmP = 0; + MBMS_flag_t flag_MBMS = 0; + sdu_size_t pdcp_pdu_size = 0; + mem_block_t *pdcp_pdu_p = NULL; + + // Create a new protocol context for handling the packet + ctxt_pP.module_id = ctxt->fsp_mod_id; + ctxt_pP.enb_flag = ctxt->fsp_enb_flag; + ctxt_pP.instance = ctxt->fsp_instance; + ctxt_pP.rnti = ctxt->fsp_rnti; + ctxt_pP.frame = ctxt->fsp_frame; + ctxt_pP.subframe = ctxt->fsp_subframe; + ctxt_pP.eNB_index = ctxt->fsp_enb_index; + + srb_flagP = rlc_data->fsp_srb_flag; + flag_MBMS = rlc_data->fsp_mbms_flag; + rb_idP = rlc_data->fsp_rb_id; + muiP = rlc_data->fsp_muip; + confirmP = rlc_data->fsp_confirm; + pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len; + pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size, __func__); + if (!pdcp_pdu_p) goto error; + memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size); + + result = rlc_data_req(&ctxt_pP + ,srb_flagP + ,flag_MBMS + ,rb_idP + ,muiP + ,confirmP + ,pdcp_pdu_size + ,pdcp_pdu_p + #ifdef Rel14 + ,NULL + ,NULL + #endif + ); + + return result; + + error: + if (pdcp_pdu_p) + free_mem_block(pdcp_pdu_p, __func__); + LOG_E(PROTO_AGENT, "%s: an error occured\n", __FUNCTION__); + return -1; + +} + +int proto_agent_destroy_pdcp_data_ind(Protocol__FlexsplitMessage *msg) +{ + if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG) + goto error; + + free(msg->data_ind_msg->header); + free(msg->data_ind_msg->rlc_data->fsp_pdu->fsp_pdu_data.data); + free(msg->data_ind_msg->rlc_data->fsp_pdu); + free(msg->data_ind_msg->rlc_data->fsp_ctxt); + free(msg->data_ind_msg->rlc_data); + free(msg->data_ind_msg); + free(msg); + return 0; + + error: + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int proto_agent_pdcp_data_ind(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) +{ + Protocol__FspCtxt *ctxt = NULL; + Protocol__FspRlcPdu *pdu = NULL; + Protocol__FspRlcData *rlc_data = NULL; + Protocol__FspPdcpDataInd *data_ind = NULL; + + // Initialize the PDCP params + data_req_args *args = (data_req_args *)params; + + // Create the protobuf header + Protocol__FspHeader *header; + xid_t xid = mod_id; + LOG_D(PROTO_AGENT, "creating the data_ind message\n"); + + if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_PDCP_DATA_IND, &header) != 0) + goto error; + + /* Begin constructing the messages. They are defined as follows: + * 1) fspRlcPdu is storing the bytes of the packet + * 2) Message fspRlcData is packing the packet + the context of the PDCP (separate message) + * 3) Messge fspRlcDataReq is packing the header, enb_id and fspRlcData + */ + + ctxt = malloc(sizeof(Protocol__FspCtxt)); + pdu = malloc(sizeof(Protocol__FspRlcPdu)); + rlc_data = malloc(sizeof(Protocol__FspRlcData)); + data_ind = malloc(sizeof(Protocol__FspPdcpDataInd)); + + protocol__fsp_ctxt__init(ctxt); + protocol__fsp_rlc_pdu__init(pdu); + protocol__fsp_rlc_data__init(rlc_data); + protocol__fsp_pdcp_data_ind__init(data_ind); + + // Copy data to the RlcPdu structure + pdu->fsp_pdu_data.data = malloc(args->sdu_size); + pdu->fsp_pdu_data.len = args->sdu_size; + + memcpy(pdu->fsp_pdu_data.data, args->sdu_p->data, args->sdu_size); + pdu->has_fsp_pdu_data = 1; + + // Copy data to the ctxt structure + ctxt->fsp_mod_id = args->ctxt->module_id; + ctxt->fsp_enb_flag = args->ctxt->enb_flag; + ctxt->fsp_instance = args->ctxt->instance; + ctxt->fsp_rnti = args->ctxt->rnti; + ctxt->fsp_frame = args->ctxt->frame; + ctxt->fsp_subframe = args->ctxt->subframe; + ctxt->fsp_enb_index = args->ctxt->eNB_index; + + ctxt->has_fsp_mod_id = 1; + ctxt->has_fsp_enb_flag = 1; + ctxt->has_fsp_instance = 1; + ctxt->has_fsp_rnti = 1; + ctxt->has_fsp_frame = 1; + ctxt->has_fsp_subframe = 1; + ctxt->has_fsp_enb_index = 1; + + rlc_data->fsp_ctxt = ctxt; + rlc_data->fsp_srb_flag = args->srb_flag; + rlc_data->fsp_mbms_flag = args->MBMS_flag; + rlc_data->fsp_rb_id = args->rb_id; + + rlc_data->fsp_sdu_buffer_size = args->sdu_size; + rlc_data->fsp_pdu = pdu; + rlc_data->has_fsp_srb_flag = 1; + rlc_data->has_fsp_mbms_flag = 1; + rlc_data->has_fsp_rb_id = 1; + rlc_data->has_fsp_sdu_buffer_size = 1; + + // Up to here, everything is a signle message that is packed inside another. The final data_req + // will be created later, after the setting of all variables + + data_ind->header = header; + data_ind->enb_id = mod_id; + data_ind->has_enb_id = 1; + data_ind->rlc_data = rlc_data; + + + *msg = malloc(sizeof(Protocol__FlexsplitMessage)); + + if(*msg == NULL) + goto error; + + protocol__flexsplit_message__init(*msg); + LOG_D(PROTO_AGENT,"setting the message case to %d\n", PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG); + + (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_DATA_IND_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__INITIATING_MESSAGE; //we will be waiting for the ACK + (*msg)->has_msg_dir = 1; + (*msg)->data_ind_msg = data_ind; //data_req; + + return 0; + + error: + if(header != NULL) + free(header); + if(pdu!=NULL) + free(pdu); + if(rlc_data!=NULL) + free(rlc_data); + if(data_ind!= NULL) + free(data_ind); + if(*msg != NULL) + free(*msg); + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + + +int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) +{ + boolean_t result = 0; + + Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params; + Protocol__FspPdcpDataInd *data_ind = input->data_ind_msg; + Protocol__FspCtxt *ctxt = NULL; + Protocol__FspRlcData *rlc_data = NULL; + + rlc_data = data_ind->rlc_data; + ctxt = rlc_data->fsp_ctxt; + + protocol_ctxt_t ctxt_pP; + srb_flag_t srb_flagP = 0; + rb_id_t rb_idP = 0; + sdu_size_t pdcp_pdu_size = 0; + MBMS_flag_t flag_MBMS = 0; + mem_block_t *pdcp_pdu_p = NULL; + + // Create a new protocol context for handling the packet + ctxt_pP.module_id = ctxt->fsp_mod_id; + ctxt_pP.enb_flag = ctxt->fsp_enb_flag; + ctxt_pP.instance = ctxt->fsp_instance; + ctxt_pP.rnti = ctxt->fsp_rnti; + ctxt_pP.frame = ctxt->fsp_frame; + ctxt_pP.subframe = ctxt->fsp_subframe; + ctxt_pP.eNB_index = ctxt->fsp_enb_index; + + srb_flagP = rlc_data->fsp_srb_flag; + flag_MBMS = rlc_data->fsp_mbms_flag; + rb_idP = rlc_data->fsp_rb_id; + pdcp_pdu_size = rlc_data->fsp_pdu->fsp_pdu_data.len; + pdcp_pdu_p = get_free_mem_block(pdcp_pdu_size, __func__); + if (!pdcp_pdu_p) goto error; + + memcpy(pdcp_pdu_p->data, rlc_data->fsp_pdu->fsp_pdu_data.data, pdcp_pdu_size); + +// if (xid == 1) +// pdcp_data_ind_wifi((const protocol_ctxt_t*) ctxt_pP, (const srb_flag_t) srb_flagP, (const MBMS_flag_t) flag_MBMS, (const rb_id_t) rb_idP, pdcp_pdu_size, pdcp_pdu_p); +// else if (xid == 0) // FIXME: USE a preprocessed definition + LOG_D(PROTO_AGENT, "[inst %d] Received PDCP PDU with size %d for UE RNTI %x RB %d, Calling pdcp_data_ind\n", ctxt_pP.instance, pdcp_pdu_size,ctxt_pP.rnti,rb_idP); + result = pdcp_data_ind(&ctxt_pP, + srb_flagP, + flag_MBMS, + rb_idP, + pdcp_pdu_size, + pdcp_pdu_p); + + return result; + + error: + if (pdcp_pdu_p) + free_mem_block(pdcp_pdu_p, __func__); + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int proto_agent_hello(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) +{ + Protocol__FspHeader *header; + Protocol__FspHello *hello_msg = NULL; + + /*TODO: Need to set random xid or xid from received hello message*/ + xid_t xid = mod_id; + if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_HELLO, &header) != 0) + goto error; + + LOG_D(PROTO_AGENT, "creating the HELLO message\n"); + hello_msg = malloc(sizeof(Protocol__FspHello)); + if(hello_msg == NULL) + goto error; + protocol__fsp_hello__init(hello_msg); + hello_msg->header = header; + + *msg = malloc(sizeof(Protocol__FlexsplitMessage)); + if(*msg == NULL) + goto error; + + protocol__flexsplit_message__init(*msg); + (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_HELLO_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__SUCCESSFUL_OUTCOME; + (*msg)->has_msg_dir = 1; + (*msg)->hello_msg = hello_msg; + return 0; + + error: + if(header != NULL) + free(header); + if(hello_msg!=NULL) + free(hello_msg); + if(*msg != NULL) + free(*msg); + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + + +int proto_agent_destroy_hello(Protocol__FlexsplitMessage *msg) +{ + if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_HELLO_MSG) + goto error; + + free(msg->hello_msg->header); + free(msg->hello_msg); + free(msg); + return 0; + + error: + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int proto_agent_echo_request(mod_id_t mod_id, const void* params, Protocol__FlexsplitMessage **msg) +{ + Protocol__FspHeader *header; + Protocol__FspEchoRequest *echo_request_msg = NULL; + + xid_t xid = mod_id; + if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_ECHO_REQUEST, &header) != 0) + goto error; + LOG_D(PROTO_AGENT, "creating the echo request message\n"); + + echo_request_msg = malloc(sizeof(Protocol__FspEchoRequest)); + if(echo_request_msg == NULL) + goto error; + + protocol__fsp_echo_request__init(echo_request_msg); + echo_request_msg->header = header; + + *msg = malloc(sizeof(Protocol__FlexsplitMessage)); + if(*msg == NULL) + goto error; + protocol__flexsplit_message__init(*msg); + + LOG_D(PROTO_AGENT,"setting the message direction to %d\n", PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG); + (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__INITIATING_MESSAGE; + (*msg)->has_msg_dir = 1; + (*msg)->echo_request_msg = echo_request_msg; + return 0; + + error: + if(header != NULL) + free(header); + if(echo_request_msg != NULL) + free(echo_request_msg); + if(*msg != NULL) + free(*msg); + return -1; +} + +int proto_agent_destroy_echo_request(Protocol__FlexsplitMessage *msg) +{ + if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REQUEST_MSG) + goto error; + + free(msg->echo_request_msg->header); + free(msg->echo_request_msg); + free(msg); + return 0; + + error: + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int proto_agent_echo_reply(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) +{ + xid_t xid; + Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params; + Protocol__FspEchoRequest *echo_req = input->echo_request_msg; + Protocol__FspEchoReply *echo_reply_msg = NULL; + xid = (echo_req->header)->xid; + + LOG_D(PROTO_AGENT, "creating the echo reply message\n"); + Protocol__FspHeader *header; + if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_ECHO_REPLY, &header) != 0) + goto error; + + echo_reply_msg = malloc(sizeof(Protocol__FspEchoReply)); + if(echo_reply_msg == NULL) + goto error; + protocol__fsp_echo_reply__init(echo_reply_msg); + echo_reply_msg->header = header; + + *msg = malloc(sizeof(Protocol__FlexsplitMessage)); + if(*msg == NULL) + goto error; + protocol__flexsplit_message__init(*msg); + (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REPLY_MSG; + (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__SUCCESSFUL_OUTCOME; + (*msg)->has_msg_dir = 1; + (*msg)->echo_reply_msg = echo_reply_msg; + return 0; + + error: + if(header != NULL) + free(header); + if(echo_reply_msg != NULL) + free(echo_reply_msg); + if(*msg != NULL) + free(*msg); + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} + +int proto_agent_destroy_echo_reply(Protocol__FlexsplitMessage *msg) { + if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_ECHO_REPLY_MSG) + goto error; + + free(msg->echo_reply_msg->header); + free(msg->echo_reply_msg); + free(msg); + return 0; + + error: + LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); + return -1; +} diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h new file mode 100644 index 0000000000000000000000000000000000000000..70e6b2a84ec4b09f1ea2221bf10482bd26bc6f0a --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h @@ -0,0 +1,147 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file enb_agent_common.h + * \brief common message primitves and utilities + * \author Navid Nikaein and Xenofon Foukas + * \date 2016 + * \version 0.1 + */ + + + +#ifndef PROTO_AGENT_COMMON_H_ +#define PROTO_AGENT_COMMON_H_ + +#include <time.h> + +#include "flexsplit.pb-c.h" + +// Do not need these +//#include "stats_messages.pb-c.h" +//#include "stats_common.pb-c.h" + +#include "proto_agent_defs.h" +//#include "ENB_APP/enb_config.h" +#include "UTIL/MEM/mem_block.h" + +//#include "LAYER2/MAC/extern.h" +//#include "LAYER2/RLC/rlc.h" + +# include "tree.h" +# include "intertask_interface.h" + +#define FLEXSPLIT_VERSION 0 + +typedef int (*proto_agent_message_decoded_callback)( + mod_id_t mod_id, + const void *params, + Protocol__FlexsplitMessage **msg +); + +typedef int (*proto_agent_message_destruction_callback)( + Protocol__FlexsplitMessage *msg +); + + +uint32_t ack_result; + +/********************************** + * progRAN protocol messages helper + * functions and generic handlers + **********************************/ + +int proto_agent_serialize_message(Protocol__FlexsplitMessage *msg, uint8_t **buf, int *size); +int proto_agent_deserialize_message(void *data, int size, Protocol__FlexsplitMessage **msg); + +uint8_t *proto_agent_pack_message(Protocol__FlexsplitMessage *msg, int *size); + +err_code_t proto_agent_destroy_flexsplit_message(Protocol__FlexsplitMessage *msg); + +int fsp_create_header(xid_t xid, Protocol__FspType type, Protocol__FspHeader **header); + +int proto_agent_hello(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); +int proto_agent_destroy_hello(Protocol__FlexsplitMessage *msg); +int proto_agent_echo_request(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); +int proto_agent_destroy_echo_request(Protocol__FlexsplitMessage *msg); +int proto_agent_echo_reply(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); +int proto_agent_destroy_echo_reply(Protocol__FlexsplitMessage *msg); + +int proto_agent_pdcp_data_req(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); +int proto_agent_pdcp_data_req_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); +int proto_agent_destroy_pdcp_data_req(Protocol__FlexsplitMessage *msg); +int proto_agent_pdcp_data_ind(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); +int proto_agent_destroy_pdcp_data_ind(Protocol__FlexsplitMessage *msg); +int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); + +int just_print(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); + + +int proto_agent_get_ack_result(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg); + + +Protocol__FlexsplitMessage* proto_agent_handle_message (mod_id_t mod_id, + uint8_t *data, + int size); + +Protocol__FlexsplitMessage *proto_agent_handle_timed_task(void *args); + +typedef struct _data_req_args data_req_args; +typedef struct _dl_data_args dl_data_args; + +struct _data_req_args{ + const protocol_ctxt_t* ctxt; + srb_flag_t srb_flag; + MBMS_flag_t MBMS_flag; + rb_id_t rb_id; + mui_t mui; + confirm_t confirm; + sdu_size_t sdu_size; + mem_block_t *sdu_p; +}; + +struct _dl_data_args{ + uint8_t pdu_type; + uint32_t sn; + frame_t frame; + sub_frame_t subframe; + rnti_t rnti; + sdu_size_t sdu_size; + mem_block_t *sdu_p; +}; + + +#endif + + + + + + + diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..08c91e70850cf87d189bf01bdd0d67057d3a3b76 --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h @@ -0,0 +1,126 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2016 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file enb_agent_defs.h + * \brief enb agent common definitions + * \author Navid Nikaein and Xenofon Foukas + * \date 2016 + * \version 0.1 + */ +#ifndef PROTO_AGENT_DEFS_H_ +#define PROTO_AGENT_DEFS_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <string.h> + +#include "openairinterface5g_limits.h" +#include "UTIL/ASYNC_IF/link_manager.h" + +#define DEFAULT_PROTO_AGENT_IPv4_ADDRESS "127.0.0.1" +#define DEFAULT_PROTO_AGENT_PORT 2210 +#define DEFAULT_PROTO_AGENT_CACHE "/mnt/oai_agent_cache" + +typedef enum { + + PROTO_AGENT_DEFAULT=0, + + ENB_AGENT_PHY=1, + ENB_AGENT_MAC=2, + ENB_AGENT_RLC=3, + ENB_AGENT_PDCP=4, + ENB_AGENT_RRC=5, + ENB_AGENT_S1AP=6, + ENB_AGENT_GTP=7, + ENB_AGENT_X2AP=8, + + ENB_AGENT_MAX=9, + +} proto_agent_id_t; + +/* +typedef enum { + ENB_AGENT_ACTION_NONE = 0x0, + + ENB_AGENT_ACTION_SEND = 0x1, + + ENB_AGENT_ACTION_APPLY = 0x2, + + ENB_AGENT_ACTION_CLEAR = 0x4, + + ENB_AGENT_ACTION_WRITE = 0x8, + + ENB_AGENT_ACTION_FILTER = 0x10, + + ENB_AGENT_ACTION_PREPROCESS = 0x20, + + ENB_AGENT_ACTION_METER = 0x40, + + ENB_AGENT_ACTION_MAX = 0x7f, +} agent_action_t; +*/ +/* +typedef enum { + + RAN_LTE_OAI= 0, + + RAN_NAME_MAX = 0x7f, +} ran_name_t; +*/ +typedef uint8_t xid_t; +typedef uint8_t mod_id_t; // module or enb id +typedef uint8_t lcid_t; +typedef int32_t err_code_t; + +typedef struct { + /* general info */ + + /* stats */ + + uint32_t total_rx_msg; + uint32_t total_tx_msg; + + uint32_t rx_msg[NUMBER_OF_eNB_MAX]; + uint32_t tx_msg[NUMBER_OF_eNB_MAX]; + +} proto_agent_info_t; + +/* forward declaration */ +struct proto_agent_channel_s; + +typedef struct proto_agent_instance_s { + mod_id_t mod_id; + proto_agent_info_t agent_info; + struct proto_agent_channel_s *channel; + pthread_t recv_thread; + uint8_t exit; +} proto_agent_instance_t; + +#endif diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c new file mode 100644 index 0000000000000000000000000000000000000000..cb65da28039c5012ade0ed08d7f8bcfee1223104 --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c @@ -0,0 +1,146 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file enb_agent_handler.c + * \brief enb agent tx and rx message handler + * \author Navid Nikaein and Xenofon Foukas + * \date 2016 + * \version 0.1 + */ + + +#include "proto_agent_common.h" +#include "common/utils/LOG/log.h" +#include "assertions.h" + +proto_agent_message_decoded_callback proto_agent_messages_callback[][3] = { + {proto_agent_hello, 0, 0}, /* agent hello */ + {proto_agent_echo_reply, 0, 0}, /* echo */ + {0, just_print, 0}, /* just print */ + {proto_agent_pdcp_data_req_process, proto_agent_pdcp_data_req_process, 0}, /* PDCP data REQ */ + {0, proto_agent_get_ack_result, 0}, /* get ACK result */ + {proto_agent_pdcp_data_ind_process, proto_agent_pdcp_data_ind_process, 0}, /* PDCP data IND */ + {0, just_print, 0}, /* just print */ +}; + +proto_agent_message_destruction_callback proto_message_destruction_callback[] = { + proto_agent_destroy_hello, + proto_agent_destroy_echo_request, + proto_agent_destroy_echo_reply, + proto_agent_destroy_pdcp_data_req, + 0, + proto_agent_destroy_pdcp_data_ind, + 0, +}; + +//static const char *proto_agent_direction2String[] = { +// "", /* not_set */ +// "originating message", /* originating message */ +// "successfull outcome", /* successfull outcome */ +// "unsuccessfull outcome", /* unsuccessfull outcome */ +//}; + + +Protocol__FlexsplitMessage* proto_agent_handle_message (mod_id_t mod_id, + uint8_t *data, + int size){ + + Protocol__FlexsplitMessage *decoded_message = NULL; + Protocol__FlexsplitMessage *reply_message = NULL; + err_code_t err_code; + DevAssert(data != NULL); + + LOG_D(PROTO_AGENT, "Deserializing message with size %u \n", size); + if (proto_agent_deserialize_message(data, (int) size, &decoded_message) < 0) { + err_code= PROTOCOL__FLEXSPLIT_ERR__MSG_DECODING; + goto error; + } + /* after deserialization, we don't need the original data memory anymore */ + free(data); + Protocol__FspHeader *header = (Protocol__FspHeader*) decoded_message; + if (header->has_type) + { + LOG_D(PROTO_AGENT, "Deserialized MSG type is %d and %u\n", decoded_message->msg_case, decoded_message->msg_dir); + } + + if ((decoded_message->msg_case > sizeof(proto_agent_messages_callback) / (3*sizeof(proto_agent_message_decoded_callback))) || + (decoded_message->msg_dir > PROTOCOL__FLEXSPLIT_DIRECTION__UNSUCCESSFUL_OUTCOME)) + { + err_code= PROTOCOL__FLEXSPLIT_ERR__MSG_NOT_HANDLED; + LOG_D(PROTO_AGENT,"Handling message: MSG NOT handled, going to error\n"); + goto error; + } + + + err_code = ((*proto_agent_messages_callback[decoded_message->msg_case-1][decoded_message->msg_dir-1])(mod_id, (void *) decoded_message, &reply_message)); + + if ( err_code < 0 ) + { + LOG_I(PROTO_AGENT, "decoded_message case : %d, direction : %d \n", decoded_message->msg_case-1, decoded_message->msg_dir-1); + goto error; + } + + protocol__flexsplit_message__free_unpacked(decoded_message, NULL); + LOG_D(PROTO_AGENT,"Returning REPLY message after the callback\n"); + return reply_message; + + error: + LOG_E(PROTO_AGENT,"errno %d occured\n",err_code); + return NULL; +} + + + +uint8_t *proto_agent_pack_message(Protocol__FlexsplitMessage *msg, int *size) +{ + uint8_t *buffer; + err_code_t err_code = PROTOCOL__FLEXSPLIT_ERR__NO_ERR; + + if (proto_agent_serialize_message(msg, &buffer, size) < 0 ) { + err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENCODING; + goto error; + } + + if (proto_message_destruction_callback[msg->msg_case-1]) + err_code = ((*proto_message_destruction_callback[msg->msg_case-1])(msg)); + + DevAssert(buffer !=NULL); + + LOG_D(PROTO_AGENT,"Serialized the enb mac stats reply (size %d)\n", *size); + return buffer; + + error : + LOG_E(PROTO_AGENT,"errno %d occured\n",err_code); + + return NULL; +} + +err_code_t proto_agent_destroy_flexsplit_message(Protocol__FlexsplitMessage *msg) { + return ((*proto_message_destruction_callback[msg->msg_case-1])(msg)); +} diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c new file mode 100644 index 0000000000000000000000000000000000000000..f64a58f8e1584580bcc25180f7edd8fca0e282ce --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c @@ -0,0 +1,160 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2016 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file enb_agent_net_comm.c + * \brief enb agent network interface abstraction + * \author Xenofon Foukas + * \date 2016 + * \version 0.1 + */ + +#include "proto_agent_net_comm.h" +#include "common/utils/LOG/log.h" + +proto_agent_channel_t *proto_channel[NUMBER_OF_eNB_MAX][ENB_AGENT_MAX]; +proto_agent_channel_instance_t channel_instance; +int proto_agent_channel_id = 0; + +int proto_agent_register_channel(mod_id_t mod_id, proto_agent_channel_t *channel, proto_agent_id_t agent_id) { + int i; + + if (channel == NULL) { + return -1; + } + + if (agent_id == ENB_AGENT_MAX) { + for (i = 0; i < ENB_AGENT_MAX; i++) { + proto_channel[mod_id][i] = channel; + } + } else { + proto_channel[mod_id][agent_id] = channel; + } + return 0; +} + +void proto_agent_unregister_channel(mod_id_t mod_id, proto_agent_id_t agent_id) { + int i; + + if (agent_id == ENB_AGENT_MAX) { + for (i = 0; i < ENB_AGENT_MAX; i++) { + proto_channel[mod_id][i] = NULL; + } + } else { + proto_channel[mod_id][agent_id] = NULL; + } +} + +int proto_agent_create_channel(void *channel_info, + int (*msg_send)(void *data, int size, int priority, void *channel_info), + int (*msg_recv)(void **data, int *priority, void *channel_info), + void (*release)(proto_agent_channel_t *channel)) { + + int channel_id = ++proto_agent_channel_id; + proto_agent_channel_t *channel = (proto_agent_channel_t *) malloc(sizeof(proto_agent_channel_t)); + channel->channel_id = channel_id; + channel->channel_info = channel_info; + channel->msg_send = msg_send; + channel->msg_recv = msg_recv; + channel->release = release; + + /*element should be a real pointer*/ + RB_INSERT(proto_agent_channel_map, &channel_instance.proto_agent_head, channel); + + LOG_D(PROTO_AGENT, "Created a new channel with id 0x%x\n", channel->channel_id); + + return channel_id; +} + +int proto_agent_destroy_channel(int channel_id) { + int i, j; + + /*Check to see if channel exists*/ + struct proto_agent_channel_s *e = NULL; + struct proto_agent_channel_s search; + memset(&search, 0, sizeof(struct proto_agent_channel_s)); + + e = RB_FIND(proto_agent_channel_map, &channel_instance.proto_agent_head, &search); + + if (e == NULL) { + return -1; + } + + /*Unregister the channel from all agents*/ + for (i = 0; i < NUMBER_OF_eNB_MAX; i++) { + for (j = 0; j < ENB_AGENT_MAX; j++) { + if (proto_channel[i][j] != NULL) { + if (proto_channel[i][j]->channel_id == e->channel_id) { + proto_channel[i][j] = NULL; + } + } + } + } + + /*Remove the channel from the tree and free memory*/ + RB_REMOVE(proto_agent_channel_map, &channel_instance.proto_agent_head, e); + e->release(e); + free(e); + + return 0; +} + +err_code_t proto_agent_init_channel_container(void) { + int i, j; + LOG_D(PROTO_AGENT, "init RB tree for channel container\n"); + + RB_INIT(&channel_instance.proto_agent_head); + + for (i = 0; i < NUMBER_OF_eNB_MAX; i++) { + for (j = 0; j < ENB_AGENT_MAX; j++) { + proto_channel[i][j] = NULL; + } + } + + return 0; +} + +RB_GENERATE(proto_agent_channel_map,proto_agent_channel_s, entry, proto_agent_compare_channel); + +int proto_agent_compare_channel(struct proto_agent_channel_s *a, struct proto_agent_channel_s *b) { + if (a->channel_id < b->channel_id) return -1; + if (a->channel_id > b->channel_id) return 1; + + // equal timers + return 0; +} + +proto_agent_channel_t * proto_agent_get_channel(int channel_id) { + + struct proto_agent_channel_s search; + memset(&search, 0, sizeof(struct proto_agent_channel_s)); + search.channel_id = channel_id; + + return RB_FIND(proto_agent_channel_map, &channel_instance.proto_agent_head, &search); + +} diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h new file mode 100644 index 0000000000000000000000000000000000000000..c956bf48b1daf93e435c7e15a800d196151f214e --- /dev/null +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h @@ -0,0 +1,90 @@ +/******************************************************************************* + OpenAirInterface + Copyright(c) 1999 - 2016 Eurecom + + OpenAirInterface is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + + OpenAirInterface is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OpenAirInterface.The full GNU General Public License is + included in this distribution in the file called "COPYING". If not, + see <http://www.gnu.org/licenses/>. + + Contact Information + OpenAirInterface Admin: openair_admin@eurecom.fr + OpenAirInterface Tech : openair_tech@eurecom.fr + OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr + + Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. + + *******************************************************************************/ + +/*! \file enb_agent_net_comm.h + * \brief enb agent network interface abstraction + * \autho Xenofon Foukas + * \date 2016 + * \version 0.1 + */ +#ifndef PROTO_AGENT_NET_COMM_H_ +#define PROTO_AGENT_NET_COMM_H_ + +#include "proto_agent_defs.h" + +#include "tree.h" +#define ENB_AGENT_MAX 9 + +/* forward declaration */ +struct proto_agent_async_channel_s; + +/*Channel related information used for Tx/Rx of protocol messages*/ +typedef struct proto_agent_channel_s { + RB_ENTRY(proto_agent_channel_s) entry; + int channel_id; + struct proto_agent_async_channel_s *channel_info; + /*Callbacks for channel message Tx and Rx*/ + int (*msg_send)(void *data, int size, int priority, void *channel_info); + int (*msg_recv)(void **data, int *priority, void *channel_info); + void (*release)(struct proto_agent_channel_s *channel); +} proto_agent_channel_t; + +typedef struct proto_agent_channel_instance_s{ + RB_HEAD(proto_agent_channel_map, proto_agent_channel_s) proto_agent_head; +} proto_agent_channel_instance_t; + + +/*Register a channel to an agent. Use ENB_AGENT_MAX to register the + *same channel to all agents*/ +int proto_agent_register_channel(mod_id_t mod_id, proto_agent_channel_t *channel, proto_agent_id_t agent_id); + +/*Unregister the current channel of an agent. Use ENB_AGENT_MAX to unregister all channels*/ +void proto_agent_unregister_channel(mod_id_t mod_id, proto_agent_id_t agent_id); + +/*Create a new channel. Returns the id of the new channel or negative number otherwise*/ +int proto_agent_create_channel(void *channel_info, + int (*msg_send)(void *data, int size, int priority, void *channel_info), + int (*msg_recv)(void **data, int *priority, void *channel_info), + void (*release)(proto_agent_channel_t *channel)); + +/*Unregister a channel from all agents and destroy it. Returns 0 in case of success*/ +int proto_agent_destroy_channel(int channel_id); + +/*Return an agent communication channel based on its id*/ +proto_agent_channel_t * proto_agent_get_channel(int channel_id); + +/*Should be called before performing any channel operations*/ +err_code_t proto_agent_init_channel_container(void); + +int proto_agent_compare_channel(struct proto_agent_channel_s *a, struct proto_agent_channel_s *b); + +/* RB_PROTOTYPE is for .h files */ +RB_PROTOTYPE(proto_agent_channel_map, proto_agent_channel_s, entry, proto_agent_compare_channel); + +#endif /*ENB_AGENT_COMM_H_*/ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 33ab7965e514ea878d7fcf648e0c11f3185c0fd7..30173b62ffacf81ebead5d3edca31e941a5b54e9 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -40,7 +40,6 @@ #include "LTE_UL-AM-RLC.h" #include "LTE_DL-AM-RLC.h" - //----------------------------------------------------------------------------- uint32_t rlc_am_get_status_pdu_buffer_occupancy( diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h index 75213116a7d04deef939aa86d742249f57efa5e0..c6a5ca721320915ccda6dbd98c5dbfca4e65a742 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h @@ -65,7 +65,7 @@ (rLC_Pp->is_data_plane) ? "DRB AM" : "SRB AM",\ rLC_Pp->rb_id -#define PROTOCOL_RLC_AM_MSC_FMT "[RNTI %"PRIx16" %s %02u]" +#define PROTOCOL_RLC_AM_MSC_FMT "[RNTI %" PRIx16 " %s %02u]" #define PROTOCOL_RLC_AM_MSC_ARGS(CTXT_Pp, rLC_Pp) \ CTXT_Pp->rnti,\ (rLC_Pp->is_data_plane) ? "DRB AM" : "SRB AM",\ @@ -79,13 +79,13 @@ if (pmtl_rc != 0){\ if (pmtl_rc == EBUSY) {\ MSC_LOG_EVENT((cTXT->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\ - "0 "PROTOCOL_RLC_AM_MSC_FMT" Warning try lock %s busy",\ + "0 " PROTOCOL_RLC_AM_MSC_FMT " Warning try lock %s busy",\ PROTOCOL_RLC_AM_MSC_ARGS(cTXT,rLC),\ #mUTEX);\ pthread_mutex_lock(mUTEX);\ } else {\ MSC_LOG_EVENT((cTXT->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\ - "0 "PROTOCOL_RLC_AM_MSC_FMT" Error try lock %s %d",\ + "0 " PROTOCOL_RLC_AM_MSC_FMT " Error try lock %s %d",\ PROTOCOL_RLC_AM_MSC_ARGS(cTXT,rLC),\ #mUTEX, pmtl_rc);\ }\ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c index d9eb6de7cccf4c1de70f3d19ca42e466bb7ef23e..7a95a62787a58c65e114ca76bf4723e2c9c15ade 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c @@ -128,6 +128,8 @@ void rlc_am_v9_3_0_test_windows() rlc_am_entity_t am2; unsigned int i; unsigned int j; + memset(am1,0,sizeof(rlc_am_entity_t)); + memset(am2,0,sizeof(rlc_am_entity_t)); rlc_am_init(&am1, g_frame); rlc_am_init(&am2, g_frame); @@ -215,19 +217,16 @@ void rlc_am_v9_3_0_test_windows() assert(rlc_am_in_rx_window(&am1, i) == 0); } } - } //----------------------------------------------------------------------------- void rlc_am_v9_3_0_test_read_write_bit_field() //----------------------------------------------------------------------------- { unsigned int bit_pos_write = 0; // range from 0 (MSB/left) to 7 (LSB/right) - uint8_t* byte_pos_write = g_buffer; - + uint8_t *byte_pos_write = g_buffer; unsigned int bit_pos_read = 0; // range from 0 (MSB/left) to 7 (LSB/right) - uint8_t* byte_pos_read = g_buffer; + uint8_t *byte_pos_read = g_buffer; uint16_t read_value; - memset (g_buffer, 0, sizeof(g_buffer)); // byte 0 rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 1); @@ -240,7 +239,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 0); assert(g_buffer[0] == 0x96); assert(g_buffer[1] == 0x00); - // byte 1 rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 1); rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 1); @@ -251,10 +249,8 @@ void rlc_am_v9_3_0_test_read_write_bit_field() rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 0); rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 1); assert(g_buffer[0] == 0x96); - assert(g_buffer[1] == 0xD9); assert(g_buffer[2] == 0x00); - // byte 2 rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 0); rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 0); @@ -266,7 +262,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() rlc_am_write8_bit_field(&byte_pos_write, &bit_pos_write, 1, 1); assert(g_buffer[0] == 0x96); assert(g_buffer[1] == 0xD9); - assert(g_buffer[2] == 0x11); assert(g_buffer[3] == 0x00); // byte 3 & 4 @@ -282,7 +277,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() assert(g_buffer[0] == 0x96); assert(g_buffer[1] == 0xD9); assert(g_buffer[2] == 0x11); - assert(g_buffer[3] == 0x99); assert(g_buffer[4] == 0xA7); assert(g_buffer[5] == 0x00); @@ -298,7 +292,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() assert(g_buffer[2] == 0x11); assert(g_buffer[3] == 0x99); assert(g_buffer[4] == 0xA7); - assert(g_buffer[5] == 0xF4); assert(g_buffer[6] == 0x86); assert(g_buffer[7] == 0x00); @@ -317,7 +310,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() assert(g_buffer[4] == 0xA7); assert(g_buffer[5] == 0xF4); assert(g_buffer[6] == 0x86); - assert(g_buffer[7] == 0xCD); assert(g_buffer[8] == 0x7D); assert(g_buffer[9] == 0x58); @@ -337,7 +329,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() assert(g_buffer[7] == 0xCD); assert(g_buffer[8] == 0x7D); assert(g_buffer[9] == 0x58); - assert(g_buffer[10] == 0xAA); assert(g_buffer[11] == 0xDB); assert(g_buffer[12] == 0xAA); @@ -368,7 +359,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() assert(g_buffer[12] == 0xAA); assert(g_buffer[13] == 0xBD); assert(g_buffer[14] == 0x34); - assert(g_buffer[15] == 0xE0); assert(g_buffer[16] == 0x3F); assert(g_buffer[17] == 0x84); @@ -385,7 +375,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() assert(g_buffer[28] == 0x87); assert(g_buffer[29] == 0x88); assert(g_buffer[30] == 0x00); - // 0x96 0xD9 read_value = rlc_am_read_bit_field(&byte_pos_read, &bit_pos_read, 1);// b0 assert(read_value == 1); @@ -419,7 +408,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() assert(read_value == 0); read_value = rlc_am_read_bit_field(&byte_pos_read, &bit_pos_read, 1);// b15 assert(read_value == 1); - // 0x11 0x99 read_value = rlc_am_read_bit_field(&byte_pos_read, &bit_pos_read, 2); assert(read_value == 0); @@ -439,7 +427,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() assert(read_value == 2); read_value = rlc_am_read_bit_field(&byte_pos_read, &bit_pos_read, 2); assert(read_value == 1); - // 0xA7 0xF4 0x86 0xCD 0x7D; read_value = rlc_am_read_bit_field(&byte_pos_read, &bit_pos_read, 10); assert(read_value == 0x29F); @@ -449,10 +436,8 @@ void rlc_am_v9_3_0_test_read_write_bit_field() assert(read_value == 0x1B3); read_value = rlc_am_read_bit_field(&byte_pos_read, &bit_pos_read, 10); assert(read_value == 0x17D); - // 0x58 0xAA 0xDB 0xAA 0xBD 0x34 // 0xE0 0x3F 0x84 0xBA 0x91 0xEC - read_value = rlc_am_read_bit_field(&byte_pos_read, &bit_pos_read, 1); assert(read_value == 0); read_value = rlc_am_read_bit_field(&byte_pos_read, &bit_pos_read, 10); @@ -475,7 +460,6 @@ void rlc_am_v9_3_0_test_read_write_bit_field() assert(read_value == 0x2EA); read_value = rlc_am_read_bit_field(&byte_pos_read, &bit_pos_read, 10); assert(read_value == 0x11E); - bit_pos_read = 0; byte_pos_read = g_buffer; // 0x96 0xD9 0x11 0x99 0xA7 0xF4 0x86 0xCD 0x7D 0x58 0xAA 0xDB 0xAA 0xBD 0x34 @@ -523,30 +507,24 @@ void rlc_am_v9_3_0_test_send_sdu(rlc_am_entity_t *am_txP, int sdu_indexP) printf("[FRAME %05d][RLC][MOD %02d][RB %02d] TX SDU %d %04d bytes\n",g_frame,am_txP->module_id, am_txP->rb_id, sdu_indexP, strlen(g_sdus[sdu_indexP]) + 1); memset (sdu->data, 0, sizeof (struct rlc_am_data_req_alloc)); strcpy (&sdu->data[sizeof (struct rlc_am_data_req_alloc)],g_sdus[sdu_indexP]); - ((struct rlc_am_data_req *) (sdu->data))->data_size = strlen(g_sdus[sdu_indexP])+ 1; ((struct rlc_am_data_req *) (sdu->data))->conf = 1; ((struct rlc_am_data_req *) (sdu->data))->mui = g_mui++; ((struct rlc_am_data_req *) (sdu->data))->data_offset = sizeof (struct rlc_am_data_req_alloc); rlc_am_data_req(am_txP, g_frame, sdu); - g_send_sdu_ids[g_send_id_write_index[am_txP->rb_id]++][am_txP->rb_id] = sdu_indexP; assert(g_send_id_write_index[am_txP->rb_id] < TEST_MAX_SEND_SDU); } else { printf("Out of memory error\n"); -// exit(-1); + // exit(-1); } } //----------------------------------------------------------------------------- -void rlc_am_v9_3_0_test_mac_rlc_loop (struct mac_data_ind *data_indP, struct mac_data_req *data_requestP, int* drop_countP, int *tx_packetsP, - int* dropped_tx_packetsP) //----------------------------------------------------------------------------- -{ - - - mem_block_t* tb_src; - mem_block_t* tb_dst; +void rlc_am_v9_3_0_test_mac_rlc_loop (struct mac_data_ind *data_indP, struct mac_data_req *data_requestP, int *drop_countP, int *tx_packetsP, + int *dropped_tx_packetsP) { //----------------------------------------------------------------------------- + mem_block_t *tb_src; + mem_block_t *tb_dst; unsigned int tb_size; - data_indP->no_tb = 0; while (data_requestP->data.nb_elements > 0) { @@ -554,10 +532,9 @@ void rlc_am_v9_3_0_test_mac_rlc_loop (struct mac_data_ind *data_indP, struct ma if (tb_src != NULL) { tb_size = ((struct mac_tb_req *) (tb_src->data))->tb_size_in_bits >> 3; - printf("[RLC-LOOP] FOUND TB SIZE IN BITS %d IN BYTES %d sizeof (mac_rlc_max_rx_header_size_t) %d\n", + printf("[RLC-LOOP] FOUND TB SIZE IN BITS %d IN BYTES %u sizeof (mac_rlc_max_rx_header_size_t) %d\n", ((struct mac_tb_req *) (tb_src->data))->tb_size_in_bits, tb_size, sizeof (mac_rlc_max_rx_header_size_t)); - *tx_packetsP = *tx_packetsP + 1; if (*drop_countP == 0) { @@ -568,16 +545,14 @@ void rlc_am_v9_3_0_test_mac_rlc_loop (struct mac_data_ind *data_indP, struct ma ((struct mac_tb_ind *) (tb_dst->data))->data_ptr = &tb_dst->data[sizeof (mac_rlc_max_rx_header_size_t)]; ((struct mac_tb_ind *) (tb_dst->data))->size = tb_size; ((struct mac_tb_ind *) (tb_dst->data))->error_indication = 0; - memcpy(((struct mac_tb_ind *) (tb_dst->data))->data_ptr, &((struct mac_tb_req *) (tb_src->data))->data_ptr[0], tb_size); - list_add_tail_eurecom(tb_dst, &data_indP->data); data_indP->no_tb += 1; } else { printf("Out of memory error\n"); -// exit(-1); + // exit(-1); } } else { printf("[RLC-LOOP] DROPPING 1 TB\n"); @@ -607,8 +582,6 @@ void rlc_am_v9_3_0_test_exchange_pdus(rlc_am_entity_t *am_txP, struct mac_status_ind tx_status; struct mac_status_resp mac_rlc_status_resp_tx; struct mac_status_resp mac_rlc_status_resp_rx; - - memset(&data_request_tx, 0, sizeof(struct mac_data_req)); memset(&data_request_rx, 0, sizeof(struct mac_data_req)); memset(&data_ind_tx, 0, sizeof(struct mac_data_ind)); @@ -616,19 +589,15 @@ void rlc_am_v9_3_0_test_exchange_pdus(rlc_am_entity_t *am_txP, memset(&tx_status, 0, sizeof(struct mac_status_ind)); memset(&mac_rlc_status_resp_tx, 0, sizeof(struct mac_status_resp)); memset(&mac_rlc_status_resp_rx, 0, sizeof(struct mac_status_resp)); - mac_rlc_status_resp_tx = rlc_am_mac_status_indication(am_txP, g_frame, bytes_txP, tx_status); data_request_tx = rlc_am_mac_data_request(am_txP, g_frame); mac_rlc_status_resp_rx = rlc_am_mac_status_indication(am_rxP, g_frame, bytes_rxP, tx_status); data_request_rx = rlc_am_mac_data_request(am_rxP, g_frame); - - rlc_am_v9_3_0_test_mac_rlc_loop(&data_ind_rx, &data_request_tx, &g_drop_tx, &g_tx_packets, &g_dropped_tx_packets); rlc_am_v9_3_0_test_mac_rlc_loop(&data_ind_tx, &data_request_rx, &g_drop_rx, &g_rx_packets, &g_dropped_rx_packets); rlc_am_mac_data_indication(am_rxP, g_frame, am_txP->is_enb, data_ind_rx); rlc_am_mac_data_indication(am_txP, g_frame, am_txP->is_enb, data_ind_tx); g_frame += 1; - //rlc_am_tx_buffer_display(am_txP,NULL); //assert(am_txP->t_status_prohibit.time_out != 1); //assert(am_rxP->t_status_prohibit.time_out != 1); @@ -660,14 +629,12 @@ void rlc_am_v9_3_0_test_data_ind (module_id_t module_idP, rb_id_t rb_idP, sdu_si assert(g_send_id_write_index[rb_idP^1] > g_send_id_read_index[rb_idP]); if (g_send_sdu_ids[g_send_id_read_index[rb_idP]][rb_idP^1] != i) { - printf("[FRAME %05d][RLC][MOD %d][RB %d][DATA-IND] g_send_sdu_ids[%d] = %d\n",g_frame,module_idP, rb_idP, g_send_id_read_index[rb_idP]-2, g_send_sdu_ids[g_send_id_read_index[rb_idP]-2][rb_idP^1]); printf("[FRAME %05d][RLC][MOD %d][RB %d][DATA-IND] g_send_sdu_ids[%d] = %d\n",g_frame,module_idP, rb_idP, g_send_id_read_index[rb_idP]-1, g_send_sdu_ids[g_send_id_read_index[rb_idP]-1][rb_idP^1]); printf("[FRAME %05d][RLC][MOD %d][RB %d][DATA-IND] g_send_sdu_ids[%d] = %d\n",g_frame,module_idP, rb_idP, g_send_id_read_index[rb_idP], g_send_sdu_ids[g_send_id_read_index[rb_idP]][rb_idP^1]); - printf("[FRAME %05d][RLC][MOD %d][RB %d][DATA-IND] g_send_id_read_index = %d sdu sent = %d\n",g_frame,module_idP, rb_idP, g_send_id_read_index[rb_idP], i); } @@ -693,17 +660,13 @@ void rlc_am_v9_3_0_test_tx_rx() uint32_t t_reordering = 5000; uint32_t t_status_prohibit = 10; int i,j,r; - srand (0); - rlc_am_init(&g_am_tx, g_frame); rlc_am_init(&g_am_rx, g_frame); rlc_am_set_debug_infos(&g_am_tx, g_frame, 0, 0, 0, 1, 1 /* LC-id = DRB-id */); rlc_am_set_debug_infos(&g_am_rx, g_frame, 1, 1, 1, 1, 1 /* LC-id = DRB-id */); - rlc_am_configure(&g_am_tx, g_frame, max_retx_threshold, poll_pdu, poll_byte, t_poll_retransmit, t_reordering, t_status_prohibit); rlc_am_configure(&g_am_rx, g_frame, max_retx_threshold, poll_pdu, poll_byte, t_poll_retransmit, t_reordering, t_status_prohibit); - #ifdef TEST1 srand (0); rlc_am_v9_3_0_test_reset_sdus(); @@ -730,7 +693,6 @@ void rlc_am_v9_3_0_test_tx_rx() rlc_am_rx_list_display(&g_am_rx, "RLC-AM RX:"); assert (g_send_id_read_index[1] == g_send_id_write_index[0]); printf("\n\n\n\n\n\n-----------------------------------------------------------------------------------------rlc_am_v9_3_0_test 1: END OF SIMPLE TEST SEVERAL SDUs IN PDU\n\n\n\n"); - rlc_am_v9_3_0_test_reset_sdus(); // RANDOM TESTS @@ -800,7 +762,6 @@ void rlc_am_v9_3_0_test_tx_rx() rlc_am_v9_3_0_test_exchange_pdus(&g_am_tx, &g_am_rx, 2000, 200); rlc_am_v9_3_0_test_exchange_pdus(&g_am_tx, &g_am_rx, 2000, 200); rlc_am_v9_3_0_test_exchange_pdus(&g_am_tx, &g_am_rx, 2000, 200); - rlc_am_v9_3_0_test_send_sdu(&g_am_tx, 1); rlc_am_v9_3_0_test_exchange_pdus(&g_am_tx, &g_am_rx, 30, 200); rlc_am_v9_3_0_test_exchange_pdus(&g_am_tx, &g_am_rx, 31, 200); @@ -957,7 +918,6 @@ void rlc_am_v9_3_0_test_tx_rx() rlc_am_v9_3_0_test_exchange_pdus(&g_am_tx, &g_am_rx, 15, 100); rlc_am_v9_3_0_test_exchange_pdus(&g_am_tx, &g_am_rx, 15, 100); rlc_am_v9_3_0_test_exchange_pdus(&g_am_tx, &g_am_rx, 15, 100); - t_poll_retransmit = 6; rlc_am_configure(&g_am_tx, g_frame, max_retx_threshold, poll_pdu, poll_byte, t_poll_retransmit, t_reordering, t_status_prohibit); @@ -1178,7 +1138,6 @@ void rlc_am_v9_3_0_test_tx_rx() assert (g_send_id_read_index[0] == g_send_id_write_index[1]); printf("REAL BLER TX=%d (TARGET=%d) BLER RX=%d (TARGET=%d) \n",(g_dropped_tx_packets*100)/g_tx_packets, g_target_tx_error_rate, (g_dropped_rx_packets*100)/g_rx_packets, g_target_rx_error_rate); - } } @@ -1193,11 +1152,10 @@ void rlc_am_v9_3_0_test_print_trace (void) size_t size; char **strings; size_t i; - size = backtrace (array, 100); strings = backtrace_symbols (array, size); + printf ("Obtained %lu stack frames.\n", (unsigned long)size); - printf ("Obtained %d stack frames.\n", size); for (i = 0; i < size; i++) { printf ("%s\n", strings[i]); @@ -1213,15 +1171,10 @@ void rlc_am_v9_3_0_test(void) // initscr(); // cbreak(); // keypad(stdscr, TRUE); - - - // under test pool_buffer_init(); set_comp_log(RLC, LOG_ERR, LOG_MED, 1); - rlc_am_v9_3_0_test_tx_rx(); - // already tested rlc_am_v9_3_0_test_windows(); rlc_am_v9_3_0_test_read_write_bit_field(); diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h index f2f91ff68e66ec6db1155950eda21d91afc5f430..fc6e449acf7b7e38dfd1d8dd229c24af58181e90 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h @@ -56,7 +56,7 @@ rLC_Pp->rb_id,\ __FUNCTION__ -#define PROTOCOL_RLC_UM_MSC_FMT "[RNTI %"PRIx16" %s %02u]" +#define PROTOCOL_RLC_UM_MSC_FMT "[RNTI %" PRIx16 " %s %02u]" #define PROTOCOL_RLC_UM_MSC_ARGS(CTXT_Pp, rLC_Pp) \ CTXT_Pp->rnti,\ (rLC_Pp->is_data_plane) ? "DRB UM" : "SRB UM",\ @@ -69,13 +69,13 @@ if (pmtl_rc != 0){\ if (pmtl_rc == EBUSY) {\ MSC_LOG_EVENT((cTXT->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\ - "0 "PROTOCOL_RLC_UM_MSC_FMT" Warning try lock %s busy",\ + "0 " PROTOCOL_RLC_UM_MSC_FMT " Warning try lock %s busy",\ PROTOCOL_RLC_UM_MSC_ARGS(cTXT,rLC),\ #mUTEX);\ pthread_mutex_lock(mUTEX);\ } else {\ MSC_LOG_EVENT((cTXT->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,\ - "0 "PROTOCOL_RLC_UM_MSC_FMT" Error try lock %s %d",\ + "0 " PROTOCOL_RLC_UM_MSC_FMT " Error try lock %s %d",\ PROTOCOL_RLC_UM_MSC_ARGS(cTXT,rLC),\ #mUTEX, pmtl_rc);\ }\ diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c index 4d238ea84175da06fa29faaad63813b505c3eafe..fda84879be06681705e62bbd15b1b7fe3f769284 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c @@ -125,7 +125,7 @@ static int8_t *g_sdus[] = {"En dépit de son volontarisme affiché, le premier m #define RLC_2_PRINT_BUFFER_LEN 10000 static char rlc_2_print_buffer[RLC_2_PRINT_BUFFER_LEN]; //----------------------------------------------------------------------------- -void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char* dataP, unsigned long sizeP) +void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, unsigned long sizeP) //----------------------------------------------------------------------------- { unsigned long octet_index = 0; @@ -136,7 +136,6 @@ void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char* dataP, uns return; } - LOG_D(RLC, "------+-------------------------------------------------|\n"); LOG_D(RLC, " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n"); LOG_D(RLC, "------+-------------------------------------------------|\n"); @@ -149,7 +148,8 @@ void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char* dataP, uns buffer_marker = 0; } - buffer_marker+=snprintf(&rlc_2_print_buffer[buffer_marker], RLC_2_PRINT_BUFFER_LEN - buffer_marker, " %04ld |", octet_index); + buffer_marker+=snprintf(&rlc_2_print_buffer[buffer_marker], RLC_2_PRINT_BUFFER_LEN - buffer_marker, + " %04lu |", octet_index); } /* @@ -180,17 +180,13 @@ void rlc_um_v9_3_0_test_windows_10() rlc_um_entity_t um1; rlc_um_entity_t um2; unsigned int h,w, sn, result; - uint32_t timer_reordering = 2000; uint32_t sn_field_length = 10; uint32_t is_mXch = 0; // boolean, true if configured for MTCH or MCCH - rlc_um_init(&um1); rlc_um_init(&um2); - rlc_um_set_debug_infos(&um1, g_frame, 0, 0, 0, 1, 1 /*LC-id = RAB-id*/); rlc_um_set_debug_infos(&um2, g_frame, 1, 1, 1, 1, 1 /*LC-id = RAB-id*/); - rlc_um_configure(&um1, g_frame, timer_reordering, sn_field_length, sn_field_length, is_mXch); rlc_um_configure(&um2, g_frame, timer_reordering, sn_field_length, sn_field_length, is_mXch); @@ -223,7 +219,6 @@ void rlc_um_v9_3_0_test_windows_10() assert(rlc_um_in_window(&um1, g_frame, (um1.vr_uh - um1.rx_um_window_size) & RLC_UM_SN_10_BITS_MASK, sn, (um1.vr_uh -1) & RLC_UM_SN_10_BITS_MASK) < 0); assert(rlc_um_in_reordering_window(&um1, g_frame, sn) < 0); } - } } } @@ -234,17 +229,13 @@ void rlc_um_v9_3_0_test_windows_5() rlc_um_entity_t um1; rlc_um_entity_t um2; unsigned int h,w, sn, result; - uint32_t timer_reordering = 2000; uint32_t sn_field_length = 5; uint32_t is_mXch = 0; // boolean, true if configured for MTCH or MCCH - rlc_um_init(&um1); rlc_um_init(&um2); - rlc_um_set_debug_infos(&um1, g_frame, 0, 0, 0, 1, 1 /* LC-id = DRB-id */); rlc_um_set_debug_infos(&um2, g_frame, 1, 1, 1, 1, 1 /* LC-id = DRB-id */); - rlc_um_configure(&um1, g_frame, timer_reordering, sn_field_length, sn_field_length, is_mXch); rlc_um_configure(&um2, g_frame, timer_reordering, sn_field_length, sn_field_length, is_mXch); @@ -277,7 +268,6 @@ void rlc_um_v9_3_0_test_windows_5() assert(rlc_um_in_window(&um1, g_frame, (um1.vr_uh - um1.rx_um_window_size) & RLC_UM_SN_5_BITS_MASK, sn, (um1.vr_uh -1) & RLC_UM_SN_5_BITS_MASK) < 0); assert(rlc_um_in_reordering_window(&um1, g_frame, sn) < 0); } - } } } @@ -308,25 +298,23 @@ void rlc_um_v9_3_0_test_send_sdu(rlc_um_entity_t *um_txP, int sdu_indexP) printf("[FRAME %05d][RLC][MOD %02d][RB %02d] TX SDU %d %04d bytes\n",g_frame,um_txP->module_id, um_txP->rb_id, sdu_indexP, strlen(g_sdus[sdu_indexP]) + 1); memset (sdu->data, 0, sizeof (struct rlc_um_data_req_alloc)); strcpy (&sdu->data[sizeof (struct rlc_um_data_req_alloc)],g_sdus[sdu_indexP]); - ((struct rlc_um_data_req *) (sdu->data))->data_size = strlen(g_sdus[sdu_indexP])+ 1; ((struct rlc_um_data_req *) (sdu->data))->data_offset = sizeof (struct rlc_um_data_req_alloc); rlc_um_data_req(um_txP, g_frame, sdu); - g_send_sdu_ids[g_send_id_write_index[um_txP->rb_id]++][um_txP->rb_id] = sdu_indexP; assert(g_send_id_write_index[um_txP->rb_id] < TEST_MAX_SEND_SDU); } else { printf("Out of memory error\n"); -// exit(-1); + // exit(-1); } } //----------------------------------------------------------------------------- -void rlc_um_v9_3_0_buffer_delayed_rx_mac_data_ind(struct mac_data_ind* data_indP, signed int time_delayedP) +void rlc_um_v9_3_0_buffer_delayed_rx_mac_data_ind(struct mac_data_ind *data_indP, signed int time_delayedP) //----------------------------------------------------------------------------- { int frame_modulo; - mem_block_t* tb; + mem_block_t *tb; if (time_delayedP <= 0) { frame_modulo = g_frame % MAX_TIME_DELAYED_PDU_DUE_TO_HARQ; @@ -351,11 +339,11 @@ void rlc_um_v9_3_0_buffer_delayed_rx_mac_data_ind(struct mac_data_ind* data_indP assert(data_indP->data.head == NULL); } //----------------------------------------------------------------------------- -void rlc_um_v9_3_0_buffer_delayed_tx_mac_data_ind(struct mac_data_ind* data_indP, signed int time_delayedP) +void rlc_um_v9_3_0_buffer_delayed_tx_mac_data_ind(struct mac_data_ind *data_indP, signed int time_delayedP) //----------------------------------------------------------------------------- { int frame_modulo; - mem_block_t* tb; + mem_block_t *tb; if (time_delayedP <= 0) { frame_modulo = g_frame % MAX_TIME_DELAYED_PDU_DUE_TO_HARQ; @@ -381,16 +369,13 @@ void rlc_um_v9_3_0_buffer_delayed_tx_mac_data_ind(struct mac_data_ind* data_indP } //----------------------------------------------------------------------------- -void rlc_um_v9_3_0_test_mac_rlc_loop (struct mac_data_ind* data_indP, struct mac_data_req* data_requestP, int* drop_countP, int* tx_packetsP, - int* dropped_tx_packetsP) +void rlc_um_v9_3_0_test_mac_rlc_loop (struct mac_data_ind *data_indP, struct mac_data_req *data_requestP, int *drop_countP, int *tx_packetsP, + int *dropped_tx_packetsP) //----------------------------------------------------------------------------- { - - - mem_block_t* tb_src; - mem_block_t* tb_dst; + mem_block_t *tb_src; + mem_block_t *tb_dst; unsigned int tb_size; - data_indP->no_tb = 0; while (data_requestP->data.nb_elements > 0) { @@ -398,14 +383,14 @@ void rlc_um_v9_3_0_test_mac_rlc_loop (struct mac_data_ind* data_indP, struct ma if (tb_src != NULL) { tb_size = ((struct mac_tb_req *) (tb_src->data))->tb_size_in_bits >> 3; - printf("[RLC-LOOP] FOUND TB SIZE IN BITS %d IN BYTES %d sizeof (mac_rlc_max_rx_header_size_t) %d\n", + printf("[RLC-LOOP] FOUND TB SIZE IN BITS %d IN BYTES %u sizeof (mac_rlc_max_rx_header_size_t) %d\n", ((struct mac_tb_req *) (tb_src->data))->tb_size_in_bits, tb_size, sizeof (mac_rlc_max_rx_header_size_t)); - *tx_packetsP = *tx_packetsP + 1; if (*drop_countP == 0) { tb_dst = get_free_mem_block(sizeof (mac_rlc_max_rx_header_size_t) + tb_size, __func__); + if (tb_dst != NULL) { memset(tb_dst->data, 0, sizeof (mac_rlc_max_rx_header_size_t) + tb_size); //printf("[RLC-LOOP] Testing tb_dst (1)\n"); @@ -415,18 +400,16 @@ void rlc_um_v9_3_0_test_mac_rlc_loop (struct mac_data_ind* data_indP, struct ma ((struct mac_tb_ind *) (tb_dst->data))->data_ptr = &tb_dst->data[sizeof (mac_rlc_max_rx_header_size_t)]; ((struct mac_tb_ind *) (tb_dst->data))->size = tb_size; ((struct mac_tb_ind *) (tb_dst->data))->error_indication = 0; - memcpy(((struct mac_tb_ind *) (tb_dst->data))->data_ptr, &((struct mac_tb_req *) (tb_src->data))->data_ptr[0], tb_size); - list_add_tail_eurecom(tb_dst, &data_indP->data); data_indP->no_tb += 1; //printf("[RLC-LOOP] Testing tb_dst (2)\n"); check_free_mem_block(tb_dst, __func__); } else { printf("Out of memory error\n"); -// exit(-1); + // exit(-1); } } else { printf("[RLC-LOOP] DROPPING 1 TB\n"); @@ -434,10 +417,8 @@ void rlc_um_v9_3_0_test_mac_rlc_loop (struct mac_data_ind* data_indP, struct ma *dropped_tx_packetsP = *dropped_tx_packetsP + 1; } - //printf("[RLC-LOOP] Testing tb_src\n"); check_free_mem_block(tb_src, __func__); - free_mem_block(tb_src, __func__); if (data_indP->no_tb > 0) { @@ -460,8 +441,6 @@ void rlc_um_v9_3_0_test_exchange_pdus(rlc_um_entity_t *um_txP, struct mac_status_ind tx_status; struct mac_status_resp mac_rlc_status_resp_tx; struct mac_status_resp mac_rlc_status_resp_rx; - - memset(&data_request_tx, 0, sizeof(struct mac_data_req)); memset(&data_request_rx, 0, sizeof(struct mac_data_req)); memset(&data_ind_tx, 0, sizeof(struct mac_data_ind)); @@ -469,13 +448,10 @@ void rlc_um_v9_3_0_test_exchange_pdus(rlc_um_entity_t *um_txP, memset(&tx_status, 0, sizeof(struct mac_status_ind)); memset(&mac_rlc_status_resp_tx, 0, sizeof(struct mac_status_resp)); memset(&mac_rlc_status_resp_rx, 0, sizeof(struct mac_status_resp)); - mac_rlc_status_resp_tx = rlc_um_mac_status_indication(um_txP, g_frame, 1, bytes_txP, tx_status,ENB_FLAG_YES); data_request_tx = rlc_um_mac_data_request(um_txP, g_frame); mac_rlc_status_resp_rx = rlc_um_mac_status_indication(um_rxP, g_frame, 0, bytes_rxP, tx_status,ENB_FLAG_YES); data_request_rx = rlc_um_mac_data_request(um_rxP, g_frame); - - rlc_um_v9_3_0_test_mac_rlc_loop(&data_ind_rx, &data_request_tx, &g_drop_tx, &g_tx_packets, &g_dropped_tx_packets); rlc_um_v9_3_0_test_mac_rlc_loop(&data_ind_tx, &data_request_rx, &g_drop_rx, &g_rx_packets, &g_dropped_rx_packets); rlc_um_mac_data_indication(um_rxP, g_frame, um_rxP->is_enb, data_ind_rx); @@ -506,8 +482,6 @@ void rlc_um_v9_3_0_test_exchange_delayed_pdus(rlc_um_entity_t *um_txP, struct mac_status_resp mac_rlc_status_resp_tx; struct mac_status_resp mac_rlc_status_resp_rx; int frame_modulo = g_frame % MAX_TIME_DELAYED_PDU_DUE_TO_HARQ; - - memset(&data_request_tx, 0, sizeof(struct mac_data_req)); memset(&data_request_rx, 0, sizeof(struct mac_data_req)); memset(&data_ind_tx, 0, sizeof(struct mac_data_ind)); @@ -515,23 +489,16 @@ void rlc_um_v9_3_0_test_exchange_delayed_pdus(rlc_um_entity_t *um_txP, memset(&tx_status, 0, sizeof(struct mac_status_ind)); memset(&mac_rlc_status_resp_tx, 0, sizeof(struct mac_status_resp)); memset(&mac_rlc_status_resp_rx, 0, sizeof(struct mac_status_resp)); - mac_rlc_status_resp_tx = rlc_um_mac_status_indication(um_txP, g_frame, 1, bytes_txP, tx_status,ENB_FLAG_YES); data_request_tx = rlc_um_mac_data_request(um_txP, g_frame); mac_rlc_status_resp_rx = rlc_um_mac_status_indication(um_rxP, g_frame, 0, bytes_rxP, tx_status,ENB_FLAG_YES); data_request_rx = rlc_um_mac_data_request(um_rxP, g_frame); - - rlc_um_v9_3_0_test_mac_rlc_loop(&data_ind_rx, &data_request_tx, &g_drop_tx, &g_tx_packets, &g_dropped_tx_packets); rlc_um_v9_3_0_test_mac_rlc_loop(&data_ind_tx, &data_request_rx, &g_drop_rx, &g_rx_packets, &g_dropped_rx_packets); - rlc_um_v9_3_0_buffer_delayed_rx_mac_data_ind(&data_ind_rx, time_tx_delayedP); rlc_um_v9_3_0_buffer_delayed_tx_mac_data_ind(&data_ind_tx, time_rx_delayedP); - - rlc_um_mac_data_indication(um_rxP, g_frame, um_rxP->is_enb, g_rx_delayed_indications[frame_modulo]); memset(&g_rx_delayed_indications[frame_modulo], 0, sizeof(struct mac_data_ind)); - rlc_um_mac_data_indication(um_txP, g_frame, um_txP->is_enb, g_tx_delayed_indications[frame_modulo]); memset(&g_tx_delayed_indications[frame_modulo], 0, sizeof(struct mac_data_ind)); @@ -564,14 +531,12 @@ void rlc_um_v9_3_0_test_data_ind (module_id_t module_idP, rb_id_t rb_idP, sdu_si assert(g_send_id_write_index[rb_idP^1] > g_send_id_read_index[rb_idP]); if (g_send_sdu_ids[g_send_id_read_index[rb_idP]][rb_idP^1] != i) { - printf("[FRAME %05d][RLC][MOD %d][RB %d][DATA-IND] g_send_sdu_ids[%d] = %d\n",g_frame,module_idP, rb_idP, g_send_id_read_index[rb_idP]-2, g_send_sdu_ids[g_send_id_read_index[rb_idP]-2][rb_idP^1]); printf("[FRAME %05d][RLC][MOD %d][RB %d][DATA-IND] g_send_sdu_ids[%d] = %d\n",g_frame,module_idP, rb_idP, g_send_id_read_index[rb_idP]-1, g_send_sdu_ids[g_send_id_read_index[rb_idP]-1][rb_idP^1]); printf("[FRAME %05d][RLC][MOD %d][RB %d][DATA-IND] g_send_sdu_ids[%d] = %d\n",g_frame,module_idP, rb_idP, g_send_id_read_index[rb_idP], g_send_sdu_ids[g_send_id_read_index[rb_idP]][rb_idP^1]); - printf("[FRAME %05d][RLC][MOD %d][RB %d][DATA-IND] g_send_id_read_index = %d sdu sent = %d\n",g_frame,module_idP, rb_idP, g_send_id_read_index[rb_idP], i); } @@ -607,23 +572,15 @@ void rlc_um_v9_3_0_test_reordering(uint32_t sn_field_lengthP) { rlc_um_info_t um_info; int i,j,r; - um_info.timer_reordering = (32 * sn_field_lengthP * sn_field_lengthP)/100; um_info.sn_field_length = sn_field_lengthP; um_info.is_mXch = 0; - srand (0); config_req_rlc_um (&um_tx, 0,0,0, &um_info, 0, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/); config_req_rlc_um (&um_rx, 0,1,1, &um_info, 1, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/); - rlc_um_display_rx_window(&um_tx); - rlc_um_display_rx_window(&um_rx); - - srand (0); - - // BIG SDU SMALL PDUS NO ERRORS rlc_um_v9_3_0_test_reset_sdus(); @@ -665,21 +622,16 @@ void rlc_um_v9_3_0_test_reordering(uint32_t sn_field_lengthP) rlc_um_v9_3_0_test_exchange_delayed_pdus(&um_tx, &um_rx, 2000, 200, 0, 0, INCREMENT_FRAME_YES); rlc_um_v9_3_0_test_exchange_delayed_pdus(&um_tx, &um_rx, 2000, 200, 0, 0, INCREMENT_FRAME_YES); rlc_um_v9_3_0_test_exchange_delayed_pdus(&um_tx, &um_rx, 2000, 200, 0, 0, INCREMENT_FRAME_YES); - assert (g_send_id_read_index[1] == g_send_id_write_index[0]); printf("\n\n\n\n\n\n\n\n"); - } printf("\n\n\n\n\n\n-----------------------------------------------------------------------------------------rlc_um_v9_3_0_test_reordering 3: END OF TEST BIG SDU, SMALL PDUs\n\n\n\n"); - rlc_um_v9_3_0_test_reset_sdus(); for (j = 0; j < 16; j++) { //i = getchar(); - rlc_um_v9_3_0_test_reset_sdus(); - rlc_um_v9_3_0_test_send_sdu(&um_tx, 1); for (i = 0; i < 32; i++) { @@ -688,8 +640,6 @@ void rlc_um_v9_3_0_test_reordering(uint32_t sn_field_lengthP) rlc_um_v9_3_0_test_exchange_delayed_pdus(&um_tx, &um_rx, 2000, 200, 0, 0, INCREMENT_FRAME_YES); assert (g_send_id_read_index[1] == g_send_id_write_index[0]); - - rlc_um_v9_3_0_test_send_sdu(&um_tx, 1); rlc_um_v9_3_0_test_exchange_delayed_pdus(&um_tx, &um_rx, 3, 200, 0, 0, INCREMENT_FRAME_YES); rlc_um_v9_3_0_test_exchange_delayed_pdus(&um_tx, &um_rx, 3, 200, 0, 0, INCREMENT_FRAME_YES); @@ -702,7 +652,6 @@ void rlc_um_v9_3_0_test_reordering(uint32_t sn_field_lengthP) rlc_um_v9_3_0_test_exchange_delayed_pdus(&um_tx, &um_rx, 2000, 200, 0, 0, INCREMENT_FRAME_YES); printf("g_send_id_read_index[1]=%d g_send_id_write_index[0]=%d Loop %d (1)\n", g_send_id_read_index[1], g_send_id_write_index[0], j); assert (g_send_id_read_index[1] != g_send_id_write_index[0]); - rlc_um_v9_3_0_test_send_sdu(&um_tx, 1); rlc_um_v9_3_0_test_exchange_delayed_pdus(&um_tx, &um_rx, 3, 200, 0, 0, INCREMENT_FRAME_YES); @@ -716,7 +665,6 @@ void rlc_um_v9_3_0_test_reordering(uint32_t sn_field_lengthP) rlc_um_v9_3_0_test_exchange_delayed_pdus(&um_tx, &um_rx, 2000, 200, 0, 0, INCREMENT_FRAME_YES); printf("g_send_id_read_index[1]=%d g_send_id_write_index[0]=%d Loop %d (2)\n", g_send_id_read_index[1], g_send_id_write_index[0], j); - assert (g_send_id_read_index[1] != g_send_id_write_index[0]); } @@ -728,21 +676,14 @@ void rlc_um_v9_3_0_test_tx_rx_10(void) { rlc_um_info_t um_info; int i,j,r; - - um_info.timer_reordering = 32; um_info.sn_field_length = 10; um_info.is_mXch = 0; - srand (0); config_req_rlc_um (&um_tx, 0,0,0, &um_info, 0, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/); config_req_rlc_um (&um_rx, 0,1,1, &um_info, 1, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/); - rlc_um_display_rx_window(&um_tx); - rlc_um_display_rx_window(&um_rx); - - #ifdef TEST1 srand (0); rlc_um_v9_3_0_test_reset_sdus(); @@ -765,7 +706,6 @@ void rlc_um_v9_3_0_test_tx_rx_10(void) rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 1000, 200); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 1000, 200); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 1000, 200); - assert (g_send_id_read_index[1] == g_send_id_write_index[0]); printf("\n\n\n\n\n\n-----------------------------------------------------------------------------------------rlc_um_v9_3_0_test 1: END OF SIMPLE TEST SEVERAL SDUs IN PDU\n\n\n\n"); sleep(2); @@ -837,7 +777,6 @@ void rlc_um_v9_3_0_test_tx_rx_10(void) rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 2000, 200); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 2000, 200); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 2000, 200); - rlc_um_v9_3_0_test_send_sdu(&um_tx, 1); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 30, 200); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 31, 200); @@ -983,8 +922,6 @@ void rlc_um_v9_3_0_test_tx_rx_10(void) rlc_um_v9_3_0_test_send_sdu(&um_tx, g_random_sdu); g_random_sdu = rand() % 37; //rlc_um_v9_3_0_test_send_sdu(&um_rx, g_random_sdu); - - g_random_nb_frames = rand() % 4; for (j = 0; j < g_random_nb_frames; j++) { @@ -995,7 +932,6 @@ void rlc_um_v9_3_0_test_tx_rx_10(void) //rlc_um_display_rx_window(&um_tx); rlc_um_display_rx_window(&um_rx); - int dropped = (rand() % 3); if ((dropped == 0) && (g_tx_packets > 0)) { @@ -1028,7 +964,6 @@ void rlc_um_v9_3_0_test_tx_rx_10(void) g_target_tx_error_rate, (g_rx_packets >0)?(g_dropped_rx_packets*100)/g_rx_packets:0, g_target_rx_error_rate); - } } @@ -1057,21 +992,14 @@ void rlc_um_v9_3_0_test_tx_rx_5(void) { rlc_um_info_t um_info; int i,j,r; - - um_info.timer_reordering = 32; um_info.sn_field_length = 5; um_info.is_mXch = 0; - srand (0); config_req_rlc_um (&um_tx, 0,0,0, &um_info, 0, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/); config_req_rlc_um (&um_rx, 0,1,1, &um_info, 1, SIGNALLING_RADIO_BEARER, SIGNALLING_RADIO_BEARER /*LC-id = DRB-id*/); - rlc_um_display_rx_window(&um_tx); - rlc_um_display_rx_window(&um_rx); - - #ifdef TEST1 srand (0); printf("\n\n\n\n\n\n-----------------------------------------------------------------------------------------rlc_um_v9_3_0_test_5 1: START OF SIMPLE TEST SEVERAL SDUs IN PDU\n\n\n\n"); @@ -1095,7 +1023,6 @@ void rlc_um_v9_3_0_test_tx_rx_5(void) rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 1000, 200); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 1000, 200); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 1000, 200); - assert (g_send_id_read_index[1] == g_send_id_write_index[0]); printf("\n\n\n\n\n\n-----------------------------------------------------------------------------------------rlc_um_v9_3_0_test_5 1: END OF SIMPLE TEST SEVERAL SDUs IN PDU\n\n\n\n"); sleep(2); @@ -1163,7 +1090,6 @@ void rlc_um_v9_3_0_test_tx_rx_5(void) rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 2000, 200); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 2000, 200); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 2000, 200); - rlc_um_v9_3_0_test_send_sdu(&um_tx, 1); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 26, 200); rlc_um_v9_3_0_test_exchange_pdus(&um_tx, &um_rx, 27, 200); @@ -1301,8 +1227,6 @@ void rlc_um_v9_3_0_test_tx_rx_5(void) rlc_um_v9_3_0_test_send_sdu(&um_tx, g_random_sdu); g_random_sdu = rand() % 37; //rlc_um_v9_3_0_test_send_sdu(&um_rx, g_random_sdu); - - g_random_nb_frames = rand() % 4; for (j = 0; j < g_random_nb_frames; j++) { @@ -1313,7 +1237,6 @@ void rlc_um_v9_3_0_test_tx_rx_5(void) //rlc_um_display_rx_window(&um_tx); rlc_um_display_rx_window(&um_rx); - int dropped = (rand() % 3); if ((dropped == 0) && (g_tx_packets > 0)) { @@ -1346,7 +1269,6 @@ void rlc_um_v9_3_0_test_tx_rx_5(void) g_target_tx_error_rate, (g_rx_packets >0)?(g_dropped_rx_packets*100)/g_rx_packets:0, g_target_rx_error_rate); - } } @@ -1378,11 +1300,9 @@ void rlc_um_v9_3_0_test_print_trace (void) size_t size; char **strings; size_t i; - size = backtrace (array, 100); strings = backtrace_symbols (array, size); - - printf ("Obtained %d stack frames.\n", size); + printf ("Obtained %lu stack frames.\n", (unsigned long)size); for (i = 0; i < size; i++) { printf ("%s\n", strings[i]); @@ -1395,23 +1315,15 @@ void rlc_um_v9_3_0_test(void) //----------------------------------------------------------------------------- { pool_buffer_init(); - set_comp_log(RLC, LOG_TRACE, LOG_MED, 1); - - // tested OK rlc_um_v9_3_0_test_reordering(10); - rlc_um_v9_3_0_test_tx_rx_10(); - // tested OK rlc_um_v9_3_0_test_windows_10(); - rlc_um_v9_3_0_test_tx_rx_5(); rlc_um_v9_3_0_test_windows_5(); rlc_um_v9_3_0_test_reordering(5); - - printf("rlc_um_v9_3_0_test: END OF TESTS\n"); exit(0); } diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index c15adb0d0e42adbe7ba1d54790c76f880fe828e6..3cde5977ff0eac3f9e4c7cd56654a2107695ac80 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -37,6 +37,9 @@ #include "targets/COMMON/openairinterface5g_limits.h" #include "assertions.h" +#include "common/ran_context.h" +extern RAN_CONTEXT_t RC; + extern boolean_t pdcp_data_ind( const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, @@ -375,7 +378,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, //DevCheck(sdu_sizeP > 0, sdu_sizeP, 0, 0); if(sdu_sizeP <= 0) { - LOG_E(RLC, "sdu_sizeP %d, file %s, line %d\n", sdu_sizeP, __FILE__ ,__LINE__); + LOG_E(RLC, "sdu_sizeP %d, file %s, line %d\n", sdu_sizeP, __FILE__,__LINE__); return RLC_OP_STATUS_BAD_PARAMETER; } @@ -564,8 +567,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, } #else - } - else { /* MBMS_flag != 0 */ + } else { /* MBMS_flag != 0 */ free_mem_block(sdu_pP, __func__); LOG_E(RLC, "MBMS_flag != 0 while Rel10/Rel14 is not defined...\n"); //handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : parameter module_id out of bounds :%d\n", __FILE__, __LINE__, module_idP); @@ -585,27 +587,33 @@ void rlc_data_ind ( const sdu_size_t sdu_sizeP, mem_block_t *sdu_pP) { //----------------------------------------------------------------------------- -#if defined(TRACE_RLC_PAYLOAD) LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] Display of rlc_data_ind: size %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, sdu_sizeP); rlc_util_print_hex_octets(RLC, (unsigned char *)sdu_pP->data, sdu_sizeP); -#endif -#if T_TRACER - if (ctxt_pP->enb_flag) + if (ctxt_pP->enb_flag) { +#if T_TRACER T(T_ENB_RLC_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP)); - #endif - pdcp_data_ind ( - ctxt_pP, - srb_flagP, - MBMS_flagP, - rb_idP, - sdu_sizeP, - sdu_pP); + const ngran_node_t type = RC.rrc[ctxt_pP->module_id]->node_type; + AssertFatal(type != ngran_eNB_CU && type != ngran_ng_eNB_CU && type != ngran_gNB_CU, + "Can't be CU, bad node type %d\n", type); + + if (NODE_IS_DU(type) && srb_flagP == 1) { + MessageDef *msg = itti_alloc_new_message(TASK_RLC_ENB, F1AP_UL_RRC_MESSAGE); + F1AP_UL_RRC_MESSAGE(msg).rnti = ctxt_pP->rnti; + F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_idP; + F1AP_UL_RRC_MESSAGE(msg).rrc_container = sdu_pP->data; + F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = sdu_sizeP; + itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg); + return; + } + } // case monolithic eNodeB or UE + + get_pdcp_data_ind_func()(ctxt_pP, srb_flagP, MBMS_flagP, rb_idP, sdu_sizeP, sdu_pP,NULL,NULL); } //----------------------------------------------------------------------------- void rlc_data_conf (const protocol_ctxt_t *const ctxt_pP, @@ -616,7 +624,7 @@ void rlc_data_conf (const protocol_ctxt_t *const ctxt_pP, //----------------------------------------------------------------------------- if (srb_flagP) { if (rlc_rrc_data_conf != NULL) { - rlc_rrc_data_conf (ctxt_pP, rb_idP , muiP, statusP); + rlc_rrc_data_conf (ctxt_pP, rb_idP, muiP, statusP); } } } @@ -640,8 +648,6 @@ rlc_module_init (void) { } for (module_id1=0; module_id1 < MAX_MOBILES_PER_ENB; module_id1++) { -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - for (k=0; k < RLC_MAX_MBMS_LC; k++) { rlc_mbms_lcid2service_session_id_ue[module_id1][k].service_id = 0; rlc_mbms_lcid2service_session_id_ue[module_id1][k].session_id = 0; @@ -650,23 +656,15 @@ rlc_module_init (void) { for (k=0; k < NB_RB_MBMS_MAX; k++) { rlc_mbms_rbid2lcid_ue[module_id1][k] = RLC_LC_UNALLOCATED; } - -#endif } - for (module_id1=0; module_id1 < NUMBER_OF_eNB_MAX; module_id1++) { -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - - for (k=0; k < RLC_MAX_MBMS_LC; k++) { - rlc_mbms_lcid2service_session_id_eNB[module_id1][k].service_id = 0; - rlc_mbms_lcid2service_session_id_eNB[module_id1][k].session_id = 0; - } - - for (k=0; k < NB_RB_MBMS_MAX; k++) { - rlc_mbms_rbid2lcid_eNB[module_id1][k] = RLC_LC_UNALLOCATED; - } + for (k=0; k < RLC_MAX_MBMS_LC; k++) { + rlc_mbms_lcid2service_session_id_eNB[0][k].service_id = 0; + rlc_mbms_lcid2service_session_id_eNB[0][k].session_id = 0; + } -#endif + for (k=0; k < NB_RB_MBMS_MAX; k++) { + rlc_mbms_rbid2lcid_eNB[0][k] = RLC_LC_UNALLOCATED; } pool_buffer_init(); @@ -677,7 +675,7 @@ void rlc_module_cleanup (void) //----------------------------------------------------------------------------- { - hashtable_destroy(rlc_coll_p); + hashtable_destroy(&rlc_coll_p); } //----------------------------------------------------------------------------- void diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index d4ec487c853e9e270fcbb1c518bae6a5d8e79486..b539970704c3f89ba280f1c44202ea8abea369b4 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -261,12 +261,12 @@ void mac_rlc_data_ind ( #ifdef DEBUG_MAC_INTERFACE if (num_tbP) { - LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_IND on channel %d (%d), rb max %d, Num_tb %d\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_IND on channel %d (%d), rb max %d, tb_sizeP %d\n", PROTOCOL_CTXT_ARGS(&ctxt), channel_idP, RLC_MAX_LC, NB_RB_MAX, - num_tbP); + tb_sizeP); } #endif // DEBUG_MAC_INTERFACE @@ -293,7 +293,7 @@ void mac_rlc_data_ind ( rlc_mode = rlc_union_p->mode; } else { rlc_mode = RLC_MODE_NONE; - //AssertFatal (0 , "%s RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP); + //AssertFatal (0 , "%s RLC not configured lcid %u ! (h_rc %d)\n", __FUNCTION__,channel_idP,h_rc); } struct mac_data_ind data_ind = mac_rlc_deserialize_tb(buffer_pP, tb_sizeP, num_tbP, crcs_pP); diff --git a/openair2/LAYER2/RLC/rlc_primitives.h b/openair2/LAYER2/RLC/rlc_primitives.h index eb7b9ae0053b925a3d52132c99e3240b1658181d..bb83852775a581618757c7e9ef7be5c72caed146 100644 --- a/openair2/LAYER2/RLC/rlc_primitives.h +++ b/openair2/LAYER2/RLC/rlc_primitives.h @@ -202,4 +202,5 @@ struct crlc_primitive { struct crlc_status_ind c_status_ind; } primitive; }; + #endif diff --git a/openair2/LAYER2/RLC/rlc_proto_agent_primitives.h b/openair2/LAYER2/RLC/rlc_proto_agent_primitives.h new file mode 100644 index 0000000000000000000000000000000000000000..75ccc9fcdd001cd20a8a83a26b10a7755d517be5 --- /dev/null +++ b/openair2/LAYER2/RLC/rlc_proto_agent_primitives.h @@ -0,0 +1,16 @@ + +#ifndef __PROTO_AGENT_RLC_PRIMITIVES_H__ +#define __PROTO_AGENT_RLC_PRIMITIVES_H__ + +#include "RRC/LTE/rrc_defs.h" +#include "LAYER2/PROTO_AGENT/proto_agent.h" +// PROTO AGENT +pthread_t async_server_thread; +int async_server_thread_finalize (void); +void async_server_thread_init (void); + +pthread_mutex_t async_server_lock; +pthread_cond_t async_server_notify; +int async_server_shutdown; + +#endif diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c index 78a893cfae0b2fe72eb2cb87172885c5d3393745..2251344c47f1c6714bfdcf9b6c3a3ea613c0248f 100644 --- a/openair2/LAYER2/openair2_proc.c +++ b/openair2/LAYER2/openair2_proc.c @@ -39,644 +39,587 @@ #include "common/ran_context.h" static mapping rrc_status_names[] = { - {"RRC_INACTIVE", 0}, - {"RRC_IDLE", 1}, - {"RRC_SI_RECEIVED",2}, - {"RRC_CONNECTED",3}, - {"RRC_RECONFIGURED",4}, - {"RRC_HO_EXECUTION",5}, - {NULL, -1} + {"RRC_INACTIVE", 0}, + {"RRC_IDLE", 1}, + {"RRC_SI_RECEIVED",2}, + {"RRC_CONNECTED",3}, + {"RRC_RECONFIGURED",4}, + {"RRC_HO_EXECUTION",5}, + {NULL, -1} }; extern RAN_CONTEXT_t RC; -int dump_eNB_l2_stats(char *buffer, int length) -{ - - int eNB_id,UE_id,number_of_cards; - int len= length; - int CC_id=0; - int i; - protocol_ctxt_t ctxt; - rlc_op_status_t rlc_status; - unsigned int stat_rlc_mode; - unsigned int stat_tx_pdcp_sdu; - unsigned int stat_tx_pdcp_bytes; - unsigned int stat_tx_pdcp_sdu_discarded; - unsigned int stat_tx_pdcp_bytes_discarded; - unsigned int stat_tx_data_pdu; - unsigned int stat_tx_data_bytes; - unsigned int stat_tx_retransmit_pdu_by_status; - unsigned int stat_tx_retransmit_bytes_by_status; - unsigned int stat_tx_retransmit_pdu; - unsigned int stat_tx_retransmit_bytes; - unsigned int stat_tx_control_pdu; - unsigned int stat_tx_control_bytes; - unsigned int stat_rx_pdcp_sdu; - unsigned int stat_rx_pdcp_bytes; - unsigned int stat_rx_data_pdus_duplicate; - unsigned int stat_rx_data_bytes_duplicate; - unsigned int stat_rx_data_pdu; - unsigned int stat_rx_data_bytes; - unsigned int stat_rx_data_pdu_dropped; - unsigned int stat_rx_data_bytes_dropped; - unsigned int stat_rx_data_pdu_out_of_window; - unsigned int stat_rx_data_bytes_out_of_window; - unsigned int stat_rx_control_pdu; - unsigned int stat_rx_control_bytes; - unsigned int stat_timer_reordering_timed_out; - unsigned int stat_timer_poll_retransmit_timed_out; - unsigned int stat_timer_status_prohibit_timed_out; - +int dump_eNB_l2_stats(char *buffer, int length) { + int eNB_id,UE_id,number_of_cards; + int len= length; + int CC_id=0; + int i; + protocol_ctxt_t ctxt; + rlc_op_status_t rlc_status; + unsigned int stat_rlc_mode; + unsigned int stat_tx_pdcp_sdu; + unsigned int stat_tx_pdcp_bytes; + unsigned int stat_tx_pdcp_sdu_discarded; + unsigned int stat_tx_pdcp_bytes_discarded; + unsigned int stat_tx_data_pdu; + unsigned int stat_tx_data_bytes; + unsigned int stat_tx_retransmit_pdu_by_status; + unsigned int stat_tx_retransmit_bytes_by_status; + unsigned int stat_tx_retransmit_pdu; + unsigned int stat_tx_retransmit_bytes; + unsigned int stat_tx_control_pdu; + unsigned int stat_tx_control_bytes; + unsigned int stat_rx_pdcp_sdu; + unsigned int stat_rx_pdcp_bytes; + unsigned int stat_rx_data_pdus_duplicate; + unsigned int stat_rx_data_bytes_duplicate; + unsigned int stat_rx_data_pdu; + unsigned int stat_rx_data_bytes; + unsigned int stat_rx_data_pdu_dropped; + unsigned int stat_rx_data_bytes_dropped; + unsigned int stat_rx_data_pdu_out_of_window; + unsigned int stat_rx_data_bytes_out_of_window; + unsigned int stat_rx_control_pdu; + unsigned int stat_rx_control_bytes; + unsigned int stat_timer_reordering_timed_out; + unsigned int stat_timer_poll_retransmit_timed_out; + unsigned int stat_timer_status_prohibit_timed_out; #ifdef EXMIMO - number_of_cards=1; + number_of_cards=1; #else - number_of_cards=NB_eNB_INST; + number_of_cards=NB_eNB_INST; #endif - eNB_MAC_INST *eNB; - UE_list_t *UE_list; - - for (eNB_id=0; eNB_id<number_of_cards; eNB_id++) { - /* reset the values */ - eNB = RC.mac[eNB_id]; - UE_list = &eNB->UE_list; - - for (CC_id=0 ; CC_id < MAX_NUM_CCs; CC_id++) { - eNB->eNB_stats[CC_id].dlsch_bitrate= 0; - - len += sprintf(&buffer[len],"eNB %d CC %d Frame %d: Active UEs %d, Available PRBs %d, nCCE %d, Scheduling decisions %d, Missed Deadlines %d \n", - eNB_id, CC_id, eNB->frame, - eNB->eNB_stats[CC_id].num_dlactive_UEs, - eNB->eNB_stats[CC_id].available_prbs, - eNB->eNB_stats[CC_id].available_ncces, - eNB->eNB_stats[CC_id].sched_decisions, - eNB->eNB_stats[CC_id].missed_deadlines); - - len += sprintf(&buffer[len],"BCCH , NB_TX_MAC = %d, transmitted bytes (TTI %d, total %d) MCS (TTI %d)\n", - eNB->eNB_stats[CC_id].total_num_bcch_pdu, - eNB->eNB_stats[CC_id].bcch_buffer, - eNB->eNB_stats[CC_id].total_bcch_buffer, - eNB->eNB_stats[CC_id].bcch_mcs); - - len += sprintf(&buffer[len],"PCCH , NB_TX_MAC = %d, transmitted bytes (TTI %d, total %d) MCS (TTI %d)\n", - eNB->eNB_stats[CC_id].total_num_pcch_pdu, - eNB->eNB_stats[CC_id].pcch_buffer, - eNB->eNB_stats[CC_id].total_pcch_buffer, - eNB->eNB_stats[CC_id].pcch_mcs); - - eNB->eNB_stats[CC_id].dlsch_bitrate=((eNB->eNB_stats[CC_id].dlsch_bytes_tx*8)/((eNB->frame + 1)*10)); - eNB->eNB_stats[CC_id].total_dlsch_pdus_tx+=eNB->eNB_stats[CC_id].dlsch_pdus_tx; - eNB->eNB_stats[CC_id].total_dlsch_bytes_tx+=eNB->eNB_stats[CC_id].dlsch_bytes_tx; - eNB->eNB_stats[CC_id].total_dlsch_bitrate=((eNB->eNB_stats[CC_id].total_dlsch_bytes_tx*8)/((eNB->frame + 1)*10)); - - eNB->eNB_stats[CC_id].ulsch_bitrate=((eNB->eNB_stats[CC_id].ulsch_bytes_rx*8)/((eNB->frame + 1)*10)); - eNB->eNB_stats[CC_id].total_ulsch_bitrate=((eNB->eNB_stats[CC_id].total_ulsch_bytes_rx*8)/((eNB->frame + 1)*10)); - - len += sprintf(&buffer[len],"DLSCH bitrate (TTI %u, avg %u) kbps, Transmitted bytes (TTI %u, total %u), Transmitted PDU (TTI %u, total %u) \n", - eNB->eNB_stats[CC_id].dlsch_bitrate, - eNB->eNB_stats[CC_id].total_dlsch_bitrate, - eNB->eNB_stats[CC_id].dlsch_bytes_tx, - eNB->eNB_stats[CC_id].total_dlsch_bytes_tx, - eNB->eNB_stats[CC_id].dlsch_pdus_tx, - eNB->eNB_stats[CC_id].total_dlsch_pdus_tx); - - len += sprintf(&buffer[len],"ULSCH bitrate (TTI %u, avg %u) kbps, Received bytes (TTI %u, total %u), Received PDU (TTI %lu, total %u) \n", - eNB->eNB_stats[CC_id].ulsch_bitrate, - eNB->eNB_stats[CC_id].total_ulsch_bitrate, - eNB->eNB_stats[CC_id].ulsch_bytes_rx, - eNB->eNB_stats[CC_id].total_ulsch_bytes_rx, - eNB->eNB_stats[CC_id].ulsch_pdus_rx, - eNB->eNB_stats[CC_id].total_ulsch_pdus_rx); - } + eNB_MAC_INST *eNB; + UE_list_t *UE_list; + + for (eNB_id=0; eNB_id<number_of_cards; eNB_id++) { + /* reset the values */ + eNB = RC.mac[eNB_id]; + UE_list = &eNB->UE_list; + + for (CC_id=0 ; CC_id < MAX_NUM_CCs; CC_id++) { + eNB->eNB_stats[CC_id].dlsch_bitrate= 0; + len += sprintf(&buffer[len],"eNB %d CC %d Frame %d: Active UEs %d, Available PRBs %d, nCCE %d, Scheduling decisions %d, Missed Deadlines %d \n", + eNB_id, CC_id, eNB->frame, + eNB->eNB_stats[CC_id].num_dlactive_UEs, + eNB->eNB_stats[CC_id].available_prbs, + eNB->eNB_stats[CC_id].available_ncces, + eNB->eNB_stats[CC_id].sched_decisions, + eNB->eNB_stats[CC_id].missed_deadlines); + len += sprintf(&buffer[len],"BCCH , NB_TX_MAC = %d, transmitted bytes (TTI %d, total %d) MCS (TTI %d)\n", + eNB->eNB_stats[CC_id].total_num_bcch_pdu, + eNB->eNB_stats[CC_id].bcch_buffer, + eNB->eNB_stats[CC_id].total_bcch_buffer, + eNB->eNB_stats[CC_id].bcch_mcs); + len += sprintf(&buffer[len],"PCCH , NB_TX_MAC = %d, transmitted bytes (TTI %d, total %d) MCS (TTI %d)\n", + eNB->eNB_stats[CC_id].total_num_pcch_pdu, + eNB->eNB_stats[CC_id].pcch_buffer, + eNB->eNB_stats[CC_id].total_pcch_buffer, + eNB->eNB_stats[CC_id].pcch_mcs); + eNB->eNB_stats[CC_id].dlsch_bitrate=((eNB->eNB_stats[CC_id].dlsch_bytes_tx*8)/((eNB->frame + 1)*10)); + eNB->eNB_stats[CC_id].total_dlsch_pdus_tx+=eNB->eNB_stats[CC_id].dlsch_pdus_tx; + eNB->eNB_stats[CC_id].total_dlsch_bytes_tx+=eNB->eNB_stats[CC_id].dlsch_bytes_tx; + eNB->eNB_stats[CC_id].total_dlsch_bitrate=((eNB->eNB_stats[CC_id].total_dlsch_bytes_tx*8)/((eNB->frame + 1)*10)); + eNB->eNB_stats[CC_id].ulsch_bitrate=((eNB->eNB_stats[CC_id].ulsch_bytes_rx*8)/((eNB->frame + 1)*10)); + eNB->eNB_stats[CC_id].total_ulsch_bitrate=((eNB->eNB_stats[CC_id].total_ulsch_bytes_rx*8)/((eNB->frame + 1)*10)); + len += sprintf(&buffer[len],"DLSCH bitrate (TTI %u, avg %u) kbps, Transmitted bytes (TTI %u, total %u), Transmitted PDU (TTI %u, total %u) \n", + eNB->eNB_stats[CC_id].dlsch_bitrate, + eNB->eNB_stats[CC_id].total_dlsch_bitrate, + eNB->eNB_stats[CC_id].dlsch_bytes_tx, + eNB->eNB_stats[CC_id].total_dlsch_bytes_tx, + eNB->eNB_stats[CC_id].dlsch_pdus_tx, + eNB->eNB_stats[CC_id].total_dlsch_pdus_tx); + len += sprintf(&buffer[len],"ULSCH bitrate (TTI %u, avg %u) kbps, Received bytes (TTI %u, total %u), Received PDU (TTI %lu, total %u) \n", + eNB->eNB_stats[CC_id].ulsch_bitrate, + eNB->eNB_stats[CC_id].total_ulsch_bitrate, + eNB->eNB_stats[CC_id].ulsch_bytes_rx, + eNB->eNB_stats[CC_id].total_ulsch_bytes_rx, + eNB->eNB_stats[CC_id].ulsch_pdus_rx, + eNB->eNB_stats[CC_id].total_ulsch_pdus_rx); + } + + len += sprintf(&buffer[len],"\n"); + + for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) { + CC_id=UE_list->ordered_CCids[i][UE_id]; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate=((UE_list->eNB_UE_stats[CC_id][UE_id].TBS*8)/((eNB->frame + 1)*10)); + UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate= ((UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes*8)/((eNB->frame + 1)*10)); + UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes+= UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes; + UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes=((UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes*8)/((eNB->frame + 1)*10)); + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_bitrate=((UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS*8)/((eNB->frame + 1)*10)); + UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_bitrate= ((UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx*8)/((eNB->frame + 1)*10)); + len += sprintf(&buffer[len],"[MAC] UE %d (DLSCH),status %s, RNTI %x : CQI %d, MCS1 %d, MCS2 %d, RB (tx %d, retx %d, total %d), ncce (tx %d, retx %d) \n", + UE_id, + map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status), + UE_list->eNB_UE_stats[CC_id][UE_id].crnti, + UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id], + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1, + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2, + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used, + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx, + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used, + UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used, + UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx + ); + len += sprintf(&buffer[len], + "[MAC] DLSCH bitrate (TTI %d, avg %d), Transmitted bytes " + "(TTI %d, total %"PRIu64"), Total Transmitted PDU %d, Overhead " + "(TTI %"PRIu64", total %"PRIu64", avg %"PRIu64")\n", + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate, + UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate, + UE_list->eNB_UE_stats[CC_id][UE_id].TBS, + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes, + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus, + UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes, + UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes, + UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes + ); + len += sprintf(&buffer[len],"[MAC] UE %d (ULSCH), Status %s, Failute timer %d, RNTI %x : rx power (normalized %d, target %d), MCS (pre %d, post %d), RB (rx %d, retx %d, total %d), Current TBS %d \n", + UE_id, + map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status), + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer, + UE_list->eNB_UE_stats[CC_id][UE_id].crnti, + UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power, + UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power, + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1, + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2, + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_rx, + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx, + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx, + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS + ); + len += sprintf(&buffer[len], + "[MAC] ULSCH bitrate (TTI %d, avg %d), received bytes (total %"PRIu64")," + "Total received PDU %d, Total errors %d\n", + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_bitrate, + UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_bitrate, + UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx, + UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus_rx, + UE_list->eNB_UE_stats[CC_id][UE_id].num_errors_rx); + len+= sprintf(&buffer[len],"[MAC] Received PHR PH = %d (db)\n", UE_list->UE_template[CC_id][UE_id].phr_info); + len+= sprintf(&buffer[len],"[MAC] Estimated size LCGID[0][1][2][3] = %u %u %u %u\n", + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID0], + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID1], + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID2], + UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID3] + ); + } + + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, + eNB_id, + ENB_FLAG_YES, + UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti, + eNB->frame, + eNB->subframe, + eNB_id); + rlc_status = rlc_stat_req(&ctxt, + SRB_FLAG_YES, + DCCH, + &stat_rlc_mode, + &stat_tx_pdcp_sdu, + &stat_tx_pdcp_bytes, + &stat_tx_pdcp_sdu_discarded, + &stat_tx_pdcp_bytes_discarded, + &stat_tx_data_pdu, + &stat_tx_data_bytes, + &stat_tx_retransmit_pdu_by_status, + &stat_tx_retransmit_bytes_by_status, + &stat_tx_retransmit_pdu, + &stat_tx_retransmit_bytes, + &stat_tx_control_pdu, + &stat_tx_control_bytes, + &stat_rx_pdcp_sdu, + &stat_rx_pdcp_bytes, + &stat_rx_data_pdus_duplicate, + &stat_rx_data_bytes_duplicate, + &stat_rx_data_pdu, + &stat_rx_data_bytes, + &stat_rx_data_pdu_dropped, + &stat_rx_data_bytes_dropped, + &stat_rx_data_pdu_out_of_window, + &stat_rx_data_bytes_out_of_window, + &stat_rx_control_pdu, + &stat_rx_control_bytes, + &stat_timer_reordering_timed_out, + &stat_timer_poll_retransmit_timed_out, + &stat_timer_status_prohibit_timed_out); + + if (rlc_status == RLC_OP_STATUS_OK) { + len+=sprintf(&buffer[len],"[RLC] DCCH Mode %s, NB_SDU_TO_TX = %u (bytes %u)\tNB_SDU_TO_TX_DISC %u (bytes %u)\n", + (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", + stat_tx_pdcp_sdu, + stat_tx_pdcp_bytes, + stat_tx_pdcp_sdu_discarded, + stat_tx_pdcp_bytes_discarded); + len+=sprintf(&buffer[len],"[RLC] DCCH Mode %s, NB_TX_DATA = %u (bytes %u)\tNB_TX_CONTROL %u (bytes %u)\tNB_TX_RETX %u (bytes %u)\tNB_TX_RETX_BY_STATUS = %u (bytes %u)\n", + (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", + stat_tx_data_pdu, + stat_tx_data_bytes, + stat_tx_control_pdu, + stat_tx_control_bytes, + stat_tx_retransmit_pdu, + stat_tx_retransmit_bytes, + stat_tx_retransmit_pdu_by_status, + stat_tx_retransmit_bytes_by_status); + len+=sprintf(&buffer[len],"[RLC] DCCH Mode %s, NB_RX_DATA = %u (bytes %u)\tNB_RX_CONTROL %u (bytes %u)\tNB_RX_DUPL %u (bytes %u)\tNB_RX_DROP = %u (bytes %u)\tNB_RX_OUT_OF_WINDOW = %u (bytes %u)\n", + (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", + stat_rx_data_pdu, + stat_rx_data_bytes, + stat_rx_control_pdu, + stat_rx_control_bytes, + stat_rx_data_pdus_duplicate, + stat_rx_data_bytes_duplicate, + stat_rx_data_pdu_dropped, + stat_rx_data_bytes_dropped, + stat_rx_data_pdu_out_of_window, + stat_rx_data_bytes_out_of_window); + len+=sprintf(&buffer[len],"[RLC] DCCH Mode %s, RX_REODERING_TIMEOUT = %u\tRX_POLL_RET_TIMEOUT %u\tRX_PROHIBIT_TIME_OUT %u\n", + (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", + stat_timer_reordering_timed_out, + stat_timer_poll_retransmit_timed_out, + stat_timer_status_prohibit_timed_out); + len+=sprintf(&buffer[len],"[RLC] DCCH Mode %s, NB_SDU_TO_RX = %u (bytes %u)\n", + (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", + stat_rx_pdcp_sdu, + stat_rx_pdcp_bytes); + } - len += sprintf(&buffer[len],"\n"); - - for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { - for (i=0; i<UE_list->numactiveCCs[UE_id]; i++) { - CC_id=UE_list->ordered_CCids[i][UE_id]; - - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate=((UE_list->eNB_UE_stats[CC_id][UE_id].TBS*8)/((eNB->frame + 1)*10)); - UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate= ((UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes*8)/((eNB->frame + 1)*10)); - UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes+= UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes; - UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes=((UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes*8)/((eNB->frame + 1)*10)); - - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_bitrate=((UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS*8)/((eNB->frame + 1)*10)); - UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_bitrate= ((UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx*8)/((eNB->frame + 1)*10)); - - len += sprintf(&buffer[len],"[MAC] UE %d (DLSCH),status %s, RNTI %x : CQI %d, MCS1 %d, MCS2 %d, RB (tx %d, retx %d, total %d), ncce (tx %d, retx %d) \n", - UE_id, - map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status), - UE_list->eNB_UE_stats[CC_id][UE_id].crnti, - UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id], - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1, - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2, - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used, - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx, - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used, - UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used, - UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx - ); - - len += sprintf(&buffer[len], - "[MAC] DLSCH bitrate (TTI %d, avg %d), Transmitted bytes " - "(TTI %d, total %"PRIu64"), Total Transmitted PDU %d, Overhead " - "(TTI %"PRIu64", total %"PRIu64", avg %"PRIu64")\n", - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_bitrate, - UE_list->eNB_UE_stats[CC_id][UE_id].total_dlsch_bitrate, - UE_list->eNB_UE_stats[CC_id][UE_id].TBS, - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes, - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus, - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes, - UE_list->eNB_UE_stats[CC_id][UE_id].total_overhead_bytes, - UE_list->eNB_UE_stats[CC_id][UE_id].avg_overhead_bytes - ); - - - len += sprintf(&buffer[len],"[MAC] UE %d (ULSCH), Status %s, Failute timer %d, RNTI %x : rx power (normalized %d, target %d), MCS (pre %d, post %d), RB (rx %d, retx %d, total %d), Current TBS %d \n", - UE_id, - map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status), - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer, - UE_list->eNB_UE_stats[CC_id][UE_id].crnti, - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power, - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power, - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1, - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2, - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_rx, - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx, - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx, - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS - ); - - len += sprintf(&buffer[len], - "[MAC] ULSCH bitrate (TTI %d, avg %d), received bytes (total %"PRIu64")," - "Total received PDU %d, Total errors %d\n", - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_bitrate, - UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_bitrate, - UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx, - UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus_rx, - UE_list->eNB_UE_stats[CC_id][UE_id].num_errors_rx); - - len+= sprintf(&buffer[len],"[MAC] Received PHR PH = %d (db)\n", UE_list->UE_template[CC_id][UE_id].phr_info); - len+= sprintf(&buffer[len],"[MAC] Estimated size LCGID[0][1][2][3] = %u %u %u %u\n", - UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID0], - UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID1], - UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID2], - UE_list->UE_template[CC_id][UE_id].ul_buffer_info[LCGID3] - ); - } - - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, - eNB_id, - ENB_FLAG_YES, - UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti, - eNB->frame, - eNB->subframe, - eNB_id); - - rlc_status = rlc_stat_req(&ctxt, - SRB_FLAG_YES, - DCCH, - &stat_rlc_mode, - &stat_tx_pdcp_sdu, - &stat_tx_pdcp_bytes, - &stat_tx_pdcp_sdu_discarded, - &stat_tx_pdcp_bytes_discarded, - &stat_tx_data_pdu, - &stat_tx_data_bytes, - &stat_tx_retransmit_pdu_by_status, - &stat_tx_retransmit_bytes_by_status, - &stat_tx_retransmit_pdu, - &stat_tx_retransmit_bytes, - &stat_tx_control_pdu, - &stat_tx_control_bytes, - &stat_rx_pdcp_sdu, - &stat_rx_pdcp_bytes, - &stat_rx_data_pdus_duplicate, - &stat_rx_data_bytes_duplicate, - &stat_rx_data_pdu, - &stat_rx_data_bytes, - &stat_rx_data_pdu_dropped, - &stat_rx_data_bytes_dropped, - &stat_rx_data_pdu_out_of_window, - &stat_rx_data_bytes_out_of_window, - &stat_rx_control_pdu, - &stat_rx_control_bytes, - &stat_timer_reordering_timed_out, - &stat_timer_poll_retransmit_timed_out, - &stat_timer_status_prohibit_timed_out); - - if (rlc_status == RLC_OP_STATUS_OK) { - len+=sprintf(&buffer[len],"[RLC] DCCH Mode %s, NB_SDU_TO_TX = %d (bytes %d)\tNB_SDU_TO_TX_DISC %d (bytes %d)\n", - (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", - stat_tx_pdcp_sdu, - stat_tx_pdcp_bytes, - stat_tx_pdcp_sdu_discarded, - stat_tx_pdcp_bytes_discarded); - - len+=sprintf(&buffer[len],"[RLC] DCCH Mode %s, NB_TX_DATA = %d (bytes %d)\tNB_TX_CONTROL %d (bytes %d)\tNB_TX_RETX %d (bytes %d)\tNB_TX_RETX_BY_STATUS = %d (bytes %d)\n", - (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", - stat_tx_data_pdu, - stat_tx_data_bytes, - stat_tx_control_pdu, - stat_tx_control_bytes, - stat_tx_retransmit_pdu, - stat_tx_retransmit_bytes, - stat_tx_retransmit_pdu_by_status, - stat_tx_retransmit_bytes_by_status); - - - len+=sprintf(&buffer[len],"[RLC] DCCH Mode %s, NB_RX_DATA = %d (bytes %d)\tNB_RX_CONTROL %d (bytes %d)\tNB_RX_DUPL %d (bytes %d)\tNB_RX_DROP = %d (bytes %d)\tNB_RX_OUT_OF_WINDOW = %d (bytes %d)\n", - (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", - stat_rx_data_pdu, - stat_rx_data_bytes, - stat_rx_control_pdu, - stat_rx_control_bytes, - stat_rx_data_pdus_duplicate, - stat_rx_data_bytes_duplicate, - stat_rx_data_pdu_dropped, - stat_rx_data_bytes_dropped, - stat_rx_data_pdu_out_of_window, - stat_rx_data_bytes_out_of_window); - - - len+=sprintf(&buffer[len],"[RLC] DCCH Mode %s, RX_REODERING_TIMEOUT = %d\tRX_POLL_RET_TIMEOUT %d\tRX_PROHIBIT_TIME_OUT %d\n", - (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", - stat_timer_reordering_timed_out, - stat_timer_poll_retransmit_timed_out, - stat_timer_status_prohibit_timed_out); - - len+=sprintf(&buffer[len],"[RLC] DCCH Mode %s, NB_SDU_TO_RX = %d (bytes %d)\n", - (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", - stat_rx_pdcp_sdu, - stat_rx_pdcp_bytes); - } - - rlc_status = rlc_stat_req(&ctxt, - SRB_FLAG_NO, - DTCH-2, // DRB_IDENTITY - &stat_rlc_mode, - &stat_tx_pdcp_sdu, - &stat_tx_pdcp_bytes, - &stat_tx_pdcp_sdu_discarded, - &stat_tx_pdcp_bytes_discarded, - &stat_tx_data_pdu, - &stat_tx_data_bytes, - &stat_tx_retransmit_pdu_by_status, - &stat_tx_retransmit_bytes_by_status, - &stat_tx_retransmit_pdu, - &stat_tx_retransmit_bytes, - &stat_tx_control_pdu, - &stat_tx_control_bytes, - &stat_rx_pdcp_sdu, - &stat_rx_pdcp_bytes, - &stat_rx_data_pdus_duplicate, - &stat_rx_data_bytes_duplicate, - &stat_rx_data_pdu, - &stat_rx_data_bytes, - &stat_rx_data_pdu_dropped, - &stat_rx_data_bytes_dropped, - &stat_rx_data_pdu_out_of_window, - &stat_rx_data_bytes_out_of_window, - &stat_rx_control_pdu, - &stat_rx_control_bytes, - &stat_timer_reordering_timed_out, - &stat_timer_poll_retransmit_timed_out, - &stat_timer_status_prohibit_timed_out); - - if (rlc_status == RLC_OP_STATUS_OK) { - len+=sprintf(&buffer[len],"[RLC] DTCH Mode %s, NB_SDU_TO_TX = %d (bytes %d)\tNB_SDU_TO_TX_DISC %d (bytes %d)\n", - (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", - stat_tx_pdcp_sdu, - stat_tx_pdcp_bytes, - stat_tx_pdcp_sdu_discarded, - stat_tx_pdcp_bytes_discarded); - - len+=sprintf(&buffer[len],"[RLC] DTCH Mode %s, NB_TX_DATA = %d (bytes %d)\tNB_TX_CONTROL %d (bytes %d)\tNB_TX_RETX %d (bytes %d)\tNB_TX_RETX_BY_STATUS = %d (bytes %d)\n", - (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", - stat_tx_data_pdu, - stat_tx_data_bytes, - stat_tx_control_pdu, - stat_tx_control_bytes, - stat_tx_retransmit_pdu, - stat_tx_retransmit_bytes, - stat_tx_retransmit_pdu_by_status, - stat_tx_retransmit_bytes_by_status); - - - len+=sprintf(&buffer[len],"[RLC] DTCH Mode %s, NB_RX_DATA = %d (bytes %d)\tNB_RX_CONTROL %d (bytes %d)\tNB_RX_DUPL %d (bytes %d)\tNB_RX_DROP = %d (bytes %d)\tNB_RX_OUT_OF_WINDOW = %d (bytes %d)\n", - (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", - stat_rx_data_pdu, - stat_rx_data_bytes, - stat_rx_control_pdu, - stat_rx_control_bytes, - stat_rx_data_pdus_duplicate, - stat_rx_data_bytes_duplicate, - stat_rx_data_pdu_dropped, - stat_rx_data_bytes_dropped, - stat_rx_data_pdu_out_of_window, - stat_rx_data_bytes_out_of_window); - - - len+=sprintf(&buffer[len],"[RLC] DTCH Mode %s, RX_REODERING_TIMEOUT = %d\tRX_POLL_RET_TIMEOUT %d\tRX_PROHIBIT_TIME_OUT %d\n", - (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", - stat_timer_reordering_timed_out, - stat_timer_poll_retransmit_timed_out, - stat_timer_status_prohibit_timed_out); - - len+=sprintf(&buffer[len],"[RLC] DTCH Mode %s, NB_SDU_TO_RX = %d (bytes %d)\n", - (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", - stat_rx_pdcp_sdu, - stat_rx_pdcp_bytes); - - } + rlc_status = rlc_stat_req(&ctxt, + SRB_FLAG_NO, + DTCH-2, // DRB_IDENTITY + &stat_rlc_mode, + &stat_tx_pdcp_sdu, + &stat_tx_pdcp_bytes, + &stat_tx_pdcp_sdu_discarded, + &stat_tx_pdcp_bytes_discarded, + &stat_tx_data_pdu, + &stat_tx_data_bytes, + &stat_tx_retransmit_pdu_by_status, + &stat_tx_retransmit_bytes_by_status, + &stat_tx_retransmit_pdu, + &stat_tx_retransmit_bytes, + &stat_tx_control_pdu, + &stat_tx_control_bytes, + &stat_rx_pdcp_sdu, + &stat_rx_pdcp_bytes, + &stat_rx_data_pdus_duplicate, + &stat_rx_data_bytes_duplicate, + &stat_rx_data_pdu, + &stat_rx_data_bytes, + &stat_rx_data_pdu_dropped, + &stat_rx_data_bytes_dropped, + &stat_rx_data_pdu_out_of_window, + &stat_rx_data_bytes_out_of_window, + &stat_rx_control_pdu, + &stat_rx_control_bytes, + &stat_timer_reordering_timed_out, + &stat_timer_poll_retransmit_timed_out, + &stat_timer_status_prohibit_timed_out); + + if (rlc_status == RLC_OP_STATUS_OK) { + len+=sprintf(&buffer[len],"[RLC] DTCH Mode %s, NB_SDU_TO_TX = %u (bytes %u)\tNB_SDU_TO_TX_DISC %u (bytes %u)\n", + (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", + stat_tx_pdcp_sdu, + stat_tx_pdcp_bytes, + stat_tx_pdcp_sdu_discarded, + stat_tx_pdcp_bytes_discarded); + len+=sprintf(&buffer[len],"[RLC] DTCH Mode %s, NB_TX_DATA = %u (bytes %u)\tNB_TX_CONTROL %u (bytes %u)\tNB_TX_RETX %u (bytes %u)\tNB_TX_RETX_BY_STATUS = %u (bytes %u)\n", + (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", + stat_tx_data_pdu, + stat_tx_data_bytes, + stat_tx_control_pdu, + stat_tx_control_bytes, + stat_tx_retransmit_pdu, + stat_tx_retransmit_bytes, + stat_tx_retransmit_pdu_by_status, + stat_tx_retransmit_bytes_by_status); + len+=sprintf(&buffer[len],"[RLC] DTCH Mode %s, NB_RX_DATA = %u (bytes %u)\tNB_RX_CONTROL %u (bytes %u)\tNB_RX_DUPL %u (bytes %u)\tNB_RX_DROP = %u (bytes %u)\tNB_RX_OUT_OF_WINDOW = %u (bytes %u)\n", + (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", + stat_rx_data_pdu, + stat_rx_data_bytes, + stat_rx_control_pdu, + stat_rx_control_bytes, + stat_rx_data_pdus_duplicate, + stat_rx_data_bytes_duplicate, + stat_rx_data_pdu_dropped, + stat_rx_data_bytes_dropped, + stat_rx_data_pdu_out_of_window, + stat_rx_data_bytes_out_of_window); + len+=sprintf(&buffer[len],"[RLC] DTCH Mode %s, RX_REODERING_TIMEOUT = %u\tRX_POLL_RET_TIMEOUT %u\tRX_PROHIBIT_TIME_OUT %u\n", + (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", + stat_timer_reordering_timed_out, + stat_timer_poll_retransmit_timed_out, + stat_timer_status_prohibit_timed_out); + len+=sprintf(&buffer[len],"[RLC] DTCH Mode %s, NB_SDU_TO_RX = %u (bytes %u)\n", + (stat_rlc_mode==RLC_MODE_AM)? "AM": (stat_rlc_mode==RLC_MODE_UM)?"UM":"NONE", + stat_rx_pdcp_sdu, + stat_rx_pdcp_bytes); + } + } } - } - - return len + 1 /* SR: for trailing \0 */; -} + return len + 1 /* SR: for trailing \0 */; +} #ifdef PROC -int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length) -{ - - int len = 0,fg,Overhead, Sign; - unsigned int i,j,k,kk; - unsigned int Mod_id = 0,CH_index; - unsigned int tx_pdcp_sdu; - unsigned int tx_pdcp_sdu_discarded; - unsigned int tx_retransmit_pdu_unblock; - unsigned int tx_retransmit_pdu_by_status; - unsigned int tx_retransmit_pdu; - unsigned int tx_data_pdu; - unsigned int tx_control_pdu; - unsigned int rx_sdu; - unsigned int rx_error_pdu; - unsigned int rx_data_pdu; - unsigned int rx_data_pdu_out_of_window; - unsigned int rx_control_pdu; - - // if (mac_xface->is_cluster_head == 0) { - for (k=0; k<NB_INST; k++) { - - - - if (Mac_rlc_xface->Is_cluster_head[k] == 0) { +int openair2_stats_read(char *buffer, char **my_buffer, off_t off, int length) { + int len = 0,fg,Overhead, Sign; + unsigned int i,j,k,kk; + unsigned int Mod_id = 0,CH_index; + unsigned int tx_pdcp_sdu; + unsigned int tx_pdcp_sdu_discarded; + unsigned int tx_retransmit_pdu_unblock; + unsigned int tx_retransmit_pdu_by_status; + unsigned int tx_retransmit_pdu; + unsigned int tx_data_pdu; + unsigned int tx_control_pdu; + unsigned int rx_sdu; + unsigned int rx_error_pdu; + unsigned int rx_data_pdu; + unsigned int rx_data_pdu_out_of_window; + unsigned int rx_control_pdu; + + // if (mac_xface->is_cluster_head == 0) { + for (k=0; k<NB_INST; k++) { + if (Mac_rlc_xface->Is_cluster_head[k] == 0) { #ifndef PHY_EMUL_ONE_MACHINE - Mod_id=k-NB_CH_INST; - - len+=sprintf(&buffer[len],"UE TTI: %d\n",Mac_rlc_xface->frame); - - for (CH_index = 0; CH_index<NB_CNX_UE; CH_index++) { - - - if (UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Active==1) { - len+=sprintf(&buffer[len],"CH %d: Wideband SINR %d dB---\n", - CH_index,UE_mac_inst[Mod_id].Def_meas[CH_index].Wideband_sinr); - len+=sprintf(&buffer[len],"CH %d: Subband SINR (dB) :", - CH_index); - - for (fg=0; fg<NUMBER_OF_MEASUREMENT_SUBBANDS; fg++) { - len+=sprintf(&buffer[len],"%d ",UE_mac_inst[Mod_id].Def_meas[CH_index].Sinr_meas[0][fg]); - } - - len+=sprintf(&buffer[len],"\n"); - - - len+=sprintf(&buffer[len],"BCCH %d, NB_RX_MAC = %d (%d errors)\n", - UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.Lchan_id.Index, - UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.NB_RX, - UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS); - - - - len+=sprintf(&buffer[len],"CCCH %d, NB_RX_MAC = %d (%d errors)\n", - UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.Lchan_id.Index, - UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.NB_RX, - UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.NB_RX_ERRORS); - - - len+=sprintf(&buffer[len],"LCHAN %d (DCCH), NB_TX_MAC = %d (%d bits/TTI, %d kbits/sec), NB_RX_MAC = %d (%d errors)\n", - UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.Lchan_id.Index, - UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_TX, - UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.output_rate, - (10*UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.output_rate)>>5, - UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX, - UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS); - - for(i=1; i<NB_RAB_MAX; i++) { - if (UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Active==1) { - Overhead=UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate - Pdcp_stats_tx_rate[k][CH_index][i]; - - if(Overhead<0) { - Overhead=-Overhead; - Sign=-1; - } else { - Sign=1; - } - - len+=sprintf(&buffer[len], - "[PDCP]LCHAN %d: NB_TX = %d ,Tx_rate =(%d bits/TTI ,%d Kbits/s), NB_RX = %d ,Rx_rate =(%d bits/TTI ,%d Kbits/s) , LAYER2 TX OVERHEAD: %d Kbits/s\n", - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, - Pdcp_stats_tx[k][CH_index][i], - Pdcp_stats_tx_rate[k][CH_index][i], - (10*Pdcp_stats_tx_rate[k][CH_index][i])>>5, - Pdcp_stats_rx[k][CH_index][i], - Pdcp_stats_rx_rate[k][CH_index][i], - (10*Pdcp_stats_rx_rate[k][CH_index][i])>>5, - Sign*(10*Overhead)>>5); - - - int status = rlc_stat_req (k, - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, - &tx_pdcp_sdu, - &tx_pdcp_sdu_discarded, - &tx_retransmit_pdu_unblock, - &tx_retransmit_pdu_by_status, - &tx_retransmit_pdu, - &tx_data_pdu, - &tx_control_pdu, - &rx_sdu, - &rx_error_pdu, - &rx_data_pdu, - &rx_data_pdu_out_of_window, - &rx_control_pdu) ; - - if (status == RLC_OP_STATUS_OK) { - len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n", - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + Mod_id=k-NB_CH_INST; + len+=sprintf(&buffer[len],"UE TTI: %d\n",Mac_rlc_xface->frame); + + for (CH_index = 0; CH_index<NB_CNX_UE; CH_index++) { + if (UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Active==1) { + len+=sprintf(&buffer[len],"CH %u: Wideband SINR %d dB---\n", + CH_index,UE_mac_inst[Mod_id].Def_meas[CH_index].Wideband_sinr); + len+=sprintf(&buffer[len],"CH %u: Subband SINR (dB) :", + CH_index); + + for (fg=0; fg<NUMBER_OF_MEASUREMENT_SUBBANDS; fg++) { + len+=sprintf(&buffer[len],"%d ",UE_mac_inst[Mod_id].Def_meas[CH_index].Sinr_meas[0][fg]); + } + + len+=sprintf(&buffer[len],"\n"); + len+=sprintf(&buffer[len],"BCCH %d, NB_RX_MAC = %d (%d errors)\n", + UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.Lchan_id.Index, + UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.NB_RX, + UE_mac_inst[Mod_id].Bcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS); + len+=sprintf(&buffer[len],"CCCH %d, NB_RX_MAC = %d (%d errors)\n", + UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.Lchan_id.Index, + UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.NB_RX, + UE_mac_inst[Mod_id].Ccch_lchan[CH_index].Lchan_info.NB_RX_ERRORS); + len+=sprintf(&buffer[len],"LCHAN %d (DCCH), NB_TX_MAC = %d (%d bits/TTI, %d kbits/sec), NB_RX_MAC = %d (%d errors)\n", + UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.Lchan_id.Index, + UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_TX, + UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.output_rate, + (10*UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.output_rate)>>5, + UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX, + UE_mac_inst[Mod_id].Dcch_lchan[CH_index].Lchan_info.NB_RX_ERRORS); + + for(i=1; i<NB_RAB_MAX; i++) { + if (UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Active==1) { + Overhead=UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate - Pdcp_stats_tx_rate[k][CH_index][i]; + + if(Overhead<0) { + Overhead=-Overhead; + Sign=-1; + } else { + Sign=1; + } + + len+=sprintf(&buffer[len], + "[PDCP]LCHAN %d: NB_TX = %d ,Tx_rate =(%d bits/TTI ,%d Kbits/s), NB_RX = %d ,Rx_rate =(%d bits/TTI ,%d Kbits/s) , LAYER2 TX OVERHEAD: %d Kbits/s\n", + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + Pdcp_stats_tx[k][CH_index][i], + Pdcp_stats_tx_rate[k][CH_index][i], + (10*Pdcp_stats_tx_rate[k][CH_index][i])>>5, + Pdcp_stats_rx[k][CH_index][i], + Pdcp_stats_rx_rate[k][CH_index][i], + (10*Pdcp_stats_rx_rate[k][CH_index][i])>>5, + Sign*(10*Overhead)>>5); + int status = rlc_stat_req (k, + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + &tx_pdcp_sdu, + &tx_pdcp_sdu_discarded, + &tx_retransmit_pdu_unblock, + &tx_retransmit_pdu_by_status, + &tx_retransmit_pdu, + &tx_data_pdu, + &tx_control_pdu, + &rx_sdu, + &rx_error_pdu, + &rx_data_pdu, + &rx_data_pdu_out_of_window, + &rx_control_pdu) ; + + if (status == RLC_OP_STATUS_OK) { + len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_SDU_TO_TX = %u\tNB_SDU_DISC %u\tNB_RX_SDU %u\n", + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + tx_pdcp_sdu, + tx_pdcp_sdu_discarded, + rx_sdu); + len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_TB_TX_DATA = %u\tNB_TB_TX_CONTROL %u\tNB_TX_TB_RETRANS %u", + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + tx_data_pdu, + tx_control_pdu, + tx_retransmit_pdu); + len+=sprintf(&buffer[len],"\tRLC LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %u\tNB_TX_TB_RETRANS_PADD %u\n", + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + tx_retransmit_pdu_by_status, + tx_retransmit_pdu_unblock); + len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_RX_DATA = %u\tNB_RX_TB_OUT_WIN %u\tNB_RX_TB_CORRUPT %u\n", + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + rx_data_pdu, + rx_data_pdu_out_of_window, + rx_error_pdu); + } + + len+=sprintf(&buffer[len],"[MAC]: LCHAN %d, NB_TX_MAC = %d (%d bits/TTI, %d kbits/s), NB_RX_MAC = %d (%d errors)\n", + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX, + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate, + (10*UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate)>>5, + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX, + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS); + len+=sprintf(&buffer[len]," TX per TB: "); + + for(kk=0; kk<MAX_NUMBER_TB_PER_LCHAN/2; kk++) { + len+=sprintf(&buffer[len],"%d . ",UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX_TB[kk]); + } + + len+=sprintf(&buffer[len],"\n"); + len+=sprintf(&buffer[len]," RXerr per TB: "); + + for(kk=0; kk<MAX_NUMBER_TB_PER_LCHAN/2; kk++) + len+=sprintf(&buffer[len],"%d/%d . ",UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS_TB[kk], + UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_TB[kk]); + + len+=sprintf(&buffer[len],"\n"); + } + } + } + } + +#endif //PHY_EMUL_ONE_MACHINE + } else if(Mac_rlc_xface->Is_cluster_head[k] ==1) { + Mod_id=k; + len+=sprintf(&buffer[len], + "-------------------------------------------------------------------CH %d: TTI: %d------------------------------------------------------------------\n", + NODE_ID[Mod_id],Mac_rlc_xface->frame); + + for(i=1; i<=NB_CNX_CH; i++) { + if (CH_mac_inst[Mod_id].Dcch_lchan[i].Active==1) { + len+=sprintf(&buffer[len],"\nMR index %u: DL SINR (feedback) %d dB, CQI: %s\n\n", + i,//CH_rrc_inst[Mod_id].Info.UE_list[i].L2_id[0], + CH_mac_inst[Mod_id].Def_meas[i].Wideband_sinr, + print_cqi(CH_mac_inst[Mod_id].Def_meas[i].cqi)); + len+=sprintf(&buffer[len], + "[MAC] LCHAN %d (DCCH), NB_TX_MAC= %d (%d bits/TTI, %d kbits/s), NB_RX_MAC= %d (errors %d, sacch errors %d, sach errors %d, sach_missing %d)\n\n", + CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.Lchan_id.Index, + CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_TX, + CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate, + (10*CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate)>>5, + CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX, + CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_ERRORS, + CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACCH_ERRORS, + CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_ERRORS, + CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_MISSING); + + for(j=0; j<NB_RAB_MAX; j++) { + if (CH_mac_inst[Mod_id].Dtch_lchan[j][i].Active==1) { + Overhead=CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate - Pdcp_stats_tx_rate[k][i][j]; + + if(Overhead<0) { + Overhead=-Overhead; + Sign=-1; + } else { + Sign=1; + } + + len+=sprintf(&buffer[len], + "[PDCP]LCHAN %d: NB_TX = %d ,Tx_rate =(%d bits/TTI ,%d Kbits/s), NB_RX = %d ,Rx_rate =(%d bits/TTI ,%d Kbits/s), LAYER2 TX OVERHEAD= %d Kbits/s\n", + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, + Pdcp_stats_tx[k][i][j], + Pdcp_stats_tx_rate[k][i][j], + (10*Pdcp_stats_tx_rate[k][i][j])>>5, + Pdcp_stats_rx[k][i][j], + Pdcp_stats_rx_rate[k][i][j], + (10*Pdcp_stats_rx_rate[k][i][j])>>5, + Sign*(10*Overhead)>>5); + int status = rlc_stat_req (k, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, + &tx_pdcp_sdu, + &tx_pdcp_sdu_discarded, + &tx_retransmit_pdu_unblock, + &tx_retransmit_pdu_by_status, + &tx_retransmit_pdu, + &tx_data_pdu, + &tx_control_pdu, + &rx_sdu, + &rx_error_pdu, + &rx_data_pdu, + &rx_data_pdu_out_of_window, + &rx_control_pdu) ; + /* + if (status == RLC_OP_STATUS_OK) { + len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n", + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, tx_pdcp_sdu, tx_pdcp_sdu_discarded, rx_sdu); - len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %d", - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %\n", + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, tx_data_pdu, tx_control_pdu, tx_retransmit_pdu); - len+=sprintf(&buffer[len],"\tRLC LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n", - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n", + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, tx_retransmit_pdu_by_status, tx_retransmit_pdu_unblock); - len+=sprintf(&buffer[len],"RLC LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n", - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, + len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n", + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, rx_data_pdu, rx_data_pdu_out_of_window, rx_error_pdu); - } - - len+=sprintf(&buffer[len],"[MAC]: LCHAN %d, NB_TX_MAC = %d (%d bits/TTI, %d kbits/s), NB_RX_MAC = %d (%d errors)\n", - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.Lchan_id.Index, - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX, - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate, - (10*UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.output_rate)>>5, - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX, - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS); - len+=sprintf(&buffer[len]," TX per TB: "); - - for(kk=0; kk<MAX_NUMBER_TB_PER_LCHAN/2; kk++) { - len+=sprintf(&buffer[len],"%d . ",UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_TX_TB[kk]); - } - - len+=sprintf(&buffer[len],"\n"); - len+=sprintf(&buffer[len]," RXerr per TB: "); - - for(kk=0; kk<MAX_NUMBER_TB_PER_LCHAN/2; kk++) - len+=sprintf(&buffer[len],"%d/%d . ",UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_ERRORS_TB[kk], - UE_mac_inst[Mod_id].Dtch_lchan[i][CH_index].Lchan_info.NB_RX_TB[kk]); - - len+=sprintf(&buffer[len],"\n"); - - - + } + */ + len+=sprintf(&buffer[len], + "[MAC]LCHAN %d (CNX %u,RAB %u), NB_TX_MAC= %d (%d bits/TTI, %d kbit/s), NB_RX_MAC= %d (errors %d, sacch_errors %d, sach_errors %d, sach_missing %d)\n", + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, + i,j, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate, + (10*CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate)>>5, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACCH_ERRORS, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_ERRORS, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_MISSING); + len+=sprintf(&buffer[len],"[MAC][SCHEDULER] TX Arrival Rate %d, TX Service Rate %d, RX Arrival rate %d, RX Service rate %d, NB_BW_REQ_RX %d\n\n", + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Arrival_rate, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Tx_rate, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Req_rate, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Rx_rate, + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_BW_REQ_RX); + /* + len+=sprintf(&buffer[len]," TX per TB: "); + for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++) + len+=sprintf(&buffer[len],"%d.",CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX_TB[kk]); + len+=sprintf(&buffer[len],"\n"); + len+=sprintf(&buffer[len]," RXerr per TB: "); + for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++) + len+=sprintf(&buffer[len],"%d/%d . ",CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS_TB[kk], + CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_TB[kk]); + len+=sprintf(&buffer[len],"\n"); + */ + } + } + } } - - } } - } - -#endif //PHY_EMUL_ONE_MACHINE - } else if(Mac_rlc_xface->Is_cluster_head[k] ==1) { - - Mod_id=k; - len+=sprintf(&buffer[len], - "-------------------------------------------------------------------CH %d: TTI: %d------------------------------------------------------------------\n", - NODE_ID[Mod_id],Mac_rlc_xface->frame); - - for(i=1; i<=NB_CNX_CH; i++) { - if (CH_mac_inst[Mod_id].Dcch_lchan[i].Active==1) { - len+=sprintf(&buffer[len],"\nMR index %d: DL SINR (feedback) %d dB, CQI: %s\n\n", - i,//CH_rrc_inst[Mod_id].Info.UE_list[i].L2_id[0], - CH_mac_inst[Mod_id].Def_meas[i].Wideband_sinr, - print_cqi(CH_mac_inst[Mod_id].Def_meas[i].cqi)); - - len+=sprintf(&buffer[len], - "[MAC] LCHAN %d (DCCH), NB_TX_MAC= %d (%d bits/TTI, %d kbits/s), NB_RX_MAC= %d (errors %d, sacch errors %d, sach errors %d, sach_missing %d)\n\n", - CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.Lchan_id.Index, - CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_TX, - CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate, - (10*CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.output_rate)>>5, - CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX, - CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_ERRORS, - CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACCH_ERRORS, - CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_ERRORS, - CH_mac_inst[Mod_id].Dcch_lchan[i].Lchan_info.NB_RX_SACH_MISSING); - - for(j=0; j<NB_RAB_MAX; j++) { - if (CH_mac_inst[Mod_id].Dtch_lchan[j][i].Active==1) { - Overhead=CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate - Pdcp_stats_tx_rate[k][i][j]; - - if(Overhead<0) { - Overhead=-Overhead; - Sign=-1; - } else { - Sign=1; - } - - len+=sprintf(&buffer[len], - "[PDCP]LCHAN %d: NB_TX = %d ,Tx_rate =(%d bits/TTI ,%d Kbits/s), NB_RX = %d ,Rx_rate =(%d bits/TTI ,%d Kbits/s), LAYER2 TX OVERHEAD= %d Kbits/s\n", - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, - Pdcp_stats_tx[k][i][j], - Pdcp_stats_tx_rate[k][i][j], - (10*Pdcp_stats_tx_rate[k][i][j])>>5, - Pdcp_stats_rx[k][i][j], - Pdcp_stats_rx_rate[k][i][j], - (10*Pdcp_stats_rx_rate[k][i][j])>>5, - Sign*(10*Overhead)>>5); - int status = rlc_stat_req (k, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, - &tx_pdcp_sdu, - &tx_pdcp_sdu_discarded, - &tx_retransmit_pdu_unblock, - &tx_retransmit_pdu_by_status, - &tx_retransmit_pdu, - &tx_data_pdu, - &tx_control_pdu, - &rx_sdu, - &rx_error_pdu, - &rx_data_pdu, - &rx_data_pdu_out_of_window, - &rx_control_pdu) ; - /* - if (status == RLC_OP_STATUS_OK) { - len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_SDU_TO_TX = %d\tNB_SDU_DISC %d\tNB_RX_SDU %d\n", - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, - tx_pdcp_sdu, - tx_pdcp_sdu_discarded, - rx_sdu); - len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TB_TX_DATA = %d\tNB_TB_TX_CONTROL %d\tNB_TX_TB_RETRANS %\n", - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, - tx_data_pdu, - tx_control_pdu, - tx_retransmit_pdu); - len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_TX_TB_RETRANS_BY_STATUS = %d\tNB_TX_TB_RETRANS_PADD %d\n", - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, - tx_retransmit_pdu_by_status, - tx_retransmit_pdu_unblock); - len+=sprintf(&buffer[len],"\t[RLC] LCHAN %d, NB_RX_DATA = %d\tNB_RX_TB_OUT_WIN %d\tNB_RX_TB_CORRUPT %d\n", - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, - rx_data_pdu, - rx_data_pdu_out_of_window, - rx_error_pdu); - } - */ - len+=sprintf(&buffer[len], - "[MAC]LCHAN %d (CNX %d,RAB %d), NB_TX_MAC= %d (%d bits/TTI, %d kbit/s), NB_RX_MAC= %d (errors %d, sacch_errors %d, sach_errors %d, sach_missing %d)\n", - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Lchan_id.Index, - i,j, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate, - (10*CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.output_rate)>>5, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACCH_ERRORS, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_ERRORS, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_SACH_MISSING); - len+=sprintf(&buffer[len],"[MAC][SCHEDULER] TX Arrival Rate %d, TX Service Rate %d, RX Arrival rate %d, RX Service rate %d, NB_BW_REQ_RX %d\n\n", - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Arrival_rate, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Tx_rate, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Req_rate, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.Rx_rate, - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_BW_REQ_RX); - - /* - len+=sprintf(&buffer[len]," TX per TB: "); - for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++) - len+=sprintf(&buffer[len],"%d.",CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_TX_TB[kk]); - len+=sprintf(&buffer[len],"\n"); - len+=sprintf(&buffer[len]," RXerr per TB: "); - for(kk=0;kk<MAX_NUMBER_TB_PER_LCHAN/2;kk++) - len+=sprintf(&buffer[len],"%d/%d . ",CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_ERRORS_TB[kk], - CH_mac_inst[Mod_id].Dtch_lchan[j][i].Lchan_info.NB_RX_TB[kk]); - len+=sprintf(&buffer[len],"\n"); - */ - } - } - } - } - } - } - return len; + return len; } #endif + diff --git a/openair2/NETWORK_DRIVER/LITE/RB_TOOL/rb_tool.c b/openair2/NETWORK_DRIVER/LITE/RB_TOOL/rb_tool.c index e918f209e37f3dab584a81a3bdcbd6f67f077550..465e134d768ee0ca4dc5f6cb09a4cb5f3e22ea51 100644 --- a/openair2/NETWORK_DRIVER/LITE/RB_TOOL/rb_tool.c +++ b/openair2/NETWORK_DRIVER/LITE/RB_TOOL/rb_tool.c @@ -46,22 +46,22 @@ #define NIPADDR(addr) \ - (uint8_t)(addr & 0x000000FF), \ - (uint8_t)((addr & 0x0000FF00) >> 8), \ - (uint8_t)((addr & 0x00FF0000) >> 16), \ - (uint8_t)((addr & 0xFF000000) >> 24) + (uint8_t)(addr & 0x000000FF), \ + (uint8_t)((addr & 0x0000FF00) >> 8), \ + (uint8_t)((addr & 0x00FF0000) >> 16), \ + (uint8_t)((addr & 0xFF000000) >> 24) #define NIP6ADDR(addr) \ - ntohs((addr)->s6_addr16[0]), \ - ntohs((addr)->s6_addr16[1]), \ - ntohs((addr)->s6_addr16[2]), \ - ntohs((addr)->s6_addr16[3]), \ - ntohs((addr)->s6_addr16[4]), \ - ntohs((addr)->s6_addr16[5]), \ - ntohs((addr)->s6_addr16[6]), \ - ntohs((addr)->s6_addr16[7]) + ntohs((addr)->s6_addr16[0]), \ + ntohs((addr)->s6_addr16[1]), \ + ntohs((addr)->s6_addr16[2]), \ + ntohs((addr)->s6_addr16[3]), \ + ntohs((addr)->s6_addr16[4]), \ + ntohs((addr)->s6_addr16[5]), \ + ntohs((addr)->s6_addr16[6]), \ + ntohs((addr)->s6_addr16[7]) // Global variables @@ -76,12 +76,9 @@ struct oai_nw_drv_ioctl gifr; void IAL_NAS_ioctl_init(int inst) //--------------------------------------------------------------------------- { - struct oai_nw_drv_msg_statistic_reply *msgrep; int err,rc; - sprintf(gifr.name, "oai%d",inst); - // Get an UDP IPv6 socket ?? fd=socket(AF_INET6, SOCK_DGRAM, 0); @@ -91,7 +88,6 @@ void IAL_NAS_ioctl_init(int inst) } sprintf(gifr.name, "oai%d",inst); - gifr.type = OAI_NW_DRV_MSG_STATISTIC_REQUEST; memset ((void *)dummy_buffer,0,800); gifr.msg= &(dummy_buffer[0]); @@ -160,7 +156,6 @@ int main(int argc,char **argv) char addr_str[46]; char mask_len_delims[] = "/"; char *result; - // scan options rb[0] = '\0'; cx[0] = '\0'; @@ -171,155 +166,154 @@ int main(int argc,char **argv) while ((c = getopt (argc, argv, "adr:i:c:f:l:m:s:t:x:y:z:")) != -1) switch (c) { - case 'a': - action = ADD_RB; - break; - - case 'd': - action = DEL_RB; - break; - - case 'r': - strcpy(rb,optarg); - rbset = 1; - break; - - case 'i': - strcpy(inst,optarg); - instset = 1; - break; - - case 'c': - strcpy(cx,optarg); - cxset = 1; - break; - - case 'f': - strcpy(classref,optarg); - classrefset = 1; - break; - - case 'l': - strcpy(mpls_outgoinglabel,optarg); - mpls_outlabelset=1; - break; - - case 'm': - strcpy(mpls_incominglabel,optarg); - mpls_inlabelset=1; - break; - - case 's': - result = strtok( optarg, mask_len_delims ); - - if ( result != NULL ) { - inet_aton(result,&saddr_ipv4); - printf("Arg Source Addr IPv4 string: %s\n",result); - saddr_ipv4set = 1; - } else { - printf("Arg Source Addr IPv4 string: ERROR\n"); + case 'a': + action = ADD_RB; break; - } - result = strtok( NULL, mask_len_delims ); + case 'd': + action = DEL_RB; + break; - if ( result != NULL ) { - splen = atoi(result); - } else { - splen = 32; - } + case 'r': + strcpy(rb,optarg); + rbset = 1; + break; - printf("Arg Source Addr IPv4 mask len: %d\n",splen); - break; + case 'i': + strcpy(inst,optarg); + instset = 1; + break; - case 't': - result = strtok( optarg, mask_len_delims ); + case 'c': + strcpy(cx,optarg); + cxset = 1; + break; - if ( result != NULL ) { - inet_aton(result,&daddr_ipv4); - printf("Arg Dest Addr IPv4 string: %s\n",result); - daddr_ipv4set = 1; - } else { - printf("Arg Dest Addr IPv4 string: ERROR\n"); + case 'f': + strcpy(classref,optarg); + classrefset = 1; + break; + + case 'l': + strcpy(mpls_outgoinglabel,optarg); + mpls_outlabelset=1; break; - } - result = strtok( NULL, mask_len_delims ); + case 'm': + strcpy(mpls_incominglabel,optarg); + mpls_inlabelset=1; + break; - if ( result != NULL ) { - dplen = atoi(result); - } else { - dplen = 32; - } + case 's': + result = strtok( optarg, mask_len_delims ); - printf("Arg Dest Addr IPv4 mask len: %d\n",dplen); - break; + if ( result != NULL ) { + inet_aton(result,&saddr_ipv4); + printf("Arg Source Addr IPv4 string: %s\n",result); + saddr_ipv4set = 1; + } else { + printf("Arg Source Addr IPv4 string: ERROR\n"); + break; + } - case 'x': - result = strtok( optarg, mask_len_delims ); + result = strtok( NULL, mask_len_delims ); - if ( result != NULL ) { - printf("Arg Source Addr IPv6 string: %s\n",result); - inet_pton(AF_INET6,result,(void *)&saddr_ipv6); - saddr_ipv6set = 1; - } else { - printf("Arg Source Addr IPv6 string: ERROR\n"); + if ( result != NULL ) { + splen = atoi(result); + } else { + splen = 32; + } + + printf("Arg Source Addr IPv4 mask len: %d\n",splen); break; - } - result = strtok( NULL, mask_len_delims ); + case 't': + result = strtok( optarg, mask_len_delims ); - if ( result != NULL ) { - splen = atoi(result); - } else { - splen = 128; - } + if ( result != NULL ) { + inet_aton(result,&daddr_ipv4); + printf("Arg Dest Addr IPv4 string: %s\n",result); + daddr_ipv4set = 1; + } else { + printf("Arg Dest Addr IPv4 string: ERROR\n"); + break; + } - printf("Arg Source Addr IPv6 mask len: %d\n",splen); - break; + result = strtok( NULL, mask_len_delims ); - case 'y': - result = strtok( optarg, mask_len_delims ); + if ( result != NULL ) { + dplen = atoi(result); + } else { + dplen = 32; + } - if ( result != NULL ) { - printf("Arg Dest Addr IPv6 string: %s\n",result); - inet_pton(AF_INET6,result,(void *)&daddr_ipv6); - daddr_ipv6set = 1; - } else { - printf("Arg Dest Addr IPv6 string: ERROR\n"); + printf("Arg Dest Addr IPv4 mask len: %d\n",dplen); break; - } - result = strtok( NULL, mask_len_delims ); + case 'x': + result = strtok( optarg, mask_len_delims ); - if ( result != NULL ) { - dplen = atoi(result); - } else { - dplen = 128; - } + if ( result != NULL ) { + printf("Arg Source Addr IPv6 string: %s\n",result); + inet_pton(AF_INET6,result,(void *)&saddr_ipv6); + saddr_ipv6set = 1; + } else { + printf("Arg Source Addr IPv6 string: ERROR\n"); + break; + } - printf("Arg Dest Addr IPv6 mask len: %d\n",dplen); - break; + result = strtok( NULL, mask_len_delims ); - case 'z': - dscpset=1; - strcpy(dscp,optarg); - break; + if ( result != NULL ) { + splen = atoi(result); + } else { + splen = 128; + } - case '?': - if (isprint (optopt)) - fprintf (stderr, "Unknown option `-%c'.\n", optopt); - else - fprintf (stderr, - "Unknown option character `\\x%x'.\n", - optopt); + printf("Arg Source Addr IPv6 mask len: %d\n",splen); + break; - return 1; + case 'y': + result = strtok( optarg, mask_len_delims ); - default: - abort (); - } + if ( result != NULL ) { + printf("Arg Dest Addr IPv6 string: %s\n",result); + inet_pton(AF_INET6,result,(void *)&daddr_ipv6); + daddr_ipv6set = 1; + } else { + printf("Arg Dest Addr IPv6 string: ERROR\n"); + break; + } + result = strtok( NULL, mask_len_delims ); + + if ( result != NULL ) { + dplen = atoi(result); + } else { + dplen = 128; + } + + printf("Arg Dest Addr IPv6 mask len: %d\n",dplen); + break; + + case 'z': + dscpset=1; + strcpy(dscp,optarg); + break; + + case '?': + if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + + return 1; + + default: + abort (); + } printf ("action = %d, rb = %s,cx = %s\n", action, rb, cx); @@ -364,13 +358,11 @@ int main(int argc,char **argv) } IAL_NAS_ioctl_init(atoi(inst)); - msgreq = (struct oai_nw_drv_msg_rb_establishment_request *)(gifr.msg); msgreq->rab_id = atoi(rb); msgreq->lcr = atoi(cx); msgreq->qos = 0; - if (action == ADD_RB) { gifr.type = OAI_NW_DRV_MSG_RB_ESTABLISHMENT_REQUEST; printf("OAI_NW_DRV_MSG_RB_ESTABLISHMENT_REQUEST: RB %d LCR %d QOS %d\n ", msgreq->rab_id, msgreq->lcr, msgreq->qos); @@ -405,8 +397,6 @@ int main(int argc,char **argv) printf(" IPV4: Dest = %d.%d.%d.%d/%d\n", NIPADDR(msgreq_class->daddr.ipv4), msgreq_class->dplen); gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr); - - msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); msgreq_class->version = 4; @@ -420,7 +410,6 @@ int main(int argc,char **argv) printf("OAI_NW_DRV_MSG_CLASS_ADD_REQUEST: OAI_NW_DRV_DIRECTION_RECEIVE RB %d LCR %d ClassRef %d ", msgreq_class->rab_id, msgreq_class->lcr, msgreq_class->classref); printf("IPV4: Source = %d.%d.%d.%d/%d ", NIPADDR(msgreq_class->saddr.ipv4), msgreq_class->splen); printf("IPV4: Dest = %d.%d.%d.%d/%d\n", NIPADDR(msgreq_class->daddr.ipv4), msgreq_class->dplen); - gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr); } @@ -443,7 +432,6 @@ int main(int argc,char **argv) msgreq_class->fct = OAI_NW_DRV_FCT_QOS_SEND; // TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule msgreq_class->protocol = OAI_NW_DRV_PROTOCOL_DEFAULT; - memcpy(&msgreq_class->saddr.ipv6,&saddr_ipv6,16); memcpy(&msgreq_class->daddr.ipv6,&daddr_ipv6,16); printf("OAI_NW_DRV_MSG_CLASS_ADD_REQUEST: OAI_NW_DRV_DIRECTION_SEND RB %d LCR %d ClassRef %d ", msgreq_class->rab_id, msgreq_class->lcr, msgreq_class->classref); @@ -451,7 +439,6 @@ int main(int argc,char **argv) printf("IPV6: Dest = %x:%x:%x:%x:%x:%x:%x:%x/%d\n", NIP6ADDR(&msgreq_class->daddr.ipv6), msgreq_class->dplen); gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr); - msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); msgreq_class->dplen = splen; @@ -468,7 +455,6 @@ int main(int argc,char **argv) } if (mpls_inlabelset == 1) { - msgreq_class = (struct oai_nw_drv_msg_class_add_request *)(gifr.msg); msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); @@ -483,40 +469,26 @@ int main(int argc,char **argv) //msgreq_class->classref = 4 + (msgreq_class->lcr<<3); msgreq_class->dir=OAI_NW_DRV_DIRECTION_SEND; msgreq_class->fct=OAI_NW_DRV_FCT_QOS_SEND; - // TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule msgreq_class->protocol = OAI_NW_DRV_PROTOCOL_DEFAULT; - mpls_outlabel = atoi(mpls_outgoinglabel); - - printf("Setting MPLS outlabel %d with exp %d\n",mpls_outlabel,msgreq_class->dscp); - + printf("Setting MPLS outlabel %u with exp %d\n",mpls_outlabel,msgreq_class->dscp); msgreq_class->daddr.mpls_label = mpls_outlabel; - gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr); - msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); - msgreq_class->classref = atoi(classref) + 1 + (msgreq_class->lcr<<8); //msgreq_class->classref = 5 + (msgreq_class->lcr<<3); msgreq_class->dir=OAI_NW_DRV_DIRECTION_RECEIVE; - - // TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule msgreq_class->protocol = OAI_NW_DRV_PROTOCOL_DEFAULT; - mpls_inlabel = atoi(mpls_incominglabel); - - printf("Setting MPLS inlabel %d with exp %d\n",mpls_inlabel,msgreq_class->dscp); - + printf("Setting MPLS inlabel %u with exp %d\n",mpls_inlabel,msgreq_class->dscp); msgreq_class->daddr.mpls_label = mpls_inlabel; - gifr.type = OAI_NW_DRV_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr); } - } else if (action == DEL_RB) { gifr.type = OAI_NW_DRV_MSG_RB_RELEASE_REQUEST; err=ioctl(fd, OAI_NW_DRV_IOCTL_RRM, &gifr); diff --git a/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c b/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c index 8e231895d97a0961da97e9f060c673a5cbe80e39..e02bf896c30399dba28555056dd917fd3fb063dd 100644 --- a/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c +++ b/openair2/NETWORK_DRIVER/MESH/RB_TOOL/rb_tool.c @@ -108,12 +108,9 @@ int NAS_RALconnect(void) void IAL_NAS_ioctl_init(int inst) //--------------------------------------------------------------------------- { - struct nas_msg_statistic_reply *msgrep; int err; - sprintf(gifr.name, "oai%d",inst); - // Get an UDP IPv6 socket ?? fd=socket(AF_INET6, SOCK_DGRAM, 0); @@ -123,7 +120,6 @@ void IAL_NAS_ioctl_init(int inst) } sprintf(gifr.name, "oai%d",inst); - gifr.type = NAS_MSG_STATISTIC_REQUEST; memset ((void *)dummy_buffer,0,800); gifr.msg= &(dummy_buffer[0]); @@ -139,8 +135,6 @@ void IAL_NAS_ioctl_init(int inst) printf("tx_bytes = %u, rx_bytes = %u\n", msgrep->tx_bytes, msgrep->rx_bytes); printf("tx_errors = %u, rx_errors = %u\n", msgrep->tx_errors, msgrep->rx_errors); printf("tx_dropped = %u, rx_dropped = %u\n", msgrep->tx_dropped, msgrep->rx_dropped); - - } @@ -160,11 +154,7 @@ int main(int argc,char **argv) in_addr_t saddr_ipv4 = 0,daddr_ipv4 = 0; struct in6_addr saddr_ipv6,daddr_ipv6; unsigned int mpls_outlabel=0,mpls_inlabel=0; - char addr_str[46]; - - - // scan options rb[0] = '\0'; cx[0] = '\0'; @@ -174,89 +164,87 @@ int main(int argc,char **argv) while ((c = getopt (argc, argv, "adr:i:c:l:m:s:t:x:y:z:")) != -1) switch (c) { - case 'a': - action = ADD_RB; - break; - - case 'd': - action = DEL_RB; - break; - - case 'r': - strcpy(rb,optarg); - rbset = 1; - break; - - case 'i': - strcpy(inst,optarg); - instset = 1; - break; - - case 'c': - strcpy(cx,optarg); - cxset = 1; - break; - - case 'l': - strcpy(mpls_outgoinglabel,optarg); - mpls_outlabelset=1; - break; - - case 'm': - strcpy(mpls_incominglabel,optarg); - mpls_inlabelset=1; - break; - - case 's': { - struct in_addr a; - inet_aton(optarg,&a); - saddr_ipv4 = a.s_addr; - saddr_ipv4set = 1; - break; - } - - case 't': { - struct in_addr a; - inet_aton(optarg,&a); - daddr_ipv4 = a.s_addr; - daddr_ipv4set = 1; - break; - } - - case 'x': - printf("IPv6: %s\n",optarg); - inet_pton(AF_INET6,optarg,(void *)&saddr_ipv6); - saddr_ipv6set = 1; - break; - - case 'y': - inet_pton(AF_INET6,optarg,(void *)&daddr_ipv6); - daddr_ipv6set = 1; - break; - - case 'z': - dscpset=1; - strcpy(dscp,optarg); - break; - - case '?': - if (isprint (optopt)) - fprintf (stderr, "Unknown option `-%c'.\n", optopt); - else - fprintf (stderr, - "Unknown option character `\\x%x'.\n", - optopt); - - return 1; - - default: - abort (); + case 'a': + action = ADD_RB; + break; + + case 'd': + action = DEL_RB; + break; + + case 'r': + strcpy(rb,optarg); + rbset = 1; + break; + + case 'i': + strcpy(inst,optarg); + instset = 1; + break; + + case 'c': + strcpy(cx,optarg); + cxset = 1; + break; + + case 'l': + strcpy(mpls_outgoinglabel,optarg); + mpls_outlabelset=1; + break; + + case 'm': + strcpy(mpls_incominglabel,optarg); + mpls_inlabelset=1; + break; + + case 's': { + struct in_addr a; + inet_aton(optarg,&a); + saddr_ipv4 = a.s_addr; + saddr_ipv4set = 1; + break; + } + + case 't': { + struct in_addr a; + inet_aton(optarg,&a); + daddr_ipv4 = a.s_addr; + daddr_ipv4set = 1; + break; + } + + case 'x': + printf("IPv6: %s\n",optarg); + inet_pton(AF_INET6,optarg,(void *)&saddr_ipv6); + saddr_ipv6set = 1; + break; + + case 'y': + inet_pton(AF_INET6,optarg,(void *)&daddr_ipv6); + daddr_ipv6set = 1; + break; + + case 'z': + dscpset=1; + strcpy(dscp,optarg); + break; + + case '?': + if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + + return 1; + + default: + abort (); } - printf ("action = %d, rb = %s,cx = %s\n", action, rb, cx); - if (rbset==0) { printf("ERROR: Specify a RAB id!!\n"); exit(-1); @@ -293,31 +281,27 @@ int main(int argc,char **argv) } IAL_NAS_ioctl_init(atoi(inst)); - msgreq = (struct nas_msg_rb_establishment_request *)(gifr.msg); msgreq->rab_id = atoi(rb); msgreq->lcr = atoi(cx); msgreq->qos = 0; - if (action == ADD_RB) { gifr.type = NAS_MSG_RB_ESTABLISHMENT_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); - if (err == -1) perror("ioctl"); + if (err == -1) perror("ioctl"); if (saddr_ipv4set == 1) { msgreq_class = (struct nas_msg_class_add_request *)(gifr.msg); msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); msgreq_class->version = 4; - msgreq_class->classref = 0 + (msgreq_class->lcr<<3); msgreq_class->dir = NAS_DIRECTION_SEND; msgreq_class->fct = NAS_FCT_QOS_SEND; msgreq_class->saddr.ipv4 = saddr_ipv4; msgreq_class->daddr.ipv4 = daddr_ipv4; - // TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule msgreq_class->protocol = NAS_PROTOCOL_DEFAULT; @@ -326,21 +310,20 @@ int main(int argc,char **argv) else msgreq_class->dscp=atoi(dscp); - gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); + msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); - msgreq_class->classref = 1+(msgreq_class->lcr<<3); msgreq_class->dir = NAS_DIRECTION_RECEIVE; - - msgreq_class->daddr.ipv4 = saddr_ipv4; msgreq_class->saddr.ipv4 = daddr_ipv4; gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); } @@ -358,38 +341,32 @@ int main(int argc,char **argv) msgreq_class->classref = 2+(msgreq_class->lcr<<3); msgreq_class->dir=NAS_DIRECTION_SEND; msgreq_class->fct=NAS_FCT_QOS_SEND; - // TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule msgreq_class->protocol = NAS_PROTOCOL_DEFAULT; - memcpy(&msgreq_class->saddr.ipv6,&saddr_ipv6,16); memcpy(&msgreq_class->daddr.ipv6,&daddr_ipv6,16); - inet_ntop(AF_INET6,(void *)&saddr_ipv6,addr_str,46); printf("IPV6: Source %s\n",addr_str); inet_ntop(AF_INET6,(void *)&daddr_ipv6,addr_str,46); printf("IPV6: Dest %s\n",addr_str); - gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); - msgreq_class->classref = 3+(msgreq_class->lcr<<3); msgreq_class->dir=NAS_DIRECTION_RECEIVE; memcpy(&msgreq_class->daddr.ipv6,&saddr_ipv6,16); memcpy(&msgreq_class->saddr.ipv6,&daddr_ipv6,16); gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); - if (err == -1) perror("ioctl"); - + if (err == -1) perror("ioctl"); } if (mpls_inlabelset == 1) { - msgreq_class = (struct nas_msg_class_add_request *)(gifr.msg); msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); @@ -403,50 +380,34 @@ int main(int argc,char **argv) msgreq_class->classref = 4 + (msgreq_class->lcr<<3); msgreq_class->dir=NAS_DIRECTION_SEND; msgreq_class->fct=NAS_FCT_QOS_SEND; - // TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule msgreq_class->protocol = NAS_PROTOCOL_DEFAULT; - mpls_outlabel = atoi(mpls_outgoinglabel); - - printf("Setting MPLS outlabel %d with exp %d\n",mpls_outlabel,msgreq_class->dscp); - + printf("Setting MPLS outlabel %u with exp %d\n",mpls_outlabel,msgreq_class->dscp); msgreq_class->daddr.mpls_label = mpls_outlabel; - gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); msgreq_class->rab_id = atoi(rb); msgreq_class->lcr = atoi(cx); - msgreq_class->classref = 5 + (msgreq_class->lcr<<3); msgreq_class->dir=NAS_DIRECTION_RECEIVE; - - // TO BE FIXED WHEN WE CAN SPECIFY A PROTOCOL-based rule msgreq_class->protocol = NAS_PROTOCOL_DEFAULT; - mpls_inlabel = atoi(mpls_incominglabel); - - printf("Setting MPLS inlabel %d with exp %d\n",mpls_inlabel,msgreq_class->dscp); - + printf("Setting MPLS inlabel %u with exp %d\n",mpls_inlabel,msgreq_class->dscp); msgreq_class->daddr.mpls_label = mpls_inlabel; - gifr.type = NAS_MSG_CLASS_ADD_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); - if (err == -1) perror("ioctl"); - + if (err == -1) perror("ioctl"); } } else if (action == DEL_RB) { gifr.type = NAS_MSG_RB_RELEASE_REQUEST; err=ioctl(fd, NAS_IOCTL_RRM, &gifr); + if (err == -1) perror("ioctl"); } - - - - - } diff --git a/openair2/NETWORK_DRIVER/MESH/classifier.c b/openair2/NETWORK_DRIVER/MESH/classifier.c index a22ac2f20045b4457b9ec6adaeed72d931a0555a..15ac51158c404368e559042229c5a33003b85391 100644 --- a/openair2/NETWORK_DRIVER/MESH/classifier.c +++ b/openair2/NETWORK_DRIVER/MESH/classifier.c @@ -37,7 +37,7 @@ //#define MPLS #ifdef MPLS -#include <net/mpls.h> + #include <net/mpls.h> #endif @@ -46,12 +46,9 @@ //--------------------------------------------------------------------------- // Add a new classifier rule (send direction) -struct classifier_entity *nas_CLASS_add_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) -{ +struct classifier_entity *nas_CLASS_add_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) { //--------------------------------------------------------------------------- struct classifier_entity *gc; - - #ifdef NAS_DEBUG_CLASS printk("NAS_CLASS_ADD_SCLASSIFIER: begin for dscp %d, classref %d\n", dscp,classref); #endif @@ -91,8 +88,7 @@ struct classifier_entity *nas_CLASS_add_sclassifier(struct cx_entity *cx, uint8_ // Add a new classifier rule (receive direction) struct classifier_entity *nas_CLASS_add_rclassifier(uint8_t dscp, uint16_t classref, - struct nas_priv *gpriv) -{ + struct nas_priv *gpriv) { //--------------------------------------------------------------------------- struct classifier_entity *gc; #ifdef NAS_DEBUG_CLASS @@ -125,8 +121,7 @@ struct classifier_entity *nas_CLASS_add_rclassifier(uint8_t dscp, //--------------------------------------------------------------------------- // Add a new classifier rule (forwarding) -struct classifier_entity *nas_CLASS_add_fclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) -{ +struct classifier_entity *nas_CLASS_add_fclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) { //--------------------------------------------------------------------------- struct classifier_entity *gc; #ifdef NAS_DEBUG_CLASS @@ -166,8 +161,7 @@ struct classifier_entity *nas_CLASS_add_fclassifier(struct cx_entity *cx, uint8_ //--------------------------------------------------------------------------- -void nas_CLASS_flush_sclassifier(struct cx_entity *cx) -{ +void nas_CLASS_flush_sclassifier(struct cx_entity *cx) { //--------------------------------------------------------------------------- uint8_t dscpi; struct classifier_entity *gc; @@ -196,8 +190,7 @@ void nas_CLASS_flush_sclassifier(struct cx_entity *cx) #endif } //--------------------------------------------------------------------------- -void nas_CLASS_flush_fclassifier(struct cx_entity *cx) -{ +void nas_CLASS_flush_fclassifier(struct cx_entity *cx) { //--------------------------------------------------------------------------- uint8_t dscpi; struct classifier_entity *gc; @@ -227,8 +220,7 @@ void nas_CLASS_flush_fclassifier(struct cx_entity *cx) } //--------------------------------------------------------------------------- -void nas_CLASS_flush_rclassifier(struct nas_priv *gpriv) -{ +void nas_CLASS_flush_rclassifier(struct nas_priv *gpriv) { //--------------------------------------------------------------------------- uint8_t dscpi; struct classifier_entity *gc; @@ -251,8 +243,7 @@ void nas_CLASS_flush_rclassifier(struct nas_priv *gpriv) //--------------------------------------------------------------------------- // Delete a classifier rule (send direction) -void nas_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) -{ +void nas_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) { //--------------------------------------------------------------------------- struct classifier_entity *p,*np; #ifdef NAS_DEBUG_CLASS @@ -295,8 +286,7 @@ void nas_CLASS_del_sclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t clas //--------------------------------------------------------------------------- // Delete a classifier rule (send direction) -void nas_CLASS_del_fclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) -{ +void nas_CLASS_del_fclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t classref) { //--------------------------------------------------------------------------- struct classifier_entity *p,*np; #ifdef NAS_DEBUG_CLASS @@ -339,8 +329,7 @@ void nas_CLASS_del_fclassifier(struct cx_entity *cx, uint8_t dscp, uint16_t clas //--------------------------------------------------------------------------- // Delete a classifier rule (receive direction) -void nas_CLASS_del_rclassifier(uint8_t dscp, uint16_t classref,struct nas_priv *gpriv) -{ +void nas_CLASS_del_rclassifier(uint8_t dscp, uint16_t classref,struct nas_priv *gpriv) { //--------------------------------------------------------------------------- struct classifier_entity *p,*np; #ifdef NAS_DEBUG_CLASS @@ -379,8 +368,7 @@ struct cx_entity *nas_CLASS_cx6(struct sk_buff *skb, unsigned char dscp, struct nas_priv *gpriv, int inst, - unsigned char *cx_searcher) -{ + unsigned char *cx_searcher) { //--------------------------------------------------------------------------- unsigned char cxi; unsigned int *addr,*dst=NULL; @@ -388,17 +376,12 @@ struct cx_entity *nas_CLASS_cx6(struct sk_buff *skb, struct classifier_entity *p=NULL; if (skb!=NULL) { - for (cxi=*cx_searcher; cxi<NAS_CX_MAX; cxi++) { - (*cx_searcher)++; - p = gpriv->cx[cxi].sclassifier[dscp]; while (p!=NULL) { if (p->version == 6) { // verify that this is an IPv4 rule - - if ((addr = (unsigned int *)(&(p->daddr.ipv6)))== NULL) { printk("nas_CLASS_cx6: addr is null \n"); p = p->next; @@ -409,9 +392,8 @@ struct cx_entity *nas_CLASS_cx6(struct sk_buff *skb, printk("cx %d : %X,%X.%X,%X\n",cxi,addr[0],addr[1],addr[2],addr[3]); #endif //NAS_DEBUG_CLASS - //if ((dst = (unsigned int*)&(((struct rt6_info *)skbdst)->rt6i_gateway)) == 0){ - if ( (dst = &((struct iphdr*)(skb_network_header(skb)))->daddr) == NULL) { + if ( (dst = &((struct iphdr *)(skb_network_header(skb)))->daddr) == NULL) { printk("nas_CLASS_cx6: dst addr is null \n"); p = p->next; continue; @@ -446,11 +428,15 @@ struct cx_entity *nas_CLASS_cx6(struct sk_buff *skb, } } - printk("nas_CLASS_cx6 NOT FOUND: %X.%X.%X.%X\n", - dst[0], - dst[1], - dst[2], - dst[3]); + + if (dst ) { + printk("nas_CLASS_cx6 NOT FOUND: %X.%X.%X.%X\n", + dst[0], + dst[1], + dst[2], + dst[3]); + } + return default_ip; } @@ -460,8 +446,7 @@ struct cx_entity *nas_CLASS_cx4(struct sk_buff *skb, unsigned char dscp, struct nas_priv *gpriv, int inst, - unsigned char *cx_searcher) -{ + unsigned char *cx_searcher) { //--------------------------------------------------------------------------- unsigned char cxi; unsigned char *addr; @@ -473,10 +458,9 @@ struct cx_entity *nas_CLASS_cx4(struct sk_buff *skb, // return(gpriv->cx); //dump to clusterhead if (skb!=NULL) { - daddr = ((struct iphdr*)(skb_network_header(skb)))->daddr; + daddr = ((struct iphdr *)(skb_network_header(skb)))->daddr; if (daddr!=0) { - #ifdef NAS_DEBUG_CLASS printk("[NAS][CLASS][IPv4] Searching for %d.%d.%d.%d\n", ((unsigned char *)&daddr)[0], @@ -491,7 +475,6 @@ struct cx_entity *nas_CLASS_cx4(struct sk_buff *skb, while (p!=NULL) { if (p->version == 4) { // verify that this is an IPv4 rule - #ifdef NAS_DEBUG_CLASS addr = (char *)(&(p->daddr.ipv4)); printk("found classifier cx %d for destination: %d.%d.%d.%d\n",cxi,addr[0],addr[1],addr[2],addr[3]); @@ -536,32 +519,23 @@ struct cx_entity *nas_CLASS_MPLS(struct sk_buff *skb, unsigned char exp, struct nas_priv *gpriv, int inst, - unsigned char *cx_searcher) -{ + unsigned char *cx_searcher) { //--------------------------------------------------------------------------- unsigned char cxi; - struct cx_entity *default_label=NULL; struct classifier_entity *p=NULL; - // if (inst >0) // return(gpriv->cx); //dump to clusterhead - - #ifdef NAS_DEBUG_CLASS - - printk("[NAS][CLASS][MPLS] Searching for label %d\n",MPLSCB(skb)->label); #endif for (cxi=*cx_searcher; cxi<NAS_CX_MAX; ++cxi) { - (*cx_searcher)++; p = gpriv->cx[cxi].sclassifier[exp]; while (p!=NULL) { if (p->version == NAS_MPLS_VERSION_CODE) { // verify that this is an MPLS rule - #ifdef NAS_DEBUG_CLASS printk("cx %d : label %d\n",cxi,p->daddr.mpls_label); #endif //NAS_DEBUG_CLASS @@ -588,11 +562,8 @@ struct cx_entity *nas_CLASS_MPLS(struct sk_buff *skb, // goto to next classification rule for the connection p = p->next; } - } - - return default_label; } @@ -600,8 +571,7 @@ struct cx_entity *nas_CLASS_MPLS(struct sk_buff *skb, //--------------------------------------------------------------------------- // Search the sending function -void nas_CLASS_send(struct sk_buff *skb,int inst) -{ +void nas_CLASS_send(struct sk_buff *skb,int inst) { //--------------------------------------------------------------------------- struct classifier_entity *p, *sp; uint8_t *protocolh,version; @@ -609,15 +579,10 @@ void nas_CLASS_send(struct sk_buff *skb,int inst) uint16_t classref; struct cx_entity *cx; //unsigned int i; - //unsigned int router_adv = 0; struct net_device *dev=nasdev[inst]; - struct nas_priv *gpriv=netdev_priv(dev); - unsigned char cx_searcher,no_connection=1; - - #ifdef NAS_DEBUG_CLASS printk("NAS_CLASS_SEND: begin - inst %d\n",inst); #endif @@ -629,9 +594,7 @@ void nas_CLASS_send(struct sk_buff *skb,int inst) return; } - #ifdef NAS_DEBUG_SEND - printk("[NAS][CLASS][SEND] Got packet from kernel:\n"); for (i=0; i<256; i++) @@ -641,80 +604,65 @@ void nas_CLASS_send(struct sk_buff *skb,int inst) #endif // find all connections related to socket cx_searcher = 0; - no_connection = 1; - //while (cx_searcher<NAS_CX_MAX) { - cx = NULL; // Address classification switch (ntohs(skb->protocol)) { - case ETH_P_IPV6: - version = 6; - - protocolh=nas_TOOL_get_protocol6( - (struct ipv6hdr *)(skb_network_header(skb)), - &protocol); - dscp=nas_TOOL_get_dscp6( - (struct ipv6hdr *)(skb_network_header(skb)) - ); + case ETH_P_IPV6: + version = 6; + protocolh=nas_TOOL_get_protocol6( + (struct ipv6hdr *)(skb_network_header(skb)), + &protocol); + dscp=nas_TOOL_get_dscp6( + (struct ipv6hdr *)(skb_network_header(skb)) + ); #ifdef NAS_DEBUG_CLASS - printk("NAS_CLASS_SEND: %p %d %p %d %p \n",skb, dscp, gpriv, inst, &cx_searcher); + printk("NAS_CLASS_SEND: %p %d %p %d %p \n",skb, dscp, gpriv, inst, &cx_searcher); #endif - cx=nas_CLASS_cx6(skb,dscp,gpriv,inst,&cx_searcher); - - + cx=nas_CLASS_cx6(skb,dscp,gpriv,inst,&cx_searcher); #ifdef NAS_DEBUG_CLASS - printk("NAS_CLASS_SEND: Got IPv6 packet, dscp = %d\n",dscp); + printk("NAS_CLASS_SEND: Got IPv6 packet, dscp = %d\n",dscp); #endif - break; - - case ETH_P_IP: - + break; - dscp=nas_TOOL_get_dscp4((struct iphdr *)(skb_network_header(skb))); - cx=nas_CLASS_cx4(skb,dscp,gpriv,inst,&cx_searcher); - protocolh=nas_TOOL_get_protocol4( - (struct iphdr *)(skb_network_header(skb)), - &protocol); + case ETH_P_IP: + dscp=nas_TOOL_get_dscp4((struct iphdr *)(skb_network_header(skb))); + cx=nas_CLASS_cx4(skb,dscp,gpriv,inst,&cx_searcher); + protocolh=nas_TOOL_get_protocol4( + (struct iphdr *)(skb_network_header(skb)), + &protocol); #ifdef NAS_DEBUG_CLASS - printk("NAS_CLASS_SEND: Got IPv4 packet (%x), dscp = %d, cx = %x\n",ntohs(skb->protocol),dscp,cx); + printk("NAS_CLASS_SEND: Got IPv4 packet (%x), dscp = %d, cx = %x\n",ntohs(skb->protocol),dscp,cx); #endif - version = 4; - - break; + version = 4; + break; #ifdef MPLS - case ETH_P_MPLS_UC: - cx=nas_CLASS_MPLS(skb,MPLSCB(skb)->exp,gpriv,inst,&cx_searcher); - + case ETH_P_MPLS_UC: + cx=nas_CLASS_MPLS(skb,MPLSCB(skb)->exp,gpriv,inst,&cx_searcher); #ifdef NAS_DEBUG_CLASS - printk("NAS_CLASS_SEND: Got MPLS unicast packet, exp = %d, label = %d, cx = %x\n",MPLSCB(skb)->exp,MPLSCB(skb)->label,cx); + printk("NAS_CLASS_SEND: Got MPLS unicast packet, exp = %d, label = %d, cx = %x\n",MPLSCB(skb)->exp,MPLSCB(skb)->label,cx); #endif - - dscp = MPLSCB(skb)->exp; - version = NAS_MPLS_VERSION_CODE; - protocol = version; - break; + dscp = MPLSCB(skb)->exp; + version = NAS_MPLS_VERSION_CODE; + protocol = version; + break; #endif - default: - printk("NAS_CLASS_SEND: Unknown protocol\n"); - version = 0; - return; + default: + printk("NAS_CLASS_SEND: Unknown protocol\n"); + version = 0; + return; } - - // If a valid connection for the DSCP/EXP with destination address // is found scan all protocol-based classification rules if (cx) { - classref=0; sp=NULL; - #ifdef NAS_DEBUG_CLASS printk("[NAS][CLASSIFIER] DSCP/EXP %d : looking for classifier entry\n",dscp); #endif @@ -738,12 +686,10 @@ void nas_CLASS_send(struct sk_buff *skb,int inst) classref=sp->classref; break; } - } if (sp!=NULL) { #ifdef NAS_DEBUG_CLASS - char sfct[10], sprotocol[10]; if (sp->fct==nas_COMMON_QOS_send) @@ -759,41 +705,38 @@ void nas_CLASS_send(struct sk_buff *skb,int inst) strcpy(sfct, "dc"); switch(protocol) { - case NAS_PROTOCOL_UDP: - strcpy(sprotocol, "udp"); - printk("udp packet\n"); - break; - - case NAS_PROTOCOL_TCP: - strcpy(sprotocol, "tcp"); - printk("tcp packet\n"); - break; - - case NAS_PROTOCOL_ICMP4: - strcpy(sprotocol, "icmp4"); - printk("icmp4 packet\n"); - break; - - case NAS_PROTOCOL_ICMP6: - strcpy(sprotocol, "icmp6"); - print_TOOL_pk_icmp6((struct icmp6hdr*)protocolh); - break; + case NAS_PROTOCOL_UDP: + strcpy(sprotocol, "udp"); + printk("udp packet\n"); + break; + + case NAS_PROTOCOL_TCP: + strcpy(sprotocol, "tcp"); + printk("tcp packet\n"); + break; + + case NAS_PROTOCOL_ICMP4: + strcpy(sprotocol, "icmp4"); + printk("icmp4 packet\n"); + break; + + case NAS_PROTOCOL_ICMP6: + strcpy(sprotocol, "icmp6"); + print_TOOL_pk_icmp6((struct icmp6hdr *)protocolh); + break; #ifdef MPLS - case NAS_MPLS_VERSION_CODE: - strcpy(sprotocol,"mpls"); - break; + case NAS_MPLS_VERSION_CODE: + strcpy(sprotocol,"mpls"); + break; #endif } printk("NAS_CLASS_SEND: (dscp %u, %s) received, (classref %u, fct %s, rab_id %u) classifier rule\n", dscp, sprotocol, sp->classref, sfct, sp->rab_id); #endif - sp->fct(skb, cx, sp,inst, NULL); - } // if classifier entry match found - else { printk("NAS_CLASS_SEND: no corresponding item in the classifier, so the message is dropped\n"); // nas_COMMON_del_send(skb, cx, NULL,inst); @@ -802,20 +745,14 @@ void nas_CLASS_send(struct sk_buff *skb,int inst) no_connection = 0; } // if connection found - #ifdef NAS_DEBUG_CLASS if (no_connection == 1) printk("NAS_CLASS_SEND: no corresponding connection, so the message is dropped\n"); #endif /* NAS_DEBUG_CLASS */ - - // } // while loop over connections - - #ifdef NAS_DEBUG_CLASS printk("NAS_CLASS_SEND: end\n"); #endif - } diff --git a/openair2/NETWORK_DRIVER/MESH/constant.h b/openair2/NETWORK_DRIVER/MESH/constant.h index 1c756765c6c1a0e86201332f5ef77bc8cca6333e..5347c5a78499f968d6d576689c3776b51fd28976 100644 --- a/openair2/NETWORK_DRIVER/MESH/constant.h +++ b/openair2/NETWORK_DRIVER/MESH/constant.h @@ -47,7 +47,8 @@ #define NAS_INET6_ADDRSTRLEN 46 #define NAS_INET_ADDRSTRLEN 16 -#define NAS_CX_MAX 128 // 32 //Identical to RRC constant +#define NAS_CX_MAX 32 //128 //Identical to RRC constant: no you cannot +/* increase to 128 without risking stack problems: KEEP ATTENTION TO COMPILATION WARNINGS */ //#define NAS_CX_MULTICAST_ALLNODE 2 #define NAS_RETRY_LIMIT_DEFAULT 5 diff --git a/openair2/NETWORK_DRIVER/MESH/ioctl.h b/openair2/NETWORK_DRIVER/MESH/ioctl.h index ffa9b4e79b7ed4c02a091fc117b2c2243e612796..904105b1d1c1d680d5b4ced361952233d349c919 100644 --- a/openair2/NETWORK_DRIVER/MESH/ioctl.h +++ b/openair2/NETWORK_DRIVER/MESH/ioctl.h @@ -64,7 +64,8 @@ // Max number of entry of a message list #define NAS_LIST_CX_MAX 32 #define NAS_LIST_RB_MAX 32 -#define NAS_LIST_CLASS_MAX 32 +#define NAS_LIST_CLASS_MAX 16 // 32 is too high!!: +/* risk of stack problems: KEEP ATTENTION TO COMPILATION WARNINGS */ typedef unsigned short nasMsgType_t; diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 4f295543dca310e933694d9b296a7f2c0b7ce87b..32f9442747d3445c067a84ab716f0260c68c6df6 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -51,13 +51,12 @@ struct net_device *ue_ip_dev[UE_IP_NB_INSTANCES_MAX]; #ifdef OAI_NW_DRIVER_USE_NETLINK -extern void ue_ip_netlink_release(void); -extern int ue_ip_netlink_init(void); + extern void ue_ip_netlink_release(void); + extern int ue_ip_netlink_init(void); #endif //--------------------------------------------------------------------------- -int ue_ip_find_inst(struct net_device *dev_pP) -{ +int ue_ip_find_inst(struct net_device *dev_pP) { //--------------------------------------------------------------------------- int i; @@ -72,15 +71,12 @@ int ue_ip_find_inst(struct net_device *dev_pP) //--------------------------------------------------------------------------- #ifndef OAI_NW_DRIVER_USE_NETLINK -void *ue_ip_interrupt(void) -{ +void *ue_ip_interrupt(void) { //--------------------------------------------------------------------------- uint8_t cxi; - // ue_ip_priv_t *priv_p=netdev_priv(dev_id); // unsigned int flags; // priv_p->lock = SPIN_LOCK_UNLOCKED; - #ifdef OAI_DRV_DEBUG_INTERRUPT printk("INTERRUPT - begin\n"); #endif @@ -100,9 +96,9 @@ void *ue_ip_interrupt(void) #endif //NETLINK //--------------------------------------------------------------------------- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) -void ue_ip_timer(struct timer_list *t) + void ue_ip_timer(struct timer_list *t) #else -void ue_ip_timer(unsigned long dataP) + void ue_ip_timer(unsigned long dataP) #endif { //--------------------------------------------------------------------------- @@ -111,7 +107,6 @@ void ue_ip_timer(unsigned long dataP) #else ue_ip_priv_t *priv_p = (ue_ip_priv_t *)dataP; #endif - spin_lock(&priv_p->lock); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) mod_timer(&priv_p->timer, jiffies + UE_IP_TIMER_TICK); @@ -121,7 +116,6 @@ void ue_ip_timer(unsigned long dataP) (priv_p->timer).data = dataP; add_timer(&priv_p->timer); #endif - spin_unlock(&priv_p->lock); return; // add_timer(&gpriv->timer); @@ -130,11 +124,9 @@ void ue_ip_timer(unsigned long dataP) //--------------------------------------------------------------------------- // Called by ifconfig when the device is activated by ifconfig -int ue_ip_open(struct net_device *dev_pP) -{ +int ue_ip_open(struct net_device *dev_pP) { //--------------------------------------------------------------------------- ue_ip_priv_t *priv_p=netdev_priv(dev_pP); - // Address has already been set at init #ifndef OAI_NW_DRIVER_USE_NETLINK @@ -161,18 +153,15 @@ int ue_ip_open(struct net_device *dev_pP) (priv_p->timer).function = ue_ip_timer; #endif //add_timer(&priv_p->timer); - printk("[UE_IP_DRV][%s] name = %s\n", __FUNCTION__, dev_pP->name); return 0; } //--------------------------------------------------------------------------- // Called by ifconfig when the device is desactivated -int ue_ip_stop(struct net_device *dev_pP) -{ +int ue_ip_stop(struct net_device *dev_pP) { //--------------------------------------------------------------------------- ue_ip_priv_t *priv_p = netdev_priv(dev_pP); - printk("[UE_IP_DRV][%s] Begin\n", __FUNCTION__); del_timer(&(priv_p->timer)); netif_stop_queue(dev_pP); @@ -182,12 +171,10 @@ int ue_ip_stop(struct net_device *dev_pP) } //--------------------------------------------------------------------------- -void ue_ip_teardown(struct net_device *dev_pP) -{ +void ue_ip_teardown(struct net_device *dev_pP) { //--------------------------------------------------------------------------- ue_ip_priv_t *priv_p; int inst; - printk("[UE_IP_DRV][%s] Begin\n", __FUNCTION__); if (dev_pP) { @@ -199,7 +186,6 @@ void ue_ip_teardown(struct net_device *dev_pP) return; } - printk("[UE_IP_DRV][%s] End\n", __FUNCTION__); } // check dev_pP else { @@ -207,8 +193,7 @@ void ue_ip_teardown(struct net_device *dev_pP) } } //--------------------------------------------------------------------------- -int ue_ip_set_config(struct net_device *dev_pP, struct ifmap *map_pP) -{ +int ue_ip_set_config(struct net_device *dev_pP, struct ifmap *map_pP) { //--------------------------------------------------------------------------- printk("[UE_IP_DRV][%s] Begin\n", __FUNCTION__); @@ -231,8 +216,7 @@ int ue_ip_set_config(struct net_device *dev_pP, struct ifmap *map_pP) //--------------------------------------------------------------------------- // -int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) -{ +int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) { //--------------------------------------------------------------------------- int inst; @@ -284,15 +268,13 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) } //--------------------------------------------------------------------------- -struct net_device_stats *ue_ip_get_stats(struct net_device *dev_pP) -{ +struct net_device_stats *ue_ip_get_stats(struct net_device *dev_pP) { //--------------------------------------------------------------------------- ue_ip_priv_t *priv_p = netdev_priv(dev_pP); return &priv_p->stats; } //--------------------------------------------------------------------------- -int ue_ip_set_mac_address(struct net_device *dev_pP, void *mac_pP) -{ +int ue_ip_set_mac_address(struct net_device *dev_pP, void *mac_pP) { //--------------------------------------------------------------------------- //struct sockaddr *addr = mac_pP; printk("[UE_IP_DRV][%s] CHANGE MAC ADDRESS UNSUPPORTED\n", __FUNCTION__); @@ -300,8 +282,7 @@ int ue_ip_set_mac_address(struct net_device *dev_pP, void *mac_pP) return 0; } //--------------------------------------------------------------------------- -int ue_ip_change_mtu(struct net_device *dev_pP, int mtuP) -{ +int ue_ip_change_mtu(struct net_device *dev_pP, int mtuP) { //--------------------------------------------------------------------------- printk("[UE_IP_DRV][%s] CHANGE MTU %d bytes\n", __FUNCTION__, mtuP); @@ -313,8 +294,7 @@ int ue_ip_change_mtu(struct net_device *dev_pP, int mtuP) return 0; } //--------------------------------------------------------------------------- -void ue_ip_change_rx_flags(struct net_device *dev_pP, int flagsP) -{ +void ue_ip_change_rx_flags(struct net_device *dev_pP, int flagsP) { //--------------------------------------------------------------------------- ue_ip_priv_t *priv_p = netdev_priv(dev_pP); printk("[UE_IP_DRV][%s] CHANGE RX FLAGS %08X\n", __FUNCTION__, flagsP); @@ -322,12 +302,10 @@ void ue_ip_change_rx_flags(struct net_device *dev_pP, int flagsP) } //--------------------------------------------------------------------------- -void ue_ip_tx_timeout(struct net_device *dev_pP) -{ +void ue_ip_tx_timeout(struct net_device *dev_pP) { //--------------------------------------------------------------------------- // Transmitter timeout, serious problems. ue_ip_priv_t *priv_p = netdev_priv(dev_pP); - printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__); // (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++; (priv_p->stats).tx_errors++; @@ -349,7 +327,7 @@ static const struct net_device_ops ue_ip_netdev_ops = { .ndo_set_mac_address = ue_ip_set_mac_address, .ndo_set_config = ue_ip_set_config, .ndo_do_ioctl = NULL, -#if RHEL_RELEASE_CODE>=1797 +#if (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1797) .extended.ndo_change_mtu = ue_ip_change_mtu, #else .ndo_change_mtu = ue_ip_change_mtu, @@ -361,8 +339,7 @@ static const struct net_device_ops ue_ip_netdev_ops = { //--------------------------------------------------------------------------- // Initialisation of the network device -void ue_ip_init(struct net_device *dev_pP) -{ +void ue_ip_init(struct net_device *dev_pP) { //--------------------------------------------------------------------------- ue_ip_priv_t *priv_p = NULL; @@ -382,13 +359,10 @@ void ue_ip_init(struct net_device *dev_pP) } } //--------------------------------------------------------------------------- -int init_module (void) -{ +int init_module (void) { //--------------------------------------------------------------------------- int err,inst; char devicename[100]; - - // Initialize parameters shared with RRC printk("[UE_IP_DRV][%s] Starting OAI IP driver", __FUNCTION__); @@ -423,15 +397,12 @@ int init_module (void) } return err; - } //--------------------------------------------------------------------------- -void cleanup_module(void) -{ +void cleanup_module(void) { //--------------------------------------------------------------------------- int inst; - printk("[UE_IP_DRV][CLEANUP] begin\n"); for (inst=0; inst<UE_IP_NB_INSTANCES_MAX; inst++) { diff --git a/openair2/NETWORK_DRIVER/UE_IP/netlink.c b/openair2/NETWORK_DRIVER/UE_IP/netlink.c index e8e36619d1b6942dcc0c1bbc73e353078baddcb5..658ae19aba91cc2718710f59f691ca58ba327a28 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/netlink.c +++ b/openair2/NETWORK_DRIVER/UE_IP/netlink.c @@ -110,7 +110,7 @@ int ue_ip_netlink_init(void) # if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) THIS_MODULE, # endif - &cfg + &cfg); #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ nas_nl_sk = netlink_kernel_create( &init_net, @@ -120,7 +120,7 @@ int ue_ip_netlink_init(void) &nasmesh_mutex, // NULL THIS_MODULE); #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ - ); + if (nas_nl_sk == NULL) { diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index 28055bfc2d52334acff100ba00a7d0e953d300e0..ad49a16cec2e52534bd4e8a1f318924c8b50878b 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -4,7 +4,7 @@ #include "LAYER2/MAC/mac_extern.h" #include "LAYER2/MAC/mac_proto.h" #include "common/ran_context.h" - +#include "nfapi/oai_integration/vendor_ext.h" #define MAX_IF_MODULES 100 IF_Module_t *if_inst[MAX_IF_MODULES]; @@ -15,216 +15,193 @@ extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind); extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind); extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); -extern uint8_t nfapi_mode; + extern uint16_t sf_ahead; uint16_t frame_cnt=0; void handle_rach(UL_IND_t *UL_info) { int i; if (UL_info->rach_ind.rach_indication_body.number_of_preambles>0) { - AssertFatal(UL_info->rach_ind.rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n"); UL_info->rach_ind.rach_indication_body.number_of_preambles=0; LOG_D(MAC,"UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->subframe, NFAPI_SFNSF2DEC(UL_info->rach_ind.sfn_sf)); initiate_ra_proc(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf), - NFAPI_SFNSF2SF(UL_info->rach_ind.sfn_sf), - UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble, - UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, - UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf), + NFAPI_SFNSF2SF(UL_info->rach_ind.sfn_sf), + UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble, + UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, + UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0 + ,0 #endif - ); + ); } -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (UL_info->rach_ind_br.rach_indication_body.number_of_preambles>0) { +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (UL_info->rach_ind_br.rach_indication_body.number_of_preambles>0) { AssertFatal(UL_info->rach_ind_br.rach_indication_body.number_of_preambles<5,"More than 4 preambles not supported\n"); - for (i=0;i<UL_info->rach_ind_br.rach_indication_body.number_of_preambles;i++) { + + for (i=0; i<UL_info->rach_ind_br.rach_indication_body.number_of_preambles; i++) { AssertFatal(UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type>0, - "Got regular PRACH preamble, not BL/CE\n"); + "Got regular PRACH preamble, not BL/CE\n"); LOG_D(MAC,"Frame %d, Subframe %d Calling initiate_ra_proc (CE_level %d)\n",UL_info->frame,UL_info->subframe, - - UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type-1); + UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type-1); UL_info->rach_ind_br.rach_indication_body.number_of_preambles=0; - initiate_ra_proc(UL_info->module_id, - UL_info->CC_id, - UL_info->frame, - UL_info->subframe, - UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.preamble, - UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.timing_advance, - UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.rnti, - UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type); + UL_info->CC_id, + UL_info->frame, + UL_info->subframe, + UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.preamble, + UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.timing_advance, + UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel8.rnti, + UL_info->rach_ind_br.rach_indication_body.preamble_list[i].preamble_rel13.rach_resource_type); } + UL_info->rach_ind_br.rach_indication_body.number_of_preambles=0; } + #endif } void handle_sr(UL_IND_t *UL_info) { - int i; - if (nfapi_mode == 1) // PNF - { - if (UL_info->sr_ind.sr_indication_body.number_of_srs>0) - { + if (NFAPI_MODE == NFAPI_MODE_PNF) { // PNF + if (UL_info->sr_ind.sr_indication_body.number_of_srs>0) { oai_nfapi_sr_indication(&UL_info->sr_ind); } - } - else - { - for (i=0;i<UL_info->sr_ind.sr_indication_body.number_of_srs;i++) + } else { + for (i=0; i<UL_info->sr_ind.sr_indication_body.number_of_srs; i++) SR_indication(UL_info->module_id, - UL_info->CC_id, - UL_info->frame, - UL_info->subframe, - UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].rx_ue_information.rnti, - UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].ul_cqi_information.ul_cqi); + UL_info->CC_id, + UL_info->frame, + UL_info->subframe, + UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].rx_ue_information.rnti, + UL_info->sr_ind.sr_indication_body.sr_pdu_list[i].ul_cqi_information.ul_cqi); } UL_info->sr_ind.sr_indication_body.number_of_srs=0; } void handle_cqi(UL_IND_t *UL_info) { - int i; - if (nfapi_mode == 1) - { - if (UL_info->cqi_ind.number_of_cqis>0) - { + if (NFAPI_MODE==NFAPI_MODE_PNF) { + if (UL_info->cqi_ind.number_of_cqis>0) { LOG_D(PHY,"UL_info->cqi_ind.number_of_cqis:%d\n", UL_info->cqi_ind.number_of_cqis); nfapi_cqi_indication_t ind; - ind.header.message_id = NFAPI_RX_CQI_INDICATION; ind.sfn_sf = UL_info->frame<<4 | UL_info->subframe; ind.cqi_indication_body = UL_info->cqi_ind; - oai_nfapi_cqi_indication(&ind); - UL_info->cqi_ind.number_of_cqis=0; } - } - else - { - for (i=0;i<UL_info->cqi_ind.number_of_cqis;i++) + } else { + for (i=0; i<UL_info->cqi_ind.number_of_cqis; i++) cqi_indication(UL_info->module_id, - UL_info->CC_id, - UL_info->frame, - UL_info->subframe, - UL_info->cqi_ind.cqi_pdu_list[i].rx_ue_information.rnti, - &UL_info->cqi_ind.cqi_pdu_list[i].cqi_indication_rel9, - UL_info->cqi_ind.cqi_raw_pdu_list[i].pdu, - &UL_info->cqi_ind.cqi_pdu_list[i].ul_cqi_information); + UL_info->CC_id, + UL_info->frame, + UL_info->subframe, + UL_info->cqi_ind.cqi_pdu_list[i].rx_ue_information.rnti, + &UL_info->cqi_ind.cqi_pdu_list[i].cqi_indication_rel9, + UL_info->cqi_ind.cqi_raw_pdu_list[i].pdu, + &UL_info->cqi_ind.cqi_pdu_list[i].ul_cqi_information); UL_info->cqi_ind.number_of_cqis=0; } } void handle_harq(UL_IND_t *UL_info) { - - int i; - - if (nfapi_mode == 1 && UL_info->harq_ind.harq_indication_body.number_of_harqs>0) // PNF - { + if (NFAPI_MODE == NFAPI_MODE_PNF && UL_info->harq_ind.harq_indication_body.number_of_harqs > 0) { // PNF //LOG_D(PHY, "UL_info->harq_ind.harq_indication_body.number_of_harqs:%d Send to VNF\n", UL_info->harq_ind.harq_indication_body.number_of_harqs); - int retval = oai_nfapi_harq_indication(&UL_info->harq_ind); - if (retval!=0) - { + if (retval != 0) { LOG_E(PHY, "Failed to encode NFAPI HARQ_IND retval:%d\n", retval); } UL_info->harq_ind.harq_indication_body.number_of_harqs = 0; - } - else - { - for (i=0;i<UL_info->harq_ind.harq_indication_body.number_of_harqs;i++) + + } else { + for (int i=0; i < UL_info->harq_ind.harq_indication_body.number_of_harqs; i++) harq_indication(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_info->harq_ind.sfn_sf), - NFAPI_SFNSF2SF(UL_info->harq_ind.sfn_sf), - &UL_info->harq_ind.harq_indication_body.harq_pdu_list[i]); + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_info->harq_ind.sfn_sf), + NFAPI_SFNSF2SF(UL_info->harq_ind.sfn_sf), + &UL_info->harq_ind.harq_indication_body.harq_pdu_list[i]); - UL_info->harq_ind.harq_indication_body.number_of_harqs=0; + UL_info->harq_ind.harq_indication_body.number_of_harqs = 0; } } void handle_ulsch(UL_IND_t *UL_info) { - int i,j; - if(nfapi_mode == 1) - { - if (UL_info->crc_ind.crc_indication_body.number_of_crcs>0) - { + if(NFAPI_MODE == NFAPI_MODE_PNF) { + if (UL_info->crc_ind.crc_indication_body.number_of_crcs>0) { //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); - oai_nfapi_crc_indication(&UL_info->crc_ind); - UL_info->crc_ind.crc_indication_body.number_of_crcs = 0; } - if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0) - { + if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0) { //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf)); oai_nfapi_rx_ind(&UL_info->rx_ind); UL_info->rx_ind.rx_indication_body.number_of_pdus = 0; } - } - else - { + } else { if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->crc_ind.crc_indication_body.number_of_crcs>0) { - for (i=0;i<UL_info->rx_ind.rx_indication_body.number_of_pdus;i++) { - for (j=0;j<UL_info->crc_ind.crc_indication_body.number_of_crcs;j++) { + for (i=0; i<UL_info->rx_ind.rx_indication_body.number_of_pdus; i++) { + for (j=0; j<UL_info->crc_ind.crc_indication_body.number_of_crcs; j++) { // find crc_indication j corresponding rx_indication i - LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", j, UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti, i, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti); + LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", j, + UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti, i, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti); + if (UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti == UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti) { LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag); + if (UL_info->crc_ind.crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->subframe); rx_sdu(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, - NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->subframe, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, - (uint8_t *)NULL, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); - } - else { + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, + NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->subframe, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, + (uint8_t *)NULL, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); + } else { LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->subframe); rx_sdu(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, - NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->subframe, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].data, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, + NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->subframe, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].data, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); } + break; } //if (UL_info->crc_ind.crc_pdu_list[j].rx_ue_information.rnti == + // UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti) } // for (j=0;j<UL_info->crc_ind.crc_indication_body.number_of_crcs;j++) } // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++) + UL_info->crc_ind.crc_indication_body.number_of_crcs=0; UL_info->rx_ind.rx_indication_body.number_of_pdus = 0; } // UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->subframe && UL_info->crc_ind.crc_indication_body.number_of_crcs>0 else if (UL_info->rx_ind.rx_indication_body.number_of_pdus!=0 || UL_info->crc_ind.crc_indication_body.number_of_crcs!=0) { LOG_E(PHY,"hoping not to have mis-match between CRC ind and RX ind - hopefully the missing message is coming shortly rx_ind:%d(SFN/SF:%05d) crc_ind:%d(SFN/SF:%05d) UL_info(SFN/SF):%04d%d\n", - UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf), - UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf), - UL_info->frame, UL_info->subframe); + UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf), + UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf), + UL_info->frame, UL_info->subframe); } } } @@ -246,257 +223,334 @@ static char s[SMAX]; static int size; static int maxsize = SMAX; -static void put(char x) -{ - if (size == maxsize) { printf("incrase SMAX\n"); exit(1); } +static void put(char x) { + if (size == maxsize) { + printf("incrase SMAX\n"); + exit(1); + } + s[size++] = x; } -static void append_string(char *t) -{ +static void append_string(char *t) { size--; + while (*t) put(*t++); + put(0); } -static void dump_ul(UL_IND_t *u) -{ +static void dump_ul(UL_IND_t *u) { int i; - C; A("XXXX UL mod %d CC %d f.sf %d.%d\n", u->module_id, u->CC_id, u->frame, u->subframe); - A("XXXX harq_ind %d\n", u->harq_ind.harq_indication_body.number_of_harqs); - for (i = 0; i < u->harq_ind.harq_indication_body.number_of_harqs; i++) { - nfapi_harq_indication_pdu_t *v = &u->harq_ind.harq_indication_body.harq_pdu_list[i]; - A("XXXX harq ind %d\n", i); - A("XXXX rnti %d\n", v->rx_ue_information.rnti); - A("XXXX tb1 %d tb2 %d\n", v->harq_indication_fdd_rel8.harq_tb1, - v->harq_indication_fdd_rel8.harq_tb2); - A("XXXX number_of_ack_nack %d\n", - v->harq_indication_fdd_rel9.number_of_ack_nack); - A("XXXX harq[0] = %d\n", - v->harq_indication_fdd_rel9.harq_tb_n[0]); - A("XXXX harq ul_cqi %d channel %d\n", v->ul_cqi_information.ul_cqi, - v->ul_cqi_information.channel); - } - A("XXXX crc_ind %d\n", u->crc_ind.crc_indication_body.number_of_crcs); + for (i = 0; i < u->harq_ind.harq_indication_body.number_of_harqs; i++) { + nfapi_harq_indication_pdu_t *v = &u->harq_ind.harq_indication_body.harq_pdu_list[i]; + A("XXXX harq ind %d\n", i); + A("XXXX rnti %d\n", v->rx_ue_information.rnti); + A("XXXX tb1 %d tb2 %d\n", v->harq_indication_fdd_rel8.harq_tb1, + v->harq_indication_fdd_rel8.harq_tb2); + A("XXXX number_of_ack_nack %d\n", + v->harq_indication_fdd_rel9.number_of_ack_nack); + A("XXXX harq[0] = %d\n", + v->harq_indication_fdd_rel9.harq_tb_n[0]); + A("XXXX harq ul_cqi %d channel %d\n", v->ul_cqi_information.ul_cqi, + v->ul_cqi_information.channel); + } + A("XXXX crc_ind %d\n", u->crc_ind.crc_indication_body.number_of_crcs); A("XXXX sr_ind %d\n", u->sr_ind.sr_indication_body.number_of_srs); - A("XXXX cqi_ind %d\n", u->cqi_ind.number_of_cqis); - for (i = 0; i < u->cqi_ind.number_of_cqis; i++) { - nfapi_cqi_indication_pdu_t *v = &u->cqi_ind.cqi_pdu_list[i]; - A("XXXX cqi ind %d\n", i); - A("XXXX cqi ul_cqi %d channel %d\n", v->ul_cqi_information.ul_cqi, - v->ul_cqi_information.channel); - } - A("XXXX rach_ind %d\n", u->rach_ind.rach_indication_body.number_of_preambles); + for (i = 0; i < u->cqi_ind.number_of_cqis; i++) { + nfapi_cqi_indication_pdu_t *v = &u->cqi_ind.cqi_pdu_list[i]; + A("XXXX cqi ind %d\n", i); + A("XXXX cqi ul_cqi %d channel %d\n", v->ul_cqi_information.ul_cqi, + v->ul_cqi_information.channel); + } + A("XXXX rach_ind %d\n", u->rach_ind.rach_indication_body.number_of_preambles); A("XXXX rx_ind %d\n", u->rx_ind.rx_indication_body.number_of_pdus); - for (i = 0; i < u->rx_ind.rx_indication_body.number_of_pdus; i++) { - nfapi_rx_indication_pdu_t *v = &u->rx_ind.rx_indication_body.rx_pdu_list[i]; - A("XXXX rx ind %d\n", i); - A("XXXX timing_advance %d\n", - v->rx_indication_rel8.timing_advance); - A("XXXX rx ul_cqi %d\n", v->rx_indication_rel8.ul_cqi); - } + + for (i = 0; i < u->rx_ind.rx_indication_body.number_of_pdus; i++) { + nfapi_rx_indication_pdu_t *v = &u->rx_ind.rx_indication_body.rx_pdu_list[i]; + A("XXXX rx ind %d\n", i); + A("XXXX timing_advance %d\n", + v->rx_indication_rel8.timing_advance); + A("XXXX rx ul_cqi %d\n", v->rx_indication_rel8.ul_cqi); + } LOG_I(PHY, "XXXX UL\nXXXX UL\n%s", s); } -static char *DL_PDU_TYPE(int x) -{ +static char *DL_PDU_TYPE(int x) { switch (x) { - case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: return "NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE"; - case NFAPI_DL_CONFIG_BCH_PDU_TYPE: return "NFAPI_DL_CONFIG_BCH_PDU_TYPE"; - case NFAPI_DL_CONFIG_MCH_PDU_TYPE: return "NFAPI_DL_CONFIG_MCH_PDU_TYPE"; - case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: return "NFAPI_DL_CONFIG_DLSCH_PDU_TYPE"; - case NFAPI_DL_CONFIG_PCH_PDU_TYPE: return "NFAPI_DL_CONFIG_PCH_PDU_TYPE"; - case NFAPI_DL_CONFIG_PRS_PDU_TYPE: return "NFAPI_DL_CONFIG_PRS_PDU_TYPE"; - case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: return "NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE"; - case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: return "NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE"; - case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: return "NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE"; - case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: return "NFAPI_DL_CONFIG_NBCH_PDU_TYPE"; - case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: return "NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE"; - case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: return "NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE"; + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: + return "NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE"; + + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: + return "NFAPI_DL_CONFIG_BCH_PDU_TYPE"; + + case NFAPI_DL_CONFIG_MCH_PDU_TYPE: + return "NFAPI_DL_CONFIG_MCH_PDU_TYPE"; + + case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: + return "NFAPI_DL_CONFIG_DLSCH_PDU_TYPE"; + + case NFAPI_DL_CONFIG_PCH_PDU_TYPE: + return "NFAPI_DL_CONFIG_PCH_PDU_TYPE"; + + case NFAPI_DL_CONFIG_PRS_PDU_TYPE: + return "NFAPI_DL_CONFIG_PRS_PDU_TYPE"; + + case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: + return "NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE"; + + case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: + return "NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE"; + + case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: + return "NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE"; + + case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: + return "NFAPI_DL_CONFIG_NBCH_PDU_TYPE"; + + case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: + return "NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE"; + + case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: + return "NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE"; } + return "UNKNOWN"; } -static char *UL_PDU_TYPE(int x) -{ +static char *UL_PDU_TYPE(int x) { switch (x) { - case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: return "NFAPI_UL_CONFIG_ULSCH_PDU_TYPE"; - case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: return "NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE"; - case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: return "NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE"; - case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: return "NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE"; - case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: return "NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE"; - case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: return "NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE"; - case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: return "NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE"; - case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: return "NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE"; - case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: return "NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE"; - case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: return "NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE"; - case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: return "NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE"; - case NFAPI_UL_CONFIG_SRS_PDU_TYPE: return "NFAPI_UL_CONFIG_SRS_PDU_TYPE"; - case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: return "NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE"; - case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: return "NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE"; - case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: return "NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE"; - case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: return "NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE"; - case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: return "NFAPI_UL_CONFIG_NULSCH_PDU_TYPE"; - case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: return "NFAPI_UL_CONFIG_NRACH_PDU_TYPE"; + case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: + return "NFAPI_UL_CONFIG_ULSCH_PDU_TYPE"; + + case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: + return "NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE"; + + case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: + return "NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE"; + + case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: + return "NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE"; + + case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: + return "NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE"; + + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: + return "NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE"; + + case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: + return "NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE"; + + case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: + return "NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE"; + + case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: + return "NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE"; + + case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: + return "NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE"; + + case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: + return "NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE"; + + case NFAPI_UL_CONFIG_SRS_PDU_TYPE: + return "NFAPI_UL_CONFIG_SRS_PDU_TYPE"; + + case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: + return "NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE"; + + case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: + return "NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE"; + + case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: + return "NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE"; + + case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: + return "NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE"; + + case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: + return "NFAPI_UL_CONFIG_NULSCH_PDU_TYPE"; + + case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: + return "NFAPI_UL_CONFIG_NRACH_PDU_TYPE"; } + return "UNKNOWN"; } -static char *HI_DCI0_PDU_TYPE(int x) -{ +static char *HI_DCI0_PDU_TYPE(int x) { switch (x) { - case NFAPI_HI_DCI0_HI_PDU_TYPE: return "NFAPI_HI_DCI0_HI_PDU_TYPE"; - case NFAPI_HI_DCI0_DCI_PDU_TYPE: return "NFAPI_HI_DCI0_DCI_PDU_TYPE"; - case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: return "NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE"; - case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: return "NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE"; - case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: return "NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE"; + case NFAPI_HI_DCI0_HI_PDU_TYPE: + return "NFAPI_HI_DCI0_HI_PDU_TYPE"; + + case NFAPI_HI_DCI0_DCI_PDU_TYPE: + return "NFAPI_HI_DCI0_DCI_PDU_TYPE"; + + case NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE: + return "NFAPI_HI_DCI0_EPDCCH_DCI_PDU_TYPE"; + + case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE: + return "NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE"; + + case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE: + return "NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE"; } + return "UNKNOWN"; } -static void dump_dl(Sched_Rsp_t *d) -{ +static void dump_dl(Sched_Rsp_t *d) { int i; - C; A("XXXX DL mod %d CC %d f.sf %d.%d\n", d->module_id, d->CC_id, d->frame, d->subframe); - if (d->DL_req != NULL) { - nfapi_dl_config_request_body_t *v=&d->DL_req->dl_config_request_body; - nfapi_dl_config_request_pdu_t *p = v->dl_config_pdu_list; - A("XXXX DL_req sfnsf %d\n", d->DL_req->sfn_sf); - A("XXXX PDCCH size %d\n", v->number_pdcch_ofdm_symbols); - A("XXXX DCIs %d\n", v->number_dci); - A("XXXX PDUs %d\n", v->number_pdu); - A("XXXX rntis %d\n", v->number_pdsch_rnti); - A("XXXX pcfich power %d\n", v->transmission_power_pcfich); - for (i = 0; i < v->number_pdu; i++) { - A("XXXX pdu %d\n", i); - A("XXXX type %d %s\n", p[i].pdu_type, DL_PDU_TYPE(p[i].pdu_type)); - switch (p[i].pdu_type) { - case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: { - nfapi_dl_config_dci_dl_pdu_rel8_t *q = - &p[i].dci_dl_pdu.dci_dl_pdu_rel8; - A("XXXX dci format %d\n", q->dci_format); - A("XXXX cce idx %d\n", q->cce_idx); - A("XXXX agg lvl %d\n", q->aggregation_level); - A("XXXX rnti %d\n", q->rnti); - A("XXXX rb coding %8.8x\n", q->resource_block_coding); - A("XXXX mcs_1 %d\n", q->mcs_1); - A("XXXX rv_1 %d\n", q->redundancy_version_1); - A("XXXX ndi_1 %d\n", q->new_data_indicator_1); - A("XXXX harq pid %d\n", q->harq_process); - A("XXXX tpc %d\n", q->tpc); - A("XXXX tbs idx %d\n", q->transport_block_size_index); - A("XXXX dl pow off %d\n", q->downlink_power_offset); - A("XXXX rnti type %d\n", q->rnti_type); - A("XXXX xmit pow %d\n", q->transmission_power); - break; - } - case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: { - nfapi_dl_config_dlsch_pdu_rel8_t *q = - &p[i].dlsch_pdu.dlsch_pdu_rel8; - A("XXXX pdu_index %d\n", q->pdu_index); - A("XXXX rnti %d\n", q->rnti); - A("XXXX rv %d\n", q->redundancy_version); - A("XXXX mcs %d\n", q->modulation); - A("XXXX pa %d\n", q->pa); - break; - }} + if (d->DL_req != NULL) { + nfapi_dl_config_request_body_t *v=&d->DL_req->dl_config_request_body; + nfapi_dl_config_request_pdu_t *p = v->dl_config_pdu_list; + A("XXXX DL_req sfnsf %d\n", d->DL_req->sfn_sf); + A("XXXX PDCCH size %d\n", v->number_pdcch_ofdm_symbols); + A("XXXX DCIs %d\n", v->number_dci); + A("XXXX PDUs %d\n", v->number_pdu); + A("XXXX rntis %d\n", v->number_pdsch_rnti); + A("XXXX pcfich power %d\n", v->transmission_power_pcfich); + + for (i = 0; i < v->number_pdu; i++) { + A("XXXX pdu %d\n", i); + A("XXXX type %d %s\n", p[i].pdu_type, DL_PDU_TYPE(p[i].pdu_type)); + + switch (p[i].pdu_type) { + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: { + nfapi_dl_config_dci_dl_pdu_rel8_t *q = + &p[i].dci_dl_pdu.dci_dl_pdu_rel8; + A("XXXX dci format %d\n", q->dci_format); + A("XXXX cce idx %d\n", q->cce_idx); + A("XXXX agg lvl %d\n", q->aggregation_level); + A("XXXX rnti %d\n", q->rnti); + A("XXXX rb coding %8.8x\n", q->resource_block_coding); + A("XXXX mcs_1 %d\n", q->mcs_1); + A("XXXX rv_1 %d\n", q->redundancy_version_1); + A("XXXX ndi_1 %d\n", q->new_data_indicator_1); + A("XXXX harq pid %d\n", q->harq_process); + A("XXXX tpc %d\n", q->tpc); + A("XXXX tbs idx %d\n", q->transport_block_size_index); + A("XXXX dl pow off %d\n", q->downlink_power_offset); + A("XXXX rnti type %d\n", q->rnti_type); + A("XXXX xmit pow %d\n", q->transmission_power); + break; } - } - if (d->HI_DCI0_req != NULL) { - nfapi_hi_dci0_request_body_t *v=&d->HI_DCI0_req->hi_dci0_request_body; - A("XXXX up HI_DCI0_req sfnsf %d (%d.%d)\n", d->HI_DCI0_req->sfn_sf, - d->HI_DCI0_req->sfn_sf/16, d->HI_DCI0_req->sfn_sf%16); - A("XXXX up sfnsf %d\n", v->sfnsf); - A("XXXX up DCIs %d\n", v->number_of_dci); - A("XXXX up HIs %d\n", v->number_of_hi); - for (i = 0; i < v->number_of_dci + v->number_of_hi; i++) { - nfapi_hi_dci0_request_pdu_t *p = &v->hi_dci0_pdu_list[i]; - A("XXXX up pdu %d\n", i); - A("XXXX up type %d %s\n",p->pdu_type,HI_DCI0_PDU_TYPE(p->pdu_type)); - if (p->pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) { - nfapi_hi_dci0_dci_pdu_rel8_t *q = &p->dci_pdu.dci_pdu_rel8; - A("XXXX up dci_format %d\n", q->dci_format); - A("XXXX up cce_index %d\n", q->cce_index); - A("XXXX up aggregation_level %d\n", q->aggregation_level); - A("XXXX up rnti %d\n", q->rnti); - A("XXXX up rb start %d\n", q->resource_block_start); - A("XXXX up # rb %d\n", q->number_of_resource_block); - A("XXXX up mcs_1 %d\n", q->mcs_1); - A("XXXX up cshift_2_for_drms %d\n", q->cyclic_shift_2_for_drms); - A("XXXX up freq hop enabled %d\n", q->frequency_hopping_enabled_flag); - A("XXXX up fre hop bits %d\n", q->frequency_hopping_bits); - A("XXXX up NDI_1 %d\n", q->new_data_indication_1); - A("XXXX up tx_antenna_seleciton %d\n", q->ue_tx_antenna_seleciton); - A("XXXX up tpc %d\n", q->tpc); - A("XXXX up cqi_csi_request %d\n", q->cqi_csi_request); - A("XXXX up ul_index %d\n", q->ul_index); - A("XXXX up dl_assignment_index %d\n", q->dl_assignment_index); - A("XXXX up tpc_bitmap %d\n", q->tpc_bitmap); - A("XXXX up transmission_power %d\n", q->transmission_power); - } - if (p->pdu_type == NFAPI_HI_DCI0_HI_PDU_TYPE) { - nfapi_hi_dci0_hi_pdu_rel8_t *q = &p->hi_pdu.hi_pdu_rel8; - A("XXXX up rb start %d\n", q->resource_block_start); - A("XXXX up cs2_drms %d\n", q->cyclic_shift_2_for_drms); - A("XXXX up ack %d\n", q->hi_value); - A("XXXX up i_phich %d\n", q->i_phich); - A("XXXX up power %d\n", q->transmission_power); - } + case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: { + nfapi_dl_config_dlsch_pdu_rel8_t *q = + &p[i].dlsch_pdu.dlsch_pdu_rel8; + A("XXXX pdu_index %d\n", q->pdu_index); + A("XXXX rnti %d\n", q->rnti); + A("XXXX rv %d\n", q->redundancy_version); + A("XXXX mcs %d\n", q->modulation); + A("XXXX pa %d\n", q->pa); + break; } } + } + } - if (d->UL_req != NULL) { - nfapi_ul_config_request_body_t *v=&d->UL_req->ul_config_request_body; - A("XXXX UL_req sfnsf %d (%d.%d)\n", d->UL_req->sfn_sf, - d->UL_req->sfn_sf/16, d->UL_req->sfn_sf%16); - A("XXXX PDUs %d\n", v->number_of_pdus); - A("XXXX ra freq %d\n", v->rach_prach_frequency_resources); - A("XXXX srs? %d\n", v->srs_present); - for (i = 0; i < v->number_of_pdus; i++) { - nfapi_ul_config_request_pdu_t *p = &v->ul_config_pdu_list[i]; - A("XXXX pdu %d\n", i); - A("XXXX type %d %s\n", p->pdu_type, UL_PDU_TYPE(p->pdu_type)); - switch(p->pdu_type) { - case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: { - nfapi_ul_config_uci_harq_pdu *q = &p->uci_harq_pdu; - nfapi_ul_config_harq_information_rel9_fdd_t *h = - &q->harq_information.harq_information_rel9_fdd; - A("XXXX rnti %d\n", - q->ue_information.ue_information_rel8.rnti); - A("XXXX harq size %d\n", h->harq_size); - A("XXXX ack_nack_mode %d\n", h->ack_nack_mode); - A("XXXX # pucch res %d\n", h->number_of_pucch_resources); - A("XXXX n_pucch_1_0 %d\n", h->n_pucch_1_0); - A("XXXX n_pucch_1_1 %d\n", h->n_pucch_1_1); - A("XXXX n_pucch_1_2 %d\n", h->n_pucch_1_2); - A("XXXX n_pucch_1_3 %d\n", h->n_pucch_1_3); - break; - } - case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: { - nfapi_ul_config_uci_sr_pdu *q = &p->uci_sr_pdu; - nfapi_ul_config_sr_information_rel8_t *h = - &q->sr_information.sr_information_rel8; - A("XXXX rnti %d\n", - q->ue_information.ue_information_rel8.rnti); - A("XXXX pucch_index %d\n", h->pucch_index); - }} + if (d->HI_DCI0_req != NULL) { + nfapi_hi_dci0_request_body_t *v=&d->HI_DCI0_req->hi_dci0_request_body; + A("XXXX up HI_DCI0_req sfnsf %d (%d.%d)\n", d->HI_DCI0_req->sfn_sf, + d->HI_DCI0_req->sfn_sf/16, d->HI_DCI0_req->sfn_sf%16); + A("XXXX up sfnsf %d\n", v->sfnsf); + A("XXXX up DCIs %d\n", v->number_of_dci); + A("XXXX up HIs %d\n", v->number_of_hi); + + for (i = 0; i < v->number_of_dci + v->number_of_hi; i++) { + nfapi_hi_dci0_request_pdu_t *p = &v->hi_dci0_pdu_list[i]; + A("XXXX up pdu %d\n", i); + A("XXXX up type %d %s\n",p->pdu_type,HI_DCI0_PDU_TYPE(p->pdu_type)); + + if (p->pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) { + nfapi_hi_dci0_dci_pdu_rel8_t *q = &p->dci_pdu.dci_pdu_rel8; + A("XXXX up dci_format %d\n", q->dci_format); + A("XXXX up cce_index %d\n", q->cce_index); + A("XXXX up aggregation_level %d\n", q->aggregation_level); + A("XXXX up rnti %d\n", q->rnti); + A("XXXX up rb start %d\n", q->resource_block_start); + A("XXXX up # rb %d\n", q->number_of_resource_block); + A("XXXX up mcs_1 %d\n", q->mcs_1); + A("XXXX up cshift_2_for_drms %d\n", q->cyclic_shift_2_for_drms); + A("XXXX up freq hop enabled %d\n", q->frequency_hopping_enabled_flag); + A("XXXX up fre hop bits %d\n", q->frequency_hopping_bits); + A("XXXX up NDI_1 %d\n", q->new_data_indication_1); + A("XXXX up tx_antenna_seleciton %d\n", q->ue_tx_antenna_seleciton); + A("XXXX up tpc %d\n", q->tpc); + A("XXXX up cqi_csi_request %d\n", q->cqi_csi_request); + A("XXXX up ul_index %d\n", q->ul_index); + A("XXXX up dl_assignment_index %d\n", q->dl_assignment_index); + A("XXXX up tpc_bitmap %d\n", q->tpc_bitmap); + A("XXXX up transmission_power %d\n", q->transmission_power); + } + + if (p->pdu_type == NFAPI_HI_DCI0_HI_PDU_TYPE) { + nfapi_hi_dci0_hi_pdu_rel8_t *q = &p->hi_pdu.hi_pdu_rel8; + A("XXXX up rb start %d\n", q->resource_block_start); + A("XXXX up cs2_drms %d\n", q->cyclic_shift_2_for_drms); + A("XXXX up ack %d\n", q->hi_value); + A("XXXX up i_phich %d\n", q->i_phich); + A("XXXX up power %d\n", q->transmission_power); + } + } + } + + if (d->UL_req != NULL) { + nfapi_ul_config_request_body_t *v=&d->UL_req->ul_config_request_body; + A("XXXX UL_req sfnsf %d (%d.%d)\n", d->UL_req->sfn_sf, + d->UL_req->sfn_sf/16, d->UL_req->sfn_sf%16); + A("XXXX PDUs %d\n", v->number_of_pdus); + A("XXXX ra freq %d\n", v->rach_prach_frequency_resources); + A("XXXX srs? %d\n", v->srs_present); + + for (i = 0; i < v->number_of_pdus; i++) { + nfapi_ul_config_request_pdu_t *p = &v->ul_config_pdu_list[i]; + A("XXXX pdu %d\n", i); + A("XXXX type %d %s\n", p->pdu_type, UL_PDU_TYPE(p->pdu_type)); + + switch(p->pdu_type) { + case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: { + nfapi_ul_config_uci_harq_pdu *q = &p->uci_harq_pdu; + nfapi_ul_config_harq_information_rel9_fdd_t *h = + &q->harq_information.harq_information_rel9_fdd; + A("XXXX rnti %d\n", + q->ue_information.ue_information_rel8.rnti); + A("XXXX harq size %d\n", h->harq_size); + A("XXXX ack_nack_mode %d\n", h->ack_nack_mode); + A("XXXX # pucch res %d\n", h->number_of_pucch_resources); + A("XXXX n_pucch_1_0 %d\n", h->n_pucch_1_0); + A("XXXX n_pucch_1_1 %d\n", h->n_pucch_1_1); + A("XXXX n_pucch_1_2 %d\n", h->n_pucch_1_2); + A("XXXX n_pucch_1_3 %d\n", h->n_pucch_1_3); + break; + } + + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: { + nfapi_ul_config_uci_sr_pdu *q = &p->uci_sr_pdu; + nfapi_ul_config_sr_information_rel8_t *h = + &q->sr_information.sr_information_rel8; + A("XXXX rnti %d\n", + q->ue_information.ue_information_rel8.rnti); + A("XXXX pucch_index %d\n", h->pucch_index); } } + } + } LOG_I(PHY, "XXXX DL\nXXXX DL\n%s", s); } @@ -510,81 +564,69 @@ static void dump_dl(Sched_Rsp_t *d) /* debug utility functions end */ /****************************************************************************/ -void UL_indication(UL_IND_t *UL_info) -{ - +void UL_indication(UL_IND_t *UL_info) { AssertFatal(UL_info!=NULL,"UL_INFO is null\n"); - #ifdef DUMP_FAPI dump_ul(UL_info); #endif - module_id_t module_id = UL_info->module_id; int CC_id = UL_info->CC_id; Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id]; IF_Module_t *ifi = if_inst[module_id]; eNB_MAC_INST *mac = RC.mac[module_id]; - LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d harqs:%d crcs:%d cqis:%d preambles:%d sr_ind:%d]\n", UL_info->frame,UL_info->subframe, module_id,CC_id, - UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.number_of_cqis, UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs); - if(UL_info->frame==1023&&UL_info->subframe==6){ // dl scheduling (0,0) - frame_cnt= (frame_cnt + 1)%7; // to prevent frame_cnt get too big - LOG_D(MAC,"current (%d,%d) frame count dl is %d\n",UL_info->frame,UL_info->subframe,frame_cnt); + UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.number_of_cqis, + UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs); + + if(UL_info->frame==1023&&UL_info->subframe==6) { // dl scheduling (0,0) + frame_cnt= (frame_cnt + 1)%7; // to prevent frame_cnt get too big + LOG_D(MAC,"current (%d,%d) frame count dl is %d\n",UL_info->frame,UL_info->subframe,frame_cnt); } - if (nfapi_mode != 1) - { + if (NFAPI_MODE != NFAPI_MODE_PNF) { if (ifi->CC_mask==0) { ifi->current_frame = UL_info->frame; ifi->current_subframe = UL_info->subframe; - } - else { + } else { AssertFatal(UL_info->frame != ifi->current_frame,"CC_mask %x is not full and frame has changed\n",ifi->CC_mask); AssertFatal(UL_info->subframe != ifi->current_subframe,"CC_mask %x is not full and subframe has changed\n",ifi->CC_mask); } + ifi->CC_mask |= (1<<CC_id); } - // clear DL/UL info for new scheduling round clear_nfapi_information(RC.mac[module_id],CC_id, - UL_info->frame,UL_info->subframe); - + UL_info->frame,UL_info->subframe); handle_rach(UL_info); - handle_sr(UL_info); - handle_cqi(UL_info); - handle_harq(UL_info); - // clear HI prior to handling ULSCH - uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_id] , UL_info->subframe); - if(sf_ahead_dl!=255){ - mac->HI_DCI0_req[CC_id][(UL_info->subframe+sf_ahead_dl)%10].hi_dci0_request_body.number_of_hi = 0; - LOG_D(MAC,"current (%d,%d) clear HI_DCI0_req[0][%d]\n",UL_info->frame,UL_info->subframe,(UL_info->subframe+sf_ahead_dl)%10); + uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_id], UL_info->subframe); + + if(sf_ahead_dl!=255) { + mac->HI_DCI0_req[CC_id][(UL_info->subframe+sf_ahead_dl)%10].hi_dci0_request_body.number_of_hi = 0; + LOG_D(MAC,"current (%d,%d) clear HI_DCI0_req[0][%d]\n",UL_info->frame,UL_info->subframe,(UL_info->subframe+sf_ahead_dl)%10); } - + handle_ulsch(UL_info); - if (nfapi_mode != 1) - { + if (NFAPI_MODE != NFAPI_MODE_PNF) { if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) { - eNB_dlsch_ulsch_scheduler(module_id, - (UL_info->frame+((UL_info->subframe>(9-sf_ahead))?1:0)) % 1024, - (UL_info->subframe+sf_ahead)%10); - + (UL_info->frame+((UL_info->subframe>(9-sf_ahead))?1:0)) % 1024, + (UL_info->subframe+sf_ahead)%10); ifi->CC_mask = 0; - sched_info->module_id = module_id; sched_info->CC_id = CC_id; sched_info->frame = (UL_info->frame + ((UL_info->subframe>(9-sf_ahead)) ? 1 : 0)) % 1024; sched_info->subframe = (UL_info->subframe+sf_ahead)%10; sched_info->DL_req = &mac->DL_req[CC_id]; sched_info->HI_DCI0_req = &mac->HI_DCI0_req[CC_id][sched_info->subframe]; + if ((mac->common_channels[CC_id].tdd_Config==NULL) || (is_UL_sf(&mac->common_channels[CC_id],sched_info->subframe)>0)) sched_info->UL_req = &mac->UL_req[CC_id]; @@ -592,17 +634,15 @@ void UL_indication(UL_IND_t *UL_info) sched_info->UL_req = NULL; sched_info->TX_req = &mac->TX_req[CC_id]; - #ifdef DUMP_FAPI dump_dl(sched_info); #endif - if (ifi->schedule_response) - { + if (ifi->schedule_response) { AssertFatal(ifi->schedule_response!=NULL, - "schedule_response is null (mod %d, cc %d)\n", - module_id, - CC_id); + "schedule_response is null (mod %d, cc %d)\n", + module_id, + CC_id); ifi->schedule_response(sched_info); } @@ -611,28 +651,24 @@ void UL_indication(UL_IND_t *UL_info) } } -IF_Module_t *IF_Module_init(int Mod_id){ - +IF_Module_t *IF_Module_init(int Mod_id) { AssertFatal(Mod_id<MAX_MODULES,"Asking for Module %d > %d\n",Mod_id,MAX_IF_MODULES); - LOG_D(PHY,"Installing callbacks for IF_Module - UL_indication\n"); if (if_inst[Mod_id]==NULL) { - if_inst[Mod_id] = (IF_Module_t*)malloc(sizeof(IF_Module_t)); - memset((void*)if_inst[Mod_id],0,sizeof(IF_Module_t)); - + if_inst[Mod_id] = (IF_Module_t *)malloc(sizeof(IF_Module_t)); + memset((void *)if_inst[Mod_id],0,sizeof(IF_Module_t)); if_inst[Mod_id]->CC_mask=0; if_inst[Mod_id]->UL_indication = UL_indication; - AssertFatal(pthread_mutex_init(&if_inst[Mod_id]->if_mutex,NULL)==0, - "allocation of if_inst[%d]->if_mutex fails\n",Mod_id); + "allocation of if_inst[%d]->if_mutex fails\n",Mod_id); } + return if_inst[Mod_id]; } void IF_Module_kill(int Mod_id) { - AssertFatal(Mod_id>MAX_MODULES,"Asking for Module %d > %d\n",Mod_id,MAX_IF_MODULES); - if (if_inst[Mod_id]!=NULL) free(if_inst[Mod_id]); + if (if_inst[Mod_id]!=NULL) free(if_inst[Mod_id]); } diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 0c961d9fbbb99a4f6b938c88137f0e7533887f0e..8d625fbdc59337c86d4609e9a386314e411243c5 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -72,7 +72,7 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND pdu->rx_indication_rel8.length = buflen; pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - // ulsch_buffer is necessary to keep its value. + // ulsch_buffer is necessary to keep its value. //pdu->data = ulsch_buffer; pdu->data = malloc(buflen); memcpy(pdu->data,ulsch_buffer,buflen); @@ -181,7 +181,7 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL // change for mutiple UE's simulation. // pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); pthread_mutex_lock(&fill_ul_mutex.rach_mutex); - + // memory allocation and free memory of UL_INFO are done in UE_phy_stub_single_thread_rxn_txnp4. // UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t)); diff --git a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h index 2e1d05038778f6d698e0323b68a019ecc5676172..270436b029d3b673a9aef9f11d6fa811097061aa 100644 --- a/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h +++ b/openair2/RRC/L2_INTERFACE/openair_rrc_L2_interface.h @@ -39,6 +39,7 @@ mac_rrc_data_req( const int CC_idP, const frame_t frameP, const rb_id_t srb_idP, + const rnti_t rntiP, const uint8_t nb_tbP, uint8_t* const buffer_pP, const uint8_t mbsfn_sync_areaP @@ -47,14 +48,15 @@ mac_rrc_data_req( /*int8_t mac_rrc_data_ind( const module_id_t module_idP, - const int CC_idP, + const int CC_id, const frame_t frameP, const sub_frame_t sub_frameP, + const int UE_id, const rnti_t rntiP, const rb_id_t srb_idP, - const uint8_t *sduP, + const uint8_t* sduP, const sdu_size_t sdu_lenP, - const uint8_t mbsfn_sync_area + const uint8_t mbsfn_sync_areaP ); int8_t diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c index 736b16422b212da7834abd1e2be2bd2e27899a8d..027a6299927abdb01014c431914c0e0fdfcefe50 100644 --- a/openair2/RRC/LITE/rrc_common.c +++ b/openair2/RRC/LITE/rrc_common.c @@ -282,7 +282,7 @@ rrc_rx_tx( UE_rrc_inst[ctxt_pP->module_id].Info[enb_indexP].T310_active = 0; rrc_t310_expiration (ctxt_pP, enb_indexP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); - LOG_I(RRC,"Returning RRC_PHY_RESYNCH: T310 expired\n"); + LOG_I(RRC,"Returning RRC_PHY_RESYNCH: T310 expired\n"); return RRC_PHY_RESYNCH; } @@ -358,7 +358,7 @@ rrc_rx_tx( } if (ue_context_p->ue_context.ue_release_timer>0) { ue_context_p->ue_context.ue_release_timer++; - if (ue_context_p->ue_context.ue_release_timer >= + if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) { LOG_I(RRC,"Removing UE %x instance (release timer %d)\n",ue_context_p->ue_context.rnti,ue_context_p->ue_context.ue_release_timer); ue_to_be_removed = ue_context_p; @@ -493,4 +493,3 @@ binary_search_float( return first; } - diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 4b57a4f5f929665ec7fd89fde8b7182a99c6a5f6..6478641438c060bd88fd09331123fc4faea6c5ef 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -42,7 +42,8 @@ #endif #include "flexran_agent_extern.h" - +#undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace +#include "f1ap_du_rrc_message_transfer.h" extern RAN_CONTEXT_t RC; @@ -53,6 +54,7 @@ mac_rrc_data_req( const int CC_id, const frame_t frameP, const rb_id_t Srb_id, + const rnti_t rnti, const uint8_t Nb_tb, uint8_t *const buffer_pP, const uint8_t mbsfn_sync_area @@ -159,14 +161,14 @@ mac_rrc_data_req( } if( (Srb_id & RAB_OFFSET ) == CCCH) { - LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id); - if(RC.rrc[Mod_idP]->carrier[CC_id].Srb0.Active==0) { - LOG_E(RRC,"[eNB %d] CCCH Not active\n",Mod_idP); - return -1; - } + struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti); + + if (ue_context_p == NULL) return(0); + eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; + LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %d, rnti %x)\n",Mod_idP,frameP, Srb_id,rnti); - Srb_info=&RC.rrc[Mod_idP]->carrier[CC_id].Srb0; + Srb_info=&ue_p->Srb0; // check if data is there for MAC if(Srb_info->Tx_buffer.payload_size>0) { //Fill buffer @@ -239,6 +241,7 @@ mac_rrc_data_req( return(0); } + //------------------------------------------------------------------------------ int8_t mac_rrc_data_ind( @@ -246,6 +249,7 @@ mac_rrc_data_ind( const int CC_id, const frame_t frameP, const sub_frame_t sub_frameP, + const int UE_id, const rnti_t rntiP, const rb_id_t srb_idP, const uint8_t *sduP, @@ -258,7 +262,25 @@ mac_rrc_data_ind( ) //-------------------------------------------------------------------------- { - SRB_INFO *Srb_info; + + + if (NODE_IS_DU(RC.rrc[module_idP]->node_type)) { + LOG_W(RRC,"[DU %d][RAPROC] Received SDU for CCCH on SRB %d length %d for UE id %d RNTI %x \n", + module_idP, srb_idP, sdu_lenP, UE_id, rntiP); + + /* do ITTI message */ + DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER( + module_idP, + CC_id, + UE_id, + rntiP, + sduP, + sdu_lenP + ); + return(0); + } + + //SRB_INFO *Srb_info; protocol_ctxt_t ctxt; sdu_size_t sdu_size = 0; /* for no gcc warnings */ @@ -269,16 +291,17 @@ mac_rrc_data_ind( PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rntiP, frameP, sub_frameP,0); if((srb_idP & RAB_OFFSET) == CCCH) { - Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0; - LOG_D(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id); + LOG_D(RRC, "[eNB %d] Received SDU for CCCH on SRB %d\n", module_idP, srb_idP); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ctxt.brOption = brOption; -#endif +#endif + /*Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0; if (sdu_lenP > 0) { memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); Srb_info->Rx_buffer.payload_size = sdu_lenP; rrc_eNB_decode_ccch(&ctxt, Srb_info, CC_id); - } + }*/ + if (sdu_lenP > 0) rrc_eNB_decode_ccch(&ctxt, sduP, sdu_lenP, CC_id); } if((srb_idP & RAB_OFFSET) == DCCH) { @@ -335,11 +358,9 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP, } else { LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP); } - - if (rrc_agent_registered[Mod_instP]) { - agent_rrc_xface[Mod_instP]->flexran_agent_notify_ue_state_change(Mod_instP, - rntiP, - PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + if (flexran_agent_get_rrc_xface(Mod_instP)) { + flexran_agent_get_rrc_xface(Mod_instP)->flexran_agent_notify_ue_state_change(Mod_instP, + rntiP, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } rrc_mac_remove_ue(Mod_instP,rntiP); diff --git a/openair2/RRC/LTE/L2_interface_common.c b/openair2/RRC/LTE/L2_interface_common.c index b03b36a557431d58f8ca8c036dd47e5ebf09bce4..b5cc99bc3a78fa1fba0dfbb1d40ab9d15545f66c 100644 --- a/openair2/RRC/LTE/L2_interface_common.c +++ b/openair2/RRC/LTE/L2_interface_common.c @@ -38,30 +38,32 @@ #include "common/ran_context.h" #if defined(ENABLE_ITTI) -# include "intertask_interface.h" + #include "intertask_interface.h" #endif //#define RRC_DATA_REQ_DEBUG //#define DEBUG_RRC 1 +extern RAN_CONTEXT_t RC; + //------------------------------------------------------------------------------ uint8_t rrc_data_req( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t rb_idP, const mui_t muiP, const confirm_t confirmP, const sdu_size_t sdu_sizeP, - uint8_t* const buffer_pP, + uint8_t *const buffer_pP, const pdcp_transmission_mode_t modeP ) //------------------------------------------------------------------------------ { - if(sdu_sizeP == 255) - { + if(sdu_sizeP == 255) { LOG_I(RRC,"sdu_sizeP == 255"); return FALSE; } + MSC_LOG_TX_MESSAGE( ctxt_pP->enb_flag ? MSC_RRC_ENB : MSC_RRC_UE, ctxt_pP->enb_flag ? MSC_PDCP_ENB : MSC_PDCP_UE, @@ -72,60 +74,49 @@ rrc_data_req( ctxt_pP->rnti, muiP, sdu_sizeP); - -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). - uint8_t *message_buffer; - - message_buffer = itti_malloc ( - ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, - ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, - sdu_sizeP); - - memcpy (message_buffer, buffer_pP, sdu_sizeP); - - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, RRC_DCCH_DATA_REQ); - RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; - RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; - RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP; - RRC_DCCH_DATA_REQ (message_p).muip = muiP; - RRC_DCCH_DATA_REQ (message_p).confirmp = confirmP; - RRC_DCCH_DATA_REQ (message_p).sdu_size = sdu_sizeP; - RRC_DCCH_DATA_REQ (message_p).sdu_p = message_buffer; - RRC_DCCH_DATA_REQ (message_p).mode = modeP; - RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id; - RRC_DCCH_DATA_REQ (message_p).rnti = ctxt_pP->rnti; - RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index; - - itti_send_msg_to_task ( - ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, - ctxt_pP->instance, - message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. - - } -#else - return pdcp_data_req ( - ctxt_pP, - SRB_FLAG_YES, - rb_idP, - muiP, - confirmP, - sdu_sizeP, - buffer_pP, - modeP); -#endif + MessageDef *message_p; + // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). + uint8_t *message_buffer; + message_buffer = itti_malloc ( + ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, + ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, + sdu_sizeP); + memcpy (message_buffer, buffer_pP, sdu_sizeP); + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, RRC_DCCH_DATA_REQ); + RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; + RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; + RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP; + RRC_DCCH_DATA_REQ (message_p).muip = muiP; + RRC_DCCH_DATA_REQ (message_p).confirmp = confirmP; + RRC_DCCH_DATA_REQ (message_p).sdu_size = sdu_sizeP; + RRC_DCCH_DATA_REQ (message_p).sdu_p = message_buffer; + //memcpy (RRC_DCCH_DATA_REQ (message_p).sdu_p, buffer_pP, sdu_sizeP); + RRC_DCCH_DATA_REQ (message_p).mode = modeP; + RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id; + RRC_DCCH_DATA_REQ (message_p).rnti = ctxt_pP->rnti; + RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index; + itti_send_msg_to_task ( + ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, + ctxt_pP->instance, + message_p); + LOG_I(RRC,"sent RRC_DCCH_DATA_REQ to TASK_PDCP_ENB\n"); + + /* Hack: only trigger PDCP if in CU, otherwise it is triggered by RU threads + * Ideally, PDCP would not neet to be triggered like this but react to ITTI + * messages automatically */ + if (ctxt_pP->enb_flag && NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) + pdcp_run(ctxt_pP); + + return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } //------------------------------------------------------------------------------ void rrc_data_ind( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, const sdu_size_t sdu_sizeP, - const uint8_t* const buffer_pP + const uint8_t *const buffer_pP ) //------------------------------------------------------------------------------ { @@ -135,7 +126,7 @@ rrc_data_ind( LOG_I(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); } else { - LOG_I(RRC, "[eNB %d] Frame %d: received a DCCH %d message on SRB %d with Size %d from UE %x\n", + LOG_D(RRC, "[eNB %d] Frame %d: received a DCCH %d message on SRB %d with Size %d from UE %x\n", ctxt_pP->module_id, ctxt_pP->frame, DCCH_index, @@ -149,10 +140,8 @@ rrc_data_ind( MessageDef *message_p; // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). uint8_t *message_buffer; - message_buffer = itti_malloc (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, sdu_sizeP); memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, RRC_DCCH_DATA_IND); RRC_DCCH_DATA_IND (message_p).frame = ctxt_pP->frame; RRC_DCCH_DATA_IND (message_p).dcch_index = DCCH_index; @@ -161,16 +150,13 @@ rrc_data_ind( RRC_DCCH_DATA_IND (message_p).rnti = ctxt_pP->rnti; RRC_DCCH_DATA_IND (message_p).module_id = ctxt_pP->module_id; RRC_DCCH_DATA_IND (message_p).eNB_index = ctxt_pP->eNB_index; - itti_send_msg_to_task (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, ctxt_pP->instance, message_p); } #else - - rrc_eNB_decode_dcch( - ctxt_pP, - DCCH_index, - buffer_pP, - sdu_sizeP); - + rrc_eNB_decode_dcch( + ctxt_pP, + DCCH_index, + buffer_pP, + sdu_sizeP); #endif } diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index b6cde649eeb03569e0e16c8dd1486111baf41ce2..d8b6974501622383f7eb77985dcf699428780f31 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -38,7 +38,7 @@ #if defined(ENABLE_ITTI) -# include "intertask_interface.h" + #include "intertask_interface.h" #endif //#define RRC_DATA_REQ_DEBUG @@ -53,67 +53,62 @@ mac_rrc_data_req_ue( const frame_t frameP, const rb_id_t Srb_id, const uint8_t Nb_tb, - uint8_t* const buffer_pP, + uint8_t *const buffer_pP, const uint8_t eNB_index, const uint8_t mbsfn_sync_area ) //-------------------------------------------------------------------------- { - LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); - - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - LOG_D(RRC,"[UE %d] Frame %d Filling SL DISCOVERY SRB_ID %d\n",Mod_idP,frameP,Srb_id); - LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); - - //TTN (for D2D) - if (Srb_id == SL_DISCOVERY && UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size > 0){ - memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); - uint8_t Ret_size=UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size; - LOG_I(RRC,"[UE %d] Sending SL_Discovery, size %d bytes\n",Mod_idP,Ret_size); - UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size = 0; - return(Ret_size); - } -#endif + LOG_D(RRC,"[UE %d] Frame %d Filling SL DISCOVERY SRB_ID %d\n",Mod_idP,frameP,Srb_id); + LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); + + //TTN (for D2D) + if (Srb_id == SL_DISCOVERY && UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size > 0) { + memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); + uint8_t Ret_size=UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size; + LOG_I(RRC,"[UE %d] Sending SL_Discovery, size %d bytes\n",Mod_idP,Ret_size); + UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size = 0; + return(Ret_size); + } +#endif LOG_D(RRC,"[UE %d] Frame %d Filling CCCH SRB_ID %d\n",Mod_idP,frameP,Srb_id); LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); if( (UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size > 0) ) { - #if defined(ENABLE_ITTI) - { - MessageDef *message_p; - int ccch_size = UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; - int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu); - - if (ccch_size > sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size); - ccch_size = sdu_size; - } - - message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_MAC_CCCH_DATA_REQ); - RRC_MAC_CCCH_DATA_REQ (message_p).frame = frameP; - RRC_MAC_CCCH_DATA_REQ (message_p).sdu_size = ccch_size; - memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload, ccch_size); - RRC_MAC_CCCH_DATA_REQ (message_p).enb_index = eNB_index; - - itti_send_msg_to_task (TASK_MAC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); + { + MessageDef *message_p; + int ccch_size = UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; + int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu); + + if (ccch_size > sdu_size) { + LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size); + ccch_size = sdu_size; } -#endif - memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); - uint8_t Ret_size=UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; - // UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size=0; - UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active = 1; - UE_rrc_inst[Mod_idP].Info[eNB_index].T300_cnt = 0; - // msg("[RRC][UE %d] Sending rach\n",Mod_id); - return(Ret_size); - } else { - return 0; + message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_MAC_CCCH_DATA_REQ); + RRC_MAC_CCCH_DATA_REQ (message_p).frame = frameP; + RRC_MAC_CCCH_DATA_REQ (message_p).sdu_size = ccch_size; + memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE); + memcpy (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload, ccch_size); + RRC_MAC_CCCH_DATA_REQ (message_p).enb_index = eNB_index; + + itti_send_msg_to_task (TASK_MAC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } +#endif + memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); + uint8_t Ret_size=UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size; + // UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size=0; + UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active = 1; + UE_rrc_inst[Mod_idP].Info[eNB_index].T300_cnt = 0; + // msg("[RRC][UE %d] Sending rach\n",Mod_id); + return(Ret_size); + } else { + return 0; + } return(0); } @@ -127,7 +122,7 @@ mac_rrc_data_ind_ue( const sub_frame_t sub_frameP, const rnti_t rntiP, const rb_id_t srb_idP, - const uint8_t* sduP, + const uint8_t *sduP, const sdu_size_t sdu_lenP, const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_areaP @@ -136,10 +131,8 @@ mac_rrc_data_ind_ue( { protocol_ctxt_t ctxt; sdu_size_t sdu_size = 0; - /* for no gcc warnings */ (void)sdu_size; - /* int si_window; */ @@ -179,131 +172,126 @@ mac_rrc_data_ind_ue( } #endif + if(srb_idP == BCCH) { + LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); +#if defined(ENABLE_ITTI) + { + MessageDef *message_p; + int msg_sdu_size = sizeof(RRC_MAC_BCCH_DATA_IND (message_p).sdu); + + if (sdu_lenP > msg_sdu_size) { + LOG_E(RRC, "SDU larger than BCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size); + sdu_size = msg_sdu_size; + } else { + sdu_size = sdu_lenP; + } + + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_DATA_IND); + memset (RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); + RRC_MAC_BCCH_DATA_IND (message_p).frame = frameP; + RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frameP; + RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; + memcpy (RRC_MAC_BCCH_DATA_IND (message_p).sdu, sduP, sdu_size); + RRC_MAC_BCCH_DATA_IND (message_p).enb_index = eNB_indexP; + RRC_MAC_BCCH_DATA_IND (message_p).rsrq = 30 /* TODO change phy to report rspq */; + RRC_MAC_BCCH_DATA_IND (message_p).rsrp = 45 /* TODO change phy to report rspp */; + itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); + } +#else + decode_BCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t *)sduP,sdu_lenP, 0, 0); +#endif + } - if(srb_idP == BCCH) { - LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); + if(srb_idP == PCCH) { + LOG_D(RRC,"[UE %d] Received SDU for PCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); + decode_PCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t *)sduP,sdu_lenP); + } + if((srb_idP & RAB_OFFSET) == CCCH) { + if (sdu_lenP>0) { + LOG_T(RRC,"[UE %d] Received SDU for CCCH on SRB %d from eNB %d\n",module_idP,srb_idP & RAB_OFFSET,eNB_indexP); #if defined(ENABLE_ITTI) { MessageDef *message_p; - int msg_sdu_size = sizeof(RRC_MAC_BCCH_DATA_IND (message_p).sdu); + int msg_sdu_size = CCCH_SDU_SIZE; if (sdu_lenP > msg_sdu_size) { - LOG_E(RRC, "SDU larger than BCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size); + LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); sdu_size = msg_sdu_size; } else { - sdu_size = sdu_lenP; + sdu_size = sdu_lenP; } - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_DATA_IND); - memset (RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); - RRC_MAC_BCCH_DATA_IND (message_p).frame = frameP; - RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frameP; - RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; - memcpy (RRC_MAC_BCCH_DATA_IND (message_p).sdu, sduP, sdu_size); - RRC_MAC_BCCH_DATA_IND (message_p).enb_index = eNB_indexP; - RRC_MAC_BCCH_DATA_IND (message_p).rsrq = 30 /* TODO change phy to report rspq */; - RRC_MAC_BCCH_DATA_IND (message_p).rsrp = 45 /* TODO change phy to report rspp */; - + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_IND); + memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size); + RRC_MAC_CCCH_DATA_IND (message_p).frame = frameP; + RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frameP; + RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size; + RRC_MAC_CCCH_DATA_IND (message_p).enb_index = eNB_indexP; + RRC_MAC_CCCH_DATA_IND (message_p).rnti = rntiP; itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); } #else - decode_BCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP, 0, 0); + SRB_INFO *Srb_info; + Srb_info = &UE_rrc_inst[module_idP].Srb0[eNB_indexP]; + memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); + Srb_info->Rx_buffer.payload_size = sdu_lenP; + rrc_ue_decode_ccch(&ctxt, Srb_info, eNB_indexP); #endif } - - if(srb_idP == PCCH) { - LOG_D(RRC,"[UE %d] Received SDU for PCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); - decode_PCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP); - } - if((srb_idP & RAB_OFFSET) == CCCH) { - if (sdu_lenP>0) { - LOG_T(RRC,"[UE %d] Received SDU for CCCH on SRB %d from eNB %d\n",module_idP,srb_idP & RAB_OFFSET,eNB_indexP); - -#if defined(ENABLE_ITTI) - { - MessageDef *message_p; - int msg_sdu_size = CCCH_SDU_SIZE; - - if (sdu_lenP > msg_sdu_size) { - LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); - sdu_size = msg_sdu_size; - } else { - sdu_size = sdu_lenP; - } - - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_IND); - memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size); - RRC_MAC_CCCH_DATA_IND (message_p).frame = frameP; - RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frameP; - RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size; - RRC_MAC_CCCH_DATA_IND (message_p).enb_index = eNB_indexP; - RRC_MAC_CCCH_DATA_IND (message_p).rnti = rntiP; - itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); - } -#else - SRB_INFO *Srb_info; - Srb_info = &UE_rrc_inst[module_idP].Srb0[eNB_indexP]; - memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); - Srb_info->Rx_buffer.payload_size = sdu_lenP; - rrc_ue_decode_ccch(&ctxt, Srb_info, eNB_indexP); -#endif - } - } + } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - if ((srb_idP & RAB_OFFSET) == MCCH) { - LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n", - module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); - + if ((srb_idP & RAB_OFFSET) == MCCH) { + LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n", + module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); #if defined(ENABLE_ITTI) - { - MessageDef *message_p; - int msg_sdu_size = sizeof(RRC_MAC_MCCH_DATA_IND (message_p).sdu); - - if (sdu_size > msg_sdu_size) { - LOG_E(RRC, "SDU larger than MCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); - sdu_size = msg_sdu_size; - } + { + MessageDef *message_p; + int msg_sdu_size = sizeof(RRC_MAC_MCCH_DATA_IND (message_p).sdu); - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_MCCH_DATA_IND); - RRC_MAC_MCCH_DATA_IND (message_p).frame = frameP; - RRC_MAC_MCCH_DATA_IND (message_p).sub_frame = sub_frameP; - RRC_MAC_MCCH_DATA_IND (message_p).sdu_size = sdu_lenP; - memset (RRC_MAC_MCCH_DATA_IND (message_p).sdu, 0, MCCH_SDU_SIZE); - memcpy (RRC_MAC_MCCH_DATA_IND (message_p).sdu, sduP, sdu_lenP); - RRC_MAC_MCCH_DATA_IND (message_p).enb_index = eNB_indexP; - RRC_MAC_MCCH_DATA_IND (message_p).mbsfn_sync_area = mbsfn_sync_areaP; - itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); + if (sdu_size > msg_sdu_size) { + LOG_E(RRC, "SDU larger than MCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size); + sdu_size = msg_sdu_size; } + + message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_MCCH_DATA_IND); + RRC_MAC_MCCH_DATA_IND (message_p).frame = frameP; + RRC_MAC_MCCH_DATA_IND (message_p).sub_frame = sub_frameP; + RRC_MAC_MCCH_DATA_IND (message_p).sdu_size = sdu_lenP; + memset (RRC_MAC_MCCH_DATA_IND (message_p).sdu, 0, MCCH_SDU_SIZE); + memcpy (RRC_MAC_MCCH_DATA_IND (message_p).sdu, sduP, sdu_lenP); + RRC_MAC_MCCH_DATA_IND (message_p).enb_index = eNB_indexP; + RRC_MAC_MCCH_DATA_IND (message_p).mbsfn_sync_area = mbsfn_sync_areaP; + itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); + } #else - decode_MCCH_Message(&ctxt, eNB_indexP, sduP, sdu_lenP, mbsfn_sync_areaP); + decode_MCCH_Message(&ctxt, eNB_indexP, sduP, sdu_lenP, mbsfn_sync_areaP); #endif - } - //TTN (for D2D) - if(srb_idP == SL_DISCOVERY) { - LOG_I(RRC,"[UE %d] Received SDU (%d bytes) for SL_DISCOVERY on SRB %d from eNB %d\n",module_idP, sdu_lenP, srb_idP,eNB_indexP); - decode_SL_Discovery_Message(&ctxt, eNB_indexP, sduP, sdu_lenP); - } + } -#endif // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + //TTN (for D2D) + if(srb_idP == SL_DISCOVERY) { + LOG_I(RRC,"[UE %d] Received SDU (%d bytes) for SL_DISCOVERY on SRB %d from eNB %d\n",module_idP, sdu_lenP, srb_idP,eNB_indexP); + decode_SL_Discovery_Message(&ctxt, eNB_indexP, sduP, sdu_lenP); + } +#endif // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) return(0); - } //------------------------------------------------------------------------------ uint8_t rrc_data_req_ue( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t rb_idP, const mui_t muiP, const confirm_t confirmP, const sdu_size_t sdu_sizeP, - uint8_t* const buffer_pP, + uint8_t *const buffer_pP, const pdcp_transmission_mode_t modeP ) //------------------------------------------------------------------------------ @@ -318,20 +306,16 @@ rrc_data_req_ue( ctxt_pP->rnti, muiP, sdu_sizeP); - #if defined(ENABLE_ITTI) { MessageDef *message_p; // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). uint8_t *message_buffer; - message_buffer = itti_malloc ( ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, sdu_sizeP); - memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, RRC_DCCH_DATA_REQ); RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; @@ -344,13 +328,11 @@ rrc_data_req_ue( RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id; RRC_DCCH_DATA_REQ (message_p).rnti = ctxt_pP->rnti; RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index; - itti_send_msg_to_task ( TASK_PDCP_UE, ctxt_pP->instance, message_p); return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. - } #else return pdcp_data_req ( @@ -365,34 +347,30 @@ rrc_data_req_ue( #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif - ); + ); #endif } //------------------------------------------------------------------------------ void rrc_data_ind_ue( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, const sdu_size_t sdu_sizeP, - const uint8_t* const buffer_pP + const uint8_t *const buffer_pP ) //------------------------------------------------------------------------------ { rb_id_t DCCH_index = Srb_id; - - LOG_I(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", - ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); - + LOG_I(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", + ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); #if defined(ENABLE_ITTI) { MessageDef *message_p; // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). uint8_t *message_buffer; - message_buffer = itti_malloc (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, sdu_sizeP); memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, RRC_DCCH_DATA_IND); RRC_DCCH_DATA_IND (message_p).frame = ctxt_pP->frame; RRC_DCCH_DATA_IND (message_p).dcch_index = DCCH_index; @@ -401,24 +379,20 @@ rrc_data_ind_ue( RRC_DCCH_DATA_IND (message_p).rnti = ctxt_pP->rnti; RRC_DCCH_DATA_IND (message_p).module_id = ctxt_pP->module_id; RRC_DCCH_DATA_IND (message_p).eNB_index = ctxt_pP->eNB_index; - itti_send_msg_to_task (TASK_RRC_UE, ctxt_pP->instance, message_p); } #else - -//#warning "LG put 0 to arg4 that is eNB index" - rrc_ue_decode_dcch( - ctxt_pP, - DCCH_index, - buffer_pP, - 0); - + //#warning "LG put 0 to arg4 that is eNB index" + rrc_ue_decode_dcch( + ctxt_pP, + DCCH_index, + buffer_pP, + 0); #endif } //-------------------------------------------------------------------------------------------// -void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) -{ +void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) { //-------------------------------------------------------------------------------------------// #if defined(ENABLE_ITTI) { @@ -427,7 +401,6 @@ void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_IN_SYNC_IND); RRC_MAC_IN_SYNC_IND (message_p).frame = frameP; RRC_MAC_IN_SYNC_IND (message_p).enb_index = eNB_index; - itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } #else @@ -441,25 +414,22 @@ void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) } //-------------------------------------------------------------------------------------------// -void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) -{ +void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) { //-------------------------------------------------------------------------------------------// if (UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt>10) LOG_I(RRC,"[UE %d] Frame %d: OUT OF SYNC FROM eNB %d (T310 active %d : T310 %d, N310 %d, N311 %d)\n ", - Mod_idP,frameP,eNB_index, - UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active, - UE_rrc_inst[Mod_idP].Info[eNB_index].T310_cnt, - UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt, - UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt); - + Mod_idP,frameP,eNB_index, + UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active, + UE_rrc_inst[Mod_idP].Info[eNB_index].T310_cnt, + UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt, + UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt); + #if defined(ENABLE_ITTI) { MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_OUT_OF_SYNC_IND); RRC_MAC_OUT_OF_SYNC_IND (message_p).frame = frameP; RRC_MAC_OUT_OF_SYNC_IND (message_p).enb_index = eNB_index; - itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } #else @@ -482,16 +452,13 @@ mac_UE_get_rrc_status( } //-------------------------------------------------------------------------------------------// -int mac_ue_ccch_success_ind(module_id_t Mod_idP, uint8_t eNB_index) -{ +int mac_ue_ccch_success_ind(module_id_t Mod_idP, uint8_t eNB_index) { //-------------------------------------------------------------------------------------------// #if defined(ENABLE_ITTI) { MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_CNF); RRC_MAC_CCCH_DATA_CNF (message_p).enb_index = eNB_index; - itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } #else diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 479296fd12bb46c8c06b898e8c8b31cac88d7f7f..21e7b0f5d350865faffa1f86b209bc0845ae6cd8 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -52,6 +52,8 @@ #include "LTE_RRCConnectionSetup.h" #include "LTE_SRB-ToAddModList.h" #include "LTE_DRB-ToAddModList.h" +#include "LTE_HandoverPreparationInformation.h" +#include "LTE_HandoverCommand.h" #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #include "LTE_MCCH-Message.h" //#define MRB1 1 @@ -619,6 +621,121 @@ uint8_t do_SIB1_MBMS(rrc_eNB_carrier_data_t *carrier, return((enc_rval.encoded+7)/8); } #endif +//----------------------------------------------------------------------------- +/* + * Generate the configuration structure for CDRX feature + */ +LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, + int CC_id, + RrcConfigurationReq *configuration, + LTE_UE_EUTRA_Capability_t *UEcap) +//----------------------------------------------------------------------------- +{ + LTE_DRX_Config_t *drxConfig = NULL; + BIT_STRING_t *featureGroupIndicators = NULL; + bool ueSupportCdrxShortFlag = false; + bool ueSupportCdrxLongFlag = false; + + /* Check the UE capabilities for short and long CDRX cycles support */ + if (UEcap) { + featureGroupIndicators = UEcap->featureGroupIndicators; + if (featureGroupIndicators) { + if (featureGroupIndicators->size > 1 || (featureGroupIndicators->size == 1 && featureGroupIndicators->bits_unused < 4)) { + ueSupportCdrxShortFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x10) > 0); + ueSupportCdrxLongFlag = ((featureGroupIndicators->buf[0] & (uint8_t) 0x08) > 0); + LOG_I(RRC,"[do_DrxConfig] featureGroupIndicators->buf[0]: %x\n", featureGroupIndicators->buf[0]); + } else LOG_W(RRC,"[do_DrxConfig] Not enough featureGroupIndicators bits\n"); + } else LOG_W(RRC,"[do_DrxConfig] No featureGroupIndicators pointer\n"); + } else LOG_W(RRC,"[do_DrxConfig] No UEcap pointer\n"); + + if (configuration->radioresourceconfig[CC_id].drx_Config_present == LTE_DRX_Config_PR_NOTHING) { + return NULL; + } + + drxConfig = (LTE_DRX_Config_t *) malloc(sizeof(LTE_DRX_Config_t)); + if (drxConfig == NULL) return NULL; + memset(drxConfig, 0, sizeof(LTE_DRX_Config_t)); + + /* Long DRX cycle support is mandatory for CDRX activation */ + if (!ueSupportCdrxLongFlag) { + drxConfig->present = LTE_DRX_Config_PR_release; + } else { + drxConfig->present = configuration->radioresourceconfig[CC_id].drx_Config_present; + } + + if (drxConfig->present == LTE_DRX_Config_PR_release) { + drxConfig->choice.release = (NULL_t) 0; + } else { + drxConfig->choice.setup.onDurationTimer = configuration->radioresourceconfig[CC_id].drx_onDurationTimer; + drxConfig->choice.setup.drx_InactivityTimer = configuration->radioresourceconfig[CC_id].drx_InactivityTimer; + drxConfig->choice.setup.drx_RetransmissionTimer = configuration->radioresourceconfig[CC_id].drx_RetransmissionTimer; + drxConfig->choice.setup.longDRX_CycleStartOffset.present = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset_present; + switch (drxConfig->choice.setup.longDRX_CycleStartOffset.present) { + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf10 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf20 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf32 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf40 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf64 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf80 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf128 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf160 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf256 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf320 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf512 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf640 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf1024 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf1280 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf2048 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560: + drxConfig->choice.setup.longDRX_CycleStartOffset.choice.sf2560 = configuration->radioresourceconfig[CC_id].drx_longDrx_CycleStartOffset; + break; + default: + break; + } + + /* Short DRX cycle configuration */ + if (!ueSupportCdrxShortFlag || configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer == 0) { + drxConfig->choice.setup.shortDRX = NULL; + } else { + drxConfig->choice.setup.shortDRX = MALLOC(sizeof(struct LTE_DRX_Config__setup__shortDRX)); + memset(drxConfig->choice.setup.shortDRX, 0, sizeof(struct LTE_DRX_Config__setup__shortDRX)); + drxConfig->choice.setup.shortDRX->shortDRX_Cycle = configuration->radioresourceconfig[CC_id].drx_shortDrx_Cycle; + drxConfig->choice.setup.shortDRX->drxShortCycleTimer = configuration->radioresourceconfig[CC_id].drx_shortDrx_ShortCycleTimer; + } + } + + return drxConfig; +} uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, int Mod_id,int CC_id @@ -1213,7 +1330,7 @@ uint8_t do_SIB23(uint8_t Mod_id, struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib2_part,*sib3_part; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - int eMTC_configured=configuration->eMTC_configured; + int eMTC_configured = configuration->eMTC_configured; struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib18_part, *sib19_part, *sib21_part; LTE_SL_CommRxPoolList_r12_t *SL_CommRxPoolList; //for SIB18 struct LTE_SL_CommResourcePool_r12 *SL_CommResourcePool; //for SIB18 @@ -2659,6 +2776,7 @@ do_RRCConnectionSetup( dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup; rrcConnectionSetup = &dl_ccch_msg.message.choice.c1.choice.rrcConnectionSetup; + LTE_MAC_MainConfig_t *mac_MainConfig = NULL; // RRCConnectionSetup // Configure SRB1 @@ -2777,30 +2895,34 @@ do_RRCConnectionSetup( physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[0]=0x22; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[1]=0x34+ue_context_pP->local_uid; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.bits_unused=0; - // CQI ReportConfig - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic)); + + /* CQI ReportConfig */ + // Aperiodic configuration + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic = CALLOC(1, sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic)); + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic= LTE_CQI_ReportModeAperiodic_rm30; + *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic = LTE_CQI_ReportModeAperiodic_rm30; // HLC CQI, no PMI #else - *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm30; // HLC CQI, no PMI + *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic = LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm30; // HLC CQI, no PMI #endif - physicalConfigDedicated2->cqi_ReportConfig->nomPDSCH_RS_EPRE_Offset = 0; // 0 dB - //physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=NULL; - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = LTE_CQI_ReportPeriodic_PR_release; + + physicalConfigDedicated2->cqi_ReportConfig->nomPDSCH_RS_EPRE_Offset = 0; // 0 dB (int -1...6) + + // Periodic configuration + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic = CALLOC(1, sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = LTE_CQI_ReportPeriodic_PR_release; /* - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = CQI_ReportPeriodic_PR_setup; - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex = 0; // n2_pucch - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex = 0; // Icqi/pmi + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = CQI_ReportPeriodic_PR_setup; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex = 0; // n2_pucch + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex = 0; // Icqi/pmi physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present = CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI; // subband CQI - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.choice.subbandCQI.k=4; - - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex=NULL; - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI=0; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.choice.subbandCQI.k = 4; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex = NULL; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI = 0; */ //soundingRS-UL-ConfigDedicated - if (rrc->srs_enable[CC_id]==1) { + if (rrc->srs_enable[CC_id] == 1) { physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->present = LTE_SoundingRS_UL_ConfigDedicated_PR_setup; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth = LTE_SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0; @@ -2969,22 +3091,33 @@ do_RRCConnectionSetup( rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.physicalConfigDedicated = physicalConfigDedicated2; rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig = CALLOC(1,sizeof(struct LTE_RadioResourceConfigDedicated__mac_MainConfig)); rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig->present = LTE_RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue; - LTE_MAC_MainConfig_t *mac_MainConfig = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig->choice.explicitValue; + + /* MAC MainConfig */ + mac_MainConfig = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig->choice.explicitValue; + + //* ul_SCH_Config *// mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); long *maxHARQ_Tx = CALLOC(1, sizeof(long)); *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; long *periodicBSR_Timer = CALLOC(1, sizeof(long)); - *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; - mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; // LTE_PeriodicBSR_Timer_r12_infinity + + mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; // max number of UL HARQ transmission mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf5120 // regular BSR timer mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + + //* timeAlignmentTimerDedicated *// mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; + + //* DRX Config *// mac_MainConfig->drx_Config = NULL; + + //* PHR Config *// mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup; - mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_infinity + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000 mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { @@ -3005,11 +3138,7 @@ do_RRCConnectionSetup( LOG_D(RRC,"RRCConnectionSetup Encoded %zd bits (%zd bytes) \n", enc_rval.encoded,(enc_rval.encoded+7)/8); - // FREEMEM(SRB_list); - // free(SRB1_config); - // free(SRB1_rlc_config); - // free(SRB1_lchan_config); - // free(SRB1_ul_SpecificParameters); + return((enc_rval.encoded+7)/8); } @@ -3385,6 +3514,27 @@ uint8_t do_RRCConnectionSetup_BR( physicalConfigDedicated2->ext7->csi_RS_ConfigNZPToReleaseListExt_r13 = NULL; + rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig = CALLOC(1,sizeof(struct LTE_RadioResourceConfigDedicated__mac_MainConfig)); + rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig->present = LTE_RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue; + LTE_MAC_MainConfig_t *mac_MainConfig = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig->choice.explicitValue; + mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); + //long *maxHARQ_Tx = CALLOC(1, sizeof(long)); + //*maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + long *periodicBSR_Timer = CALLOC(1, sizeof(long)); + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; + //mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; + mac_MainConfig->drx_Config = NULL; + mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); + mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB + + rrcConnectionSetup->rrc_TransactionIdentifier = Transaction_id; rrcConnectionSetup->criticalExtensions.present = LTE_RRCConnectionSetup__criticalExtensions_PR_c1; rrcConnectionSetup->criticalExtensions.choice.c1.present =LTE_RRCConnectionSetup__criticalExtensions__c1_PR_rrcConnectionSetup_r8 ; @@ -3393,7 +3543,7 @@ uint8_t do_RRCConnectionSetup_BR( rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.drb_ToReleaseList = NULL; rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.sps_Config = NULL; rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.physicalConfigDedicated = physicalConfigDedicated2; - rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig = NULL; + // rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig = NULL; #ifdef XER_PRINT xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg); @@ -3703,9 +3853,12 @@ uint16_t do_RRCConnectionReconfiguration_BR(const protocol_ctxt_t* const #endif //------------------------------------------------------------------------------ -uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, - uint8_t *buffer, - uint8_t Transaction_id, +/* + * Copy the different Information Elements in the RRC structure + */ +uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, LTE_SRB_ToAddModList_t *SRB_list, LTE_DRB_ToAddModList_t *DRB_list, LTE_DRB_ToReleaseList_t *DRB_list2, @@ -3718,6 +3871,7 @@ uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctx LTE_MAC_MainConfig_t *mac_MainConfig, LTE_MeasGapConfig_t *measGapConfig, LTE_MobilityControlInfo_t *mobilityInfo, + LTE_SecurityConfigHO_t *securityConfigHO, struct LTE_MeasConfig__speedStatePars *speedStatePars, LTE_RSRP_Range_t *rsrp, LTE_C_RNTI_t *cba_rnti, @@ -3726,7 +3880,7 @@ uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctx LTE_SL_CommConfig_r12_t *sl_CommConfig, LTE_SL_DiscConfig_r12_t *sl_DiscConfig #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , LTE_SCellToAddMod_r10_t *SCell_config + , LTE_SCellToAddMod_r10_t *SCell_config #endif ) //------------------------------------------------------------------------------ @@ -3738,7 +3892,8 @@ uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctx dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration; rrcConnectionReconfiguration = &dl_dcch_msg.message.choice.c1.choice.rrcConnectionReconfiguration; - // RRCConnectionReconfiguration + + /* RRC Connection Reconfiguration */ rrcConnectionReconfiguration->rrc_TransactionIdentifier = Transaction_id; rrcConnectionReconfiguration->criticalExtensions.present = LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1; rrcConnectionReconfiguration->criticalExtensions.choice.c1.present = LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8 ; @@ -3808,8 +3963,16 @@ uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctx rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo = NULL; } + if (securityConfigHO != NULL) { + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.securityConfigHO = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.securityConfigHO)); + memcpy((void*)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.securityConfigHO, (void*)securityConfigHO, + sizeof(LTE_SecurityConfigHO_t)); + } else { + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.securityConfigHO = NULL; + } + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.dedicatedInfoNASList = dedicatedInfoNASList; - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.securityConfigHO = NULL; //TTN for D2D //allocate dedicated resource pools for SL communication (sl_CommConfig_r12) @@ -4017,7 +4180,6 @@ do_RRCConnectionReestablishment( rrc->carrier[CC_id].dl_CarrierFreq, earfcn_dl, is_rel8_only == true ? "true": "false"); -#if defined(ENABLE_SECURITY) if (ue_context_pP->ue_context.nh_ncc >= 0) { derive_keNB_star(ue_context_pP->ue_context.nh, pci, earfcn_dl, is_rel8_only, KeNB_star); @@ -4031,9 +4193,6 @@ do_RRCConnectionReestablishment( // copy KeNB_star to ue_context_pP->ue_context.kenb memcpy (ue_context_pP->ue_context.kenb, KeNB_star, 32); ue_context_pP->ue_context.kenb_ncc = 0; -#else - rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nextHopChainingCount = 0; -#endif rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nonCriticalExtension = NULL; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { @@ -4481,6 +4640,88 @@ uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t return encoded; } +int do_HandoverPreparation(char *ho_buf, int ho_size, LTE_UE_EUTRA_Capability_t *ue_eutra_cap, int rrc_size) +{ + asn_enc_rval_t enc_rval; + LTE_HandoverPreparationInformation_t ho; + LTE_HandoverPreparationInformation_r8_IEs_t *ho_info; + LTE_UE_CapabilityRAT_Container_t *ue_cap_rat_container; + + char rrc_buf[rrc_size]; + + memset(rrc_buf, 0, rrc_size); + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UE_EUTRA_Capability, + NULL, + ue_eutra_cap, + rrc_buf, + rrc_size); + + /* TODO: free the OCTET_STRING */ + + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + + memset(&ho, 0, sizeof(ho)); + + ho.criticalExtensions.present = LTE_HandoverPreparationInformation__criticalExtensions_PR_c1; + ho.criticalExtensions.choice.c1.present = LTE_HandoverPreparationInformation__criticalExtensions__c1_PR_handoverPreparationInformation_r8; + + ho_info = &ho.criticalExtensions.choice.c1.choice.handoverPreparationInformation_r8; + { + ue_cap_rat_container = (LTE_UE_CapabilityRAT_Container_t *)calloc(1,sizeof(LTE_UE_CapabilityRAT_Container_t)); + ue_cap_rat_container->rat_Type = LTE_RAT_Type_eutra; + + AssertFatal (OCTET_STRING_fromBuf( + &ue_cap_rat_container->ueCapabilityRAT_Container, + rrc_buf, rrc_size) != -1, "fatal: OCTET_STRING_fromBuf failed\n"); + + ASN_SEQUENCE_ADD(&ho_info->ue_RadioAccessCapabilityInfo.list, ue_cap_rat_container); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_HandoverPreparationInformation, + NULL, + &ho, + ho_buf, + ho_size); + + /* TODO: free the OCTET_STRING */ + + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + return((enc_rval.encoded+7)/8); +} + +int do_HandoverCommand(char *ho_buf, int ho_size, char *rrc_buf, int rrc_size) +{ + asn_enc_rval_t enc_rval; + LTE_HandoverCommand_t ho; + + memset(&ho, 0, sizeof(ho)); + + ho.criticalExtensions.present = LTE_HandoverCommand__criticalExtensions_PR_c1; + ho.criticalExtensions.choice.c1.present = LTE_HandoverCommand__criticalExtensions__c1_PR_handoverCommand_r8; + + AssertFatal (OCTET_STRING_fromBuf( + &ho.criticalExtensions.choice.c1.choice.handoverCommand_r8.handoverCommandMessage, + rrc_buf, rrc_size) != -1, "fatal: OCTET_STRING_fromBuf failed\n"); + + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_HandoverCommand, + NULL, + &ho, + ho_buf, + ho_size); + + /* TODO: free the OCTET_STRING */ + + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + return((enc_rval.encoded+7)/8); +} + OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) { static OAI_UECapability_t UECapability; /* TODO declared static to allow returning this has an address should be allocated in a cleaner way. */ static LTE_SupportedBandEUTRA_t Bandlist[4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 338f868c5794e818e722d88e1c5e04e6c485ead0..f8dd7f10fdeb16c902ee6f9ef5a93419344e49de 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -71,6 +71,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich ); /** +<<<<<<< HEAD \brief Generate configuration for MIB (eNB). @param carrier pointer to Carrier information @param N_RB_DL Number of downlink PRBs @@ -78,6 +79,14 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich @param frame radio frame number @return size of encoded bit stream in bytes*/ uint8_t do_MIB_MBMS(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t additionalNonMBSFNSubframes, uint32_t frame); +/** +\brief Generate configuration structure for DRX_Config +@param Mod_id Instance of eNB +@param CC_id Id of component to configure +@param configuration Pointer Configuration Request structure +@param UEcap Pointer Configuration UE capablities +@return DRX_Config structure pointer or NULL => error */ +LTE_DRX_Config_t *do_DrxConfig(uint8_t Mod_id, int CC_id, RrcConfigurationReq *configuration, LTE_UE_EUTRA_Capability_t *UEcap); /** \brief Generate configuration for SIB1 (eNB). @@ -267,6 +276,7 @@ do_RRCConnectionReconfiguration( LTE_MAC_MainConfig_t *mac_MainConfig, LTE_MeasGapConfig_t *measGapConfig, LTE_MobilityControlInfo_t *mobilityInfo, + LTE_SecurityConfigHO_t *securityConfigHO, struct LTE_MeasConfig__speedStatePars *speedStatePars, LTE_RSRP_Range_t *rsrp, LTE_C_RNTI_t *cba_rnti, @@ -357,6 +367,10 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer); +int do_HandoverPreparation(char *ho_buf, int ho_size, LTE_UE_EUTRA_Capability_t *ue_eutra_cap, int rrc_size); + +int do_HandoverCommand(char *ho_buf, int ho_size, char *rrc_buf, int rrc_size); + OAI_UECapability_t *fill_ue_capability(char *LTE_UE_EUTRA_Capability_xer); uint8_t diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h index 160d92a610888b1c0e194c3e1d62db6109084e85..26eca6d781fd246814f65eaa3a8189b530c07595 100644 --- a/openair2/RRC/LTE/defs_NB_IoT.h +++ b/openair2/RRC/LTE/defs_NB_IoT.h @@ -63,24 +63,12 @@ #include "LTE_UE-Capability-NB-r13.h" //equivalent of UE-EUTRA-Capability.h //------------------- -#if defined(ENABLE_ITTI) # include "intertask_interface.h" -#endif - -/* TODO: be sure this include is correct. - * It solves a problem of compilation of the RRH GW, - * issue #186. - */ -#if !defined(ENABLE_ITTI) -# include "as_message.h" -#endif - -#if defined(ENABLE_USE_MME) # include "commonDef.h" -#endif + #if ENABLE_RAL -# include "collection/hashtable/obj_hashtable.h" + #include "collection/hashtable/obj_hashtable.h" #endif @@ -104,12 +92,12 @@ typedef struct uid_linear_allocator_NB_IoT_s { //left as they are --> used in LAYER2/epenair2_proc.c and UE side typedef enum UE_STATE_NB_IoT_e { - RRC_INACTIVE_NB_IoT=0, - RRC_IDLE_NB_IoT, - RRC_SI_RECEIVED_NB_IoT, - RRC_CONNECTED_NB_IoT, - RRC_RECONFIGURED_NB_IoT, - RRC_HO_EXECUTION_NB_IoT //maybe not needed? + RRC_INACTIVE_NB_IoT=0, + RRC_IDLE_NB_IoT, + RRC_SI_RECEIVED_NB_IoT, + RRC_CONNECTED_NB_IoT, + RRC_RECONFIGURED_NB_IoT, + RRC_HO_EXECUTION_NB_IoT //maybe not needed? } UE_STATE_NB_IoT_t; @@ -250,20 +238,20 @@ typedef struct eNB_RRC_UE_NB_IoT_s { * * SRB_configList --> is used for the actual list of SRBs that is managed/that should be send over the RRC message * SRB_configList2--> refers to all the SRBs configured for that specific transaction identifier - * this because in a single transaction one or more SRBs could be established - * and you want to keep memory on what happen for every transaction + * this because in a single transaction one or more SRBs could be established + * and you want to keep memory on what happen for every transaction * Transaction ID (xid): is used to associate the proper RRC....Complete message received by the UE to the corresponding - * message previously sent by the eNB (e.g. RRCConnectionSetup -- RRCConnectionSetupComplete) - * this because it could happen that more messages are transmitted at the same time + * message previously sent by the eNB (e.g. RRCConnectionSetup -- RRCConnectionSetupComplete) + * this because it could happen that more messages are transmitted at the same time */ - LTE_SRB_ToAddModList_NB_r13_t* SRB_configList;//for SRB1 and SRB1bis - LTE_SRB_ToAddModList_NB_r13_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; - LTE_DRB_ToAddModList_NB_r13_t* DRB_configList; //for all the DRBs - LTE_DRB_ToAddModList_NB_r13_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; //for the configured DRBs of a xid - uint8_t DRB_active[2];//in LTE was 8 --> at most 2 for NB-IoT + LTE_SRB_ToAddModList_NB_r13_t *SRB_configList;//for SRB1 and SRB1bis + LTE_SRB_ToAddModList_NB_r13_t *SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + LTE_DRB_ToAddModList_NB_r13_t *DRB_configList; //for all the DRBs + LTE_DRB_ToAddModList_NB_r13_t *DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; //for the configured DRBs of a xid + uint8_t DRB_active[2];//in LTE was 8 --> at most 2 for NB-IoT - struct LTE_PhysicalConfigDedicated_NB_r13* physicalConfigDedicated_NB_IoT; - LTE_MAC_MainConfig_NB_r13_t* mac_MainConfig_NB_IoT; + struct LTE_PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated_NB_IoT; + LTE_MAC_MainConfig_NB_r13_t *mac_MainConfig_NB_IoT; //No SPS(semi-persistent scheduling) in NB-IoT //No Measurement report in NB-IoT @@ -273,10 +261,8 @@ typedef struct eNB_RRC_UE_NB_IoT_s { SRB_INFO_TABLE_ENTRY_NB_IoT Srb1; SRB_INFO_TABLE_ENTRY_NB_IoT Srb1bis; -#if defined(ENABLE_SECURITY) /* KeNB as derived from KASME received from EPC */ uint8_t kenb[32]; -#endif /* Used integrity/ciphering algorithms--> maintained the same for NB-IoT */ e_LTE_CipheringAlgorithm_r12 ciphering_algorithm; //Specs. TS 36.331 V14.1.0 pag 432 Change position of chipering enumerative w.r.t previous version @@ -315,7 +301,7 @@ typedef struct eNB_RRC_UE_NB_IoT_s { transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; - //Which timers are referring to? + //Which timers are referring to? uint32_t ul_failure_timer; uint32_t ue_release_timer; //threshold of the release timer--> set in RRCConnectionRelease @@ -352,13 +338,13 @@ typedef struct rrc_eNB_ue_context_NB_IoT_s { typedef struct { // buffer that contains the encoded messages - uint8_t *MIB_NB_IoT; - uint8_t sizeof_MIB_NB_IoT; + uint8_t *MIB_NB_IoT; + uint8_t sizeof_MIB_NB_IoT; uint8_t *SIB1_NB_IoT; uint8_t sizeof_SIB1_NB_IoT; - uint8_t *SIB23_NB_IoT; - uint8_t sizeof_SIB23_NB_IoT; + uint8_t *SIB23_NB_IoT; + uint8_t sizeof_SIB23_NB_IoT; //not actually implemented in OAI @@ -372,18 +358,18 @@ typedef struct { uint8_t sizeof_SIB16_NB_IoT; //TS 36.331 V14.2.1 -// uint8_t *SIB15_NB; -// uint8_t sizeof_SIB15_NB; -// uint8_t *SIB20_NB; -// uint8_t sizeof_SIB20_NB; -// uint8_t *SIB22_NB; -// uint8_t sizeof_SIB22_NB; + // uint8_t *SIB15_NB; + // uint8_t sizeof_SIB15_NB; + // uint8_t *SIB20_NB; + // uint8_t sizeof_SIB20_NB; + // uint8_t *SIB22_NB; + // uint8_t sizeof_SIB22_NB; //implicit parameters needed int Ncp; //cyclic prefix for DL - int Ncp_UL; //cyclic prefix for UL + int Ncp_UL; //cyclic prefix for UL int p_eNB; //number of tx antenna port - int p_rx_eNB; //number of receiving antenna ports + int p_rx_eNB; //number of receiving antenna ports uint32_t dl_CarrierFreq; //detected by the UE uint32_t ul_CarrierFreq; //detected by the UE uint16_t physCellId; //not stored in the MIB-NB but is getting through NPSS/NSSS @@ -393,12 +379,12 @@ typedef struct { LTE_BCCH_DL_SCH_Message_NB_t siblock1_NB_IoT; //SIB1-NB LTE_BCCH_DL_SCH_Message_NB_t systemInformation_NB_IoT; //SI - LTE_SystemInformationBlockType1_NB_t *sib1_NB_IoT; - LTE_SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; - LTE_SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + LTE_SystemInformationBlockType1_NB_t *sib1_NB_IoT; + LTE_SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + LTE_SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; //not implemented yet - LTE_SystemInformationBlockType4_NB_r13_t *sib4_NB_IoT; - LTE_SystemInformationBlockType5_NB_r13_t *sib5_NB_IoT; + LTE_SystemInformationBlockType4_NB_r13_t *sib4_NB_IoT; + LTE_SystemInformationBlockType5_NB_r13_t *sib5_NB_IoT; LTE_SystemInformationBlockType14_NB_r13_t *sib14_NB_IoT; LTE_SystemInformationBlockType16_NB_r13_t *sib16_NB_IoT; @@ -414,9 +400,9 @@ typedef struct { SystemInformationBlockType20_NB_r14_t *sib20; SystemInformationBlockType22_NB_r14_t *sib22; - uint8_t SCPTM_flag; - uint8_t sizeof_SC_MCHH_MESS[]; - SC_MCCH_Message_NB_t scptm;*/ + uint8_t SCPTM_flag; + uint8_t sizeof_SC_MCHH_MESS[]; + SC_MCCH_Message_NB_t scptm;*/ } rrc_eNB_carrier_data_NB_IoT_t; @@ -463,9 +449,9 @@ typedef struct eNB_RRC_INST_NB_IoT_s { //not needed for the moment typedef struct OAI_UECapability_NB_IoT_s { - uint8_t sdu[MAX_UE_CAPABILITY_SIZE_NB_IoT]; - uint8_t sdu_size; -////NB-IoT------ + uint8_t sdu[MAX_UE_CAPABILITY_SIZE_NB_IoT]; + uint8_t sdu_size; + ////NB-IoT------ LTE_UE_Capability_NB_r13_t UE_Capability_NB_IoT; //replace the UE_EUTRA_Capability of LTE } OAI_UECapability_NB_IoT_t; @@ -476,17 +462,15 @@ typedef struct OAI_UECapability_NB_IoT_s { typedef struct UE_RRC_INST_NB_IoT_s { Rrc_State_NB_IoT_t RrcState; Rrc_Sub_State_NB_IoT_t RrcSubState; -# if defined(ENABLE_USE_MME) plmn_t plmnID; Byte_t rat; as_nas_info_t initialNasMsg; -# endif OAI_UECapability_NB_IoT_t *UECap; uint8_t *UECapability; uint8_t UECapability_size; UE_RRC_INFO_NB_IoT Info[NB_SIG_CNX_UE]; - + SRB_INFO_NB_IoT Srb0[NB_SIG_CNX_UE]; SRB_INFO_TABLE_ENTRY_NB_IoT Srb1[NB_CNX_UE]; SRB_INFO_TABLE_ENTRY_NB_IoT Srb2[NB_CNX_UE]; @@ -513,7 +497,7 @@ typedef struct UE_RRC_INST_NB_IoT_s { SystemInformationBlockType10_t *sib10[NB_CNX_UE]; SystemInformationBlockType11_t *sib11[NB_CNX_UE]; -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t MBMS_flag; uint8_t *MCCH_MESSAGE[NB_CNX_UE]; uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE]; @@ -521,11 +505,11 @@ typedef struct UE_RRC_INST_NB_IoT_s { MBSFNAreaConfiguration_r9_t *mcch_message[NB_CNX_UE]; SystemInformationBlockType12_r9_t *sib12[NB_CNX_UE]; SystemInformationBlockType13_r9_t *sib13[NB_CNX_UE]; -#endif -#ifdef CBA + #endif + #ifdef CBA uint8_t num_active_cba_groups; uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; -#endif + #endif uint8_t num_srb; struct SRB_ToAddMod *SRB1_config[NB_CNX_UE]; struct SRB_ToAddMod *SRB2_config[NB_CNX_UE]; @@ -551,14 +535,14 @@ typedef struct UE_RRC_INST_NB_IoT_s { float rsrq_db[7]; float rsrp_db_filtered[7]; float rsrq_db_filtered[7]; -#if ENABLE_RAL + #if ENABLE_RAL obj_hash_table_t *ral_meas_thresholds; ral_transaction_id_t scan_transaction_id; -#endif -#if defined(ENABLE_SECURITY) + #endif + #if defined(ENABLE_SECURITY) // KeNB as computed from parameters within USIM card // uint8_t kenb[32]; -#endif + #endif // Used integrity/ciphering algorithms // CipheringAlgorithm_r12_t ciphering_algorithm; diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 9dddef1ab4ff29ac6bd68fd76e7ded75ed507ed6..a75ce3cdda89c1e36579385a3abd900999f6cc28 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -69,17 +69,14 @@ #include "rrc_UE_ral.h" #endif -#if defined(ENABLE_SECURITY) - #include "UTIL/OSA/osa_defs.h" -#endif +#include "UTIL/OSA/osa_defs.h" #include "pdcp.h" #include "plmn_data.h" #include "msc.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" + #include "SIMULATION/TOOLS/sim.h" // for taus @@ -158,9 +155,9 @@ static uint8_t check_trigger_meas_event( LTE_Q_OffsetRange_t ofs, LTE_Q_OffsetRange_t ocs, long a3_offset, LTE_TimeToTrigger_t ttt); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area); -uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, - SL_TRIGGER_t mode); + static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area); + uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index,LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, + SL_TRIGGER_t mode); #endif @@ -171,12 +168,11 @@ uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t *const ctxt /*------------------------------------------------------------------------------*/ -/* to avoid gcc warnings when compiling with certain options */ -#if defined(ENABLE_USE_MME) || ENABLE_RAL + static Rrc_State_t rrc_get_state (module_id_t ue_mod_idP) { return UE_rrc_inst[ue_mod_idP].RrcState; } -#endif + static Rrc_Sub_State_t rrc_get_sub_state (module_id_t ue_mod_idP) { return UE_rrc_inst[ue_mod_idP].RrcSubState; @@ -196,27 +192,25 @@ static int rrc_set_state (module_id_t ue_mod_idP, Rrc_State_t state) { //----------------------------------------------------------------------------- static int rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_t subState ) { -#if (defined(ENABLE_ITTI) && (defined(ENABLE_USE_MME) || ENABLE_RAL)) - - switch (UE_rrc_inst[ue_mod_idP].RrcState) { - case RRC_STATE_INACTIVE: - AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST), - "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState); - break; + if (EPC_MODE_ENABLED) { + switch (UE_rrc_inst[ue_mod_idP].RrcState) { + case RRC_STATE_INACTIVE: + AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST), + "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState); + break; - case RRC_STATE_IDLE: - AssertFatal ((RRC_SUB_STATE_IDLE_FIRST <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST), - "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState); - break; + case RRC_STATE_IDLE: + AssertFatal ((RRC_SUB_STATE_IDLE_FIRST <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST), + "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState); + break; - case RRC_STATE_CONNECTED: - AssertFatal ((RRC_SUB_STATE_CONNECTED_FIRST <= subState) && (subState <= RRC_SUB_STATE_CONNECTED_LAST), - "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState); - break; + case RRC_STATE_CONNECTED: + AssertFatal ((RRC_SUB_STATE_CONNECTED_FIRST <= subState) && (subState <= RRC_SUB_STATE_CONNECTED_LAST), + "Invalid sub state %d for state %d!\n", subState, UE_rrc_inst[ue_mod_idP].RrcState); + break; + } } -#endif - if (UE_rrc_inst[ue_mod_idP].RrcSubState != subState) { UE_rrc_inst[ue_mod_idP].RrcSubState = subState; return (1); @@ -248,7 +242,7 @@ openair_rrc_on_ue( } //----------------------------------------------------------------------------- -static void init_SI_UE( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { +static void init_SI_UE( protocol_ctxt_t const *ctxt_pP, const uint8_t eNB_index ) { UE_rrc_inst[ctxt_pP->module_id].sizeof_SIB1[eNB_index] = 0; UE_rrc_inst[ctxt_pP->module_id].sizeof_SI[eNB_index] = 0; UE_rrc_inst[ctxt_pP->module_id].SIB1[eNB_index] = (uint8_t *)malloc16_clear( 32 ); @@ -455,7 +449,6 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) { //----------------------------------------------------------------------------- void openair_rrc_ue_init_security( const protocol_ctxt_t *const ctxt_pP ) { -#if defined(ENABLE_SECURITY) // uint8_t *kRRCenc; // uint8_t *kRRCint; char ascii_buffer[65]; @@ -469,7 +462,6 @@ void openair_rrc_ue_init_security( const protocol_ctxt_t *const ctxt_pP ) { LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT"[OSA] kenb = %s\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), ascii_buffer); -#endif } //----------------------------------------------------------------------------- @@ -561,9 +553,9 @@ void rrc_ue_generate_RRCConnectionRequest( const protocol_ctxt_t *const ctxt_pP, mui_t rrc_mui=0; -#if !(defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)) + /* NAS Attach request with IMSI */ -static const char const nas_attach_req_imsi[] = { +static const char nas_attach_req_imsi[] = { 0x07, 0x41, /* EPS Mobile identity = IMSI */ 0x71, 0x08, 0x29, 0x80, 0x43, 0x21, 0x43, 0x65, 0x87, @@ -575,7 +567,7 @@ static const char const nas_attach_req_imsi[] = { 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2, 0x01, 0x27, 0x11, }; -#endif /* !(defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)) */ + //----------------------------------------------------------------------------- void @@ -623,13 +615,15 @@ static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t *c uint8_t size; const char *nas_msg; int nas_msg_length; -#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME) - nas_msg = (char *) UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data; - nas_msg_length = UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length; -#else - nas_msg = nas_attach_req_imsi; - nas_msg_length = sizeof(nas_attach_req_imsi); -#endif + + if (EPC_MODE_ENABLED) { + nas_msg = (char *) UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data; + nas_msg_length = UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length; + } else { + nas_msg = nas_attach_req_imsi; + nas_msg_length = sizeof(nas_attach_req_imsi); + } + size = do_RRCConnectionSetupComplete(ctxt_pP->module_id, buffer, Transaction_id, nas_msg_length, nas_msg); LOG_I(RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (bytes%d, eNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index); @@ -827,50 +821,40 @@ rrc_ue_establish_drb( //----------------------------------------------------------------------------- { // add descriptor from RRC PDU -#ifdef PDCP_USE_NETLINK int oip_ifup=0,ip_addr_offset3=0,ip_addr_offset4=0; /* avoid gcc warnings */ (void)oip_ifup; (void)ip_addr_offset3; (void)ip_addr_offset4; -#endif LOG_I(RRC,"[UE %d] Frame %d: processing RRCConnectionReconfiguration: reconfiguring DRB %ld/LCID %d\n", ue_mod_idP, frameP, DRB_config->drb_Identity, (int)*DRB_config->logicalChannelIdentity); - /* - rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD, - (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, UNDEF_SECURITY_MODE); - rrc_rlc_config_req(ue_mod_idP+NB_eNB_INST,frameP,0,CONFIG_ACTION_ADD, - (eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, - RADIO_ACCESS_BEARER,Rlc_info_um); - */ -#ifdef PDCP_USE_NETLINK -# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U) - ip_addr_offset3 = 0; - ip_addr_offset4 = 1; - LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oai%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, - ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1); - oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP, // interface_id - ip_addr_offset3+ue_mod_idP+1, // third_octet - ip_addr_offset4+ue_mod_idP+1); // fourth_octet - - if (oip_ifup == 0 ) { // interface is up --> send a config the DRB - LOG_I(OIP,"[UE %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", - ue_mod_idP, - ip_addr_offset3+ue_mod_idP, - (long int)((eNB_index * maxDRB) + DRB_config->drb_Identity)); - rb_conf_ipv4(0,//add - ue_mod_idP,//cx align with the UE index - ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index - (eNB_index * maxDRB) + DRB_config->drb_Identity,//rb - 0,//dscp - ipv4_address(ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1),//saddr - ipv4_address(ip_addr_offset3+ue_mod_idP+1,eNB_index+1));//daddr - LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index); - } + if(!EPC_MODE_ENABLED) { + ip_addr_offset3 = 0; + ip_addr_offset4 = 1; + LOG_I(OIP,"[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, + ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1); + oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id + UE_NAS_USE_TUN?1:(ip_addr_offset3+ue_mod_idP+1), // third_octet + ip_addr_offset4+ue_mod_idP+1, // fourth_octet + "oip"); // interface suffix (when using kernel module) + + if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB + LOG_I(OIP,"[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n", + ue_mod_idP, + ip_addr_offset3+ue_mod_idP, + (long int)((eNB_index * LTE_maxDRB) + DRB_config->drb_Identity)); + rb_conf_ipv4(0,//add + ue_mod_idP,//cx align with the UE index + ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index + (eNB_index * LTE_maxDRB) + DRB_config->drb_Identity,//rb + 0,//dscp + ipv4_address(ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1),//saddr + ipv4_address(ip_addr_offset3+ue_mod_idP+1,eNB_index+1));//daddr + LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index); + } + } // !EPC_MODE_ENABLED -# endif -#endif return(0); } @@ -1342,12 +1326,10 @@ rrc_ue_process_radioResourceConfigDedicated( if (radioResourceConfigDedicated->srb_ToAddModList) { uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; -#if defined(ENABLE_SECURITY) derive_key_rrc_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCenc); derive_key_rrc_int(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCint); -#endif // Refresh SRBs rrc_pdcp_config_asn1_req(ctxt_pP, radioResourceConfigDedicated->srb_ToAddModList, @@ -1534,10 +1516,8 @@ rrc_ue_process_radioResourceConfigDedicated( } uint8_t *kUPenc = NULL; -#if defined(ENABLE_SECURITY) derive_key_up_enc(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, &kUPenc); -#endif MSC_LOG_TX_MESSAGE( MSC_RRC_UE, MSC_PDCP_UE, @@ -1719,7 +1699,6 @@ rrc_ue_process_securityModeCommand( ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure; } -#if defined(ENABLE_SECURITY) uint8_t *kRRCenc = NULL; uint8_t *kUPenc = NULL; uint8_t *kRRCint = NULL; @@ -1769,8 +1748,6 @@ rrc_ue_process_securityModeCommand( LOG_I(RRC, "Could not get PDCP instance where key=0x%ld\n", key); } -#endif //#if defined(ENABLE_SECURITY) - if (securityModeCommand->criticalExtensions.present == LTE_SecurityModeCommand__criticalExtensions_PR_c1) { if (securityModeCommand->criticalExtensions.choice.c1.present != LTE_SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8) LOG_W(RRC,"securityModeCommand->criticalExtensions.choice.c1.present (%d) != SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8\n", @@ -1960,7 +1937,6 @@ rrc_ue_process_rrcConnectionReconfiguration( ); } */ -#if defined(ENABLE_ITTI) /* Check if there is dedicated NAS information to forward to NAS */ if (rrcConnectionReconfiguration_r8->dedicatedInfoNASList != NULL) { @@ -1998,7 +1974,7 @@ rrc_ue_process_rrcConnectionReconfiguration( for (i=0; ( i<rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count) - && (i < maxDRB); i++) { + && (i < LTE_maxDRB); i++) { // why minus 1 in RRC code for drb_identity ? connection_reestablishment_ind.drb_id[i] = rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity; @@ -2024,7 +2000,6 @@ rrc_ue_process_rrcConnectionReconfiguration( LOG_I(RRC, "Sending RRC_RAL_CONNECTION_REESTABLISHMENT_IND to mRAL\n"); itti_send_msg_to_task (TASK_RAL_UE, ctxt_pP->instance, message_ral_p); } -#endif #endif } // c1 present } // critical extensions present @@ -2195,9 +2170,7 @@ rrc_ue_decode_dcch( // asn_dec_rval_t dec_rval; // int i; uint8_t target_eNB_index=0xFF; -#if defined(ENABLE_ITTI) MessageDef *msg_p; -#endif if (Srb_id != 1) { LOG_E(RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%d), should not have ...\n", @@ -2227,7 +2200,6 @@ rrc_ue_decode_dcch( break; case LTE_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: { -#if defined(ENABLE_ITTI) LTE_DLInformationTransfer_t *dlInformationTransfer = &dl_dcch_msg->message.choice.c1.choice.dlInformationTransfer; if ((dlInformationTransfer->criticalExtensions.present == LTE_DLInformationTransfer__criticalExtensions_PR_c1) @@ -2250,7 +2222,6 @@ rrc_ue_decode_dcch( itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); } -#endif break; } @@ -2305,7 +2276,6 @@ rrc_ue_decode_dcch( UE_rrc_inst[ctxt_pP->module_id].Info[target_eNB_index].State = RRC_RECONFIGURED; LOG_I(RRC, "[UE %d] State = RRC_RECONFIGURED during HO (eNB %d)\n", ctxt_pP->module_id, target_eNB_index); -#if defined(ENABLE_ITTI) #if ENABLE_RAL { MessageDef *message_ral_p = NULL; @@ -2322,7 +2292,7 @@ rrc_ue_decode_dcch( for (i=0; ( i<dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count) - && (i < maxDRB); i++) { + && (i < LTE_maxDRB); i++) { // why minus 1 in RRC code for drb_identity ? connection_reconfiguration_ho_ind.drb_id[i] = dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity; @@ -2350,7 +2320,6 @@ rrc_ue_decode_dcch( LOG_I(RRC, "Sending RRC_RAL_CONNECTION_RECONFIGURATION_HO_IND to mRAL\n"); itti_send_msg_to_task (TASK_RAL_UE, ctxt_pP->instance, message_ral_p); } -#endif #endif } else { rrc_ue_generate_RRCConnectionReconfigurationComplete( @@ -2361,7 +2330,6 @@ rrc_ue_decode_dcch( LOG_I(RRC, "[UE %d] State = RRC_RECONFIGURED (eNB %d)\n", ctxt_pP->module_id, eNB_indexP); -#if defined(ENABLE_ITTI) #if ENABLE_RAL { MessageDef *message_ral_p = NULL; @@ -2378,7 +2346,7 @@ rrc_ue_decode_dcch( for (i=0; ( i<dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count) - && (i < maxDRB); i++) { + && (i < LTE_maxDRB); i++) { // why minus 1 in RRC code for drb_identity ? connection_reconfiguration_ind.drb_id[i] = dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity; @@ -2406,7 +2374,6 @@ rrc_ue_decode_dcch( LOG_I(RRC, "Sending RRC_RAL_CONNECTION_RECONFIGURATION_IND to mRAL\n"); itti_send_msg_to_task (TASK_RAL_UE, ctxt_pP->instance, message_ral_p); } -#endif #endif } @@ -2430,7 +2397,6 @@ rrc_ue_decode_dcch( break; case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: -#if defined(ENABLE_ITTI) msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_RELEASE_IND); if ((dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.present @@ -2446,7 +2412,6 @@ rrc_ue_decode_dcch( msg_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_CONNECTION_RELEASE_IND); RRC_RAL_CONNECTION_RELEASE_IND(msg_p).ue_id = ctxt_pP->module_id; itti_send_msg_to_task(TASK_RAL_UE, ctxt_pP->instance, msg_p); -#endif #endif break; @@ -2889,13 +2854,11 @@ int decode_BCCH_DLSCH_Message( } } - if ((rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) -#if defined(ENABLE_USE_MME) - && (UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) -#endif - ) { - rrc_ue_generate_RRCConnectionRequest(ctxt_pP, 0); - rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING ); + if (rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE) { + if ( (UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) || (!EPC_MODE_ENABLED)) { + rrc_ue_generate_RRCConnectionRequest(ctxt_pP, 0); + rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING ); + } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); @@ -3137,7 +3100,7 @@ int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_in cell_valid = 1; break; } - } + } } if (cell_valid == 0) { @@ -4301,8 +4264,7 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { #endif LOG_D( RRC, "[UE] (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count %d\n", (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count ); - } - else { + } else { LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel8)\n" ); return -1; } @@ -4367,10 +4329,9 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { if (UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option #endif -#if !(defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)) - rrc_ue_generate_RRCConnectionRequest( ctxt_pP, eNB_index ); - -#endif + if (EPC_MODE_ENABLED) { + rrc_ue_generate_RRCConnectionRequest( ctxt_pP, eNB_index ); + } if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_IDLE) { LOG_I( RRC, "[UE %d] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED\n", ctxt_pP->module_id ); @@ -4640,7 +4601,7 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { sib1->schedulingInfoList.list.count); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI , VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT); return 0; } @@ -4908,7 +4869,7 @@ uint8_t check_trigger_meas_event( uint8_t eNB_offset; // uint8_t currentCellIndex = frame_parms->Nid_cell; uint8_t tmp_offset; - LOG_I(RRC,"[UE %d] ofn(%ld) ocn(%ld) hys(%ld) ofs(%ld) ocs(%ld) a3_offset(%ld) ttt(%ld) rssi %3.1f\n", + LOG_D(RRC,"[UE %d] ofn(%ld) ocn(%ld) hys(%ld) ofs(%ld) ocs(%ld) a3_offset(%ld) ttt(%ld) rssi %3.1f\n", ue_mod_idP, ofn,ocn,hys,ofs,ocs,a3_offset,ttt, 10*log10(get_RSSI(ue_mod_idP,0))-get_rx_total_gain_dB(ue_mod_idP,0)); @@ -5111,7 +5072,6 @@ void decode_MBSFNAreaConfiguration( module_id_t ue_mod_idP, uint8_t eNB_index, f #endif // rel10 -#if defined(ENABLE_ITTI) //----------------------------------------------------------------------------- void *rrc_ue_task( void *args_p ) { MessageDef *msg_p; @@ -5135,6 +5095,7 @@ void *rrc_ue_task( void *args_p ) { break; case MESSAGE_TEST: + LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); break; /* MAC messages */ @@ -5255,7 +5216,6 @@ void *rrc_ue_task( void *args_p ) { result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_IND (msg_p).sdu_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); break; -# if defined(ENABLE_USE_MME) case NAS_KENB_REFRESH_REQ: memcpy((void *)UE_rrc_inst[ue_mod_id].kenb, (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(UE_rrc_inst[ue_mod_id].kenb)); @@ -5406,7 +5366,6 @@ void *rrc_ue_task( void *args_p ) { break; } -# endif # if ENABLE_RAL case RRC_RAL_SCAN_REQ: @@ -5558,7 +5517,7 @@ void *rrc_ue_task( void *args_p ) { msg_p = NULL; } } -#endif + @@ -5864,7 +5823,7 @@ rrc_control_socket_init() { // error("ERROR: Failed on opening socket"); optval = 1; setsockopt(ctrl_sock_fd, SOL_SOCKET, SO_REUSEADDR, - (const void *)&optval , sizeof(int)); + (const void *)&optval, sizeof(int)); //build the server's address bzero((char *) &rrc_ctrl_socket_addr, sizeof(rrc_ctrl_socket_addr)); rrc_ctrl_socket_addr.sin_family = AF_INET; diff --git a/openair2/RRC/LTE/rrc_UE_ral.c b/openair2/RRC/LTE/rrc_UE_ral.c index c972d280d5a577982ed8891c348b8cf588da2ab9..d7ace8c242c4e88c6a59588786fc9a4339d6c908 100644 --- a/openair2/RRC/LTE/rrc_UE_ral.c +++ b/openair2/RRC/LTE/rrc_UE_ral.c @@ -46,8 +46,7 @@ int rrc_ue_ral_delete_all_thresholds_type(unsigned int mod_idP, ral_link_param_t rrc_ral_threshold_key_t *keys = NULL; unsigned int num_keys = 0; int return_code = 0; - - rc = obj_hashtable_get_keys(UE_rrc_inst[mod_idP].ral_meas_thresholds, (void*)&keys, &num_keys); + rc = obj_hashtable_get_keys(UE_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&keys, &num_keys); if (rc == HASH_TABLE_OK) { key = keys; @@ -82,10 +81,9 @@ int rrc_ue_ral_delete_threshold(unsigned int mod_idP, ral_link_param_type_t *par { hashtable_rc_t rc; rrc_ral_threshold_key_t ref_key; - memcpy(&ref_key.link_param_type, param_type_pP, sizeof(ral_link_param_type_t)); memcpy(&ref_key.threshold, threshold_pP, sizeof(ral_threshold_t)); - rc = obj_hashtable_remove (UE_rrc_inst[mod_idP].ral_meas_thresholds, (void*)&ref_key, sizeof(rrc_ral_threshold_key_t)); + rc = obj_hashtable_remove (UE_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&ref_key, sizeof(rrc_ral_threshold_key_t)); if (rc == HASH_TABLE_OK) { return 0; @@ -106,135 +104,131 @@ int rrc_ue_ral_handle_configure_threshold_request(unsigned int mod_idP, MessageD MessageDef *message_p = NULL; unsigned int ix_param = 0; unsigned int ix_thresholds = 0; - DevAssert(msg_pP != NULL); - LOG_I(RRC, "[UE %d] Received %s\n", mod_idP, ITTI_MSG_NAME (msg_pP)); configure_threshold_req_p = &RRC_RAL_CONFIGURE_THRESHOLD_REQ(msg_pP); - transaction_id = configure_threshold_req_p->transaction_id; for (ix_param = 0; ix_param < configure_threshold_req_p->num_link_cfg_params; ix_param++) { link_cfg_param_p = &configure_threshold_req_p->link_cfg_params[ix_param]; switch (link_cfg_param_p->th_action) { - case RAL_TH_ACTION_SET_NORMAL_THRESHOLD: - case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD: - switch (link_cfg_param_p->link_param_type.choice) { - - case RAL_LINK_PARAM_TYPE_CHOICE_GEN: - switch (link_cfg_param_p->link_param_type._union.link_param_gen) { - case RAL_LINK_PARAM_GEN_DATA_RATE: - case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH: - case RAL_LINK_PARAM_GEN_SINR: - case RAL_LINK_PARAM_GEN_THROUGHPUT: - case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE: - message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; - - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_gen %d\n", link_cfg_param_p->link_param_type._union.link_param_gen); - return -1; - } + case RAL_TH_ACTION_SET_NORMAL_THRESHOLD: + case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD: + switch (link_cfg_param_p->link_param_type.choice) { + case RAL_LINK_PARAM_TYPE_CHOICE_GEN: + switch (link_cfg_param_p->link_param_type._union.link_param_gen) { + case RAL_LINK_PARAM_GEN_DATA_RATE: + case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH: + case RAL_LINK_PARAM_GEN_SINR: + case RAL_LINK_PARAM_GEN_THROUGHPUT: + case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE: + message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; + + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_gen %d\n", link_cfg_param_p->link_param_type._union.link_param_gen); + return -1; + } + + break; + + case RAL_LINK_PARAM_TYPE_CHOICE_QOS: + switch (link_cfg_param_p->link_param_type._union.link_param_qos) { + case RAL_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED: + case RAL_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY: + case RAL_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO: + message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; + + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_qos %d\n", link_cfg_param_p->link_param_type._union.link_param_qos); + return -1; + } + + break; + + case RAL_LINK_PARAM_TYPE_CHOICE_LTE: + switch (link_cfg_param_p->link_param_type._union.link_param_lte) { + // group by dest task id + case RAL_LINK_PARAM_LTE_UE_RSRP: + case RAL_LINK_PARAM_LTE_UE_RSRQ: + case RAL_LINK_PARAM_LTE_UE_CQI: + message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; + + case RAL_LINK_PARAM_LTE_AVAILABLE_BW: + case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE: + case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS: + case RAL_LINK_PARAM_LTE_PACKET_DELAY: + message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; + + case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: + case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY: + case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY: + case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS: + case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW: +#warning "TO DO MIH LTE LINK PARAMS IN RRC UE" + break; - break; + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_lte %d\n", link_cfg_param_p->link_param_type._union.link_param_lte); + return -1; + } + + break; - case RAL_LINK_PARAM_TYPE_CHOICE_QOS: - switch (link_cfg_param_p->link_param_type._union.link_param_qos) { - case RAL_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED: - case RAL_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY: - case RAL_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO: - message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; - - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_qos %d\n", link_cfg_param_p->link_param_type._union.link_param_qos); - return -1; + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_type choice %d\n", link_cfg_param_p->link_param_type.choice); + return -1; } - break; + for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { + threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; + } - case RAL_LINK_PARAM_TYPE_CHOICE_LTE: - switch (link_cfg_param_p->link_param_type._union.link_param_lte) { - // group by dest task id - case RAL_LINK_PARAM_LTE_UE_RSRP: - case RAL_LINK_PARAM_LTE_UE_RSRQ: - case RAL_LINK_PARAM_LTE_UE_CQI: - message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; - - case RAL_LINK_PARAM_LTE_AVAILABLE_BW: - case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE: - case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS: - case RAL_LINK_PARAM_LTE_PACKET_DELAY: - message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; - - case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: - case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY: - case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY: - case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS: - case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW: -#warning "TO DO MIH LTE LINK PARAMS IN RRC UE" - break; + break; - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_lte %d\n", link_cfg_param_p->link_param_type._union.link_param_lte); - return -1; + case RAL_TH_ACTION_CANCEL_THRESHOLD: + + // IEEE Std 802.21-2008, Table F4, Data type name=LINK_CFG_PARAM (page 228): + // When “Cancel threshold†is selected and no thresholds are specified, then all + // currently configured thresholds for the given LINK_PARAM_TYPE are cancelled. + if (link_cfg_param_p->num_thresholds == 0) { + rrc_ue_ral_delete_all_thresholds_type(mod_idP, &link_cfg_param_p->link_param_type); + } else { + // + // When “Cancel threshold†is selected and thresholds are specified only those + // configured thresholds for the given LINK_PARAM_TYPE and whose threshold value match what was + // specified are cancelled. + for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { + threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; + rrc_ue_ral_delete_threshold(mod_idP, &link_cfg_param_p->link_param_type, threshold_p); + } } + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ with RAL_TH_ACTION_CANCEL_THRESHOLD\n"); break; default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_type choice %d\n", link_cfg_param_p->link_param_type.choice); + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown th_action %d\n", link_cfg_param_p->th_action); return -1; - } - - for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { - threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; - } - - break; - - case RAL_TH_ACTION_CANCEL_THRESHOLD: - - // IEEE Std 802.21-2008, Table F4, Data type name=LINK_CFG_PARAM (page 228): - // When “Cancel threshold†is selected and no thresholds are specified, then all - // currently configured thresholds for the given LINK_PARAM_TYPE are cancelled. - if (link_cfg_param_p->num_thresholds == 0) { - rrc_ue_ral_delete_all_thresholds_type(mod_idP, &link_cfg_param_p->link_param_type); - } else { - // - // When “Cancel threshold†is selected and thresholds are specified only those - // configured thresholds for the given LINK_PARAM_TYPE and whose threshold value match what was - // specified are cancelled. - for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { - threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; - rrc_ue_ral_delete_threshold(mod_idP, &link_cfg_param_p->link_param_type, threshold_p); - } - } - - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ with RAL_TH_ACTION_CANCEL_THRESHOLD\n"); - break; - - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown th_action %d\n", link_cfg_param_p->th_action); - return -1; } } diff --git a/openair2/RRC/LTE/rrc_common.c b/openair2/RRC/LTE/rrc_common.c index cf0196441e21d118e4ff8e64830bd85de27aa052..1744719308acf52be3890802fc920ba1e24dd075 100644 --- a/openair2/RRC/LTE/rrc_common.c +++ b/openair2/RRC/LTE/rrc_common.c @@ -55,9 +55,7 @@ rrc_init_global_param( ) //----------------------------------------------------------------------------- { - rrc_rlc_register_rrc (rrc_data_ind, NULL); //register with rlc - DCCH_LCHAN_DESC.transport_block_size = 4; DCCH_LCHAN_DESC.max_transport_blocks = 16; DCCH_LCHAN_DESC.Delay_class = 1; @@ -67,13 +65,11 @@ rrc_init_global_param( DTCH_UL_LCHAN_DESC.transport_block_size = 52; DTCH_UL_LCHAN_DESC.max_transport_blocks = 20; DTCH_UL_LCHAN_DESC.Delay_class = 1; - Rlc_info_um.rlc_mode = RLC_MODE_UM; Rlc_info_um.rlc.rlc_um_info.timer_reordering = 5; Rlc_info_um.rlc.rlc_um_info.sn_field_length = 10; Rlc_info_um.rlc.rlc_um_info.is_mXch = 0; //Rlc_info_um.rlc.rlc_um_info.sdu_discard_mode=16; - Rlc_info_am_config.rlc_mode = RLC_MODE_AM; Rlc_info_am_config.rlc.rlc_am_info.max_retx_threshold = 50; Rlc_info_am_config.rlc.rlc_am_info.poll_pdu = 8; @@ -81,20 +77,18 @@ rrc_init_global_param( Rlc_info_am_config.rlc.rlc_am_info.t_poll_retransmit = 15; Rlc_info_am_config.rlc.rlc_am_info.t_reordering = 50; Rlc_info_am_config.rlc.rlc_am_info.t_status_prohibit = 10; - return 0; } //----------------------------------------------------------------------------- void rrc_config_buffer( - SRB_INFO* Srb_info, + SRB_INFO *Srb_info, uint8_t Lchan_type, uint8_t Role ) //----------------------------------------------------------------------------- { - Srb_info->Rx_buffer.payload_size = 0; Srb_info->Tx_buffer.payload_size = 0; } @@ -200,7 +194,7 @@ static band_freq bands[] = { { BAND_TYPE_FDD, 3, 1710000000UL, 1785000000UL, 1805000000UL, 1880000000UL }, { BAND_TYPE_FDD, 4, 1710000000UL, 1755000000UL, 2110000000UL, 2155000000UL }, { BAND_TYPE_FDD, 5, 824000000UL, 849000000UL, 869000000UL, 894000000UL }, - /* to remove? */{ BAND_TYPE_FDD, 6, 830000000UL, 840000000UL, 875000000UL, 885000000UL }, + /* to remove? */{ BAND_TYPE_FDD, 6, 830000000UL, 840000000UL, 875000000UL, 885000000UL }, { BAND_TYPE_FDD, 7, 2500000000UL, 2570000000UL, 2620000000UL, 2690000000UL }, { BAND_TYPE_FDD, 8, 880000000UL, 915000000UL, 925000000UL, 960000000UL }, { BAND_TYPE_FDD, 9, 1749900000UL, 1784900000UL, 1844900000UL, 1879900000UL }, @@ -278,17 +272,17 @@ static earfcn earfcn_table[] = { { 42, 3400000000UL, 41590, 41590, 43589, 3400000000UL, 41590, 41590, 43589 }, { 43, 3600000000UL, 43590, 43590, 45589, 3600000000UL, 43590, 43590, 45589 }, }; - -int freq_to_arfcn10(int band, unsigned long freq) -{ - int N = sizeof(earfcn_table) / sizeof(earfcn_table[0]); + +int freq_to_arfcn10(int band, unsigned long freq) { + int N = sizeof(earfcn_table) / sizeof(earfcn_table[0]); int i; - - for (i = 0; i < N; i++) if (bands[i].band == band) break; + + for (i = 0; i < N; i++) if (bands[i].band == band) break; + if (i == N) return -1; - + if (!(bands[i].dl_minfreq < freq && freq < bands[i].dl_maxfreq)) return -1; - + return (freq - earfcn_table[i].dl_flow) / 100000UL + earfcn_table[i].dl_off; } diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index eddc9a7a241e9a4fa6246e40a35b6ee7c3d1005b..2f3f6799355b6f69e024c3338a5395b0dccdb2e4 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -16,7 +16,7 @@ * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org + * conmnc_digit_lengtht@openairinterface.org */ /*! \file RRC/LTE/defs.h @@ -36,6 +36,7 @@ #include <string.h> #include "collection/tree.h" +#include "common/ngran_types.h" #include "rrc_types.h" //#include "PHY/phy_defs.h" #include "LAYER2/RLC/rlc.h" @@ -199,6 +200,8 @@ void *send_UE_status_notification(void *); /* for ImsiMobileIdentity_t */ #include "MobileIdentity.h" +#include "LTE_DRX-Config.h" + /* correct Rel(8|10)/Rel14 differences * the code is in favor of Rel14, those defines do the translation */ @@ -284,21 +287,14 @@ void *send_UE_status_notification(void *); #include "rrc_rrm_interface.h" #endif -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif -/* TODO: be sure this include is correct. - * It solves a problem of compilation of the RRH GW, - * issue #186. - */ -#if !defined(ENABLE_ITTI) - #include "as_message.h" -#endif +#include "intertask_interface.h" + + + + +#include "commonDef.h" -#if defined(ENABLE_USE_MME) - #include "commonDef.h" -#endif //-------- typedef unsigned int uid_t; @@ -344,10 +340,15 @@ typedef enum UE_STATE_e { typedef enum HO_STATE_e { HO_IDLE=0, - HO_MEASURMENT, + HO_MEASUREMENT, HO_PREPARE, HO_CMD, // initiated by the src eNB - HO_COMPLETE // initiated by the target eNB + HO_COMPLETE, // initiated by the target eNB + HO_REQUEST, + HO_ACK, + HO_CONFIGURED, + HO_RELEASE, + HO_CANCEL } HO_STATE_t; typedef enum SL_TRIGGER_e { @@ -440,11 +441,12 @@ typedef struct UE_S_TMSI_s { m_tmsi_t m_tmsi; } __attribute__ ((__packed__)) UE_S_TMSI; -#if defined(ENABLE_ITTI) + typedef enum e_rab_satus_e { E_RAB_STATUS_NEW, E_RAB_STATUS_DONE, // from the eNB perspective E_RAB_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE + E_RAB_STATUS_REESTABLISHED, // after HO E_RAB_STATUS_FAILED, E_RAB_STATUS_TORELEASE // to release DRB between eNB and UE } e_rab_status_t; @@ -456,22 +458,23 @@ typedef struct e_rab_param_s { s1ap_Cause_t cause; uint8_t cause_value; } __attribute__ ((__packed__)) e_rab_param_t; -#endif - /* Intermediate structure for Handover management. Associated per-UE in eNB_RRC_INST */ typedef struct HANDOVER_INFO_s { uint8_t ho_prepare; uint8_t ho_complete; - uint8_t modid_s; //module_idP of serving cell - uint8_t modid_t; //module_idP of target cell + HO_STATE_t state; //current state of handover + uint32_t modid_s; //module_idP of serving cell + uint32_t modid_t; //module_idP of target cell + int assoc_id; uint8_t ueid_s; //UE index in serving cell uint8_t ueid_t; //UE index in target cell LTE_AS_Config_t as_config; /* these two parameters are taken from 36.331 section 10.2.2: HandoverPreparationInformation-r8-IEs */ LTE_AS_Context_t as_context; /* They are mandatory for HO */ uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */ int size; /* size of above message in bytes */ + int x2_id; /* X2AP UE ID in the target eNB */ } HANDOVER_INFO; #define RRC_HEADER_SIZE_MAX 64 @@ -523,6 +526,14 @@ typedef struct HANDOVER_INFO_UE_s { uint8_t measFlag; } HANDOVER_INFO_UE; +typedef struct rrc_gummei_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_len; + uint8_t mme_code; + uint16_t mme_group_id; +} rrc_gummei_t; + typedef struct eNB_RRC_UE_s { uint8_t primaryCC_id; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -549,17 +560,17 @@ typedef struct eNB_RRC_UE_s { LTE_MeasConfig_t *measConfig; HANDOVER_INFO *handover_info; LTE_MeasResults_t *measResults; + LTE_MobilityControlInfo_t *mobilityInfo; LTE_UE_EUTRA_Capability_t *UE_Capability; + int UE_Capability_size; ImsiMobileIdentity_t imsi; -#if defined(ENABLE_SECURITY) /* KeNB as derived from KASME received from EPC */ uint8_t kenb[32]; int8_t kenb_ncc; uint8_t nh[32]; int8_t nh_ncc; -#endif /* Used integrity/ciphering algorithms */ LTE_CipheringAlgorithm_r12_t ciphering_algorithm; e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; @@ -568,7 +579,7 @@ typedef struct eNB_RRC_UE_s { rnti_t rnti; uint64_t random_ue_identity; -#if defined(ENABLE_ITTI) + /* Information from UE RRC ConnectionRequest */ UE_S_TMSI Initialue_identity_s_TMSI; LTE_EstablishmentCause_t establishment_cause; @@ -582,8 +593,15 @@ typedef struct eNB_RRC_UE_s { /* Information from S1AP initial_context_setup_req */ uint32_t eNB_ue_s1ap_id :24; + uint32_t mme_ue_s1ap_id; + rrc_gummei_t ue_gummei; + security_capabilities_t security_capabilities; + int next_hop_chain_count; + + uint8_t next_security_key[SECURITY_KEY_LENGTH]; + /* Total number of e_rab already setup in the list */ uint8_t setup_e_rabs; /* Number of e_rab to be setup in the list */ @@ -594,14 +612,17 @@ typedef struct eNB_RRC_UE_s { e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; /* list of e_rab to be setup by RRC layers */ e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; + /* UE aggregate maximum bitrate */ + ambr_t ue_ambr; //release e_rabs uint8_t nb_release_of_e_rabs; + /* list of e_rab to be released by RRC layers */ + uint8_t e_rabs_tobereleased[NB_RB_MAX]; e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB]; // LG: For GTPV1 TUNNELS uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; -#endif uint32_t ul_failure_timer; uint32_t ue_release_timer; uint32_t ue_release_timer_thres; @@ -657,10 +678,14 @@ typedef struct { int p_eNB; uint32_t dl_CarrierFreq; uint32_t ul_CarrierFreq; + uint32_t eutra_band; + uint32_t N_RB_DL; uint32_t pbch_repetition; LTE_BCCH_BCH_Message_t mib; + LTE_BCCH_BCH_Message_t *mib_DU; LTE_BCCH_DL_SCH_Message_t siblock1; LTE_BCCH_DL_SCH_Message_t siblock1_BR; + LTE_BCCH_DL_SCH_Message_t *siblock1_DU; LTE_BCCH_DL_SCH_Message_t systemInformation; LTE_BCCH_DL_SCH_Message_t systemInformation_BR; // SystemInformation_t systemInformation; @@ -695,14 +720,17 @@ typedef struct { LTE_SystemInformationBlockType21_r14_t *sib21; // End - TTN SRB_INFO SI; - SRB_INFO Srb0; uint8_t *paging[MAX_MOBILES_PER_ENB]; uint32_t sizeof_paging[MAX_MOBILES_PER_ENB]; } rrc_eNB_carrier_data_t; + typedef struct eNB_RRC_INST_s { /// southbound midhaul configuration + ngran_node_t node_type; eth_params_t eth_params_s; + char *node_name; + uint32_t node_id; rrc_eNB_carrier_data_t carrier[MAX_NUM_CCs]; uid_allocator_t uid_allocator; // for rrc_ue_head RB_HEAD(rrc_ue_tree_s, rrc_eNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti @@ -723,9 +751,10 @@ typedef struct eNB_RRC_INST_s { #endif //RRC configuration -#if defined(ENABLE_ITTI) RrcConfigurationReq configuration; -#endif + + /// NR cell id + uint64_t nr_cellid; // other RAN parameters int srb1_timer_poll_retransmit; @@ -735,6 +764,11 @@ typedef struct eNB_RRC_INST_s { int srb1_timer_reordering; int srb1_timer_status_prohibit; int srs_enable[MAX_NUM_CCs]; + int cell_info_configured; + pthread_mutex_t cell_info_mutex; + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; + } eNB_RRC_INST; #define MAX_UE_CAPABILITY_SIZE 255 @@ -747,11 +781,9 @@ typedef struct OAI_UECapability_s { typedef struct UE_RRC_INST_s { Rrc_State_t RrcState; Rrc_Sub_State_t RrcSubState; -# if defined(ENABLE_USE_MME) plmn_t plmnID; Byte_t rat; as_nas_info_t initialNasMsg; -# endif OAI_UECapability_t *UECap; uint8_t *UECapability; uint8_t UECapability_size; @@ -854,12 +886,10 @@ typedef struct UE_RRC_INST_s { float rsrq_db[7]; float rsrp_db_filtered[7]; float rsrq_db_filtered[7]; -#if defined(ENABLE_SECURITY) /* KeNB as computed from parameters within USIM card */ uint8_t kenb[32]; uint8_t nh[32]; int8_t nh_ncc; -#endif /* Used integrity/ciphering algorithms */ LTE_CipheringAlgorithm_r12_t ciphering_algorithm; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index b0896a344b4725c40cd74326892cebd137926b96..f943521800651707793c13df764c1fffdfc6c159 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -53,6 +53,7 @@ #include "LTE_UL-DCCH-Message.h" #include "LTE_DL-DCCH-Message.h" #include "LTE_TDD-Config.h" +#include "LTE_HandoverPreparationInformation.h" #include "LTE_HandoverCommand.h" #include "rlc.h" #include "rrc_eNB_UE_context.h" @@ -68,6 +69,7 @@ #include "LTE_NonMBSFN-SubframeConfig-r14.h" #endif #include "common/utils/LOG/vcd_signal_dumper.h" +#include "x2ap_eNB.h" #include "T.h" @@ -80,32 +82,15 @@ #include "OCG.h" #include "OCG_extern.h" -#if defined(ENABLE_SECURITY) - #include "UTIL/OSA/osa_defs.h" -#endif +#include "UTIL/OSA/osa_defs.h" -#if defined(ENABLE_USE_MME) - #include "rrc_eNB_S1AP.h" - #include "rrc_eNB_GTPV1U.h" - #if defined(ENABLE_ITTI) - #else - #include "../../S1AP/s1ap_eNB.h" - #endif - /* temporary warning removale while implementing noS1 */ - /* as config option */ -#else - #ifdef EPC_MODE_ENABLED - #undef EPC_MODE_ENABLED - #endif - #define EPC_MODE_ENABLED 0 -#endif +#include "rrc_eNB_S1AP.h" +#include "rrc_eNB_GTPV1U.h" #include "pdcp.h" #include "gtpv1u_eNB_task.h" -#if defined(ENABLE_ITTI) - #include "intertask_interface.h" -#endif +#include "intertask_interface.h" #if ENABLE_RAL #include "rrc_eNB_ral.h" @@ -126,6 +111,11 @@ extern uint16_t two_tier_hexagonal_cellIds[7]; mui_t rrc_eNB_mui = 0; +extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); +extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, security_capabilities_t *security_capabilities_pP); +extern void process_eNB_security_key (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP); +extern int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, const bool is_rel8_only, uint8_t * kenb_star); + void openair_rrc_on( const protocol_ctxt_t *const ctxt_pP @@ -139,17 +129,15 @@ openair_rrc_on( for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI.Active = 1; - rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0, CCCH, 1); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Active = 1; } } //----------------------------------------------------------------------------- static void init_SI( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const int CC_id, - RrcConfigurationReq * configuration + RrcConfigurationReq *configuration ) //----------------------------------------------------------------------------- { @@ -282,294 +270,359 @@ if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE } #endif + eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; + rrc_eNB_carrier_data_t *carrier=&rrc->carrier[CC_id]; - - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 = 0; - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = 0; - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1 = (uint8_t *) malloc16(32); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1 allocated\n", + carrier->MIB = (uint8_t*) malloc16(4); + carrier->sizeof_SIB1 = 0; + carrier->sizeof_SIB23 = 0; + carrier->SIB1 = (uint8_t*) malloc16(32); + + AssertFatal(carrier->SIB1!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1 allocated\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],ctxt_pP->module_id,CC_id + LOG_I(RRC,"[eNB %d] Node type %d \n ", ctxt_pP->module_id, rrc->node_type); + if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { + // copy basic Cell parameters + carrier->physCellId = configuration->Nid_cell[CC_id]; + carrier->p_eNB = configuration->nb_antenna_ports[CC_id]; + carrier->Ncp = configuration->prefix_type[CC_id]; + carrier->dl_CarrierFreq = configuration->downlink_frequency[CC_id]; + carrier->ul_CarrierFreq = configuration->downlink_frequency[CC_id]+ configuration->uplink_frequency_offset[CC_id]; + carrier->eutra_band = configuration->eutra_band[CC_id]; + carrier->N_RB_DL = configuration->N_RB_DL[CC_id]; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,FALSE + carrier->pbch_repetition = configuration->pbch_repetition[CC_id]; + LOG_I(RRC, "configuration->schedulingInfoSIB1_BR_r13[CC_id] %d\n",(int)configuration->schedulingInfoSIB1_BR_r13[CC_id]); #endif - , configuration - ); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255"); + LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", + (int)configuration->N_RB_DL[CC_id], + (int)configuration->radioresourceconfig[CC_id].phich_resource, + (int)configuration->radioresourceconfig[CC_id].phich_duration); - + carrier->sizeof_MIB = do_MIB(&rrc->carrier[CC_id], + configuration->N_RB_DL[CC_id], + configuration->radioresourceconfig[CC_id].phich_resource, + configuration->radioresourceconfig[CC_id].phich_duration, + 0 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = 0; - if (configuration->schedulingInfoSIB1_BR_r13[CC_id]>0) { - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_BR = (uint8_t*) malloc16(32); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],ctxt_pP->module_id,CC_id - ,TRUE - , configuration - ); - } + ,configuration->schedulingInfoSIB1_BR_r13[CC_id] #endif - - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23 = (uint8_t*) malloc16(64); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23!=NULL,"cannot allocate memory for SIB"); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = do_SIB23( - ctxt_pP->module_id, - CC_id + ); + + + carrier->sizeof_SIB1 = do_SIB1(&rrc->carrier[CC_id], + ctxt_pP->module_id, + CC_id #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,FALSE + ,FALSE #endif - , configuration - ); - - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 != 255,"FATAL, RC.rrc[mod].carrier[CC_id].sizeof_SIB23 == 255"); + , configuration + ); + + AssertFatal(carrier->sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255"); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23_BR = 0; - if (configuration->schedulingInfoSIB1_BR_r13[CC_id]>0) { - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23_BR = (uint8_t*) malloc16(64); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23_BR!=NULL,"cannot allocate memory for SIB"); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23_BR = do_SIB23( - ctxt_pP->module_id, - CC_id + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = 0; + + if (configuration->schedulingInfoSIB1_BR_r13[CC_id] > 0) { + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_BR = (uint8_t *) malloc16(32); + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id], + ctxt_pP->module_id, + CC_id, TRUE, configuration); + } +#endif + + } + if (!NODE_IS_DU(rrc->node_type)) { + carrier->SIB23 = (uint8_t*) malloc16(64); + AssertFatal(carrier->SIB23!=NULL,"cannot allocate memory for SIB"); + carrier->sizeof_SIB23 = do_SIB23(ctxt_pP->module_id, + CC_id #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,TRUE + ,FALSE #endif - ,configuration - ); + , configuration + ); + + LOG_I(RRC,"do_SIB23, size %d \n ", carrier->sizeof_SIB23); + + AssertFatal(carrier->sizeof_SIB23 != 255,"FATAL, RC.rrc[mod].carrier[CC_id].sizeof_SIB23 == 255"); + +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + carrier->sizeof_SIB23_BR = 0; + if (configuration->schedulingInfoSIB1_BR_r13[CC_id]>0) { + carrier->SIB23_BR = (uint8_t*) malloc16(64); + AssertFatal(carrier->SIB23_BR!=NULL,"cannot allocate memory for SIB"); + carrier->sizeof_SIB23_BR = do_SIB23(ctxt_pP->module_id, CC_id, TRUE, configuration); } + #endif - - LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" SIB2/3 Contents (partial)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); - LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.n_SB = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - pusch_ConfigBasic.n_SB); - LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.hoppingMode = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - pusch_ConfigBasic.hoppingMode); - LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.pusch_HoppingOffset = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - pusch_ConfigBasic.pusch_HoppingOffset); - LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.enable64QAM = %d\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - pusch_ConfigBasic.enable64QAM); - LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupHoppingEnabled = %d\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - ul_ReferenceSignalsPUSCH.groupHoppingEnabled); - LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupAssignmentPUSCH = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); - LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.sequenceHoppingEnabled = %d\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled); - LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.cyclicShift = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - ul_ReferenceSignalsPUSCH.cyclicShift); - + LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" SIB2/3 Contents (partial)\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); + LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.n_SB = %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB); + LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.hoppingMode = %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode); + LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.pusch_HoppingOffset = %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset); + LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.enable64QAM = %d\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM); + LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupHoppingEnabled = %d\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled); + LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupAssignmentPUSCH = %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); + LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.sequenceHoppingEnabled = %d\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + (int)carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled); + LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.cyclicShift = %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib2->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift); + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - - if (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag > 0) { - for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count; i++) { - // SIB 2 - // LOG_D(RRC, "[eNB %d] mbsfn_SubframeConfigList.list.count = %ld\n", enb_mod_idP, RC.rrc[enb_mod_idP].sib2->mbsfn_SubframeConfigList->list.count); - LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN subframe allocation %d/%d(partial)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - i, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count); - LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" mbsfn_Subframe_pattern is = %x\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0] >> 0); - LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_period = %ld (just index number, not the real value)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod); // need to display the real value, using array of char (like in dumping SIB2) - LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_offset = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset); - } - - - - // SIB13 - for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count; i++) { - LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN sync area %d/%d (partial)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - i, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count); - LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Repetition Period: %ld (just index number, not real value)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); - LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Offset: %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9); - } - } - else memset((void*)&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13,0,sizeof(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13)); - - //TTN - SIB 18 - if (configuration->SL_configured>0) { - for (int j = 0; j < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.count; j++) { - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB18 %d/%d \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - j+1, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.count); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 rxPool_sc_CP_Len: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_CP_Len_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 sc_Period_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_Period_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 data_CP_Len_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->data_CP_Len_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Num_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Num_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Start_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Start_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_End_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_End_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 offsetIndicator: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 subframeBitmap_choice_bs_buf: %s \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf); + + if (carrier->MBMS_flag > 0) { + for (i = 0; i < carrier->sib2->mbsfn_SubframeConfigList->list.count; i++) { + // SIB 2 + // LOG_D(RRC, "[eNB %d] mbsfn_SubframeConfigList.list.count = %ld\n", enb_mod_idP, RC.rrc[enb_mod_idP].sib2->mbsfn_SubframeConfigList->list.count); + LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN subframe allocation %d/%d(partial)\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + i, + carrier->sib2->mbsfn_SubframeConfigList->list.count); + LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" mbsfn_Subframe_pattern is = %x\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib2->mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0] >> 0); + LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_period = %ld (just index number, not the real value)\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod); // need to display the real value, using array of char (like in dumping SIB2) + LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_offset = %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset); + } - } - - - - - for (int j = 0; j < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.count; j++) { - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB19 %d/%d \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - j+1, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.count); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 cp_Len_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->cp_Len_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 discPeriod_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->discPeriod_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRetx_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRetx_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRepetition_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRepetition_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Num_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Num_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Start_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Start_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_End_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_End_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 offsetIndicator: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 subframeBitmap_choice_bs_buf: %s \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf); + // SIB13 + for (i = 0; i < carrier->sib13->mbsfn_AreaInfoList_r9.list.count; i++) { + LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN sync area %d/%d (partial)\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + i, + carrier->sib13->mbsfn_AreaInfoList_r9.list.count); + LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Repetition Period: %ld (just index number, not real value)\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Offset: %ld\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9); + } + } else memset((void *)&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13,0,sizeof(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13)); + + //TTN - SIB 18 + if (configuration->SL_configured > 0) { + for (int j = 0; j < carrier->sib18->commConfig_r12->commRxPool_r12.list.count; j++) { + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB18 %d/%d \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + j+1, + carrier->sib18->commConfig_r12->commRxPool_r12.list.count); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 rxPool_sc_CP_Len: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_CP_Len_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 sc_Period_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_Period_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 data_CP_Len_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->data_CP_Len_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Num_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Num_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Start_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Start_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_End_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_End_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 offsetIndicator: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 subframeBitmap_choice_bs_buf: %s \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf); + } + //TTN - SIB 19 + for (int j = 0; j < carrier->sib19->discConfig_r12->discRxPool_r12.list.count; j++) { + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB19 %d/%d \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + j+1, + carrier->sib19->discConfig_r12->discRxPool_r12.list.count); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 cp_Len_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->cp_Len_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 discPeriod_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->discPeriod_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRetx_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRetx_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRepetition_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRepetition_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Num_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Num_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Start_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Start_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_End_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_End_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 offsetIndicator: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 subframeBitmap_choice_bs_buf: %s \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + carrier->sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf); + } } - } - #endif // (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - - + } + LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" RRC_UE --- MAC_CONFIG_REQ (SIB1.tdd & SIB2 params) ---> MAC_UE\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - if ((RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib.message.schedulingInfoSIB1_BR_r13>0) && - (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR!=NULL)) { - - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension!=NULL, - "sib2_br->nonCriticalExtension is null (v8.9)\n"); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL, - "sib2_br->nonCriticalExtension is null (v9.2)\n"); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, - "sib2_br->nonCriticalExtension is null (v11.3)\n"); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, - "sib2_br->nonCriticalExtension is null (v12.5)\n"); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, - "sib2_br->nonCriticalExtension is null (v13.10)\n"); - sib1_v13ext = RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension; + // LTE-M stuff here (take out CU-DU for now) + if (NODE_IS_MONOLITHIC(rrc->node_type)) { + if ((carrier->mib.message.schedulingInfoSIB1_BR_r13>0) && + (carrier->sib1_BR!=NULL)) { + AssertFatal(carrier->sib1_BR->nonCriticalExtension!=NULL, + "sib2_br->nonCriticalExtension is null (v8.9)\n"); + AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL, + "sib2_br->nonCriticalExtension is null (v9.2)\n"); + AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, + "sib2_br->nonCriticalExtension is null (v11.3)\n"); + AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, + "sib2_br->nonCriticalExtension is null (v12.5)\n"); + AssertFatal(carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, + "sib2_br->nonCriticalExtension is null (v13.10)\n"); + + sib1_v13ext = carrier->sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension; // Basic Asserts for CE_level0 PRACH configuration - - LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR = &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2_BR->radioResourceConfigCommon; - struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; - + LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR = &carrier[CC_id].sib2_BR->radioResourceConfigCommon; + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; AssertFatal(prach_ParametersListCE_r13->list.count>0,"prach_ParametersListCE_r13 is empty\n"); - LTE_PRACH_ParametersCE_r13_t *p = prach_ParametersListCE_r13->list.array[0]; + LTE_PRACH_ParametersCE_r13_t *p = prach_ParametersListCE_r13->list.array[0]; AssertFatal(p->prach_StartingSubframe_r13 != NULL, "prach_StartingSubframe_r13 celevel0 is null\n"); AssertFatal((1<<p->numRepetitionPerPreambleAttempt_r13)<=(2<<*p->prach_StartingSubframe_r13), - "prachce0->numReptitionPerPreambleAttempt_r13 %d > prach_StartingSubframe_r13 %d\n", - 1<<p->numRepetitionPerPreambleAttempt_r13, - 2<<*p->prach_StartingSubframe_r13); + "prachce0->numReptitionPerPreambleAttempt_r13 %d > prach_StartingSubframe_r13 %d\n", + 1<<p->numRepetitionPerPreambleAttempt_r13, + 2<<*p->prach_StartingSubframe_r13); + } + } - #endif - LOG_D(RRC, "About to call rrc_mac_config_req_eNB\n"); - rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->freqBandIndicator, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq, + /* + if (rrc->node_type == ngran_eNB_DU) { + LOG_D(RRC, "About to call rrc_mac_config_req_eNB for ngran_eNB_DU\n"); + + rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, + carrier->physCellId, + carrier->p_eNB, + carrier->Ncp, + carrier->sib1->freqBandIndicator, + carrier->dl_CarrierFreq, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition, + carrier->pbch_repetition, #endif - 0, // rnti - (LTE_BCCH_BCH_Message_t *) - &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib, - (LTE_RadioResourceConfigCommonSIB_t *) & - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon, + 0, // rnti + (BCCH_BCH_Message_t *) + &carrier->mib, + (RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) & - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2_BR->radioResourceConfigCommon, + (RadioResourceConfigCommonSIB_t *) NULL, #endif - (struct LTE_PhysicalConfigDedicated *)NULL, + (struct PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (SCellToAddMod_r10_t *)NULL, + //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, +#endif + (MeasObjectToAddMod_t **) NULL, + (MAC_MainConfig_t *) NULL, 0, + (struct LogicalChannelConfig *)NULL, + (MeasGapConfig_t *) NULL, + carrier->sib1->tdd_Config, + NULL, + &carrier->sib1->schedulingInfoList, + carrier->ul_CarrierFreq, + NULL, + NULL, + NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , + carrier->MBMS_flag, + NULL, + (PMCH_InfoList_r9_t *) NULL +#endif +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + , + NULL +#endif + ); + } + else + */ + if (NODE_IS_MONOLITHIC(rrc->node_type)) { + LOG_D(RRC, "About to call rrc_mac_config_req_eNB for ngran_eNB\n"); + + rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, + carrier->physCellId, + carrier->p_eNB, + carrier->Ncp, + carrier->sib1->freqBandIndicator, + carrier->dl_CarrierFreq, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + carrier->pbch_repetition, +#endif + 0, // rnti + (LTE_BCCH_BCH_Message_t *) &carrier->mib, + (LTE_RadioResourceConfigCommonSIB_t *) &carrier->sib2->radioResourceConfigCommon, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) &carrier->sib2_BR->radioResourceConfigCommon, #endif - (LTE_MeasObjectToAddMod_t **) NULL, - (LTE_MAC_MainConfig_t *) NULL, 0, - (struct LTE_LogicalChannelConfig *)NULL, - (LTE_MeasGapConfig_t *) NULL, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->tdd_Config, - NULL, - &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->schedulingInfoList, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].ul_CarrierFreq, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.ul_Bandwidth, - &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.additionalSpectrumEmission, - (LTE_MBSFN_SubframeConfigList_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, +#endif + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + carrier->sib1->tdd_Config, + NULL, + &carrier->sib1->schedulingInfoList, + carrier->ul_CarrierFreq, + carrier->sib2->freqInfo.ul_Bandwidth, + &carrier->sib2->freqInfo.additionalSpectrumEmission, + (LTE_MBSFN_SubframeConfigList_t*) carrier->sib2->mbsfn_SubframeConfigList #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag, - (LTE_MBSFN_AreaInfoList_r9_t *) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9, - (LTE_PMCH_InfoList_r9_t *) NULL + , + carrier->MBMS_flag, + (LTE_MBSFN_AreaInfoList_r9_t*) & carrier->sib13->mbsfn_AreaInfoList_r9, + (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - sib1_v13ext + , + sib1_v13ext #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , @@ -581,6 +634,12 @@ if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif ); + } + /* set flag to indicate that cell information is configured. This is required + * in DU to trigger F1AP_SETUP procedure */ + pthread_mutex_lock(&rrc->cell_info_mutex); + rrc->cell_info_configured=1; + pthread_mutex_unlock(&rrc->cell_info_mutex); } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -594,6 +653,8 @@ init_MCCH( { int sync_area = 0; // initialize RRC_eNB_INST MCCH entry + eNB_RRC_INST *rrc = RC.rrc[enb_mod_idP]; + RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE = malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t *)); @@ -630,40 +691,37 @@ init_MCCH( // call mac_config_req with appropriate structure from ASN.1 description // LOG_I(RRC, "DUY: serviceID is %d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->tmgi_r9.serviceId_r9.buf[2]); // LOG_I(RRC, "DUY: session ID is %d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->sessionId_r9->buf[0]); - rrc_mac_config_req_eNB(enb_mod_idP, CC_id, - 0,0,0,0,0, + if (NODE_IS_MONOLITHIC(rrc->node_type)) { + rrc_mac_config_req_eNB(enb_mod_idP, CC_id, + 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - 0,//rnti - (LTE_BCCH_BCH_Message_t *)NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + 0,//rnti + (LTE_BCCH_BCH_Message_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - (struct LTE_PhysicalConfigDedicated *)NULL, -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, -#endif - (LTE_MeasObjectToAddMod_t **) NULL, - (LTE_MAC_MainConfig_t *) NULL, - 0, - (struct LTE_LogicalChannelConfig *)NULL, - (LTE_MeasGapConfig_t *) NULL, - (LTE_TDD_Config_t *) NULL, - (LTE_MobilityControlInfo_t *)NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , - 0, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) -#endif + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, + 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *)NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + , + 0, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , @@ -675,6 +733,7 @@ init_MCCH( (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif ); + } //LOG_I(RRC,"DUY: lcid after rrc_mac_config_req is %02d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9); } @@ -701,20 +760,21 @@ static void init_MBMS( NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) -#endif ,NULL); - rrc_rlc_config_asn1_req(&ctxt, - NULL, // LTE_SRB_ToAddModList - NULL, // LTE_DRB_ToAddModList - NULL, // DRB_ToReleaseList - &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) + + if (!NODE_IS_CU(RC.rrc[enb_mod_idP]->node_type)) { + rrc_rlc_config_asn1_req(&ctxt, + NULL, // LTE_SRB_ToAddModList + NULL, // LTE_DRB_ToAddModList + NULL, // DRB_ToReleaseList + &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + ,0, 0 #endif - ); - //rrc_mac_config_req(); + ); + } + //rrc_mac_config_req(); } } #endif @@ -849,6 +909,7 @@ rrc_eNB_get_next_free_ue_context( PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); return NULL; } + return(ue_context_p); } //----------------------------------------------------------------------------- @@ -939,7 +1000,8 @@ rrc_eNB_free_mem_UE_context( ue_context_pP->ue_context.measGapConfig = NULL; }*/ if (ue_context_pP->ue_context.handover_info) { - ASN_STRUCT_FREE(asn_DEF_LTE_Handover, ue_context_pP->ue_context.handover_info); + /* TODO: be sure free is enough here (check memory leaks) */ + free(ue_context_pP->ue_context.handover_info); ue_context_pP->ue_context.handover_info = NULL; } @@ -957,10 +1019,9 @@ rrc_eNB_free_mem_UE_context( ue_context_pP->ue_context.measConfig = NULL; } +#if 0 //HANDOVER_INFO *handover_info; -#if defined(ENABLE_SECURITY) //uint8_t kenb[32]; -#endif //e_SecurityAlgorithmConfig__cipheringAlgorithm ciphering_algorithm; //e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; //uint8_t Status; @@ -979,6 +1040,7 @@ rrc_eNB_free_mem_UE_context( //transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; //rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; #endif +#endif } //----------------------------------------------------------------------------- @@ -1002,30 +1064,36 @@ rrc_eNB_free_UE( return; } - if (EPC_MODE_ENABLED) { - if ((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { - LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n", - enb_mod_idP, - rnti); - rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); - // send cause 21: radio connection with ue lost - /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) - * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before - * triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery - * procedure, see TS 23.401 [17]. - */ - return; - } + if(EPC_MODE_ENABLED) { + if (!NODE_IS_DU(RC.rrc[enb_mod_idP]->node_type)) { + if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { + LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n", + enb_mod_idP, + rnti); + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, + ue_context_pP, + S1AP_CAUSE_RADIO_NETWORK, + 21); // send cause 21: radio connection with ue lost + /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) + * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before + * triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery + * procedure, see TS 23.401 [17]. + */ + return; + } - if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres) && - (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED) && - (RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres > 0)) { - LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n", - enb_mod_idP, - rnti); - rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 20); - // send cause 20: user inactivity - return; + if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres) && + (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED) && + (RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres > 0)) { + LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n", + enb_mod_idP, + rnti); + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, + ue_context_pP, + S1AP_CAUSE_RADIO_NETWORK, + 20); // send cause 20: user inactivity + return; + } } } @@ -1123,9 +1191,9 @@ void release_UE_in_freeList(module_id_t mod_id) { } } - if (rrc_agent_registered[mod_id]) { - agent_rrc_xface[mod_id]->flexran_agent_notify_ue_state_change(mod_id, - rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + if (flexran_agent_get_rrc_xface(mod_id)) { + flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change( + mod_id, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } for(j = 0; j < 10; j++) { @@ -1153,13 +1221,23 @@ void release_UE_in_freeList(module_id_t mod_id) { } } - rrc_mac_remove_ue(mod_id,rnti); - rrc_rlc_remove_ue(&ctxt); - pdcp_remove_UE(&ctxt); + if (!NODE_IS_CU(RC.rrc[mod_id]->node_type)) { + rrc_mac_remove_ue(mod_id,rnti); + rrc_rlc_remove_ue(&ctxt); + pdcp_remove_UE(&ctxt); + } + else { + MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD); + F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = rnti; + F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; + F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = NULL; + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = 0; + itti_send_msg_to_task(TASK_CU_F1, mod_id, m); + } if(remove_UEContext) { - ue_context_pP = rrc_eNB_get_ue_context( - RC.rrc[mod_id],rnti); + ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[mod_id],rnti); if(ue_context_pP) { rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id], @@ -1185,14 +1263,18 @@ rrc_eNB_process_RRCConnectionSetupComplete( ) //----------------------------------------------------------------------------- { - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n", + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + ue_context_pP->ue_context.Srb1.Active = 1; ue_context_pP->ue_context.Status = RRC_CONNECTED; - ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity timer when UE goes into RRC_CONNECTED + + T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, + T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(ctxt_pP->rnti)); if (EPC_MODE_ENABLED == 1) { // Forward message to S1AP layer @@ -1242,14 +1324,18 @@ rrc_eNB_generate_SecurityModeCommand( ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + + if (!NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) { + LOG_I(RRC,"calling rrc_data_req :securityModeCommand\n"); + + rrc_data_req(ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + } } //----------------------------------------------------------------------------- @@ -1309,110 +1395,134 @@ rrc_eNB_generate_RRCConnectionReject( { T(T_ENB_RRC_CONNECTION_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size = + + eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + ue_p->Srb0.Tx_buffer.payload_size = do_RRCConnectionReject(ctxt_pP->module_id, - (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload); + (uint8_t*) ue_p->Srb0.Tx_buffer.Payload); + LOG_DUMPMSG(RRC,DEBUG_RRC, - (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, + (char *)(ue_p->Srb0.Tx_buffer.Payload), + ue_p->Srb0.Tx_buffer.payload_size, "[MSG] RRCConnectionReject\n"); MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, + ue_p->Srb0.Tx_buffer.Header, + ue_p->Srb0.Tx_buffer.payload_size, MSC_AS_TIME_FMT" LTE_RRCConnectionReject UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); + ue_p->Srb0.Tx_buffer.payload_size); LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReject (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); + ue_p->Srb0.Tx_buffer.payload_size); } //----------------------------------------------------------------------------- +/* + * Generate a RCC Connection Reestablishment after requested + */ void rrc_eNB_generate_RRCConnectionReestablishment( - const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - const int CC_id -) + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + const int CC_id) //----------------------------------------------------------------------------- { - LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig; - LTE_SRB_ToAddModList_t **SRB_configList; - LTE_SRB_ToAddMod_t *SRB1_config; - int cnt; - T(T_ENB_RRC_CONNECTION_REESTABLISHMENT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - SRB_configList = &ue_context_pP->ue_context.SRB_configList; - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size = - do_RRCConnectionReestablishment(ctxt_pP, - ue_context_pP, - CC_id, - (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload, - (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), - SRB_configList, - &ue_context_pP->ue_context.physicalConfigDedicated); - LOG_DUMPMSG(RRC,DEBUG_RRC, - (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, - "[MSG] RRCConnectionReestablishment\n" - ); - // configure SRB1 for UE - + int UE_id = -1; + LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL; + LTE_SRB_ToAddModList_t **SRB_configList; + LTE_SRB_ToAddMod_t *SRB1_config = NULL; + rrc_eNB_carrier_data_t *carrier = NULL; + eNB_RRC_UE_t *ue_context = NULL; + + module_id_t module_id = ctxt_pP->module_id; + uint16_t rnti = ctxt_pP->rnti; + + T(T_ENB_RRC_CONNECTION_REESTABLISHMENT, + T_INT(module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(rnti)); + + SRB_configList = &(ue_context_pP->ue_context.SRB_configList); + carrier = &(RC.rrc[ctxt_pP->module_id]->carrier[CC_id]); + ue_context = &(ue_context_pP->ue_context); + + ue_context->Srb0.Tx_buffer.payload_size = do_RRCConnectionReestablishment(ctxt_pP, + ue_context_pP, + CC_id, + (uint8_t *) ue_context->Srb0.Tx_buffer.Payload, + (uint8_t) carrier->p_eNB, // at this point we do not have the UE capability information, so it can only be TM1 or TM2 + rrc_eNB_get_next_transaction_identifier(module_id), + SRB_configList, + &(ue_context->physicalConfigDedicated)); + + LOG_DUMPMSG(RRC, DEBUG_RRC, + (char *)(ue_context->Srb0.Tx_buffer.Payload), + ue_context->Srb0.Tx_buffer.payload_size, + "[MSG] RRCConnectionReestablishment \n"); + + /* Configure SRB1 for UE */ if (*SRB_configList != NULL) { - for (cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { + for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) { SRB1_config = (*SRB_configList)->list.array[cnt]; if (SRB1_config->logicalChannelConfig) { - if (SRB1_config->logicalChannelConfig->present == - LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { - SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; + if (SRB1_config->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + SRB1_logicalChannelConfig = &(SRB1_config->logicalChannelConfig->choice.explicitValue); } else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + SRB1_logicalChannelConfig = &(SRB1_logicalChannelConfig_defaultValue); } } else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + SRB1_logicalChannelConfig = &(SRB1_logicalChannelConfig_defaultValue); } - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_eNB\n", + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_mac_config_req_eNB(ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { + rrc_mac_config_req_eNB(module_id, + ue_context->primaryCC_id, + 0, + 0, + 0, + 0, + 0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - ctxt_pP->rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - (struct LTE_PhysicalConfigDedicated * ) ue_context_pP->ue_context.physicalConfigDedicated, + (struct LTE_PhysicalConfigDedicated * ) ue_context->physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, -#endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - 1, - SRB1_logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, - (LTE_TDD_Config_t *) NULL, - NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_SCellToAddMod_r10_t *)NULL, +#endif + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context->mac_MainConfig, + 1, + SRB1_logicalChannelConfig, + ue_context->measGapConfig, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, + NULL, + NULL, + (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - ,(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + ,(LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , @@ -1423,40 +1533,42 @@ rrc_eNB_generate_RRCConnectionReestablishment( (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif - ); - break; - } - } - } + ); + break; + } + } // if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) + } // for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) + } // if (*SRB_configList != NULL) MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_RRC_UE, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, + ue_context->Srb0.Tx_buffer.Header, + ue_context->Srb0.Tx_buffer.payload_size, MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishment UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_context.rnti, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishment (bytes %d)\n", + ue_context->rnti, + ue_context->Srb0.Tx_buffer.payload_size); + + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishment (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); - int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); + ue_context->Srb0.Tx_buffer.payload_size); - if(UE_id != -1) { - // activate release timer, if RRCComplete not received after 100 frames, remove UE - RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1; - // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered - RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 1000; + UE_id = find_UE_id(module_id, rnti); + + if (UE_id != -1) { + /* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */ + RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1; + /* Reject UE after 10 frames, LTE_RRCConnectionReestablishmentReject is triggered */ + RC.mac[module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 100; } else { - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); + LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + rnti); } - // activate release timer, if RRCComplete not received after 100 frames, remove UE + /* Activate release timer, if RRCComplete not received after 100 frames, remove UE */ ue_context_pP->ue_context.ue_reestablishment_timer = 1; - // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered + /* Remove UE after 100 frames after LTE_RRCConnectionReestablishmentReject is triggered */ ue_context_pP->ue_context.ue_reestablishment_timer_thres = 1000; } @@ -1502,6 +1614,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( /* for no gcc warnings */ (void)dedicatedInfoNas; LTE_C_RNTI_t *cba_RNTI = NULL; + int x2_enabled; uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); ue_context_pP->ue_context.Status = RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED @@ -1524,16 +1637,12 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( } } - SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[next_xid]; - DRB_configList2 = &ue_context_pP->ue_context.DRB_configList2[next_xid]; + SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[next_xid]); + DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[next_xid]); - if(SRB_configList2!=NULL) { - if (*SRB_configList2) { - free(*SRB_configList2); - LOG_D(RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid); - } - } else { - LOG_E(RRC, "SRB_configList2 is null\n"); + if (*SRB_configList2) { + free(*SRB_configList2); + LOG_D(RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid); } *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); @@ -1551,13 +1660,9 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( LOG_W(RRC,"SRB2 configuration does not exist in SRB configuration list\n"); } - if(DRB_configList2!=NULL) { - if (*DRB_configList2) { - free(*DRB_configList2); - LOG_D(RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid); - } - } else { - LOG_E(RRC, "DRB_configList2 is null\n"); + if (*DRB_configList2) { + free(*DRB_configList2); + LOG_D(RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid); } *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); @@ -1574,7 +1679,8 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ue_context_pP->ue_context.Srb1.Active = 1; //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; -#if defined(ENABLE_USE_MME) + + if (EPC_MODE_ENABLED) { hashtable_rc_t h_rc; int j; rrc_ue_s1ap_ids_t *rrc_ue_s1ap_ids_p = NULL; @@ -1619,18 +1725,21 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ctxt_pP->instance, &create_tunnel_req, reestablish_rnti); -#endif + } /* EPC_MODE_ENABLED */ + /* Update RNTI in ue_context */ ue_context_pP->ue_id_rnti = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else ue_context_pP->ue_context.rnti = ctxt_pP->rnti; -#if defined(ENABLE_USE_MME) + + if (EPC_MODE_ENABLED) { uint8_t send_security_mode_command = FALSE; rrc_pdcp_config_security( ctxt_pP, ue_context_pP, send_security_mode_command); LOG_D(RRC, "set security successfully \n"); -#endif + } + // Measurement ID list MeasId_list = CALLOC(1, sizeof(*MeasId_list)); memset((void *)MeasId_list, 0, sizeof(*MeasId_list)); @@ -1734,7 +1843,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1); - if (RC.rrc[ctxt_pP->module_id]->HO_flag == 1 /*HO_MEASURMENT */ ) { + if (RC.rrc[ctxt_pP->module_id]->HO_flag == 1 /*HO_MEASUREMENT */ ) { LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, A5, and A6 event reporting\n", ctxt_pP->module_id, ctxt_pP->frame); ReportConfig_A2->reportConfigId = 3; @@ -1883,7 +1992,6 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( } #endif -#if defined(ENABLE_ITTI) /* Initialize NAS list */ dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); @@ -1907,6 +2015,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( } /* TODO should test if e RAB are Ok before! */ ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; + ue_context_pP->ue_context.e_rab[i].xid = xid; LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); } @@ -1917,7 +2026,8 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( dedicatedInfoNASList = NULL; } -#endif + x2_enabled = is_x2ap_enabled(); + // send LTE_RRCConnectionReconfiguration memset(buffer, 0, RRC_BUF_SIZE); size = do_RRCConnectionReconfiguration(ctxt_pP, @@ -1928,17 +2038,18 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, (struct LTE_SPS_Config *)NULL, // maybe ue_context_pP->ue_context.sps_Config, (struct LTE_PhysicalConfigDedicated *)ue_context_pP->ue_context.physicalConfigDedicated, -#ifdef EXMIMO_IOT - NULL, NULL, NULL,NULL, -#else - (LTE_MeasObjectToAddModList_t *)MeasObj_list, // MeasObj_list, - (LTE_ReportConfigToAddModList_t *)ReportConfig_list, // ReportConfig_list, - (LTE_QuantityConfig_t *)quantityConfig, //quantityConfig, +//#ifdef EXMIMO_IOT +// NULL, NULL, NULL,NULL, +//#else + x2_enabled ? (LTE_MeasObjectToAddModList_t *)MeasObj_list : NULL, // MeasObj_list, + x2_enabled ? (LTE_ReportConfigToAddModList_t *)ReportConfig_list : NULL, // ReportConfig_list, + x2_enabled ? (LTE_QuantityConfig_t *)quantityConfig : NULL, //quantityConfig, (LTE_MeasIdToAddModList_t *)NULL, -#endif +//#endif (LTE_MAC_MainConfig_t *)ue_context_pP->ue_context.mac_MainConfig, (LTE_MeasGapConfig_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, + (LTE_SecurityConfigHO_t *)NULL, (struct LTE_MeasConfig__speedStatePars *)Sparams, // Sparams, (LTE_RSRP_Range_t *)rsrp, // rsrp, (LTE_C_RNTI_t *)cba_RNTI, // cba_RNTI @@ -1951,7 +2062,6 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Connection Reconfiguration\n"); -#if defined(ENABLE_ITTI) /* Free all NAS PDUs */ for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { @@ -1962,8 +2072,6 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( } } -#endif - if(size==65535) { LOG_E(RRC,"RRC decode err!!! do_RRCConnectionReconfiguration\n"); put_UE_in_freelist(ctxt_pP->module_id, reestablish_rnti, 0); @@ -2048,6 +2156,7 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( ) //----------------------------------------------------------------------------- { + if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); if(UE_id != -1) { @@ -2058,29 +2167,34 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishmentReject without UE_id(MAC) rnti %x\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); } - + } T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size = + + eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + + ue_p->Srb0.Tx_buffer.payload_size = do_RRCConnectionReestablishmentReject(ctxt_pP->module_id, - (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload); + (uint8_t*) ue_p->Srb0.Tx_buffer.Payload); + LOG_DUMPMSG(RRC,DEBUG_RRC, - (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, + (char *)(ue_p->Srb0.Tx_buffer.Payload), + ue_p->Srb0.Tx_buffer.payload_size, "[MSG] RRCConnectionReestablishmentReject\n"); MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, + ue_p->Srb0.Tx_buffer.Header, + ue_p->Srb0.Tx_buffer.payload_size, MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishmentReject UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); + ue_p->Srb0.Tx_buffer.payload_size); + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishmentReject (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); + ue_p->Srb0.Tx_buffer.payload_size); } //----------------------------------------------------------------------------- @@ -2147,19 +2261,28 @@ rrc_eNB_generate_RRCConnectionRelease( } pthread_mutex_unlock(&rrc_release_freelist); - rrc_data_req(ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD); + F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti; + F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; + F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = buffer; + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = size; + itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m); + } else { + rrc_data_req(ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + } } uint8_t qci_to_priority[9]= {2,4,3,5,1,6,7,8,9}; // TBD: this directive can be remived if we create a similar e_rab_param_t structure in RRC context -#if defined(ENABLE_ITTI) //----------------------------------------------------------------------------- void rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, @@ -2363,7 +2486,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *co (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, (struct LTE_SPS_Config *)NULL, // *sps_Config, NULL, NULL, NULL, NULL,NULL, - NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, (LTE_SL_CommConfig_r12_t *)NULL, (LTE_SL_DiscConfig_r12_t *)NULL @@ -2372,7 +2495,6 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *co #endif ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Connection Reconfiguration\n"); -#if defined(ENABLE_ITTI) /* Free all NAS PDUs */ for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { @@ -2383,7 +2505,6 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *co } } -#endif LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); @@ -2614,7 +2735,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *cons (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, (struct LTE_SPS_Config *)NULL, // *sps_Config, NULL, NULL, NULL, NULL,NULL, - NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, (LTE_SL_CommConfig_r12_t *)NULL, (LTE_SL_DiscConfig_r12_t *)NULL @@ -2624,7 +2745,6 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *cons ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Connection Reconfiguration\n"); -#if defined(ENABLE_ITTI) /* Free all NAS PDUs */ for (i = 0; i < ue_context_pP->ue_context.nb_of_modify_e_rabs; i++) { @@ -2635,7 +2755,6 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *cons } } -#endif LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); @@ -2729,6 +2848,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ NULL, NULL, NULL, + NULL, (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, (LTE_SL_CommConfig_r12_t *)NULL, (LTE_SL_DiscConfig_r12_t *)NULL @@ -2739,7 +2859,6 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ ue_context_pP->ue_context.e_rab_release_command_flag = 1; LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Connection Reconfiguration\n"); -#if defined(ENABLE_ITTI) /* Free all NAS PDUs */ if (nas_length > 0) { @@ -2747,7 +2866,6 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ free(nas_buffer); } -#endif LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); @@ -2773,20 +2891,22 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ buffer, PDCP_TRANSMISSION_MODE_CONTROL); } -#endif + //----------------------------------------------------------------------------- -void -rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - const uint8_t ho_state - ) +/* + * Generate the basic (first) RRC Connection Reconfiguration (non BR UE) + */ +void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + const uint8_t ho_state) //----------------------------------------------------------------------------- { - uint8_t buffer[RRC_BUF_SIZE]; - uint16_t size; - int i; - // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE - eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size; + int i; + + /* Configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE */ + eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; struct LTE_SRB_ToAddMod *SRB2_config = NULL; struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; @@ -2794,7 +2914,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB2_ul_SpecificParameters = NULL; LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; - LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; + LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; struct LTE_DRB_ToAddMod *DRB_config = NULL; struct LTE_RLC_Config *DRB_rlc_config = NULL; struct LTE_PDCP_Config *DRB_pdcp_config = NULL; @@ -2804,7 +2924,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; LTE_DRB_ToAddModList_t **DRB_configList = &ue_context_pP->ue_context.DRB_configList; - LTE_DRB_ToAddModList_t **DRB_configList2 = NULL; + LTE_DRB_ToAddModList_t **DRB_configList2 = NULL; LTE_MAC_MainConfig_t *mac_MainConfig = NULL; LTE_MeasObjectToAddModList_t *MeasObj_list = NULL; LTE_MeasObjectToAddMod_t *MeasObj = NULL; @@ -2813,26 +2933,31 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; LTE_MeasIdToAddModList_t *MeasId_list = NULL; LTE_MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; + #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - long *sr_ProhibitTimer_r9 = NULL; - // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); - //uint8_t sCellIndexToAdd = 0; + long *sr_ProhibitTimer_r9 = NULL; #endif - long *logicalchannelgroup, *logicalchannelgroup_drb; - long *maxHARQ_Tx, *periodicBSR_Timer; + + long *logicalchannelgroup = NULL; + long *logicalchannelgroup_drb = NULL; + long *maxHARQ_Tx = NULL; + long *periodicBSR_Timer = NULL; LTE_RSRP_Range_t *rsrp = NULL; struct LTE_MeasConfig__speedStatePars *Sparams = NULL; LTE_QuantityConfig_t *quantityConfig = NULL; - LTE_CellsToAddMod_t *CellToAdd = NULL; - LTE_CellsToAddModList_t *CellsToAddModList = NULL; - struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList + *dedicatedInfoNASList = NULL; LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; - /* for no gcc warnings */ - (void)dedicatedInfoNas; + + /* For no gcc warnings */ + (void) dedicatedInfoNas; LTE_C_RNTI_t *cba_RNTI = NULL; + int x2_enabled; uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, -#ifdef CBA - //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; + uint8_t cc_id = ue_context_pP->ue_context.primaryCC_id; + LTE_UE_EUTRA_Capability_t *UEcap = ue_context_pP->ue_context.UE_Capability; + +#ifdef CBA // Contention Based Access uint8_t *cba_RNTI_buf; cba_RNTI = CALLOC(1, sizeof(LTE_C_RNTI_t)); cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t)); @@ -2840,27 +2965,33 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons cba_RNTI->size = 2; cba_RNTI->bits_unused = 0; - // associate UEs to the CBa groups as a function of their UE id + /* Associate UEs to the CBA groups as a function of their UE id */ if (rrc_inst->num_active_cba_groups) { cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff; cba_RNTI->buf[1] = 0xff; - LOG_D(RRC, - "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n", - enb_mod_idP, frameP, + LOG_D(RRC, "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n", + enb_mod_idP, + frameP, rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups], ue_mod_idP % rrc_inst->num_active_cba_groups, ue_mod_idP); } else { cba_RNTI->buf[0] = 0x0; cba_RNTI->buf[1] = 0x0; - LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", enb_mod_idP, frameP, ue_mod_idP); + LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", + enb_mod_idP, + frameP, + ue_mod_idP); } - #endif - T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - // Configure SRB2 - /// SRB2 - SRB_configList2=&ue_context_pP->ue_context.SRB_configList2[xid]; + + T(T_ENB_RRC_CONNECTION_RECONFIGURATION, + T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(ctxt_pP->rnti)); + + /* Configure SRB2 */ + SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[xid]); if (*SRB_configList2) { free(*SRB_configList2); @@ -2885,22 +3016,19 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs - SRB2_ul_SpecificParameters->prioritisedBitRate = - LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - SRB2_ul_SpecificParameters->bucketSizeDuration = - LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; - // LCG for CCCH and DCCH is 0 as defined in 36331 + SRB2_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + SRB2_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + /* LCG for CCCH and DCCH is 0 as defined in 36331 */ logicalchannelgroup = CALLOC(1, sizeof(long)); *logicalchannelgroup = 0; SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters; - // this list has the configuration for SRB1 and SRB2 - ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); - // this list has only the configuration for SRB2 - ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); + + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); // this list has the configuration for SRB1 and SRB2 + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); // this list has only the configuration for SRB2 - // Configure DRB - //*DRB_configList = CALLOC(1, sizeof(*DRB_configList)); + /* Configure DRB */ // list for all the configured DRB if (*DRB_configList) { free(*DRB_configList); @@ -2908,8 +3036,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons *DRB_configList = CALLOC(1, sizeof(**DRB_configList)); memset(*DRB_configList, 0, sizeof(**DRB_configList)); - // list for the configured DRB for a this xid - DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; + + DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; // list for the configured DRB for a this xid if (*DRB_configList2) { free(*DRB_configList2); @@ -2917,17 +3045,17 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); memset(*DRB_configList2, 0, sizeof(**DRB_configList2)); - /// DRB + DRB_config = CALLOC(1, sizeof(*DRB_config)); DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4 - // DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; //allowed values 1..32 // NN: this is the 1st DRB for this ue, so set it to 1 DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; // (ue_mod_idP+1); //allowed values 1..32, value: x DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2 DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); DRB_config->rlc_Config = DRB_rlc_config; + #ifdef RRC_DEFAULT_RAB_IS_AM DRB_rlc_config->present = LTE_RLC_Config_PR_am; DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; @@ -2940,21 +3068,25 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + #ifdef CBA - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms5;//T_Reordering_ms25; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms5; //T_Reordering_ms25; #else DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; #endif + #endif + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; - /* avoid gcc warnings */ + /* Avoid gcc warnings */ (void)PDCP_rlc_AM; (void)PDCP_rlc_UM; + #ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; @@ -2964,57 +3096,102 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; #endif + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); DRB_config->logicalChannelConfig = DRB_lchan_config; DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; - DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer - DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; - //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - DRB_ul_SpecificParameters->bucketSizeDuration = - LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; // LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) logicalchannelgroup_drb = CALLOC(1, sizeof(long)); *logicalchannelgroup_drb = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config); ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); - //ue_context_pP->ue_context.DRB_configList2[0] = &(*DRB_configList); + + /* MAC Main Config */ + // The different parts of MAC main config are set below mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig)); ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig; mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); maxHARQ_Tx = CALLOC(1, sizeof(long)); *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + + /* BSR reconfiguration */ periodicBSR_Timer = CALLOC(1, sizeof(long)); - *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; //LTE_PeriodicBSR_Timer_r12_infinity; // LTE_PeriodicBSR_Timer_r12_sf64; // LTE_PeriodicBSR_Timer_r12_sf20 mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf5120 mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; - mac_MainConfig->drx_Config = NULL; + + /* PHR reconfiguration */ mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup; - mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf500; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_infinity + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf200; // sf20 = 20 subframes // LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf1000 + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3; // Value dB1 =1 dB, dB3 = 3 dB + + if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + /* CDRX Configuration */ + // Need to check if UE is a BR UE + rnti_t rnti = ue_context_pP->ue_id_rnti; + module_id_t module_id = ctxt_pP->module_id; + int UE_id = find_UE_id(module_id, rnti); + eNB_MAC_INST *mac = RC.mac[module_id]; + UE_list_t *UE_list = &(mac->UE_list); + + if (UE_id != -1) { + if ((rrc_inst->carrier[cc_id].sib1->tdd_Config == NULL) && + (UE_list->UE_template[ue_context_pP->ue_context.primaryCC_id][UE_id].rach_resource_type == 0)) { + // CDRX can be only configured in case of FDD and non BR UE (09/04/19) + + LOG_D(RRC, "Processing the DRX configuration in RRC Connection Reconfiguration\n"); + + /* Process the IE drx_Config */ + if (cc_id < MAX_NUM_CCs) { + mac_MainConfig->drx_Config = do_DrxConfig(module_id, cc_id, &rrc_inst->configuration, UEcap); // drx_Config IE + } else { + LOG_E(RRC, "Invalid CC_id for DRX configuration\n"); + } + + /* Set timers and thresholds values in local MAC context of UE */ + eNB_Config_Local_DRX(module_id, ue_context_pP->ue_id_rnti, mac_MainConfig->drx_Config); + + LOG_D(RRC, "DRX configured in mac main config for RRC Connection Reconfiguration\n"); + + } else { // CDRX not implemented for TDD and LTE-M (09/04/19) + mac_MainConfig->drx_Config = NULL; + } + } else { // UE_id invalid + LOG_E(RRC, "Invalid UE_id found!\n"); + mac_MainConfig->drx_Config = NULL; + } + } else { // No CDRX with the CU/DU split in this version + LOG_E(RRC, "CU/DU split activated\n"); + mac_MainConfig->drx_Config = NULL; + } + #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); - *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR + *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2 = 2*SR mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1)); mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9; - //sps_RA_ConfigList_rlola = NULL; #endif - //change the transmission mode for the primary component carrier - //TODO: add codebook subset restriction here - //TODO: change TM for secondary CC in SCelltoaddmodlist + // change the transmission mode for the primary component carrier + // TODO: add codebook subset restriction here + // TODO: change TM for secondary CC in SCelltoaddmodlist if (*physicalConfigDedicated) { if ((*physicalConfigDedicated)->antennaInfo) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode; LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode); + if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm3) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); @@ -3024,8 +3201,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; - } - else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) { + } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = @@ -3034,8 +3210,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; - } - else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) { + } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = @@ -3044,8 +3219,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; - } - else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) { + } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = @@ -3055,23 +3229,24 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4; } - } - else { + } else { LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); } - if ((*physicalConfigDedicated)->cqi_ReportConfig) { + /* CSI RRC Reconfiguration */ + if ((*physicalConfigDedicated)->cqi_ReportConfig != NULL) { + if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm4) || + (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm6)) { + + // feedback mode needs to be set as well + // TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable + LOG_I(RRC, "Setting cqi reporting mode to rm31 (hardcoded)\n"); - if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) || - (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) || - (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6)) { - //feedback mode needs to be set as well - //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable - printf("setting cqi reporting mode to rm31\n"); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic) = LTE_CQI_ReportModeAperiodic_rm31; // HLC CQI, single PMI #else - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic) = LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, single PMI #endif } } else { @@ -3123,8 +3298,10 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons memset((void *)MeasObj, 0, sizeof(*MeasObj)); MeasObj->measObjectId = 1; MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA; - MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz - //MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; //band 33, 1.909GHz + MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = + to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0], + RC.rrc[ctxt_pP->module_id]->configuration.downlink_frequency[0], + RC.rrc[ctxt_pP->module_id]->configuration.N_RB_DL[0]); MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25; MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t)); @@ -3132,19 +3309,18 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6; MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB - MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = - (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); - CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; - - // Add adjacent cell lists (6 per eNB) - for (i = 0; i < 6; i++) { - CellToAdd = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd)); - CellToAdd->cellIndex = i + 1; - CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); - CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0; - ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd); - } - + // MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = + // (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); + // CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; + // + // // Add adjacent cell lists (6 per eNB) + // for (i = 0; i < 6; i++) { + // CellToAdd = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd)); + // CellToAdd->cellIndex = i + 1; + // CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); + // CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0; + // ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd); + // } ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj); // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list; // Report Configurations for periodical, A1-A5 events @@ -3183,132 +3359,108 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1); + //if (ho_state == 1 /*HO_MEASURMENT */ ) { + LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, and A5 event reporting\n", + ctxt_pP->module_id, ctxt_pP->frame); + ReportConfig_A2->reportConfigId = 3; + ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present = + LTE_ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA2.a2_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA2.a2_Threshold.choice.threshold_RSRP = 10; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity = + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; + ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A2); + ReportConfig_A3->reportConfigId = 4; + ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = + LTE_ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 0; //10; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA3.reportOnLeave = 1; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity = + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0; // FIXME ...hysteresis is of type long! + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = + LTE_TimeToTrigger_ms40; + ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3); + ReportConfig_A4->reportConfigId = 5; + ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = + LTE_ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA4.a4_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA4.a4_Threshold.choice.threshold_RSRP = 10; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity = + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; + ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A4); + ReportConfig_A5->reportConfigId = 6; + ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = + LTE_ReportConfigEUTRA__triggerType_PR_event; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA5.a5_Threshold2.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA5.a5_Threshold1.choice.threshold_RSRP = 10; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA5.a5_Threshold2.choice.threshold_RSRP = 10; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity = + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; + ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5); + // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; + rsrp = CALLOC(1, sizeof(LTE_RSRP_Range_t)); + *rsrp = 20; + Sparams = CALLOC(1, sizeof(*Sparams)); + Sparams->present = LTE_MeasConfig__speedStatePars_PR_setup; + Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75; + Sparams->choice.setup.timeToTrigger_SF.sf_Medium = LTE_SpeedStateScaleFactors__sf_High_oDot5; + Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh = 10; + Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5; + Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60; + Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120; + quantityConfig = CALLOC(1, sizeof(*quantityConfig)); + memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); + quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA)); + memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA)); + quantityConfig->quantityConfigCDMA2000 = NULL; + quantityConfig->quantityConfigGERAN = NULL; + quantityConfig->quantityConfigUTRA = NULL; + quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = + CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP))); + quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = + CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ))); + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; - if (ho_state == 1 /*HO_MEASURMENT */ ) { - LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, A5, and A6 event reporting\n", - ctxt_pP->module_id, ctxt_pP->frame); - ReportConfig_A2->reportConfigId = 3; - ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present = - LTE_ReportConfigEUTRA__triggerType_PR_event; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA2.a2_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA2.a2_Threshold.choice.threshold_RSRP = 10; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity = - LTE_ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A2); - ReportConfig_A3->reportConfigId = 4; - ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = - LTE_ReportConfigEUTRA__triggerType_PR_event; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 1; //10; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA3.reportOnLeave = 1; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity = - LTE_ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0.5; // FIXME ...hysteresis is of type long! - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = - LTE_TimeToTrigger_ms40; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3); - ReportConfig_A4->reportConfigId = 5; - ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = - LTE_ReportConfigEUTRA__triggerType_PR_event; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA4.a4_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA4.a4_Threshold.choice.threshold_RSRP = 10; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity = - LTE_ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A4); - ReportConfig_A5->reportConfigId = 6; - ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = - LTE_ReportConfigEUTRA__triggerType_PR_event; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA5.a5_Threshold2.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA5.a5_Threshold1.choice.threshold_RSRP = 10; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA5.a5_Threshold2.choice.threshold_RSRP = 10; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity = - LTE_ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5); - // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; - rsrp = CALLOC(1, sizeof(LTE_RSRP_Range_t)); - *rsrp = 20; - Sparams = CALLOC(1, sizeof(*Sparams)); - Sparams->present = LTE_MeasConfig__speedStatePars_PR_setup; - Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75; - Sparams->choice.setup.timeToTrigger_SF.sf_Medium = LTE_SpeedStateScaleFactors__sf_High_oDot5; - Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh = 10; - Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5; - Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60; - Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120; - quantityConfig = CALLOC(1, sizeof(*quantityConfig)); - memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); - quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA)); - memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA)); - quantityConfig->quantityConfigCDMA2000 = NULL; - quantityConfig->quantityConfigGERAN = NULL; - quantityConfig->quantityConfigUTRA = NULL; - quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = - CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP))); - quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = - CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ))); - *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; - *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; - LOG_I(RRC, - "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n", - ctxt_pP->module_id, ctxt_pP->frame); - // store the information in an intermediate structure for Hanodver management - //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof()); - ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info))); - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(LTE_SRB_ToAddModList_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2; - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(LTE_DRB_ToAddModList_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList = *DRB_configList; - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig = - CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig)); - memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, - (void *)mac_MainConfig, sizeof(LTE_MAC_MainConfig_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated = - CALLOC(1, sizeof(LTE_PhysicalConfigDedicated_t)); - memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, - (void *)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t)); - ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL; - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t)); - } - -#if defined(ENABLE_ITTI) /* Initialize NAS list */ dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); @@ -3329,7 +3481,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; } - /* TODO should test if e RAB are Ok before! */ + + /* TODO should test if e RAB are OK before! */ ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); @@ -3341,40 +3494,38 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons dedicatedInfoNASList = NULL; } -#endif + x2_enabled = is_x2ap_enabled(); + memset(buffer, 0, RRC_BUF_SIZE); + size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, - xid, //Transaction_id, - (LTE_SRB_ToAddModList_t *)*SRB_configList2, // SRB_configList - (LTE_DRB_ToAddModList_t *)*DRB_configList, - (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, - (struct LTE_SPS_Config *)NULL, // *sps_Config, - (struct LTE_PhysicalConfigDedicated *)*physicalConfigDedicated, -#ifdef EXMIMO_IOT - NULL, NULL, NULL,NULL, -#else - (LTE_MeasObjectToAddModList_t *)MeasObj_list, - (LTE_ReportConfigToAddModList_t *)ReportConfig_list, - (LTE_QuantityConfig_t *)quantityConfig, - (LTE_MeasIdToAddModList_t *)MeasId_list, -#endif - (LTE_MAC_MainConfig_t *)mac_MainConfig, - (LTE_MeasGapConfig_t *)NULL, - (LTE_MobilityControlInfo_t *)NULL, - (struct LTE_MeasConfig__speedStatePars *)Sparams, - (LTE_RSRP_Range_t *)rsrp, - (LTE_C_RNTI_t *)cba_RNTI, - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, - (LTE_SL_CommConfig_r12_t *)NULL, - (LTE_SL_DiscConfig_r12_t *)NULL + xid, // Transaction_id, + (LTE_SRB_ToAddModList_t *) *SRB_configList2, // SRB_configList + (LTE_DRB_ToAddModList_t *) *DRB_configList, + (LTE_DRB_ToReleaseList_t *) NULL, // DRB2_list, + (struct LTE_SPS_Config *) NULL, // *sps_Config, + (struct LTE_PhysicalConfigDedicated *) *physicalConfigDedicated, + x2_enabled ? (LTE_MeasObjectToAddModList_t *) MeasObj_list : NULL, + x2_enabled ? (LTE_ReportConfigToAddModList_t *) ReportConfig_list : NULL, + x2_enabled ? (LTE_QuantityConfig_t *) quantityConfig : NULL, + x2_enabled ? (LTE_MeasIdToAddModList_t *) MeasId_list : NULL, + (LTE_MAC_MainConfig_t *) mac_MainConfig, + (LTE_MeasGapConfig_t *) NULL, + (LTE_MobilityControlInfo_t *) NULL, + (LTE_SecurityConfigHO_t *) NULL, + (struct LTE_MeasConfig__speedStatePars *) Sparams, + (LTE_RSRP_Range_t *) rsrp, + (LTE_C_RNTI_t *) cba_RNTI, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *) dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t *) NULL, + (LTE_SL_DiscConfig_r12_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_SCellToAddMod_r10_t *)NULL + , (LTE_SCellToAddMod_r10_t *) NULL #endif ); - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, - "[MSG] RRC Connection Reconfiguration\n"); -#if defined(ENABLE_ITTI) + + LOG_DUMPMSG(RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Connection Reconfiguration\n"); /* Free all NAS PDUs */ for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { @@ -3385,31 +3536,38 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *cons } } -#endif - LOG_I(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", - ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - LOG_D(RRC, - "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", - ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - buffer, - size, - MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_context.rnti, - rrc_eNB_mui, - size); - rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", + ctxt_pP->module_id, + ctxt_pP->frame, + size, + ue_context_pP->ue_context.rnti); + + LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", + ctxt_pP->frame, + ctxt_pP->module_id, + size, + ue_context_pP->ue_context.rnti, + rrc_eNB_mui, + ctxt_pP->module_id, + DCCH); + + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_eNB_mui, + size); + + rrc_data_req(ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } //----------------------------------------------------------------------------- @@ -3469,6 +3627,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt /* for no gcc warnings */ (void)dedicatedInfoNas; LTE_C_RNTI_t *cba_RNTI = NULL; + int x2_enabled; uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, #ifdef CBA //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; @@ -3653,8 +3812,9 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt if ((*physicalConfigDedicated)->antennaInfo) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode; LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode); + if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm3) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; @@ -3663,7 +3823,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; @@ -3671,10 +3831,8 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; - } - else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) { - - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; @@ -3682,10 +3840,8 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; - } - - else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; @@ -3693,21 +3849,20 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4; - } - } - else { + } else { LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); } - if ((*physicalConfigDedicated)->cqi_ReportConfig) { - if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) || - (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) || - (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6)) { + /* CSI Configuration through RRC */ + if ((*physicalConfigDedicated)->cqi_ReportConfig != NULL) { + if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm4) || + (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode == LTE_AntennaInfoDedicated__transmissionMode_tm6)) { + //feedback mode needs to be set as well + //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable + LOG_I(RRC, "Setting cqi aperiodic reporting mode to rm31 (hardcoded)\n"); - //feedback mode needs to be set as well - //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable - printf("setting cqi reporting mode to rm31\n"); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; #else @@ -3810,7 +3965,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ))); *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; -#if defined(ENABLE_ITTI) /* Initialize NAS list */ dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); @@ -3843,7 +3997,8 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt dedicatedInfoNASList = NULL; } -#endif + x2_enabled = is_x2ap_enabled(); + memset(buffer, 0, RRC_BUF_SIZE); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, @@ -3856,14 +4011,15 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt // #ifdef EXMIMO_IOT // NULL, NULL, NULL,NULL, // #else - (LTE_MeasObjectToAddModList_t *)MeasObj_list, - (LTE_ReportConfigToAddModList_t *)ReportConfig_list, - (LTE_QuantityConfig_t *)quantityConfig, - (LTE_MeasIdToAddModList_t *)MeasId_list, + x2_enabled ? (LTE_MeasObjectToAddModList_t *)MeasObj_list : NULL, + x2_enabled ? (LTE_ReportConfigToAddModList_t *)ReportConfig_list : NULL, + x2_enabled ? (LTE_QuantityConfig_t *)quantityConfig : NULL, + x2_enabled ? (LTE_MeasIdToAddModList_t *)MeasId_list : NULL, // #endif (LTE_MAC_MainConfig_t *)mac_MainConfig, (LTE_MeasGapConfig_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, + (LTE_SecurityConfigHO_t *)NULL, (struct LTE_MeasConfig__speedStatePars *)Sparams, (LTE_RSRP_Range_t *)rsrp, (LTE_C_RNTI_t *)cba_RNTI, @@ -3876,7 +4032,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Connection Reconfiguration\n"); -#if defined(ENABLE_ITTI) /* Free all NAS PDUs */ for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { @@ -3887,7 +4042,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt } } -#endif LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); @@ -3955,6 +4109,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( (LTE_MAC_MainConfig_t *)NULL, (LTE_MeasGapConfig_t *)NULL, (LTE_MobilityControlInfo_t *)NULL, + (LTE_SecurityConfigHO_t *)NULL, (struct LTE_MeasConfig__speedStatePars *)NULL, (LTE_RSRP_Range_t *)NULL, (LTE_C_RNTI_t *)NULL, @@ -4000,6 +4155,11 @@ rrc_eNB_process_MeasurementReport( { int i=0; int neighboring_cells=-1; + int ncell_index = 0; + long ncell_max = -150; + uint32_t earfcn_dl; + uint8_t KeNB_star[32] = { 0 }; + T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -4012,6 +4172,38 @@ rrc_eNB_process_MeasurementReport( } ue_context_pP->ue_context.measResults->measId=measResults2->measId; + + switch (measResults2->measId) { + case 1: + LOG_D(RRC,"Periodic report at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe); + break; + + case 2: + LOG_D(RRC,"A1 event report (Serving becomes better than absolute threshold) at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe); + break; + + case 3: + LOG_D(RRC,"A2 event report (Serving becomes worse than absolute threshold) at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe); + break; + + case 4: + LOG_D(RRC,"A3 event report (Neighbour becomes amount of offset better than PCell) at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe); + break; + + case 5: + LOG_D(RRC,"A4 event report (Neighbour becomes better than absolute threshold) at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe); + break; + + case 6: + LOG_D(RRC,"A5 event report (PCell becomes worse than absolute threshold1 AND Neighbour becomes better than another absolute threshold2) at frame %d and subframe %d \n", ctxt_pP->frame, + ctxt_pP->subframe); + break; + + default: + LOG_D(RRC,"Other event report frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe); + break; + } + ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult=measResults2->measResultPCell.rsrpResult; ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult=measResults2->measResultPCell.rsrqResult; LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRP of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId, @@ -4027,308 +4219,480 @@ rrc_eNB_process_MeasurementReport( neighboring_cells = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count; if (ue_context_pP->ue_context.measResults->measResultNeighCells == NULL) { - ue_context_pP->ue_context.measResults->measResultNeighCells = CALLOC(1, sizeof(*measResults2->measResultNeighCells)*neighboring_cells); + ue_context_pP->ue_context.measResults->measResultNeighCells = CALLOC(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells)); } - ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count = neighboring_cells; - for (i=0; i < neighboring_cells; i++) { - memcpy (ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i], - measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i], - sizeof(LTE_MeasResultListEUTRA_t)); + if (i>=ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count) { + //printf("NeighCells number: %d \n", ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count); + ASN_SEQUENCE_ADD(&ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list,measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]); + } + + ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId = + measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId; + ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult = + measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult; + ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult = + measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult; LOG_D(RRC, "Physical Cell Id %d\n", (int)ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId); - LOG_D(RRC, "RSRP of Target %d\n", - (int)*(ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult)); - LOG_D(RRC, "RSRQ of Target %d\n", - (int)*(ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult)); + LOG_D(RRC, "RSRP of Target %ld\n", + (*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult)-140); + LOG_D(RRC, "RSRQ of Target %ld\n", + (*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult)/2 - 20); + + if ( *measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult >= ncell_max ) { + ncell_max = *measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult; + ncell_index = i; + } + + //LOG_D(RRC, "Physical Cell Id2 %d\n", + //(int)measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId); + //LOG_D(RRC, "RSRP of Target2 %ld\n", + //(*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]-> + //measResult.rsrpResult))-140); + //LOG_D(RRC, "RSRQ of Target2 %ld\n", + //(*(measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]-> + //measResult.rsrqResult))/2 - 20); } } - // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - // #else - // LOG_I(RRC, "RSRP of Source %d\n", measResults2->measResultServCell.rsrpResult); - // LOG_I(RRC, "RSRQ of Source %d\n", measResults2->measResultServCell.rsrqResult); - // #endif - // if (ue_context_pP->ue_context.handover_info->ho_prepare != 0xF0) { - // rrc_eNB_generate_HandoverPreparationInformation(ctxt_pP, - // ue_context_pP, - // measResults2->measResultNeighCells->choice. - // measResultListEUTRA.list.array[0]->physCellId); - // } else { - // LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame, - // ctxt_pP->rnti); - // } - //Look for IP address of the target eNB - //Send Handover Request -> target eNB - //Wait for Handover Acknowledgement <- target eNB - //Send Handover Command - //x2delay(); - // handover_request_x2(ue_mod_idP,enb_mod_idP,measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId); - // uint8_t buffer[100]; - // int size=rrc_eNB_generate_Handover_Command_TeNB(0,0,buffer); - // - // send_check_message((char*)buffer,size); - //send_handover_command(); + /* Decide whether to trigger HO or not */ + if (!(measResults2->measId == 4)) + return; + + /* if X2AP is disabled, do nothing */ + if (!is_x2ap_enabled()) + return; + + LOG_D(RRC, "A3 event is triggered...\n"); + + /* if the UE is not in handover mode, start handover procedure */ + if (ue_context_pP->ue_context.Status != RRC_HO_EXECUTION) { + MessageDef *msg; + LOG_I(RRC, "Send HO preparation message at frame %d and subframe %d \n", ctxt_pP->frame, ctxt_pP->subframe); + /* HO info struct may not be needed anymore */ + ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info))); + ue_context_pP->ue_context.Status = RRC_HO_EXECUTION; + ue_context_pP->ue_context.handover_info->state = HO_REQUEST; + /* HO Preparation message */ + msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ); + rrc_eNB_generate_HandoverPreparationInformation( + ue_context_pP, + X2AP_HANDOVER_REQ(msg).rrc_buffer, + &X2AP_HANDOVER_REQ(msg).rrc_buffer_size); + X2AP_HANDOVER_REQ(msg).rnti = ctxt_pP->rnti; + X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice. + measResultListEUTRA.list.array[ncell_index]->physCellId; + X2AP_HANDOVER_REQ(msg).ue_gummei.mcc = ue_context_pP->ue_context.ue_gummei.mcc; + X2AP_HANDOVER_REQ(msg).ue_gummei.mnc = ue_context_pP->ue_context.ue_gummei.mnc; + X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len = ue_context_pP->ue_context.ue_gummei.mnc_len; + X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code = ue_context_pP->ue_context.ue_gummei.mme_code; + X2AP_HANDOVER_REQ(msg).ue_gummei.mme_group_id = ue_context_pP->ue_context.ue_gummei.mme_group_id; + // Don't know how to get this ID? + X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ue_context_pP->ue_context.mme_ue_s1ap_id; + X2AP_HANDOVER_REQ(msg).security_capabilities = ue_context_pP->ue_context.security_capabilities; + // compute keNB* + earfcn_dl = (uint32_t)to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->carrier[0].eutra_band, RC.rrc[ctxt_pP->module_id]->carrier[0].dl_CarrierFreq, + RC.rrc[ctxt_pP->module_id]->carrier[0].N_RB_DL); + derive_keNB_star(ue_context_pP->ue_context.kenb, X2AP_HANDOVER_REQ(msg).target_physCellId, earfcn_dl, true, KeNB_star); + memcpy(X2AP_HANDOVER_REQ(msg).kenb, KeNB_star, 32); + X2AP_HANDOVER_REQ(msg).kenb_ncc = ue_context_pP->ue_context.kenb_ncc; + //X2AP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr; + X2AP_HANDOVER_REQ(msg).nb_e_rabs_tobesetup = ue_context_pP->ue_context.setup_e_rabs; + + for (int i=0; i<ue_context_pP->ue_context.setup_e_rabs; i++) { + X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].e_rab_id = ue_context_pP->ue_context.e_rab[i].param.e_rab_id; + X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr = ue_context_pP->ue_context.e_rab[i].param.sgw_addr; + X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].gtp_teid = ue_context_pP->ue_context.e_rab[i].param.gtp_teid; + X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.qci = ue_context_pP->ue_context.e_rab[i].param.qos.qci; + X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.priority_level; + X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_capability; + X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_vulnerability; + } + + /* TODO: don't do that, X2AP should find the target by itself */ + //X2AP_HANDOVER_REQ(msg).target_mod_id = 0; + LOG_I(RRC, + "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n", + ctxt_pP->module_id, ctxt_pP->frame); + itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg); + } else { + LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame, + ctxt_pP->rnti); + } } //----------------------------------------------------------------------------- void rrc_eNB_generate_HandoverPreparationInformation( - const protocol_ctxt_t *const ctxt_pP, + //const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, - LTE_PhysCellId_t targetPhyId -) -//----------------------------------------------------------------------------- -{ + uint8_t *buffer, + int *_size +) { + memset(buffer, 0, RRC_BUF_SIZE); + char *ho_buf = (char *) buffer; + int ho_size; + ho_size = do_HandoverPreparation(ho_buf, 1024, ue_context_pP->ue_context.UE_Capability, ue_context_pP->ue_context.UE_Capability_size); + *_size = ho_size; +} + +void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m) { struct rrc_eNB_ue_context_s *ue_context_target_p = NULL; - //uint8_t UE_id_target = -1; - uint8_t mod_id_target = get_adjacent_cell_mod_id(targetPhyId); - HANDOVER_INFO *handoverInfo = CALLOC(1, sizeof(*handoverInfo)); - /* - uint8_t buffer[100]; - uint8_t size; - struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &RC.rrc[enb_mod_idP]->physicalConfigDedicated[ue_mod_idP]; - RadioResourceConfigDedicated_t *radioResourceConfigDedicated = CALLOC(1,sizeof(RadioResourceConfigDedicated_t)); - */ - T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - handoverInfo->as_config.antennaInfoCommon.antennaPortsCount = 0; //Not used 0- but check value - handoverInfo->as_config.sourceDl_CarrierFreq = 36090; //Verify! - memcpy((void *)&handoverInfo->as_config.sourceMasterInformationBlock, - (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.mib, sizeof(LTE_MasterInformationBlock_t)); - memcpy((void *)&handoverInfo->as_config.sourceMeasConfig, - (void *)ue_context_pP->ue_context.measConfig, sizeof(LTE_MeasConfig_t)); - // FIXME handoverInfo not used... - free( handoverInfo ); - handoverInfo = 0; - //to be configured - memset((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSecurityAlgorithmConfig, - 0, sizeof(LTE_SecurityAlgorithmConfig_t)); - memcpy((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType1, - (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB1, sizeof(LTE_SystemInformationBlockType1_t)); - memcpy((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType2, - (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB23, sizeof(LTE_SystemInformationBlockType2_t)); - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo = - CALLOC(1, sizeof(LTE_ReestablishmentInfo_t)); - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->sourcePhysCellId = - RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.physCellId; - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.buf = NULL; // Check values later - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.size = 0; - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.bits_unused = 0; - ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->additionalReestabInfoList = NULL; - ue_context_pP->ue_context.handover_info->ho_prepare = 0xFF; //0xF0; - ue_context_pP->ue_context.handover_info->ho_complete = 0; - - if (mod_id_target != 0xFF) { - //UE_id_target = rrc_find_free_ue_index(modid_target); - ue_context_target_p = - rrc_eNB_get_ue_context( - RC.rrc[mod_id_target], - ue_context_pP->ue_context.rnti); + /* TODO: get proper UE rnti */ + int rnti = taus() & 0xffff; + int i; + //global_rnti = rnti; + LTE_HandoverPreparationInformation_t *ho = NULL; + LTE_HandoverPreparationInformation_r8_IEs_t *ho_info; + asn_dec_rval_t dec_rval; + ue_context_target_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - /*UE_id_target = rrc_eNB_get_next_free_UE_index( - mod_id_target, - RC.rrc[ctxt_pP->module_id]->Info.UE_list[ue_mod_idP]); //this should return a new index*/ + if (ue_context_target_p != NULL) { + LOG_E(RRC, "\nError in obtaining free UE id in target eNB for handover \n"); + return; + } - if (ue_context_target_p == NULL) { // if not already in target cell - ue_context_target_p = rrc_eNB_allocate_new_UE_context(RC.rrc[ctxt_pP->module_id]); - ue_context_target_p->ue_id_rnti = ue_context_pP->ue_context.rnti; // LG: should not be the same - ue_context_target_p->ue_context.rnti = ue_context_target_p->ue_id_rnti; // idem - LOG_I(RRC, - "[eNB %d] Frame %d : Emulate sending HandoverPreparationInformation msg from eNB source %d to eNB target %ld: source UE_id %x target UE_id %x source_modId: %d target_modId: %d\n", - ctxt_pP->module_id, - ctxt_pP->frame, - RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.physCellId, - targetPhyId, - ue_context_pP->ue_context.rnti, - ue_context_target_p->ue_id_rnti, - ctxt_pP->module_id, - mod_id_target); - ue_context_target_p->ue_context.handover_info = - CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info))); - memcpy((void *)&ue_context_target_p->ue_context.handover_info->as_context, - (void *)&ue_context_pP->ue_context.handover_info->as_context, - sizeof(LTE_AS_Context_t)); - memcpy((void *)&ue_context_target_p->ue_context.handover_info->as_config, - (void *)&ue_context_pP->ue_context.handover_info->as_config, - sizeof(LTE_AS_Config_t)); - ue_context_target_p->ue_context.handover_info->ho_prepare = 0x00;// 0xFF; - ue_context_target_p->ue_context.handover_info->ho_complete = 0; - ue_context_pP->ue_context.handover_info->modid_t = mod_id_target; - ue_context_pP->ue_context.handover_info->ueid_s = ue_context_pP->ue_context.rnti; - ue_context_pP->ue_context.handover_info->modid_s = ctxt_pP->module_id; - ue_context_target_p->ue_context.handover_info->modid_t = mod_id_target; - ue_context_target_p->ue_context.handover_info->modid_s = ctxt_pP->module_id; - ue_context_target_p->ue_context.handover_info->ueid_t = ue_context_target_p->ue_context.rnti; - } else { - LOG_E(RRC, "\nError in obtaining free UE id in target eNB %ld for handover \n", targetPhyId); - } - } else { - LOG_E(RRC, "\nError in obtaining Module ID of target eNB for handover \n"); + ue_context_target_p = rrc_eNB_allocate_new_UE_context(RC.rrc[mod_id]); + + if (ue_context_target_p == NULL) { + LOG_E(RRC, "Cannot create new UE context\n"); + return; + } + + ue_context_target_p->ue_id_rnti = rnti; + ue_context_target_p->ue_context.rnti = rnti; + RB_INSERT(rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head, ue_context_target_p); + LOG_D(RRC, "eNB %d: Created new UE context uid %u\n", mod_id, ue_context_target_p->local_uid); + ue_context_target_p->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info))); + ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION; + ue_context_target_p->ue_context.handover_info->state = HO_ACK; + ue_context_target_p->ue_context.handover_info->x2_id = m->x2_id; + ue_context_target_p->ue_context.handover_info->assoc_id = m->target_assoc_id; + memset (ue_context_target_p->ue_context.nh, 0, 32); + ue_context_target_p->ue_context.nh_ncc = -1; + memcpy (ue_context_target_p->ue_context.kenb, m->kenb, 32); + ue_context_target_p->ue_context.kenb_ncc = m->kenb_ncc; + ue_context_target_p->ue_context.security_capabilities.encryption_algorithms = m->security_capabilities.encryption_algorithms; + ue_context_target_p->ue_context.security_capabilities.integrity_algorithms = m->security_capabilities.integrity_algorithms; + + dec_rval = uper_decode(NULL, + &asn_DEF_LTE_HandoverPreparationInformation, + (void **)&ho, + m->rrc_buffer, + m->rrc_buffer_size, 0, 0); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_HandoverPreparationInformation, ho); + } + + if (dec_rval.code != RC_OK || + ho->criticalExtensions.present != LTE_HandoverPreparationInformation__criticalExtensions_PR_c1 || + ho->criticalExtensions.choice.c1.present != LTE_HandoverPreparationInformation__criticalExtensions__c1_PR_handoverPreparationInformation_r8) { + LOG_E(RRC, "could not decode Handover Preparation\n"); + abort(); + } + + ho_info = &ho->criticalExtensions.choice.c1.choice.handoverPreparationInformation_r8; + + if (ue_context_target_p->ue_context.UE_Capability) { + LOG_I(RRC, "freeing old UE capabilities for UE %x\n", rnti); + ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, + ue_context_target_p->ue_context.UE_Capability); + ue_context_target_p->ue_context.UE_Capability = 0; + } + + dec_rval = uper_decode(NULL, + &asn_DEF_LTE_UE_EUTRA_Capability, + (void **)&ue_context_target_p->ue_context.UE_Capability, + ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.buf, + ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.size, 0, 0); + + ue_context_target_p->ue_context.UE_Capability_size = ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.size; + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_target_p->ue_context.UE_Capability); + } + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC, "Failed to decode UE capabilities (%zu bytes)\n", dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, + ue_context_target_p->ue_context.UE_Capability); + ue_context_target_p->ue_context.UE_Capability = 0; + } + + ue_context_target_p->ue_context.nb_of_e_rabs = m->nb_e_rabs_tobesetup; + ue_context_target_p->ue_context.setup_e_rabs = m->nb_e_rabs_tobesetup; + ue_context_target_p->ue_context.mme_ue_s1ap_id = m->mme_ue_s1ap_id; + ue_context_target_p->ue_context.ue_gummei.mcc = m->ue_gummei.mcc; + ue_context_target_p->ue_context.ue_gummei.mnc = m->ue_gummei.mnc; + ue_context_target_p->ue_context.ue_gummei.mnc_len = m->ue_gummei.mnc_len; + ue_context_target_p->ue_context.ue_gummei.mme_code = m->ue_gummei.mme_code; + ue_context_target_p->ue_context.ue_gummei.mme_group_id = m->ue_gummei.mme_group_id; + LOG_I(RRC, "eNB %d: Update the E-RABS %u\n", mod_id, ue_context_target_p->ue_context.nb_of_e_rabs); + + for (i = 0; i < ue_context_target_p->ue_context.nb_of_e_rabs; i++) { + ue_context_target_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW; + ue_context_target_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobesetup[i].e_rab_id; + ue_context_target_p->ue_context.e_rab[i].param.sgw_addr = m->e_rabs_tobesetup[i].eNB_addr; + ue_context_target_p->ue_context.e_rab[i].param.gtp_teid= m->e_rabs_tobesetup[i].gtp_teid; + LOG_I(RRC, "eNB %d: Update the UE context after HO, e_rab_id %u gtp_teid %u\n", mod_id, + ue_context_target_p->ue_context.e_rab[i].param.e_rab_id, + ue_context_target_p->ue_context.e_rab[i].param.gtp_teid); } } -//----------------------------------------------------------------------------- -void -rrc_eNB_process_handoverPreparationInformation( - const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP -) -//----------------------------------------------------------------------------- -{ - T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - LOG_I(RRC, - "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending LTE_RRCConnectionReconfiguration to UE %d \n", - ctxt_pP->module_id, ctxt_pP->frame, ue_context_pP->ue_context.rnti); - rrc_eNB_generate_RRCConnectionReconfiguration_handover( - ctxt_pP, - ue_context_pP, - NULL, - 0); +void rrc_eNB_process_handoverCommand( + int mod_id, + struct rrc_eNB_ue_context_s *ue_context, + x2ap_handover_req_ack_t *m) { + asn_dec_rval_t dec_rval; + LTE_HandoverCommand_t *ho = NULL; + dec_rval = uper_decode( + NULL, + &asn_DEF_LTE_HandoverCommand, + (void **)&ho, + m->rrc_buffer, + m->rrc_buffer_size, + 0, + 0); + + if (dec_rval.code != RC_OK || + ho->criticalExtensions.present != LTE_HandoverCommand__criticalExtensions_PR_c1 || + ho->criticalExtensions.choice.c1.present != LTE_HandoverCommand__criticalExtensions__c1_PR_handoverCommand_r8) { + LOG_E(RRC, "could not decode Handover Command\n"); + abort(); + } + + unsigned char *buf = ho->criticalExtensions.choice.c1.choice.handoverCommand_r8.handoverCommandMessage.buf; + int size = ho->criticalExtensions.choice.c1.choice.handoverCommand_r8.handoverCommandMessage.size; + + if (size > RRC_BUF_SIZE) { + printf("%s:%d: fatal\n", __FILE__, __LINE__); + abort(); + } + + memcpy(ue_context->ue_context.handover_info->buf, buf, size); + ue_context->ue_context.handover_info->size = size; } +void rrc_eNB_handover_ue_context_release( + protocol_ctxt_t *const ctxt_pP, + struct rrc_eNB_ue_context_s *ue_context_p) { + int e_rab = 0; + //MessageDef *msg_release_p = NULL; + MessageDef *msg_delete_tunnels_p = NULL; + uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; + + //msg_release_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE); + //itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_release_p); + s1ap_ue_context_release(ctxt_pP->instance, ue_context_p->ue_context.eNB_ue_s1ap_id); + + //MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + + for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = + ue_context_p->ue_context.enb_gtp_ebi[e_rab]; + // erase data + ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); + ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; + } + + itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; + rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); + + if (rrc_ue_s1ap_ids != NULL) { + rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids); + } +} + +/* This function may be incorrect. */ +void rrc_eNB_handover_cancel( + protocol_ctxt_t *const ctxt_pP, + struct rrc_eNB_ue_context_s *ue_context_p) { + int s1_cause = 1; /* 1 = tx2relocoverall-expiry */ + + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(ctxt_pP->module_id, ue_context_p, + S1AP_CAUSE_RADIO_NETWORK, s1_cause); +} -//----------------------------------------------------------------------------- void check_handovers( protocol_ctxt_t *const ctxt_pP ) //----------------------------------------------------------------------------- { - int result; struct rrc_eNB_ue_context_s *ue_context_p; - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head) { + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { ctxt_pP->rnti = ue_context_p->ue_id_rnti; - if (ue_context_p->ue_context.handover_info != NULL) { - if (ue_context_p->ue_context.handover_info->ho_prepare == 0xFF) { + if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION && ue_context_p->ue_context.handover_info != NULL) { + /* in the source, UE in HO_PREPARE mode */ + if (ue_context_p->ue_context.handover_info->state == HO_PREPARE) { LOG_D(RRC, - "[eNB %d] Frame %d: Incoming handover detected for new UE_idx %d (source eNB %d->target eNB %d) \n", + "[eNB %d] Frame %d: Incoming handover detected for new UE_id %x) \n", ctxt_pP->module_id, ctxt_pP->frame, - ctxt_pP->rnti, - ctxt_pP->module_id, - ue_context_p->ue_context.handover_info->modid_t); - // source eNB generates LTE_RRCConnectionreconfiguration to prepare the HO - rrc_eNB_process_handoverPreparationInformation( + ctxt_pP->rnti); + // source eNB generates rrcconnectionreconfiguration to prepare the HO + LOG_I(RRC, + "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending RRCConnectionReconfiguration to UE %d \n", + ctxt_pP->module_id, ctxt_pP->frame, ue_context_p->ue_context.rnti); + rrc_data_req( ctxt_pP, - ue_context_p); - ue_context_p->ue_context.handover_info->ho_prepare = 0xF1; - } - - if (ue_context_p->ue_context.handover_info->ho_complete == 0xF1) { - LOG_D(RRC, - "[eNB %d] Frame %d: handover Command received for new UE_id %x current eNB %d target eNB: %d \n", - ctxt_pP->module_id, - ctxt_pP->frame, - ctxt_pP->rnti, - ctxt_pP->module_id, - ue_context_p->ue_context.handover_info->modid_t); - //rrc_eNB_process_handoverPreparationInformation(enb_mod_idP,frameP,i); - result = pdcp_data_req(ctxt_pP, - SRB_FLAG_YES, DCCH, rrc_eNB_mui++, SDU_CONFIRM_NO, ue_context_p->ue_context.handover_info->size, ue_context_p->ue_context.handover_info->buf, - PDCP_TRANSMISSION_MODE_CONTROL -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL -#endif - ); + PDCP_TRANSMISSION_MODE_CONTROL); + + ue_context_p->ue_context.handover_info->state = HO_COMPLETE; + LOG_I(RRC, "RRC Sends RRCConnectionReconfiguration to UE %d at frame %d and subframe %d \n", ue_context_p->ue_context.rnti, ctxt_pP->frame,ctxt_pP->subframe); + } - //AssertFatal(result == TRUE, "PDCP data request failed!\n"); - if(result != TRUE) { - LOG_I(RRC, "PDCP data request failed!\n"); - return; + /* in the target, UE in HO_ACK mode */ + if (ue_context_p->ue_context.handover_info->state == HO_ACK) { + MessageDef *msg; + // Configure target + ue_context_p->ue_context.handover_info->state = HO_CONFIGURED; + msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ_ACK); + rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p, X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, + &X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size); + rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP); + + X2AP_HANDOVER_REQ_ACK(msg).rnti = ue_context_p->ue_context.rnti; + X2AP_HANDOVER_REQ_ACK(msg).x2_id_target = ue_context_p->ue_context.handover_info->x2_id; + X2AP_HANDOVER_REQ_ACK(msg).source_assoc_id = ue_context_p->ue_context.handover_info->assoc_id; + /* Call admission control not implemented yet */ + X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = ue_context_p->ue_context.setup_e_rabs; + + for (int i=0; i<ue_context_p->ue_context.setup_e_rabs; i++) { + X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id; } - ue_context_p->ue_context.handover_info->ho_complete = 0xF2; + itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg); + LOG_I(RRC, "RRC Sends X2 HO ACK to the source eNB at frame %d and subframe %d \n", ctxt_pP->frame,ctxt_pP->subframe); } } } } -// 5.3.5.4 LTE_RRCConnectionReconfiguration including the mobilityControlInfo to prepare the UE handover -//----------------------------------------------------------------------------- void -rrc_eNB_generate_RRCConnectionReconfiguration_handover( - const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - uint8_t *const nas_pdu, - const uint32_t nas_length -) +rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t *buffer, + int *_size + //const uint8_t ho_state + ) //----------------------------------------------------------------------------- { + uint16_t size; + int i; + uint8_t rv[2]; + // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE + eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; + // phy config dedicated + LTE_PhysicalConfigDedicated_t *physicalConfigDedicated2; + // srb 1: for HO + struct LTE_SRB_ToAddMod *SRB1_config = NULL; + struct LTE_SRB_ToAddMod__rlc_Config *SRB1_rlc_config = NULL; + struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB1_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters + *SRB1_ul_SpecificParameters = NULL; + struct LTE_SRB_ToAddMod *SRB2_config = NULL; + struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; + struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters + *SRB2_ul_SpecificParameters = NULL; + LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; + LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; + struct LTE_DRB_ToAddMod *DRB_config = NULL; + struct LTE_RLC_Config *DRB_rlc_config = NULL; + struct LTE_PDCP_Config *DRB_pdcp_config = NULL; + struct LTE_PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; + struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters + *DRB_ul_SpecificParameters = NULL; + LTE_DRB_ToAddModList_t **DRB_configList = &ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t **DRB_configList2 = NULL; + LTE_MAC_MainConfig_t *mac_MainConfig = NULL; + LTE_MeasObjectToAddModList_t *MeasObj_list = NULL; + LTE_MeasObjectToAddMod_t *MeasObj = NULL; + LTE_ReportConfigToAddModList_t *ReportConfig_list = NULL; + LTE_ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, + *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; + LTE_MeasIdToAddModList_t *MeasId_list = NULL; + LTE_MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + long *sr_ProhibitTimer_r9 = NULL; + // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); + //uint8_t sCellIndexToAdd = 0; +#endif + long *logicalchannelgroup, *logicalchannelgroup_drb; + long *maxHARQ_Tx, *periodicBSR_Timer; + LTE_RSRP_Range_t *rsrp = NULL; + struct LTE_MeasConfig__speedStatePars *Sparams = NULL; + LTE_QuantityConfig_t *quantityConfig = NULL; + LTE_MobilityControlInfo_t *mobilityInfo = NULL; + LTE_SecurityConfigHO_t *securityConfigHO = NULL; + //CellsToAddMod_t *CellToAdd = NULL; + //CellsToAddModList_t *CellsToAddModList = NULL; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; + /* for no gcc warnings */ + (void)dedicatedInfoNas; + LTE_C_RNTI_t *cba_RNTI = NULL; + int x2_enabled; + uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, +#ifdef CBA + //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; + uint8_t *cba_RNTI_buf; + cba_RNTI = CALLOC(1, sizeof(C_RNTI_t)); + cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t)); + cba_RNTI->buf = cba_RNTI_buf; + cba_RNTI->size = 2; + cba_RNTI->bits_unused = 0; + + // associate UEs to the CBa groups as a function of their UE id + if (rrc_inst->num_active_cba_groups) { + cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff; + cba_RNTI->buf[1] = 0xff; + LOG_D(RRC, + "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n", + enb_mod_idP, frameP, + rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups], + ue_mod_idP % rrc_inst->num_active_cba_groups, ue_mod_idP); + } else { + cba_RNTI->buf[0] = 0x0; + cba_RNTI->buf[1] = 0x0; + LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", enb_mod_idP, frameP, ue_mod_idP); + } + +#endif T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - uint8_t buffer[RRC_BUF_SIZE]; - int i; - uint8_t rv[2]; - uint16_t Idx; - // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE - eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; - struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; - struct LTE_SRB_ToAddMod *SRB2_config; - struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config; - struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config; - struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB2_ul_SpecificParameters; - LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL; - LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; // not used in this context: may be removed - LTE_SRB_ToAddModList_t *SRB_configList2; - struct LTE_DRB_ToAddMod *DRB_config; - struct LTE_RLC_Config *DRB_rlc_config; - struct LTE_PDCP_Config *DRB_pdcp_config; - struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM; - struct LTE_LogicalChannelConfig *DRB_lchan_config; - struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters; - LTE_DRB_ToAddModList_t *DRB_configList2; - LTE_MAC_MainConfig_t *mac_MainConfig; - LTE_MeasObjectToAddModList_t *MeasObj_list; - LTE_MeasObjectToAddMod_t *MeasObj; - LTE_ReportConfigToAddModList_t *ReportConfig_list; - LTE_ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, - *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; - LTE_MeasIdToAddModList_t *MeasId_list; - LTE_MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; - LTE_QuantityConfig_t *quantityConfig; - LTE_MobilityControlInfo_t *mobilityInfo; - // HandoverCommand_t handoverCommand; - //uint8_t sourceModId = - // get_adjacent_cell_mod_id(ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->sourcePhysCellId); -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - long *sr_ProhibitTimer_r9; -#endif - long *logicalchannelgroup, *logicalchannelgroup_drb; - long *maxHARQ_Tx, *periodicBSR_Timer; - // LTE_RSRP_Range_t *rsrp; - struct LTE_MeasConfig__speedStatePars *Sparams; - LTE_CellsToAddMod_t *CellToAdd; - LTE_CellsToAddModList_t *CellsToAddModList; - // srb 1: for HO - struct LTE_SRB_ToAddMod *SRB1_config; - struct LTE_SRB_ToAddMod__rlc_Config *SRB1_rlc_config; - struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB1_lchan_config; - struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB1_ul_SpecificParameters; - // phy config dedicated - LTE_PhysicalConfigDedicated_t *physicalConfigDedicated2; - struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList; - protocol_ctxt_t ctxt; - LOG_D(RRC, "[eNB %d] Frame %d: handover preparation: get the newSourceUEIdentity (C-RNTI): ", + rv[0] = (ue_context_pP->ue_context.rnti >> 8) & 255; + rv[1] = ue_context_pP->ue_context.rnti & 255; + LOG_I(RRC, "target UE rnti = %x (decimal: %d)\n", ue_context_pP->ue_context.rnti, ue_context_pP->ue_context.rnti); + LOG_D(RRC, "[eNB %d] Frame %d : handover preparation: add target eNB SRB1 and PHYConfigDedicated reconfiguration\n", ctxt_pP->module_id, ctxt_pP->frame); - for (i = 0; i < 2; i++) { - rv[i] = taus() & 0xff; - LOG_D(RRC, " %x.", rv[i]); + if (SRB_configList) { + free(SRB_configList); } - LOG_D(RRC, "[eNB %d] Frame %d : handover reparation: add target eNB SRB1 and PHYConfigDedicated reconfiguration\n", - ctxt_pP->module_id, ctxt_pP->frame); - // 1st: reconfigure SRB - SRB_configList2 = CALLOC(1, sizeof(*SRB_configList)); + SRB_configList = CALLOC(1, sizeof(*SRB_configList)); + memset(SRB_configList, 0, sizeof(*SRB_configList)); SRB1_config = CALLOC(1, sizeof(*SRB1_config)); SRB1_config->srb_Identity = 1; SRB1_rlc_config = CALLOC(1, sizeof(*SRB1_rlc_config)); @@ -4356,8 +4720,166 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( logicalchannelgroup = CALLOC(1, sizeof(long)); *logicalchannelgroup = 0; SRB1_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; - ASN_SEQUENCE_ADD(&SRB_configList2->list, SRB1_config); - //2nd: now reconfigure phy config dedicated + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB1_config); + ue_context_pP->ue_context.SRB_configList = SRB_configList; + // Configure SRB2 + /// SRB2 + SRB_configList2=&ue_context_pP->ue_context.SRB_configList2[xid]; + + if (*SRB_configList2) { + free(*SRB_configList2); + } + + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); + memset(*SRB_configList2, 0, sizeof(**SRB_configList2)); + SRB2_config = CALLOC(1, sizeof(*SRB2_config)); + SRB2_config->srb_Identity = 2; + SRB2_rlc_config = CALLOC(1, sizeof(*SRB2_rlc_config)); + SRB2_config->rlc_Config = SRB2_rlc_config; + SRB2_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10; + SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config)); + SRB2_config->logicalChannelConfig = SRB2_lchan_config; + SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; + SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); + SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs + SRB2_ul_SpecificParameters->prioritisedBitRate = + LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + SRB2_ul_SpecificParameters->bucketSizeDuration = + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + // LCG for CCCH and DCCH is 0 as defined in 36331 + logicalchannelgroup = CALLOC(1, sizeof(long)); + *logicalchannelgroup = 0; + SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; + SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters; + // this list has the configuration for SRB1 and SRB2 + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); + // this list has only the configuration for SRB2 + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); + + // Configure DRB + //*DRB_configList = CALLOC(1, sizeof(*DRB_configList)); + // list for all the configured DRB + if (*DRB_configList) { + free(*DRB_configList); + } + + *DRB_configList = CALLOC(1, sizeof(**DRB_configList)); + memset(*DRB_configList, 0, sizeof(**DRB_configList)); + // list for the configured DRB for a this xid + DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; + + if (*DRB_configList2) { + free(*DRB_configList2); + } + + *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); + memset(*DRB_configList2, 0, sizeof(**DRB_configList2)); + /// DRB + DRB_config = CALLOC(1, sizeof(*DRB_config)); + DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); + *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4 + // DRB_config->drb_Identity = (DRB_Identity_t) 1; //allowed values 1..32 + // NN: this is the 1st DRB for this ue, so set it to 1 + DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; // (ue_mod_idP+1); //allowed values 1..32, value: x + DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2 + DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); + DRB_config->rlc_Config = DRB_rlc_config; +#ifdef RRC_DEFAULT_RAB_IS_AM + DRB_rlc_config->present = RLC_Config_PR_am; + DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms50; + DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = PollPDU_p16; + DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity; + DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8; + DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; + DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms25; +#else + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; +#ifdef CBA + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms5;//T_Reordering_ms25; +#else + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; +#endif +#endif + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + DRB_config->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + /* avoid gcc warnings */ + (void)PDCP_rlc_AM; + (void)PDCP_rlc_UM; +#ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT + PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); + DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; + PDCP_rlc_AM->statusReportRequired = FALSE; +#else + PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; +#endif + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; + DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); + DRB_config->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer + DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM) + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + *logicalchannelgroup_drb = 1; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config); + ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); + //ue_context_pP->ue_context.DRB_configList2[0] = &(*DRB_configList); + mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig)); + ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig; + mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); + maxHARQ_Tx = CALLOC(1, sizeof(long)); + *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + periodicBSR_Timer = CALLOC(1, sizeof(long)); + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; + mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; + mac_MainConfig->drx_Config = NULL; + mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); + mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + sr_ProhibitTimer_r9 = CALLOC(1, sizeof(long)); + *sr_ProhibitTimer_r9 = 0; // SR tx on PUCCH, Value in number of SR period(s). Value 0 = no timer for SR, Value 2= 2*SR + mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1)); + mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9; + //sps_RA_ConfigList_rlola = NULL; +#endif + + //change the transmission mode for the primary component carrier + //TODO: add codebook subset restriction here + //TODO: change TM for secondary CC in SCelltoaddmodlist + /// now reconfigure phy config dedicated + if (*physicalConfigDedicated) { + free(*physicalConfigDedicated); + } + + //if (*physicalConfigDedicated) { physicalConfigDedicated2 = CALLOC(1, sizeof(*physicalConfigDedicated2)); *physicalConfigDedicated = physicalConfigDedicated2; physicalConfigDedicated2->pdsch_ConfigDedicated = @@ -4373,7 +4895,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH = CALLOC(1, sizeof(*physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH)); physicalConfigDedicated2->cqi_ReportConfig = NULL; //CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig)); - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated)); + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL; //CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated)); physicalConfigDedicated2->antennaInfo = CALLOC(1, sizeof(*physicalConfigDedicated2->antennaInfo)); physicalConfigDedicated2->schedulingRequestConfig = CALLOC(1, sizeof(*physicalConfigDedicated2->schedulingRequestConfig)); @@ -4420,68 +4942,95 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[0] = 0x22; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[1] = 0x34 + ue_context_pP->local_uid; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.bits_unused = 0; - // CQI ReportConfig - /* - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic)); - assign_enum(physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic, - CQI_ReportConfig__cqi_ReportModeAperiodic_rm30); // HLC CQI, no PMI - physicalConfigDedicated2->cqi_ReportConfig->nomPDSCH_RS_EPRE_Offset = 0; // 0 dB - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = CQI_ReportPeriodic_PR_setup; - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex = 0; // n2_pucch - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex = 0; // Icqi/pmi - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present = CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI; // subband CQI - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.choice.subbandCQI.k=4; - - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex=NULL; - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI=0; - */ - //soundingRS-UL-ConfigDedicated - /* - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->present = SoundingRS_UL_ConfigDedicated_PR_setup; - assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth, - SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0); - assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth, - SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0); - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0; - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1; - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=1; - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb=0; - assign_enum(&physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift, - SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0); - */ //AntennaInfoDedicated physicalConfigDedicated2->antennaInfo = CALLOC(1, sizeof(*physicalConfigDedicated2->antennaInfo)); physicalConfigDedicated2->antennaInfo->present = LTE_PhysicalConfigDedicated__antennaInfo_PR_explicitValue; - //assign_enum(&physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode, - // LTE_AntennaInfoDedicated__transmissionMode_tm2); - /* - switch (transmission_mode){ - case 1: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm1; - break; - case 2: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm2; - break; - case 4: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm4; - break; - case 5: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm5; - break; - case 6: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm6; - break; - } - */ + //if ((*physicalConfigDedicated)->antennaInfo) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode; + LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode); + + if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm3) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; + } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; + } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; + } else if (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4; + } + physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.present = LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection_PR_release; physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.release = 0; + //} + //else { + //LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); + //} + // CQI ReportConfig + physicalConfigDedicated2->cqi_ReportConfig = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig)); + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic)); + physicalConfigDedicated2->cqi_ReportConfig->nomPDSCH_RS_EPRE_Offset = 0; // 0 dB + //physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=NULL; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = LTE_CQI_ReportPeriodic_PR_release; + + //if ((*physicalConfigDedicated)->cqi_ReportConfig) { + if ((rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm4) || + (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.radioresourceconfig[0].ue_TransmissionMode==LTE_AntennaInfoDedicated__transmissionMode_tm6)) { + //feedback mode needs to be set as well + //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable + printf("setting cqi reporting mode to rm31\n"); +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; +#else + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI +#endif + } else { +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic= LTE_CQI_ReportModeAperiodic_rm30; +#else + *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CQI_ReportConfig__cqi_ReportModeAperiodic_rm30; // HLC CQI, no PMI +#endif + } + + //} + //else { + //LOG_E(RRC,"cqi_ReportConfig not present in physical_config_dedicated. Not reconfiguring!\n"); + //} // SchedulingRequestConfig physicalConfigDedicated2->schedulingRequestConfig->present = LTE_SchedulingRequestConfig_PR_setup; physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = ue_context_pP->local_uid; - if (rrc_inst->carrier[0].sib1->tdd_Config==NULL) { // FD + if (rrc_inst->carrier[0].sib1->tdd_Config==NULL) { // FDD physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 5 + (ue_context_pP->local_uid % 10); // Isr = 5 (every 10 subframes, offset=2+UE_id mod3) } else { @@ -4536,7 +5085,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( (LTE_MeasObjectToAddMod_t **) NULL, ue_context_pP->ue_context.mac_MainConfig, 1, - SRB1_logicalChannelConfig, + NULL,//SRB1_logicalChannelConfig, ue_context_pP->ue_context.measGapConfig, (LTE_TDD_Config_t *) NULL, (LTE_MobilityControlInfo_t *) NULL, @@ -4593,7 +5142,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( SRB2_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB2_ul_SpecificParameters; ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); - ASN_SEQUENCE_ADD(&SRB_configList2->list, SRB2_config); + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); // Configure target eNB DRB DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2)); /// DRB @@ -4630,7 +5179,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( logicalchannelgroup_drb = CALLOC(1, sizeof(long)); *logicalchannelgroup_drb = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; - ASN_SEQUENCE_ADD(&DRB_configList2->list, DRB_config); + ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig)); ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig; mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); @@ -4688,7 +5237,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( MeasId5->measObjectId = 1; MeasId5->reportConfigId = 6; ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5); - // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; + // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; // Add one EUTRA Measurement Object MeasObj_list = CALLOC(1, sizeof(*MeasObj_list)); memset((void *)MeasObj_list, 0, sizeof(*MeasObj_list)); @@ -4697,7 +5246,10 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( memset((void *)MeasObj, 0, sizeof(*MeasObj)); MeasObj->measObjectId = 1; MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA; - MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; + MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = + to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0], + RC.rrc[ctxt_pP->module_id]->configuration.downlink_frequency[0], + RC.rrc[ctxt_pP->module_id]->configuration.N_RB_DL[0]); MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw25; MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t)); @@ -4705,21 +5257,19 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6; MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB - MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = - (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); - CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; - + //MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = + //(CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); + //CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; // Add adjacent cell lists (6 per eNB) - for (i = 0; i < 6; i++) { - CellToAdd = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd)); - CellToAdd->cellIndex = i + 1; - CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); - CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0; - ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd); - } - + //for (i = 0; i < 6; i++) { + //CellToAdd = (CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd)); + //CellToAdd->cellIndex = 1;//i + 1; + //CellToAdd->physCellId = 1;//get_adjacent_cell_id(ctxt_pP->module_id, i); + //CellToAdd->cellIndividualOffset = Q_OffsetRange_dB0; + //ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd); + //} ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj); - // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list; + // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list; // Report Configurations for periodical, A1-A5 events ReportConfig_list = CALLOC(1, sizeof(*ReportConfig_list)); ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per)); @@ -4756,17 +5306,21 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1); + // if (ho_state == 1 /*HO_MEASUREMENT */ ) { + LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, and A5 event reporting\n", + ctxt_pP->module_id, ctxt_pP->frame); ReportConfig_A2->reportConfigId = 3; ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present = LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA2. - a2_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA2. - a2_Threshold.choice.threshold_RSRP = 10; - ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA2.a2_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA2.a2_Threshold.choice.threshold_RSRP = 10; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity = + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; @@ -4778,15 +5332,18 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = - 10; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 0; //10; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. eventA3.reportOnLeave = 1; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity = + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0; // FIXME ...hysteresis is of type long! + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = + LTE_TimeToTrigger_ms40; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3); ReportConfig_A4->reportConfigId = 5; ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; @@ -4794,11 +5351,12 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA4. - a4_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA4. - a4_Threshold.choice.threshold_RSRP = 10; - ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA4.a4_Threshold.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. + eventA4.a4_Threshold.choice.threshold_RSRP = 10; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity = + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; @@ -4818,12 +5376,16 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( eventA5.a5_Threshold1.choice.threshold_RSRP = 10; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. eventA5.a5_Threshold2.choice.threshold_RSRP = 10; - ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity = + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5); + // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; + rsrp = CALLOC(1, sizeof(RSRP_Range_t)); + *rsrp = 20; Sparams = CALLOC(1, sizeof(*Sparams)); Sparams->present = LTE_MeasConfig__speedStatePars_PR_setup; Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75; @@ -4834,31 +5396,37 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120; quantityConfig = CALLOC(1, sizeof(*quantityConfig)); memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); - quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(*quantityConfig->quantityConfigEUTRA)); + quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA)); memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA)); quantityConfig->quantityConfigCDMA2000 = NULL; quantityConfig->quantityConfigGERAN = NULL; quantityConfig->quantityConfigUTRA = NULL; quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = - CALLOC(1, sizeof(*quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP)); + CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP))); quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = - CALLOC(1, sizeof(*quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ)); + CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ))); *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; /* mobilityinfo */ + mobilityInfo = ue_context_pP->ue_context.mobilityInfo; + + if (mobilityInfo) { + free(mobilityInfo); + } + mobilityInfo = CALLOC(1, sizeof(*mobilityInfo)); memset((void *)mobilityInfo, 0, sizeof(*mobilityInfo)); - mobilityInfo->targetPhysCellId = - (LTE_PhysCellId_t) two_tier_hexagonal_cellIds[ue_context_pP->ue_context.handover_info->modid_t]; + mobilityInfo->targetPhysCellId = RC.rrc[ctxt_pP->module_id]->carrier[0].physCellId; + //(PhysCellId_t) two_tier_hexagonal_cellIds[ue_context_pP->ue_context.handover_info->modid_t]; LOG_D(RRC, "[eNB %d] Frame %d: handover preparation: targetPhysCellId: %ld mod_id: %d ue: %x \n", ctxt_pP->module_id, ctxt_pP->frame, mobilityInfo->targetPhysCellId, - ctxt_pP->module_id, + ctxt_pP->module_id, // get_adjacent_cell_mod_id(mobilityInfo->targetPhysCellId), ue_context_pP->ue_context.rnti); mobilityInfo->additionalSpectrumEmission = CALLOC(1, sizeof(*mobilityInfo->additionalSpectrumEmission)); - *mobilityInfo->additionalSpectrumEmission = 1; //Check this value! - mobilityInfo->t304 = LTE_MobilityControlInfo__t304_ms50; // need to configure an appropriate value here + *mobilityInfo->additionalSpectrumEmission = (LTE_AdditionalSpectrumEmission_t) 1; //Check this value! + mobilityInfo->t304 = LTE_MobilityControlInfo__t304_ms200; // need to configure an appropriate value here // New UE Identity (C-RNTI) to identify an UE uniquely in a cell mobilityInfo->newUE_Identity.size = 2; mobilityInfo->newUE_Identity.bits_unused = 0; @@ -4903,154 +5471,258 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( mobilityInfo->radioResourceConfigCommon.antennaInfoCommon = NULL; mobilityInfo->radioResourceConfigCommon.p_Max = NULL; // CALLOC(1,sizeof(*mobilityInfo->radioResourceConfigCommon.p_Max)); //memcpy((void *)mobilityInfo->radioResourceConfigCommon.p_Max,(void *)rrc_inst->sib1->p_Max,sizeof(P_Max_t)); - mobilityInfo->radioResourceConfigCommon.tdd_Config = NULL; //CALLOC(1,sizeof(LTE_TDD_Config_t)); - //memcpy((void *)mobilityInfo->radioResourceConfigCommon.tdd_Config,(void *)rrc_inst->sib1->tdd_Config,sizeof(LTE_TDD_Config_t)); + mobilityInfo->radioResourceConfigCommon.tdd_Config = NULL; //CALLOC(1,sizeof(TDD_Config_t)); + //memcpy((void *)mobilityInfo->radioResourceConfigCommon.tdd_Config,(void *)rrc_inst->sib1->tdd_Config,sizeof(TDD_Config_t)); mobilityInfo->radioResourceConfigCommon.ul_CyclicPrefixLength = rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.ul_CyclicPrefixLength; //End of configuration of radioResourceConfigCommon mobilityInfo->carrierFreq = CALLOC(1, sizeof(*mobilityInfo->carrierFreq)); //CALLOC(1,sizeof(CarrierFreqEUTRA_t)); 36090 - mobilityInfo->carrierFreq->dl_CarrierFreq = 36090; + mobilityInfo->carrierFreq->dl_CarrierFreq = + to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0], + RC.rrc[ctxt_pP->module_id]->configuration.downlink_frequency[0], + RC.rrc[ctxt_pP->module_id]->configuration.N_RB_DL[0]); mobilityInfo->carrierFreq->ul_CarrierFreq = NULL; mobilityInfo->carrierBandwidth = CALLOC(1, sizeof( - *mobilityInfo->carrierBandwidth)); //CALLOC(1,sizeof(struct LTE_CarrierBandwidthEUTRA)); LTE_AllowedMeasBandwidth_mbw25 + *mobilityInfo->carrierBandwidth)); //CALLOC(1,sizeof(struct CarrierBandwidthEUTRA)); AllowedMeasBandwidth_mbw25 mobilityInfo->carrierBandwidth->dl_Bandwidth = LTE_CarrierBandwidthEUTRA__dl_Bandwidth_n25; mobilityInfo->carrierBandwidth->ul_Bandwidth = NULL; mobilityInfo->rach_ConfigDedicated = NULL; - // store the srb and drb list for ho management, mainly in case of failure - memcpy(ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList, - (void *)SRB_configList2, - sizeof(LTE_SRB_ToAddModList_t)); - memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList, - (void *)DRB_configList2, - sizeof(LTE_DRB_ToAddModList_t)); + ue_context_pP->ue_context.mobilityInfo = mobilityInfo; +#if 0 + LOG_I(RRC, + "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n", + ctxt_pP->module_id, ctxt_pP->frame); + // store the information in an intermediate structure for Hanodver management + //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof()); + ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info))); + //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(SRB_ToAddModList_t)); + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2; + //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(DRB_ToAddModList_t)); + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList = *DRB_configList; ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig = + CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig)); memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, - (void *)mac_MainConfig, - sizeof(LTE_MAC_MainConfig_t)); + (void *)mac_MainConfig, sizeof(MAC_MainConfig_t)); + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated = + CALLOC(1, sizeof(PhysicalConfigDedicated_t)); memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, - (void *)ue_context_pP->ue_context.physicalConfigDedicated, - sizeof(LTE_PhysicalConfigDedicated_t)); - /* memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config, - (void *)rrc_inst->sps_Config[ue_mod_idP], - sizeof(SPS_Config_t)); - */ - LOG_I(RRC, "[eNB %d] Frame %d: adding new UE\n", - ctxt_pP->module_id, ctxt_pP->frame); - //Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; + (void *)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(PhysicalConfigDedicated_t)); + ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL; + //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t)); +#endif + // } + securityConfigHO = CALLOC(1, sizeof(*securityConfigHO)); + memset((void *)securityConfigHO, 0, sizeof(*securityConfigHO)); + securityConfigHO->handoverType.present = LTE_SecurityConfigHO__handoverType_PR_intraLTE; + securityConfigHO->handoverType.choice.intraLTE.securityAlgorithmConfig = NULL; /* TODO: to be checked */ + securityConfigHO->handoverType.choice.intraLTE.keyChangeIndicator = 0; + securityConfigHO->handoverType.choice.intraLTE.nextHopChainingCount = 0; +#if defined(ENABLE_ITTI) + /* Initialize NAS list */ + dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); + + /* Add all NAS PDUs to the list */ + for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { + if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { + dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); + memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(dedicatedInfoNas, + (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, + ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length); + ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); + } + + /* TODO parameters yet to process ... */ + { + // ue_context_pP->ue_context.e_rab[i].param.qos; + // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; + // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; + } + /* TODO should test if e RAB are Ok before! */ + ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; + LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", + i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); + } + + /* If list is empty free the list and reset the address */ + if (dedicatedInfoNASList->list.count == 0) { + free(dedicatedInfoNASList); + dedicatedInfoNASList = NULL; + } + +#endif + + x2_enabled = is_x2ap_enabled(); + + memset(buffer, 0, RRC_BUF_SIZE); + char rrc_buf[1000 /* arbitrary, should be big enough, has to be less than size of return buf by a few bits/bytes */]; + int rrc_size; + rrc_size = do_RRCConnectionReconfiguration(ctxt_pP, + (unsigned char *)rrc_buf, + xid, //Transaction_id, + NULL, // SRB_configList + NULL, + NULL, // DRB2_list, + (struct LTE_SPS_Config *)NULL, // *sps_Config, + (struct LTE_PhysicalConfigDedicated *)*physicalConfigDedicated, + //#ifdef EXMIMO_IOT + // NULL, NULL, NULL,NULL, + //#else + x2_enabled ? (LTE_MeasObjectToAddModList_t *)MeasObj_list : NULL, + x2_enabled ? (LTE_ReportConfigToAddModList_t *)ReportConfig_list : NULL, + x2_enabled ? (LTE_QuantityConfig_t *)quantityConfig : NULL, + x2_enabled ? (LTE_MeasIdToAddModList_t *)MeasId_list : NULL, + //#endif + (LTE_MAC_MainConfig_t *)mac_MainConfig, + (LTE_MeasGapConfig_t *)NULL, + (LTE_MobilityControlInfo_t *)mobilityInfo, + (LTE_SecurityConfigHO_t *)securityConfigHO, + (struct LTE_MeasConfig__speedStatePars *)Sparams, + (LTE_RSRP_Range_t *)rsrp, + (LTE_C_RNTI_t *)cba_RNTI, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t *)NULL +#endif + ); + + if (rrc_size <= 0) { + printf("%s:%d: fatal\n", __FILE__, __LINE__); + abort(); + } + + char *ho_buf = (char *)buffer; + int ho_size; + ho_size = do_HandoverCommand( + ho_buf, 1024 /* TODO: this is the value found in struct x2ap_handover_req_ack_s for array rrc_buffer */, + rrc_buf, + rrc_size); + *_size = size = ho_size; + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, + "[MSG] RRC Connection Reconfiguration handover\n"); +#if defined(ENABLE_ITTI) + + /* Free all NAS PDUs */ + for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { + if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { + /* Free the NAS PDU buffer and invalidate it */ + free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer); + ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL; + } + } + +#endif + LOG_I(RRC, + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration handover (bytes %d, UE id %x)\n", + ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + LOG_D(RRC, + "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration handover to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", + ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" rrcConnectionReconfiguration handover UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_eNB_mui, + size); +} + +void +rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protocol_ctxt_t *const ctxt_pP) { + uint16_t Idx; Idx = DCCH; +#if 1 + // Activate the radio bearers // SRB1 - ue_context_pP->ue_context.Srb1.Active = 1; - ue_context_pP->ue_context.Srb1.Srb_info.Srb_id = Idx; - memcpy(&ue_context_pP->ue_context.Srb1.Srb_info.Lchan_desc[0], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); - memcpy(&ue_context_pP->ue_context.Srb1.Srb_info.Lchan_desc[1], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); + ue_context_p->ue_context.Srb1.Active = 1; + ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx; + memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); + memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); // SRB2 - ue_context_pP->ue_context.Srb2.Active = 1; - ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = Idx; - memcpy(&ue_context_pP->ue_context.Srb2.Srb_info.Lchan_desc[0], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); - memcpy(&ue_context_pP->ue_context.Srb2.Srb_info.Lchan_desc[1], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); + ue_context_p->ue_context.Srb2.Active = 1; + ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx; + memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); + memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); +#endif LOG_I(RRC, "[eNB %d] CALLING RLC CONFIG SRB1 (rbid %d) for UE %x\n", - ctxt_pP->module_id, Idx, ue_context_pP->ue_context.rnti); - // rrc_pdcp_config_req (enb_mod_idP, frameP, 1, CONFIG_ACTION_ADD, idx, UNDEF_SECURITY_MODE); - // rrc_rlc_config_req(enb_mod_idP,frameP,1,CONFIG_ACTION_ADD,Idx,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); - rrc_pdcp_config_asn1_req(&ctxt, - ue_context_pP->ue_context.SRB_configList, - (LTE_DRB_ToAddModList_t *) NULL, (LTE_DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ctxt_pP->module_id, Idx, ue_context_p->ue_context.rnti); + // Configure PDCP/RLC for the target + rrc_pdcp_config_asn1_req(ctxt_pP, + ue_context_p->ue_context.SRB_configList, + (LTE_DRB_ToAddModList_t *) NULL, + (LTE_DRB_ToReleaseList_t *) NULL, + 0xff, + NULL, + NULL, + NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL #endif - ,NULL); - rrc_rlc_config_asn1_req(&ctxt, - ue_context_pP->ue_context.SRB_configList, - (LTE_DRB_ToAddModList_t *) NULL, (LTE_DRB_ToReleaseList_t *) NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , NULL); + rrc_rlc_config_asn1_req(ctxt_pP, + ue_context_p->ue_context.SRB_configList, + (LTE_DRB_ToAddModList_t *) NULL, + (LTE_DRB_ToReleaseList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL , 0, 0 #endif ); - /* Initialize NAS list */ - dedicatedInfoNASList = NULL; - // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; - memset(buffer, 0, RRC_BUF_SIZE); - int size=do_RRCConnectionReconfiguration( - ctxt_pP, - buffer, - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id, - SRB_configList2, - DRB_configList2, - NULL, // DRB2_list, - NULL, //*sps_Config, - ue_context_pP->ue_context.physicalConfigDedicated, - MeasObj_list, - ReportConfig_list, - NULL, //quantityConfig, - MeasId_list, - mac_MainConfig, - NULL, - mobilityInfo, - Sparams, - NULL, - NULL, - dedicatedInfoNASList, - (LTE_SL_CommConfig_r12_t *)NULL, - (LTE_SL_DiscConfig_r12_t *)NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , NULL // SCellToAddMod_r10_t -#endif - ); - if (size <= 0) - LOG_E(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration for handover (bytes %d, UE rnti %x) failed\n", - ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - else - LOG_I(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration for handover (bytes %d, UE rnti %x)\n", - ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + if (EPC_MODE_ENABLED) { + rrc_eNB_process_security ( + ctxt_pP, + ue_context_p, + &ue_context_p->ue_context.security_capabilities); + process_eNB_security_key ( + ctxt_pP, + ue_context_p, + ue_context_p->ue_context.kenb); + rrc_pdcp_config_security( + ctxt_pP, + ue_context_p, + FALSE); + } - // to be updated if needed - /*if (RC.rrc[ctxt_pP->module_id]->SRB1_config[ue_mod_idP]->logicalChannelConfig) { - if (RC.rrc[ctxt_pP->module_id]->SRB1_config[ue_mod_idP]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { - SRB1_logicalChannelConfig = &RC.rrc[ctxt_pP->module_id]->SRB1_config[ue_mod_idP]->logicalChannelConfig->choice.explicitValue; - } - else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; - } - } - else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; - } - */ - LOG_D(RRC, - "[FRAME %05d][RRC_eNB][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration_handover to UE %x MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", - ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); - //rrc_rlc_data_req(ctxt_pP->module_id,frameP, 1,(ue_mod_idP*NB_RB_MAX)+DCCH,rrc_eNB_mui++,0,size,(char*)buffer); - //pdcp_data_req (ctxt_pP->module_id, frameP, 1, (ue_mod_idP * NB_RB_MAX) + DCCH,rrc_eNB_mui++, 0, size, (char *) buffer, 1); + // Add a new user (called during the HO procedure) + LOG_I(RRC, "rrc_eNB_target_add_ue_handover module_id %d rnti %d\n", ctxt_pP->module_id, ctxt_pP->rnti); + // Configure MAC for the target rrc_mac_config_req_eNB( ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, + ue_context_p->ue_context.primaryCC_id, 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif - ue_context_pP->ue_context.rnti, + ue_context_p->ue_context.rnti, (LTE_BCCH_BCH_Message_t *) NULL, (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - ue_context_pP->ue_context.physicalConfigDedicated, + ue_context_p->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, + ue_context_p->ue_context.mac_MainConfig, 1, - SRB1_logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, + NULL,//SRB1_logicalChannelConfig, + ue_context_p->ue_context.measGapConfig, (LTE_TDD_Config_t *) NULL, - (LTE_MobilityControlInfo_t *) mobilityInfo, - (LTE_SchedulingInfoList_t *) NULL, 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_MobilityControlInfo_t *) ue_context_p->ue_context.mobilityInfo, + (LTE_SchedulingInfoList_t *) NULL, + 0, + NULL, + NULL, + (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif @@ -5068,147 +5740,108 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif ); - /* - handoverCommand.criticalExtensions.present = HandoverCommand__criticalExtensions_PR_c1; - handoverCommand.criticalExtensions.choice.c1.present = HandoverCommand__criticalExtensions__c1_PR_handoverCommand_r8; - handoverCommand.criticalExtensions.choice.c1.choice.handoverCommand_r8.handoverCommandMessage.buf = buffer; - handoverCommand.criticalExtensions.choice.c1.choice.handoverCommand_r8.handoverCommandMessage.size = size; - */ - //#warning "COMPILATION PROBLEM" -#ifdef PROBLEM_COMPILATION_RESOLVED - - if (sourceModId != 0xFF) { - memcpy(RC.rrc[sourceModId].handover_info[RC.rrc[ctxt_pP->module_id]->handover_info[ue_mod_idP]->ueid_s]->buf, - (void *)buffer, size); - RC.rrc[sourceModId].handover_info[RC.rrc[ctxt_pP->module_id]->handover_info[ue_mod_idP]->ueid_s]->size = size; - RC.rrc[sourceModId].handover_info[RC.rrc[ctxt_pP->module_id]->handover_info[ue_mod_idP]->ueid_s]->ho_complete = - 0xF1; - //RC.rrc[ctxt_pP->module_id]->handover_info[ue_mod_idP]->ho_complete = 0xFF; - LOG_D(RRC, "[eNB %d] Frame %d: setting handover complete to 0xF1 for (%d,%d) and to 0xFF for (%d,%d)\n", - ctxt_pP->module_id, - ctxt_pP->frame, - sourceModId, - RC.rrc[ctxt_pP->module_id]->handover_info[ue_mod_idP]->ueid_s, - ctxt_pP->module_id, - ue_mod_idP); - } else - LOG_W(RRC, - "[eNB %d] Frame %d: rrc_eNB_generate_RRCConnectionReconfiguration_handover: Could not find source eNB mod_id.\n", - ctxt_pP->module_id, ctxt_pP->frame); - -#endif +//#if 0 +//} +//#endif } -/* - void ue_rrc_process_rrcConnectionReconfiguration(uint8_t enb_mod_idP,frame_t frameP, - LTE_RRCConnectionReconfiguration_t *rrcConnectionReconfiguration, - uint8_t CH_index) { - - if (rrcConnectionReconfiguration->criticalExtensions.present == LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1) - if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present == LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) { - - if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated) { - rrc_ue_process_radioResourceConfigDedicated(enb_mod_idP,frameP,CH_index, - LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated); - - } - - // check other fields for - } - } -*/ - //----------------------------------------------------------------------------- /* -* TODO: * add function description -* * format the function correctly +* Process the RRC Connection Reconfiguration Complete from the UE */ void rrc_eNB_process_RRCConnectionReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *ue_context_pP, + rrc_eNB_ue_context_t *ue_context_pP, const uint8_t xid ) //----------------------------------------------------------------------------- { - int i, drb_id; -#ifdef PDCP_USE_NETLINK + int drb_id; int oip_ifup = 0; int dest_ip_offset = 0; - /* avoid gcc warnings */ - (void)oip_ifup; - (void)dest_ip_offset; -#endif uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; uint8_t *kUPenc = NULL; + LTE_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; + LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; + LTE_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; + LTE_DRB_Identity_t *drb_id_p = NULL; + ue_context_pP->ue_context.ue_reestablishment_timer = 0; - LTE_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; - LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; - LTE_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; - LTE_DRB_Identity_t *drb_id_p = NULL; - T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); -#if defined(ENABLE_SECURITY) + ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // reset rrc inactivity timer + + if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + /* CDRX: activated if ack was expected */ + int UE_id_mac = find_UE_id(ctxt_pP->module_id, ue_context_pP->ue_context.rnti); + UE_sched_ctrl *UE_scheduling_control = &(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id_mac]); + + if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { + UE_scheduling_control->cdrx_waiting_ack = FALSE; + UE_scheduling_control->cdrx_configured = TRUE; + LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); + } + } // No CDRX with the CU/DU split in this version of the code + + T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, + T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(ctxt_pP->rnti)); /* Derive the keys from kenb */ if (DRB_configList != NULL) { derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, &kUPenc); + ue_context_pP->ue_context.kenb, + &kUPenc); } derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, &kRRCenc); + ue_context_pP->ue_context.kenb, + &kRRCenc); + derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kenb, &kRRCint); -#endif - // Refresh SRBs/DRBs - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_PDCP_ENB, - NULL, - 0, - MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_context.rnti); - rrc_pdcp_config_asn1_req( - ctxt_pP, - SRB_configList, //NULL, //LG-RK 14/05/2014 SRB_configList, - DRB_configList, - // (LTE_DRB_ToReleaseList_t *) NULL, - DRB_Release_configList2, - /*RC.rrc[ctxt_pP->module_id]->ciphering_algorithm[ue_mod_idP] | - (RC.rrc[ctxt_pP->module_id]->integrity_algorithm[ue_mod_idP] << 4), - */ - 0xff, // already configured during the securitymodecommand - kRRCenc, - kRRCint, - kUPenc + ue_context_pP->ue_context.kenb, + &kRRCint); + + /* Refresh SRBs/DRBs */ + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti); + + rrc_pdcp_config_asn1_req(ctxt_pP, + SRB_configList, // NULL, + DRB_configList, + DRB_Release_configList2, + 0xff, // already configured during the securitymodecommand + kRRCenc, + kRRCint, + kUPenc #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL + , (LTE_PMCH_InfoList_r9_t *) NULL #endif - ,NULL); - // Refresh SRBs/DRBs - rrc_rlc_config_asn1_req( - ctxt_pP, - SRB_configList, // NULL, //LG-RK 14/05/2014 SRB_configList, - DRB_configList, - // (LTE_DRB_ToReleaseList_t *) NULL - DRB_Release_configList2 + , NULL); + + /* Refresh SRBs/DRBs */ + rrc_rlc_config_asn1_req(ctxt_pP, + SRB_configList, // NULL, + DRB_configList, + DRB_Release_configList2 #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL - , 0, 0 + , (LTE_PMCH_InfoList_r9_t *) NULL, + 0, + 0 #endif - ); + ); - // set the SRB active in Ue context + /* Set the SRB active in UE context */ if (SRB_configList != NULL) { - for (i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { - if (SRB_configList->list.array[i]->srb_Identity == 1 ) { - ue_context_pP->ue_context.Srb1.Active=1; - } else if (SRB_configList->list.array[i]->srb_Identity == 2 ) { - ue_context_pP->ue_context.Srb2.Active=1; - ue_context_pP->ue_context.Srb2.Srb_info.Srb_id=2; + for (int i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { + if (SRB_configList->list.array[i]->srb_Identity == 1) { + ue_context_pP->ue_context.Srb1.Active = 1; + } else if (SRB_configList->list.array[i]->srb_Identity == 2) { + ue_context_pP->ue_context.Srb2.Active = 1; + ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; LOG_I(RRC,"[eNB %d] Frame %d CC %d : SRB2 is now active\n", ctxt_pP->module_id, ctxt_pP->frame, @@ -5226,22 +5859,21 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.SRB_configList2[xid] = NULL; } - // Loop through DRBs and establish if necessary - + /* Loop through DRBs and establish if necessary */ if (DRB_configList != NULL) { - for (i = 0; i < DRB_configList->list.count; i++) { // num max DRB (11-3-8) + for (int i = 0; i < DRB_configList->list.count; i++) { // num max DRB (11-3-8) if (DRB_configList->list.array[i]) { drb_id = (int)DRB_configList->list.array[i]->drb_Identity; - LOG_I(RRC, - "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n", + + LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)DRB_configList->list.array[i]->drb_Identity, (int)*DRB_configList->list.array[i]->logicalChannelIdentity); - // for pre-ci tests - LOG_I(RRC, - "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE %u, reconfiguring DRB %d/LCID %d\n", + + /* For pre-ci tests */ + LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE %u, reconfiguring DRB %d/LCID %d\n", ctxt_pP->module_id, ctxt_pP->frame, oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid], @@ -5249,49 +5881,40 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (int)*DRB_configList->list.array[i]->logicalChannelIdentity); if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) { - /* - rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_ADD, - (ue_mod_idP * NB_RB_MAX) + *DRB_configList->list.array[i]->logicalChannelIdentity,UNDEF_SECURITY_MODE); - rrc_rlc_config_req(ctxt_pP->module_id,frameP,1,CONFIG_ACTION_ADD, - (ue_mod_idP * NB_RB_MAX) + (int)*RC.rrc[ctxt_pP->module_id]->DRB_config[ue_mod_idP][i]->logicalChannelIdentity, - RADIO_ACCESS_BEARER,Rlc_info_um); - */ ue_context_pP->ue_context.DRB_active[drb_id] = 1; - LOG_D(RRC, - "[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", + LOG_D(RRC, "[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); -#if defined(PDCP_USE_NETLINK) && !defined(LINK_ENB_PDCP_TO_GTPV1U) - // can mean also IPV6 since ether -> ipv6 autoconf -# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) - LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n", - ctxt_pP->module_id, - ctxt_pP->module_id); - oip_ifup = nas_config( - ctxt_pP->module_id, // interface index - ctxtReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA_pP->module_id + 1, // thrid octet - ctxt_pP->module_id + 1); // fourth octet - - if (oip_ifup == 0) { // interface is up --> send a config the DRB - module_id_t ue_module_id; - dest_ip_offset = 8; - LOG_I(OIP, - "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", - ctxt_pP->module_id, ctxt_pP->module_id, - (long int)((ue_context_pP->local_uid * maxDRB) + DRB_configList->list.array[i]->drb_Identity)); - ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid]; - rb_conf_ipv4(0, //add - ue_module_id, //cx - ctxt_pP->module_id, //inst - (ue_module_id * maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB - 0, //dscp - ipv4_address(ctxt_pP->module_id + 1, ctxt_pP->module_id + 1), //saddr - ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1)); //daddr - LOG_D(RRC, "[eNB %d] State = Attached (UE rnti %x module id %u)\n", - ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id); - } -# endif -#endif + if (!EPC_MODE_ENABLED && !ENB_NAS_USE_TUN) { + LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n", + ctxt_pP->module_id, + ctxt_pP->module_id); + + oip_ifup = nas_config(ctxt_pP->module_id, // interface index + ctxt_pP->module_id + 1, // third octet + ctxt_pP->module_id + 1, // fourth octet + "oai"); + + if (oip_ifup == 0) { // interface is up --> send a config the DRB + module_id_t ue_module_id; + dest_ip_offset = 8; + LOG_I(OIP, + "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", + ctxt_pP->module_id, ctxt_pP->module_id, + (long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity)); + ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid]; + rb_conf_ipv4(0, //add + ue_module_id, //cx + ctxt_pP->module_id, //inst + (ue_module_id * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB + 0, //dscp + ipv4_address(ctxt_pP->module_id + 1, ctxt_pP->module_id + 1), //saddr + ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1)); //daddr + LOG_D(RRC, "[eNB %d] State = Attached (UE rnti %x module id %u)\n", + ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id); + } /* oip_ifup */ + } /* !EPC_MODE_ENABLED && ENB_NAS_USE_TUN*/ + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); @@ -5300,39 +5923,47 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity; } - rrc_mac_config_req_eNB( - ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { + rrc_mac_config_req_eNB(ctxt_pP->module_id, + ue_context_pP->ue_context.primaryCC_id, + 0, + 0, + 0, + 0, + 0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - ue_context_pP->ue_context.rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - ue_context_pP->ue_context.physicalConfigDedicated, + ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, -#endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - DRB2LCHAN[i], - DRB_configList->list.array[i]->logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, - (LTE_TDD_Config_t *) NULL, - NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_SCellToAddMod_r10_t *)NULL, +#endif + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + DRB2LCHAN[i], + DRB_configList->list.array[i]->logicalChannelConfig, + ue_context_pP->ue_context.measGapConfig, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, + NULL, + NULL, + (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , @@ -5344,57 +5975,69 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif ); + } } else { // remove LCHAN from MAC/PHY if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { // DRB has just been removed so remove RLC + PDCP for DRB /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, (ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE); */ - rrc_rlc_config_req( - ctxt_pP, - SRB_FLAG_NO, - MBMS_FLAG_NO, - CONFIG_ACTION_REMOVE, - DRB2LCHAN[i], - Rlc_info_um); + if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + rrc_rlc_config_req(ctxt_pP, + SRB_FLAG_NO, + MBMS_FLAG_NO, + CONFIG_ACTION_REMOVE, + DRB2LCHAN[i], + Rlc_info_um); + } } ue_context_pP->ue_context.DRB_active[drb_id] = 0; - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", + + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_mac_config_req_eNB(ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) { + rrc_mac_config_req_eNB(ctxt_pP->module_id, + ue_context_pP->ue_context.primaryCC_id, + 0, + 0, + 0, + 0, + 0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - ue_context_pP->ue_context.rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - ue_context_pP->ue_context.physicalConfigDedicated, + ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, -#endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - DRB2LCHAN[i], - (LTE_LogicalChannelConfig_t *) NULL, - (LTE_MeasGapConfig_t *) NULL, - (LTE_TDD_Config_t *) NULL, - NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, NULL + (LTE_SCellToAddMod_r10_t *) NULL, +#endif + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + DRB2LCHAN[i], + (LTE_LogicalChannelConfig_t *) NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, + NULL, + NULL, + NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , + 0, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , @@ -5405,17 +6048,18 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL #endif - ); - } - } - } + ); + } + } // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) + } // end if (DRB_configList->list.array[i]) + } // end for (int i = 0; i < DRB_configList->list.count; i++) free(DRB_configList); ue_context_pP->ue_context.DRB_configList2[xid] = NULL; - } + } // end if DRB_configList != NULL if(DRB_Release_configList2 != NULL) { - for (i = 0; i < DRB_Release_configList2->list.count; i++) { + for (int i = 0; i < DRB_Release_configList2->list.count; i++) { if (DRB_Release_configList2->list.array[i]) { drb_id_p = DRB_Release_configList2->list.array[i]; drb_id = *drb_id_p; @@ -5432,107 +6076,144 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( } //----------------------------------------------------------------------------- -void rrc_eNB_generate_RRCConnectionSetup(const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - const int CC_id - ) +void +rrc_eNB_generate_RRCConnectionSetup( + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + const int CC_id +) //----------------------------------------------------------------------------- { - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) boolean_t is_mtc = ctxt_pP->brOption; #endif - LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; LTE_SRB_ToAddModList_t **SRB_configList; LTE_SRB_ToAddMod_t *SRB1_config; - int cnt; - T(T_ENB_RRC_CONNECTION_SETUP, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - SRB_configList = &ue_context_pP->ue_context.SRB_configList; + MessageDef *message_p; + + T(T_ENB_RRC_CONNECTION_SETUP, + T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(ctxt_pP->rnti)); + + eNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + SRB_configList = &ue_p->SRB_configList; + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + if (is_mtc) { - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size = + ue_p->Srb0.Tx_buffer.payload_size = do_RRCConnectionSetup_BR(ctxt_pP, - ue_context_pP, - CC_id, - (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload, - (const uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), - SRB_configList, - &ue_context_pP->ue_context.physicalConfigDedicated); - } else + ue_context_pP, + CC_id, + (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, + (const uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), + SRB_configList, + &ue_context_pP->ue_context.physicalConfigDedicated); + } else #endif { - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size = + ue_p->Srb0.Tx_buffer.payload_size = do_RRCConnectionSetup(ctxt_pP, - ue_context_pP, - CC_id, - (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload, - (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), - SRB_configList, - &ue_context_pP->ue_context.physicalConfigDedicated); - LOG_DUMPMSG(RRC,DEBUG_RRC, - (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, - "[MSG] RRC Connection Setup\n"); - - // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE - - if (*SRB_configList != NULL) { - for (cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { - if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) { - SRB1_config = (*SRB_configList)->list.array[cnt]; - - if (SRB1_config->logicalChannelConfig) { - if (SRB1_config->logicalChannelConfig->present == - LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { - SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; - } else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; - } - } else { - SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; - } - - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_mac_config_req_eNB( - ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + ue_context_pP, + CC_id, + (uint8_t*) ue_p->Srb0.Tx_buffer.Payload, + (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), + SRB_configList, + &ue_context_pP->ue_context.physicalConfigDedicated); + } + LOG_DUMPMSG(RRC,DEBUG_RRC, + (char *)(ue_p->Srb0.Tx_buffer.Payload), + ue_p->Srb0.Tx_buffer.payload_size, + "[MSG] RRC Connection Setup\n"); + + // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE + switch (RC.rrc[ctxt_pP->module_id]->node_type){ + case ngran_eNB_CU : + case ngran_ng_eNB_CU : + case ngran_gNB_CU : + // create an ITTI message + /* TODO: F1 IDs ar missing in RRC */ + message_p = itti_alloc_new_message (TASK_RRC_ENB, F1AP_DL_RRC_MESSAGE); + F1AP_DL_RRC_MESSAGE (message_p).rrc_container = (uint8_t*)ue_p->Srb0.Tx_buffer.Payload; + + F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size; + F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id = 0; + F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id = 0; + F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id = 0xFFFFFFFF; // unknown + F1AP_DL_RRC_MESSAGE (message_p).rnti = ue_p->rnti; + F1AP_DL_RRC_MESSAGE (message_p).srb_id = CCCH; + F1AP_DL_RRC_MESSAGE (message_p).execute_duplication = 1; + F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc = 0; + itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); + LOG_D(RRC, "Send F1AP_DL_RRC_MESSAGE with ITTI\n"); + break; + case ngran_eNB_DU : + case ngran_gNB_DU : + // nothing to do for DU + AssertFatal(1==0,"nothing to do for DU\n"); + break; + case ngran_eNB: + case ngran_ng_eNB : + case ngran_gNB : + + if (*SRB_configList != NULL) { + for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { + if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) { + SRB1_config = (*SRB_configList)->list.array[cnt]; + + if (SRB1_config->logicalChannelConfig) { + if (SRB1_config->logicalChannelConfig->present == + LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; + } else { + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + } + } else { + SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; + } + + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + if (RC.rrc[ctxt_pP->module_id]->node_type == ngran_eNB) { + rrc_mac_config_req_eNB(ctxt_pP->module_id, + ue_context_pP->ue_context.primaryCC_id, + 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - ue_context_pP->ue_context.rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - ue_context_pP->ue_context.physicalConfigDedicated, + ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, -#endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - 1, - SRB1_logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, - (LTE_TDD_Config_t *) NULL, - NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, +#endif + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + 1, + SRB1_logicalChannelConfig, + ue_context_pP->ue_context.measGapConfig, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , @@ -5548,39 +6229,48 @@ void rrc_eNB_generate_RRCConnectionSetup(const protocol_ctxt_t *const ctxt_pP, } } } - - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header, // LG WARNING - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, - MSC_AS_TIME_FMT" LTE_RRCConnectionSetup UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_context.rnti, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionSetup (bytes %d)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); - //ue_context_pP->ue_context.ue_release_timer_thres=100; - // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE - ue_context_pP->ue_context.ue_release_timer=1; - // remove UE after 10 frames after LTE_RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres=1000; + + break; + default : + LOG_W(RRC, "Unknown node type %d\n", RC.rrc[ctxt_pP->module_id]->node_type); + } + + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + ue_p->Srb0.Tx_buffer.Header, // LG WARNING + ue_p->Srb0.Tx_buffer.payload_size, + MSC_AS_TIME_FMT" RRCConnectionSetup UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + ue_p->Srb0.Tx_buffer.payload_size); + + + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionSetup (bytes %d)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_p->Srb0.Tx_buffer.payload_size); + + // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE + ue_context_pP->ue_context.ue_release_timer = 1; + // remove UE after 10 frames after RRCConnectionRelease is triggered + ue_context_pP->ue_context.ue_release_timer_thres = 1000; + + /* init timers */ + ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; } } + +void setup_ngran_CU(eNB_RRC_INST *rrc) { + -#if defined(ENABLE_ITTI) +} + //----------------------------------------------------------------------------- char openair_rrc_eNB_configuration( - const module_id_t enb_mod_idP, - RrcConfigurationReq *configuration - ) -#else -char openair_rrc_eNB_init( - const module_id_t enb_mod_idP - ) -#endif + const module_id_t enb_mod_idP, + RrcConfigurationReq *configuration +) //----------------------------------------------------------------------------- { protocol_ctxt_t ctxt; @@ -5599,29 +6289,11 @@ char openair_rrc_eNB_init( #endif AssertFatal(RC.rrc[enb_mod_idP] != NULL, "RC.rrc not initialized!"); AssertFatal(MAX_MOBILES_PER_ENB < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow"); -#ifdef ENABLE_ITTI AssertFatal(configuration!=NULL,"configuration input is null\n"); -#endif - // for (j = 0; j < MAX_MOBILES_PER_ENB; j++) - // RC.rrc[ctxt.module_id].Info.UE[j].Status = RRC_IDLE; //CH_READY; - // - //#if defined(ENABLE_USE_MME) - // // Connect eNB to MME - // if (EPC_MODE_ENABLED <= 0) - //#endif - // { - // /* Init security parameters */ - // for (j = 0; j < MAX_MOBILES_PER_ENB; j++) { - // RC.rrc[ctxt.module_id].ciphering_algorithm[j] = SecurityAlgorithmConfig__cipheringAlgorithm_eea0; - // RC.rrc[ctxt.module_id].integrity_algorithm[j] = SecurityAlgorithmConfig__integrityProtAlgorithm_eia2; - // rrc_eNB_init_security(enb_mod_idP, j); - // } - // } RC.rrc[ctxt.module_id]->Nb_ue = 0; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - RC.rrc[ctxt.module_id]->carrier[CC_id].Srb0.Active = 0; - } + pthread_mutex_init(&RC.rrc[ctxt.module_id]->cell_info_mutex,NULL); + RC.rrc[ctxt.module_id]->cell_info_configured = 0; uid_linear_allocator_init(&RC.rrc[ctxt.module_id]->uid_allocator); RB_INIT(&RC.rrc[ctxt.module_id]->rrc_ue_head); @@ -5630,7 +6302,7 @@ char openair_rrc_eNB_init( // } RC.rrc[ctxt.module_id]->initial_id2_s1ap_ids = hashtable_create (MAX_MOBILES_PER_ENB * 2, NULL, NULL); RC.rrc[ctxt.module_id]->s1ap_id2_s1ap_ids = hashtable_create (MAX_MOBILES_PER_ENB * 2, NULL, NULL); - memcpy(&RC.rrc[ctxt.module_id]->configuration,configuration,sizeof(RrcConfigurationReq)); + /// System Information INIT LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Checking release \n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); @@ -5672,12 +6344,7 @@ char openair_rrc_eNB_init( #endif for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - init_SI(&ctxt, - CC_id -#if defined(ENABLE_ITTI) - , configuration -#endif - ); + init_SI(&ctxt, CC_id, configuration); for (int ue_id = 0; ue_id < MAX_MOBILES_PER_ENB; ue_id++) { RC.rrc[ctxt.module_id]->carrier[CC_id].sizeof_paging[ue_id] = 0; @@ -5718,15 +6385,31 @@ char openair_rrc_eNB_init( #endif openair_rrc_top_init_eNB(RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag,0); } + openair_rrc_on(&ctxt); + +/* + RC.rrc[ctxt.module_id]->mcc= rrc_configuration_req->mcc; + RC.rrc[ctxt.module_id]->mnc= rrc_configuration_req->mnc; + RC.rrc[ctxt.module_id]->mnc_digit_length= rrc_configuration_req->mnc_digit_length; + RC.rrc[ctxt.module_id]->tac= rrc_configuration_req->tac; + + LOG_W(RRC, "[inst %d] RRC->MCC/MSG->MCC %d/%d \n", ctxt.module_id, RC.rrc[ctxt.module_id]->mcc, rrc_configuration_req->mcc); + */ + if (NODE_IS_CU(RC.rrc[ctxt.module_id]->node_type)) + // msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SCTP_REQ); + // RCconfig_CU_F1(msg_p, enb_id); + setup_ngran_CU(RC.rrc[ctxt.module_id]); + return 0; } /*------------------------------------------------------------------------------*/ int rrc_eNB_decode_ccch( - protocol_ctxt_t *const ctxt_pP, - const SRB_INFO *const Srb_info, + protocol_ctxt_t* const ctxt_pP, + const uint8_t *buffer, + int buffer_length, const int CC_id ) //----------------------------------------------------------------------------- @@ -5745,17 +6428,17 @@ rrc_eNB_decode_ccch( //memset(ul_ccch_msg,0,sizeof(UL_CCCH_Message_t)); LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Decoding UL CCCH %x.%x.%x.%x.%x.%x (%p)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ((uint8_t *) Srb_info->Rx_buffer.Payload)[0], - ((uint8_t *) Srb_info->Rx_buffer.Payload)[1], - ((uint8_t *) Srb_info->Rx_buffer.Payload)[2], - ((uint8_t *) Srb_info->Rx_buffer.Payload)[3], - ((uint8_t *) Srb_info->Rx_buffer.Payload)[4], - ((uint8_t *) Srb_info->Rx_buffer.Payload)[5], (uint8_t *) Srb_info->Rx_buffer.Payload); + ((uint8_t*) buffer)[0], + ((uint8_t *) buffer)[1], + ((uint8_t *) buffer)[2], + ((uint8_t *) buffer)[3], + ((uint8_t *) buffer)[4], + ((uint8_t *) buffer)[5], (uint8_t *) buffer); dec_rval = uper_decode( NULL, &asn_DEF_LTE_UL_CCCH_Message, (void **)&ul_ccch_msg, - (uint8_t *) Srb_info->Rx_buffer.Payload, + (uint8_t *) buffer, 100, 0, 0); @@ -5782,8 +6465,7 @@ rrc_eNB_decode_ccch( case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentRequest: T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Srb_info->Rx_buffer.Payload), - Srb_info->Rx_buffer.payload_size, + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(buffer), buffer_length, "[MSG] RRC Connection Reestablishment Request\n"); LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB--- MAC_DATA_IND (rrcConnectionReestablishmentRequest on SRB0) --> RRC_eNB\n", @@ -5796,25 +6478,6 @@ rrc_eNB_decode_ccch( ((rrcConnectionReestablishmentRequest->reestablishmentCause == LTE_ReestablishmentCause_otherFailure) ? "Other Failure" : (rrcConnectionReestablishmentRequest->reestablishmentCause == LTE_ReestablishmentCause_handoverFailure) ? "Handover Failure" : "reconfigurationFailure")); - /*{ - uint64_t c_rnti = 0; - - memcpy(((uint8_t *) & c_rnti) + 3, rrcConnectionReestablishmentRequest.UE_identity.c_RNTI.buf, - rrcConnectionReestablishmentRequest.UE_identity.c_RNTI.size); - ue_mod_id = rrc_eNB_get_UE_index(enb_mod_idP, c_rnti); - } - - if ((RC.rrc[enb_mod_idP]->phyCellId == rrcConnectionReestablishmentRequest.UE_identity.physCellId) && - (ue_mod_id != UE_INDEX_INVALID)){ - rrc_eNB_generate_RRCConnectionReestablishment(enb_mod_idP, frameP, ue_mod_id); - }else { - rrc_eNB_generate_RRCConnectionReestablishmentReject(enb_mod_idP, frameP, ue_mod_id); - } - */ - /* reject all reestablishment attempts for the moment */ - // rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, - // rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rnti), - // CC_id); { uint16_t c_rnti = 0; @@ -5923,16 +6586,11 @@ rrc_eNB_decode_ccch( LOG_D(RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n", i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]); -#if defined(ENABLE_ITTI) ue_context_p->ue_context.reestablishment_cause = rrcConnectionReestablishmentRequest->reestablishmentCause; LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept connection reestablishment request from UE physCellId %ld cause %ld\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), rrcConnectionReestablishmentRequest->ue_Identity.physCellId, ue_context_p->ue_context.reestablishment_cause); -#else - LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept connection restablishment request for UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); -#endif #ifndef NO_RRM send_msg(&S_rrc, msg_rrc_MR_attach_ind(ctxt_pP->module_id, Mac_id)); #else @@ -5976,19 +6634,17 @@ rrc_eNB_decode_ccch( NULL, NULL, NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL -#endif ,NULL); - rrc_rlc_config_asn1_req(ctxt_pP, - ue_context_p->ue_context.SRB_configList, - (LTE_DRB_ToAddModList_t *) NULL, - (LTE_DRB_ToReleaseList_t *) NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL, - 0,0 -# endif - ); + if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + rrc_rlc_config_asn1_req(ctxt_pP, + ue_context_p->ue_context.SRB_configList, + (LTE_DRB_ToAddModList_t *) NULL, + (LTE_DRB_ToReleaseList_t *) NULL + , (LTE_PMCH_InfoList_r9_t *) NULL, + 0,0 + ); + } #endif //NO_RRM } break; @@ -5996,8 +6652,9 @@ rrc_eNB_decode_ccch( case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionRequest: T(T_ENB_RRC_CONNECTION_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Srb_info->Rx_buffer.Payload), - Srb_info->Rx_buffer.payload_size, + + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer, + buffer_length, "[MSG] RRC Connection Request\n"); LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB --- MAC_DATA_IND (rrcConnectionRequest on SRB0) --> RRC_eNB\n", @@ -6012,7 +6669,7 @@ rrc_eNB_decode_ccch( MSC_LOG_RX_DISCARDED_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, - Srb_info->Rx_buffer.Payload, + buffer, dec_rval.consumed, MSC_AS_TIME_FMT" LTE_RRCConnectionRequest UE %x size %u (UE already in context)", MSC_AS_TIME_ARGS(ctxt_pP), @@ -6042,6 +6699,14 @@ rrc_eNB_decode_ccch( } ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value); + + ue_context_p->ue_context.Srb0.Srb_id = 0; + ue_context_p->ue_context.Srb0.Active = 1; + memcpy(ue_context_p->ue_context.Srb0.Rx_buffer.Payload, + buffer, + buffer_length); + ue_context_p->ue_context.Srb0.Rx_buffer.payload_size = buffer_length; + } else if (LTE_InitialUE_Identity_PR_s_TMSI == rrcConnectionRequest->ue_Identity.present) { /* Save s-TMSI */ LTE_S_TMSI_t s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI; @@ -6051,7 +6716,20 @@ rrc_eNB_decode_ccch( if ((ue_context_p = rrc_eNB_ue_context_stmsi_exist(ctxt_pP, mme_code, m_tmsi))) { LOG_I(RRC," S-TMSI exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p,ue_context_p->ue_context.rnti,ctxt_pP->rnti); - rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti); + + if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti); + } + else { + MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD); + F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti; + F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; + F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = NULL; + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = 0; + itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m); + } + stmsi_received=1; /* replace rnti in the context */ /* for that, remove the context from the RB tree */ @@ -6088,7 +6766,7 @@ rrc_eNB_decode_ccch( MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, - Srb_info->Rx_buffer.Payload, + buffer, dec_rval.consumed, MSC_AS_TIME_FMT" RRCConnectionRequest UE %x size %u (s-TMSI mmec %u m_TMSI %u random UE id (0x%" PRIx64 ")", MSC_AS_TIME_ARGS(ctxt_pP), @@ -6113,7 +6791,6 @@ rrc_eNB_decode_ccch( ue_context_p); if (ue_context_p != NULL) { -#if defined(ENABLE_ITTI) ue_context_p->ue_context.establishment_cause = rrcConnectionRequest->establishmentCause; ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1; @@ -6131,18 +6808,12 @@ rrc_eNB_decode_ccch( ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, ue_context_p->ue_context.establishment_cause); -#else - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection for UE random UE identity (0x%" PRIx64 ")\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_context_p->ue_context.random_ue_identity); -#endif - if (stmsi_received == 0) RC.rrc[ctxt_pP->module_id]->Nb_ue++; } else { // no context available - if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) { + flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ctxt_pP->rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } @@ -6150,7 +6821,17 @@ rrc_eNB_decode_ccch( LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Can't create new context for UE random UE identity (0x%" PRIx64 ")\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), random_value); - rrc_mac_remove_ue(ctxt_pP->module_id,ctxt_pP->rnti); + if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) + rrc_mac_remove_ue(ctxt_pP->module_id,ctxt_pP->rnti); + else if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD); + F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti; + F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; + F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = NULL; + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = 0; + itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m); + } return -1; } } @@ -6203,15 +6884,18 @@ rrc_eNB_decode_ccch( , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); - rrc_rlc_config_asn1_req(ctxt_pP, - ue_context_p->ue_context.SRB_configList, - (LTE_DRB_ToAddModList_t *) NULL, - (LTE_DRB_ToReleaseList_t *) NULL + + if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + rrc_rlc_config_asn1_req(ctxt_pP, + ue_context_p->ue_context.SRB_configList, + (LTE_DRB_ToAddModList_t *) NULL, + (LTE_DRB_ToReleaseList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL - , 0, 0 + , (LTE_PMCH_InfoList_r9_t *) NULL + , 0, 0 #endif - ); + ); + } #endif //NO_RRM break; @@ -6369,6 +7053,9 @@ rrc_eNB_decode_dcch( break; } + AssertFatal(!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type), + "CU cannot decode DCCH: no access to RC.mac[]\n"); + if(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1) { LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld) C-RNTI Complete\n", @@ -6376,6 +7063,22 @@ rrc_eNB_decode_dcch( dedicated_DRB = 2; RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; } + } else if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION) { + int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); + + if(UE_id == -1) { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReconfigurationComplete without rnti %x, fault\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); + break; + } + + dedicated_DRB = 3; + RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; + ue_context_p->ue_context.Status = RRC_RECONFIGURED; + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_HO_EXECUTION (xid %ld)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); } else { dedicated_DRB = 0; ue_context_p->ue_context.Status = RRC_RECONFIGURED; @@ -6399,65 +7102,72 @@ rrc_eNB_decode_dcch( ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future - if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) { + flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED); } } -#if defined(ENABLE_ITTI) -#if defined(ENABLE_USE_MME) - - if (dedicated_DRB == 1) { - // rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP, - // ue_context_p, - // ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { - rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - ue_context_p->ue_context.nb_of_modify_e_rabs = 0; - ue_context_p->ue_context.nb_of_failed_e_rabs = 0; - memset(ue_context_p->ue_context.modify_e_rab, 0, sizeof(ue_context_p->ue_context.modify_e_rab)); - - for(int i = 0; i < NB_RB_MAX; i++) { - ue_context_p->ue_context.modify_e_rab[i].xid = -1; - } - } else if(ue_context_p->ue_context.e_rab_release_command_flag == 1) { - xid = ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier; - ue_context_p->ue_context.e_rab_release_command_flag = 0; - //gtp tunnel delete - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); - memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; - - for(i = 0; i < NB_RB_MAX; i++) { - if(xid == ue_context_p->ue_context.e_rab[i].xid) { - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = ue_context_p->ue_context.enb_gtp_ebi[i]; - ue_context_p->ue_context.enb_gtp_teid[i] = 0; - memset(&ue_context_p->ue_context.enb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[i])); - ue_context_p->ue_context.enb_gtp_ebi[i] = 0; + if (EPC_MODE_ENABLED) { + if (dedicated_DRB == 1) { + // rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP, + // ue_context_p, + // ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { + rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + ue_context_p->ue_context.nb_of_modify_e_rabs = 0; + ue_context_p->ue_context.nb_of_failed_e_rabs = 0; + memset(ue_context_p->ue_context.modify_e_rab, 0, sizeof(ue_context_p->ue_context.modify_e_rab)); + + for(int i = 0; i < NB_RB_MAX; i++) { + ue_context_p->ue_context.modify_e_rab[i].xid = -1; + } + } else if(ue_context_p->ue_context.e_rab_release_command_flag == 1) { + xid = ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier; + ue_context_p->ue_context.e_rab_release_command_flag = 0; + //gtp tunnel delete + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + + for(i = 0; i < NB_RB_MAX; i++) { + if(xid == ue_context_p->ue_context.e_rab[i].xid) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = ue_context_p->ue_context.enb_gtp_ebi[i]; + ue_context_p->ue_context.enb_gtp_teid[i] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[i])); + ue_context_p->ue_context.enb_gtp_ebi[i] = 0; + } } - } - itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p); - //S1AP_E_RAB_RELEASE_RESPONSE - rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(ctxt_pP, - ue_context_p, - xid); - } else { - rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - } - } else if(dedicated_DRB == 0) { - if(ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1) { - rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, - ue_context_p); - } else { - ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1; + itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p); + //S1AP_E_RAB_RELEASE_RESPONSE + rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(ctxt_pP, + ue_context_p, + xid); + } else { + rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + } + } else if(dedicated_DRB == 0) { + if(ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1) { + rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, + ue_context_p); + } else { + ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1; + for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { + ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; + } else { + ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; + } + } + } + } else if(dedicated_DRB == 2) { for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; @@ -6465,26 +7175,20 @@ rrc_eNB_decode_dcch( ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; } } - } - } else if(dedicated_DRB == 2) { - for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { - if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { - ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; - } else { - ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; + } else if(dedicated_DRB == 3) { //x2 path switch + for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { + ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; + } else { + ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; + } } - } - } -#endif -#else // establish a dedicated bearer - - if (dedicated_DRB == 0 ) { - // ue_context_p->ue_context.e_rab[0].status = E_RAB_STATUS_ESTABLISHED; - rrc_eNB_reconfigure_DRBs(ctxt_pP,ue_context_p); - } + LOG_I(RRC,"issue rrc_eNB_send_PATH_SWITCH_REQ \n"); + rrc_eNB_send_PATH_SWITCH_REQ(ctxt_pP,ue_context_p); + } + } /* EPC_MODE_ENABLED */ -#endif break; case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: @@ -6554,8 +7258,8 @@ rrc_eNB_decode_dcch( &ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.choice.rrcConnectionReestablishmentComplete_r8); //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future - if (mac_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) { + flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } @@ -6599,6 +7303,8 @@ rrc_eNB_decode_dcch( if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1. present == LTE_RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8) { + AssertFatal(!NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type), + "should not be reached in DU\n"); rrc_eNB_process_RRCConnectionSetupComplete( ctxt_pP, ue_context_p, @@ -6607,8 +7313,8 @@ rrc_eNB_decode_dcch( PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future - if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + if (flexran_agent_get_rrc_xface(ctxt_pP->module_id)) { + flexran_agent_get_rrc_xface(ctxt_pP->module_id)->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, ue_context_p->ue_id_rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); } @@ -6747,6 +7453,9 @@ rrc_eNB_decode_dcch( ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. array[0]->ueCapabilityRAT_Container.size, 0, 0); + ue_context_p->ue_context.UE_Capability_size = ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. + choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. + array[0]->ueCapabilityRAT_Container.size; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); @@ -6762,11 +7471,9 @@ rrc_eNB_decode_dcch( } if (EPC_MODE_ENABLED) { - if (EPC_MODE_ENABLED == 1) { rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP, ue_context_p, ul_dcch_msg); - } } else { ue_context_p->ue_context.nb_of_e_rabs = 1; @@ -6866,7 +7573,7 @@ rrc_eNB_decode_dcch( return 0; //TTN for D2D } else if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_messageClassExtension) { - LOG_I(RRC, "THINH [UL_DCCH_MessageType_PR_messageClassExtension]\n"); + LOG_I(RRC, "THINH [LTE_UL_DCCH_MessageType_PR_messageClassExtension]\n"); switch (ul_dcch_msg->message.choice.messageClassExtension.present) { case LTE_UL_DCCH_MessageType__messageClassExtension_PR_NOTHING: /* No components present */ @@ -6874,7 +7581,7 @@ rrc_eNB_decode_dcch( case LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation - LOG_I(RRC,"THINH [UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); + LOG_I(RRC,"THINH [LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, "[MSG] RRC SidelinkUEInformation \n"); MSC_LOG_RX_MESSAGE( @@ -6913,7 +7620,6 @@ rrc_eNB_decode_dcch( return 0; } -#if defined(ENABLE_ITTI) void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *ue_context_pP) { int i; @@ -6945,6 +7651,120 @@ void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(ctxt_pP, ue_context_pP, 0); } +void handle_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { + + + LOG_I(RRC,"Received F1 Setup Request from gNB_DU %llu (%s)\n",(unsigned long long int)f1_setup_req->gNB_DU_id,f1_setup_req->gNB_DU_name); + + //uint16_t num_cells_to_activate = 0; + + int cu_cell_ind=0; + + MessageDef *msg_p = NULL; + + //LOG_W(RRC,"num_cells_available %d \n", f1_setup_req->num_cells_available); + for (int i=0;i<f1_setup_req->num_cells_available;i++) { + // check that mcc/mnc match and grab MIB/SIB1 + int found_cell=0; + for (int j=0;j<RC.nb_inst;j++) { + eNB_RRC_INST *rrc = RC.rrc[j]; + if (rrc->configuration.mcc[0] == f1_setup_req->mcc[i] && + rrc->configuration.mnc[0] == f1_setup_req->mnc[i] && + rrc->nr_cellid == f1_setup_req->nr_cellid[i]) { + // check that CU rrc instance corresponds to mcc/mnc/cgi (normally cgi should be enough, but just in case) + + rrc->carrier[0].MIB = malloc(f1_setup_req->mib_length[i]); + rrc->carrier[0].sizeof_MIB = f1_setup_req->mib_length[i]; + LOG_W(RRC, "instance %d mib length %d\n", i, f1_setup_req->mib_length[i]); + LOG_W(RRC, "instance %d sib1 length %d\n", i, f1_setup_req->sib1_length[i]); + + memcpy((void*)rrc->carrier[0].MIB,f1_setup_req->mib[i],f1_setup_req->mib_length[i]); + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_LTE_BCCH_BCH_Message, + (void **)&rrc->carrier[0].mib_DU, + f1_setup_req->mib[i], + f1_setup_req->mib_length[i]); + AssertFatal(dec_rval.code == RC_OK, + "[eNB_DU %"PRIu8"] Failed to decode LTE_BCCH_BCH_MESSAGE (%zu bits)\n", + j, + dec_rval.consumed ); + LTE_BCCH_BCH_Message_t *mib = &rrc->carrier[0].mib; + LTE_BCCH_BCH_Message_t *mib_DU = rrc->carrier[0].mib_DU; + mib->message.dl_Bandwidth = mib_DU->message.dl_Bandwidth; + mib->message.phich_Config.phich_Resource = mib_DU->message.phich_Config.phich_Resource; + mib->message.phich_Config.phich_Duration = mib_DU->message.phich_Config.phich_Duration; + + rrc->carrier[0].SIB1 = malloc(f1_setup_req->sib1_length[i]); + rrc->carrier[0].sizeof_SIB1 = f1_setup_req->sib1_length[i]; + memcpy((void*)rrc->carrier[0].SIB1,f1_setup_req->sib1[i],f1_setup_req->sib1_length[i]); + dec_rval = uper_decode_complete(NULL, + &asn_DEF_LTE_BCCH_DL_SCH_Message, + (void **)&rrc->carrier[0].siblock1_DU, + f1_setup_req->sib1[i], + f1_setup_req->sib1_length[i]); + AssertFatal(dec_rval.code == RC_OK, + "[eNB_DU %"PRIu8"] Failed to decode LTE_BCCH_DLSCH_MESSAGE (%zu bits)\n", + j, + dec_rval.consumed ); + // Parse message and extract SystemInformationBlockType1 field + LTE_BCCH_DL_SCH_Message_t *bcch_message = rrc->carrier[0].siblock1_DU; + AssertFatal(bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_PR_c1, + "bcch_message->message.present != LTE_BCCH_DL_SCH_MessageType_PR_c1\n"); + AssertFatal(bcch_message->message.choice.c1.present == LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1, + "bcch_message->message.choice.c1.present != LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1\n"); + rrc->carrier[0].sib1 = &bcch_message->message.choice.c1.choice.systemInformationBlockType1; + rrc->carrier[0].physCellId = f1_setup_req->nr_pci[i]; + // prepare F1_SETUP_RESPONSE + + if (msg_p == NULL) { + msg_p = itti_alloc_new_message (TASK_CU_F1,F1AP_SETUP_RESP); + } + F1AP_SETUP_RESP (msg_p).gNB_CU_name = rrc->node_name; + F1AP_SETUP_RESP (msg_p).mcc[cu_cell_ind] = rrc->configuration.mcc[0]; + F1AP_SETUP_RESP (msg_p).mnc[cu_cell_ind] = rrc->configuration.mnc[0]; + F1AP_SETUP_RESP (msg_p).mnc_digit_length[cu_cell_ind] = rrc->configuration.mnc_digit_length[0]; + F1AP_SETUP_RESP (msg_p).nr_cellid[cu_cell_ind] = rrc->nr_cellid; + F1AP_SETUP_RESP (msg_p).nrpci[cu_cell_ind] = f1_setup_req->nr_pci[i]; + int num_SI= 0; + if (rrc->carrier[0].SIB23) { + F1AP_SETUP_RESP (msg_p).SI_container[cu_cell_ind][num_SI] = rrc->carrier[0].SIB23; + F1AP_SETUP_RESP (msg_p).SI_container_length[cu_cell_ind][num_SI] = rrc->carrier[0].sizeof_SIB23; + //printf("SI %d size %d: ", 0, F1AP_SETUP_RESP(msg_p).SI_container_length[j][num_SI]); + //for (int n = 0; n < F1AP_SETUP_RESP(msg_p).SI_container_length[j][num_SI]; n++) + // printf("%02x ", F1AP_SETUP_RESP(msg_p).SI_container[0][num_SI][n]); + //printf("\n"); + num_SI++; + } + F1AP_SETUP_RESP (msg_p).num_SI[cu_cell_ind] = num_SI; + + cu_cell_ind++; + found_cell=1; + + F1AP_SETUP_RESP (msg_p).num_cells_to_activate = cu_cell_ind; + // send ITTI message to F1AP-CU task + itti_send_msg_to_task (TASK_CU_F1, ENB_MODULE_ID_TO_INSTANCE(j), msg_p); + break; + } else {// setup_req mcc/mnc match rrc internal list element + + LOG_W(RRC,"[Inst %d] No matching MCC/MNC: rrc->mcc/f1_setup_req->mcc %d/%d rrc->mnc/f1_setup_req->mnc %d/%d \n", + j, rrc->configuration.mcc[0], f1_setup_req->mcc[i],rrc->configuration.mnc[0], f1_setup_req->mnc[i]); + + } + }// for (int j=0;j<RC.nb_inst;j++) + if (found_cell==0) { + AssertFatal(1==0,"No cell found\n"); + /*msg_p = itti_alloc_new_message (TASK_CU_F1,F1AP_SETUP_FAILURE); + F1AP_SETUP_RESP (msg_p).cause = rrc->node_name; + F1AP_SETUP_RESP (msg_p).time_to_wait = rrc->node_id; + F1AP_SETUP_RESP (msg_p).criticality_diagnostics = rrc->node_name;*/ + } + // handle other failure cases + }//for (int i=0;i<f1_setup_req->num_cells_available;i++) +} + + + // ignore 5GNR fields for now, just take MIB and SIB1 +//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void rrc_enb_init(void) { pthread_mutex_init(&lock_ue_freelist, NULL); @@ -6952,20 +7772,270 @@ void rrc_enb_init(void) { memset(&rrc_release_info,0,sizeof(RRC_release_list_t)); } +//----------------------------------------------------------------------------- +void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) +{ + int32_t current_timestamp_ms = 0; + int32_t ref_timestamp_ms = 0; + struct timeval ts; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_to_be_removed = NULL; +#ifdef LOCALIZATION + double estimated_distance = 0; + protocol_ctxt_t ctxt; +#endif + MessageDef *msg; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN); + + if (is_x2ap_enabled()) { + /* send a tick to x2ap */ + msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS); + itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg); + + check_handovers(ctxt_pP); // counter, get the value and aggregate + } + + // check for UL failure or for UE to be released + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { + ctxt_pP->rnti = ue_context_p->ue_id_rnti; + + if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, + ue_context_p->ue_context.ul_failure_timer); + } else { + LOG_I(RRC, "UE rnti %x failure timer %d/8\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.ul_failure_timer); + } + } + + if (ue_context_p->ue_context.ul_failure_timer > 0) { + ue_context_p->ue_context.ul_failure_timer++; + + if (ue_context_p->ue_context.ul_failure_timer >= 20000) { + // remove UE after 20 seconds after MAC (or else) has indicated UL failure + LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", + ue_context_p->ue_context.rnti); + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } + } + + if (ue_context_p->ue_context.ue_release_timer_s1 > 0) { + ue_context_p->ue_context.ue_release_timer_s1++; + + if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) { + LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.ue_release_timer_thres_s1); + + if (EPC_MODE_ENABLED && !NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) + rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p); + else + ue_to_be_removed = ue_context_p; + + ue_context_p->ue_context.ue_release_timer_s1 = 0; + break; // break RB_FOREACH + } // end if timer_s1 timeout + } // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing) + + if (ue_context_p->ue_context.ue_release_timer_rrc > 0) { + ue_context_p->ue_context.ue_release_timer_rrc++; + + if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) { + LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", + ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ue_release_timer_rrc = 0; + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } + } + + if (ue_context_p->ue_context.handover_info != NULL) { + if (ue_context_p->ue_context.handover_info->state == HO_RELEASE) { + ue_to_be_removed = ue_context_p; + rrc_eNB_handover_ue_context_release(ctxt_pP, ue_context_p); + break; //break RB_FOREACH (why to break ?) + } + if (ue_context_p->ue_context.handover_info->state == HO_CANCEL) { + rrc_eNB_handover_cancel(ctxt_pP, ue_context_p); + /* freeing handover_info and setting it to NULL to let + * RRC wait for MME to later on release the UE + */ + free(ue_context_p->ue_context.handover_info); + ue_context_p->ue_context.handover_info = NULL; + } + } + + pthread_mutex_lock(&rrc_release_freelist); + + if (rrc_release_info.num_UEs > 0) { + uint16_t release_total = 0; + + for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { + release_total++; + } + + if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && + (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) { + ue_context_p->ue_context.ue_release_timer_rrc = 1; + ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; + + if (EPC_MODE_ENABLED && !NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) { + if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0 + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(ctxt_pP->module_id, + ue_context_p->ue_context.eNB_ue_s1ap_id); + } + + rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(ctxt_pP->module_id, + ue_context_p); + // erase data of GTP tunnels in UE context + for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], + 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); + ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; + } + + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; + rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, + ue_context_p->ue_context.eNB_ue_s1ap_id); + + if (rrc_ue_s1ap_ids != NULL) { + rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids); + } + } /* EPC_MODE_ENABLED && !NODE_IS_DU */ + + rrc_release_info.RRC_release_ctrl[release_num].flag = 0; + rrc_release_info.num_UEs--; + break; // break for (release_num) + } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ... + + if (release_total >= rrc_release_info.num_UEs) { + break; // break for (release_num) + } + } // end for (release_num) + } // end if (rrc_release_info.num_UEs > 0) + + pthread_mutex_unlock(&rrc_release_freelist); + + if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { + ue_context_p->ue_context.ue_rrc_inactivity_timer++; + + if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", + ue_context_p->ue_context.rnti); + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } + } + + if (ue_context_p->ue_context.ue_reestablishment_timer > 0) { + ue_context_p->ue_context.ue_reestablishment_timer++; + + if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n", + ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ + ue_to_be_removed = ue_context_p; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + break; // break RB_FOREACH + } + } + + if (ue_context_p->ue_context.ue_release_timer > 0) { + ue_context_p->ue_context.ue_release_timer++; + + if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n", + ue_context_p->ue_context.rnti); + /* + * TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent. + * It is no more the case. + * The timer should be renamed. + */ + ue_to_be_removed = ue_context_p; + ue_context_p->ue_context.ue_release_timer = 0; + break; // break RB_FOREACH + } + } + } // end RB_FOREACH + + if (ue_to_be_removed) { + if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) || + ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && + (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) { + ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; + ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; + ue_to_be_removed->ue_context.ue_release_timer = 0; + ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; + } + + rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed); + + if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { + ue_to_be_removed->ue_context.ul_failure_timer = 0; + } + + if ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && + (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { + ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent + } + } + +#ifdef RRC_LOCALIZATION + /* for the localization, only primary CC_id might be relevant*/ + gettimeofday(&ts, NULL); + current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000; + ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms; + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { + ctxt = *ctxt_pP; + ctxt.rnti = ue_context_p->ue_context.rnti; + estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type); + + if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) && + estimated_distance != -1) { + LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n", + ctxt.rnti, + ctxt_pP->module_id, + current_timestamp_ms, + ctxt_pP->frame, + estimated_distance); + LOG_D(LOCALIZE, "RRC status %d\n", + ue_context_p->ue_context.Status); + push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance); + RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms; + } // end if + } // end RB_FOREACH +#endif + (void)ts; /* remove gcc warning "unused variable" */ + (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */ + (void)current_timestamp_ms; /* remove gcc warning "unused variable" */ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT); +} + //----------------------------------------------------------------------------- void *rrc_enb_process_itti_msg(void *notUsed) { MessageDef *msg_p; const char *msg_name_p; instance_t instance; int result; - SRB_INFO *srb_info_p; - int CC_id; protocol_ctxt_t ctxt; + + memset(&ctxt, 0, sizeof(ctxt)); + // Wait for a message itti_receive_msg(TASK_RRC_ENB, &msg_p); msg_name_p = ITTI_MSG_NAME(msg_p); instance = ITTI_MSG_INSTANCE(msg_p); - LOG_I(RRC,"Received message %s\n",msg_name_p); + /* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */ + if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS) + LOG_I(RRC,"Received message %s\n",msg_name_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -6980,31 +8050,31 @@ void *rrc_enb_process_itti_msg(void *notUsed) { /* Messages from MAC */ case RRC_MAC_CCCH_DATA_IND: PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, - instance, + RRC_MAC_CCCH_DATA_IND(msg_p).enb_index, ENB_FLAG_YES, RRC_MAC_CCCH_DATA_IND(msg_p).rnti, msg_p->ittiMsgHeader.lte_time.frame, msg_p->ittiMsgHeader.lte_time.slot); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received %s\n", - PROTOCOL_RRC_CTXT_UE_ARGS(&ctxt), - msg_name_p); - CC_id = RRC_MAC_CCCH_DATA_IND(msg_p).CC_id; - srb_info_p = &RC.rrc[instance]->carrier[CC_id].Srb0; + LOG_I(RRC,"Decoding CCCH : inst %d, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n", - instance,CC_id,&ctxt, RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); + instance, + RRC_MAC_CCCH_DATA_IND(msg_p).CC_id, + &ctxt, + RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); if (RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= RRC_BUFFER_SIZE_MAX) { - LOG_I(RRC, "CCCH message has size %d > %d\n",RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,RRC_BUFFER_SIZE_MAX); + LOG_I(RRC, "CCCH message has size %d > %d\n", + RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,RRC_BUFFER_SIZE_MAX); break; } - memcpy(srb_info_p->Rx_buffer.Payload, - RRC_MAC_CCCH_DATA_IND(msg_p).sdu, - RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); - srb_info_p->Rx_buffer.payload_size = RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size; - rrc_eNB_decode_ccch(&ctxt, srb_info_p, CC_id); + rrc_eNB_decode_ccch(&ctxt, + (uint8_t*)RRC_MAC_CCCH_DATA_IND(msg_p).sdu, + RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size, + RRC_MAC_CCCH_DATA_IND(msg_p).CC_id); break; + /* Messages from PDCP */ case RRC_DCCH_DATA_IND: PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, @@ -7013,7 +8083,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { RRC_DCCH_DATA_IND(msg_p).rnti, msg_p->ittiMsgHeader.lte_time.frame, msg_p->ittiMsgHeader.lte_time.slot); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received on DCCH %d %s\n", + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received on DCCH %d %s\n", PROTOCOL_RRC_CTXT_UE_ARGS(&ctxt), RRC_DCCH_DATA_IND(msg_p).dcch_index, msg_name_p); @@ -7030,7 +8100,6 @@ void *rrc_enb_process_itti_msg(void *notUsed) { } break; -# if defined(ENABLE_USE_MME) /* Messages from S1AP */ case S1AP_DOWNLINK_NAS: @@ -7071,26 +8140,124 @@ void *rrc_enb_process_itti_msg(void *notUsed) { rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND(msg_p, msg_name_p, instance); break; - case GTPV1U_ENB_DELETE_TUNNEL_RESP: + case GTPV1U_ENB_DELETE_TUNNEL_RESP: { + rrc_eNB_ue_context_t *ue = rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti); + + if (ue != NULL + && ue->ue_context.ue_release_timer_rrc > 0 + && (ue->ue_context.handover_info == NULL || + (ue->ue_context.handover_info->state != HO_RELEASE && + ue->ue_context.handover_info->state != HO_CANCEL))) { + ue->ue_context.ue_release_timer_rrc = ue->ue_context.ue_release_timer_thres_rrc; + } + + break; + } + + case S1AP_PATH_SWITCH_REQ_ACK: + LOG_I(RRC, "[eNB %d] received path switch ack %s\n", instance, msg_name_p); + rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK(msg_p, msg_name_p, instance); + break; + + case X2AP_HANDOVER_REQ: + LOG_I(RRC, "[eNB %d] target eNB Receives X2 HO Req %s\n", instance, msg_name_p); + rrc_eNB_process_handoverPreparationInformation(instance, &X2AP_HANDOVER_REQ(msg_p)); + break; - /* Nothing to do. Apparently everything is done in S1AP processing */ - //LOG_I(RRC, "[eNB %d] Received message %s, not processed because procedure not synched\n", - //instance, msg_name_p); - if (rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti) - && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0) { - rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc = - rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_thres_rrc; + case X2AP_HANDOVER_REQ_ACK: { + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_REQ_ACK(msg_p).rnti); + if (ue_context_p == NULL) { + /* is it possible? */ + LOG_E(RRC, "could not find UE (rnti %x) while processing X2AP_HANDOVER_REQ_ACK\n", + X2AP_HANDOVER_REQ_ACK(msg_p).rnti); + exit(1); } + LOG_I(RRC, "[eNB %d] source eNB receives the X2 HO ACK %s\n", instance, msg_name_p); + DevAssert(ue_context_p != NULL); + + if (ue_context_p->ue_context.handover_info->state != HO_REQUEST) abort(); + + rrc_eNB_process_handoverCommand(instance, ue_context_p, &X2AP_HANDOVER_REQ_ACK(msg_p)); + ue_context_p->ue_context.handover_info->state = HO_PREPARE; + break; + } + + case X2AP_UE_CONTEXT_RELEASE: { + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_UE_CONTEXT_RELEASE(msg_p).rnti); + LOG_I(RRC, "[eNB %d] source eNB receives the X2 UE CONTEXT RELEASE %s\n", instance, msg_name_p); + DevAssert(ue_context_p != NULL); + + if (ue_context_p->ue_context.handover_info->state != HO_COMPLETE) abort(); + ue_context_p->ue_context.handover_info->state = HO_RELEASE; + break; + } + + case X2AP_HANDOVER_CANCEL: { + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + char *cause; + switch (X2AP_HANDOVER_CANCEL(msg_p).cause) { + case X2AP_T_RELOC_PREP_TIMEOUT: + cause = "T_RelocPrep timeout"; + break; + case X2AP_TX2_RELOC_OVERALL_TIMEOUT: + cause = "Tx2_RelocOverall timeout"; + break; + default: + /* cannot come here */ + exit(1); + } + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_CANCEL(msg_p).rnti); + if (ue_context_p != NULL && + ue_context_p->ue_context.handover_info != NULL) { + LOG_I(RRC, "[eNB %d] eNB receives X2 HANDOVER CANCEL for rnti %x, cause %s [%s]\n", + instance, + X2AP_HANDOVER_CANCEL(msg_p).rnti, + cause, + msg_name_p); + if (X2AP_HANDOVER_CANCEL(msg_p).cause == X2AP_T_RELOC_PREP_TIMEOUT) { + /* for prep timeout, simply return to normal state */ + /* TODO: be sure that it's correct to set Status to RRC_RECONFIGURED */ + ue_context_p->ue_context.Status = RRC_RECONFIGURED; + /* TODO: be sure free is enough here (check memory leaks) */ + free(ue_context_p->ue_context.handover_info); + ue_context_p->ue_context.handover_info = NULL; + } else { + /* for overall timeout, remove UE entirely */ + ue_context_p->ue_context.handover_info->state = HO_CANCEL; + } + } else { + char *failure_cause; + if (ue_context_p == NULL) + failure_cause = "no UE found"; + else + failure_cause = "UE not in handover"; + LOG_W(RRC, "[eNB %d] cannot process (%s) X2 HANDOVER CANCEL for rnti %x, cause %s, ignoring\n", + instance, failure_cause, X2AP_HANDOVER_CANCEL(msg_p).rnti, cause); + } break; -# endif + } /* Messages from eNB app */ case RRC_CONFIGURATION_REQ: - LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p,&RRC_CONFIGURATION_REQ(msg_p)); + LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p)); openair_rrc_eNB_configuration(ENB_INSTANCE_TO_MODULE_ID(instance), &RRC_CONFIGURATION_REQ(msg_p)); break; + /* Messages from F1AP task */ + case F1AP_SETUP_REQ: + AssertFatal(NODE_IS_CU(RC.rrc[instance]->node_type), + "should not receive F1AP_SETUP_REQUEST, need call by CU!\n"); + LOG_I(RRC,"[eNB %d] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p)); + handle_f1_setup_req(&F1AP_SETUP_REQ(msg_p)); + break; + + case RRC_SUBFRAME_PROCESS: + rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id); + break; + default: LOG_E(RRC, "[eNB %d] Received unexpected message %s\n", instance, msg_name_p); break; @@ -7121,7 +8288,6 @@ rrc_enb_task( (void) rrc_enb_process_itti_msg(NULL); } } -#endif /*------------------------------------------------------------------------------*/ void @@ -7334,7 +8500,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, (struct LTE_SPS_Config *)NULL, // *sps_Config, NULL, NULL, NULL, NULL,NULL, - NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)NULL, (LTE_SL_CommConfig_r12_t *)&sl_CommConfig, (LTE_SL_DiscConfig_r12_t *)NULL @@ -7358,7 +8524,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, (struct LTE_SPS_Config *)NULL, // *sps_Config, NULL, NULL, NULL, NULL,NULL, - NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)NULL, (LTE_SL_CommConfig_r12_t *)NULL, (LTE_SL_DiscConfig_r12_t *)&sl_DiscConfig @@ -7467,238 +8633,10 @@ rrc_rx_tx( ) //----------------------------------------------------------------------------- { - int32_t current_timestamp_ms = 0; - int32_t ref_timestamp_ms = 0; - struct timeval ts; - struct rrc_eNB_ue_context_s *ue_context_p = NULL; - struct rrc_eNB_ue_context_s *ue_to_be_removed = NULL; -#ifdef LOCALIZATION - double estimated_distance = 0; - protocol_ctxt_t ctxt; -#endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN); - check_handovers(ctxt_pP); // counter, get the value and aggregate - // check for UL failure or for UE to be released - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { - ctxt_pP->rnti = ue_context_p->ue_id_rnti; - - if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) { - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { - LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, - ue_context_p->ue_context.ul_failure_timer); - } else { - LOG_I(RRC, "UE rnti %x failure timer %d/8\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.ul_failure_timer); - } - } - - if (ue_context_p->ue_context.ul_failure_timer > 0) { - ue_context_p->ue_context.ul_failure_timer++; - - if (ue_context_p->ue_context.ul_failure_timer >= 20000) { - // remove UE after 20 seconds after MAC (or else) has indicated UL failure - LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", - ue_context_p->ue_context.rnti); - ue_to_be_removed = ue_context_p; - break; // break RB_FOREACH - } - } - - if (ue_context_p->ue_context.ue_release_timer_s1 > 0) { - ue_context_p->ue_context.ue_release_timer_s1++; - - if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) { - LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.ue_release_timer_thres_s1); -#if defined(ENABLE_USE_MME) -#if defined(ENABLE_ITTI) - rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p); -#endif -#else - ue_to_be_removed = ue_context_p; -#endif - ue_context_p->ue_context.ue_release_timer_s1 = 0; - break; // break RB_FOREACH - } // end if timer_s1 timeout - } // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing) - - if (ue_context_p->ue_context.ue_release_timer_rrc > 0) { - ue_context_p->ue_context.ue_release_timer_rrc++; - - if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) { - LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", - ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ue_release_timer_rrc = 0; - ue_to_be_removed = ue_context_p; - break; // break RB_FOREACH - } - } - - pthread_mutex_lock(&rrc_release_freelist); - - if (rrc_release_info.num_UEs > 0) { - uint16_t release_total = 0; - - for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { - if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { - release_total++; - } - - if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && - (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) { - ue_context_p->ue_context.ue_release_timer_rrc = 1; - ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; -#if defined(ENABLE_USE_MME) -#if defined(ENABLE_ITTI) - int e_rab = 0; - MessageDef *msg_complete_p = NULL; - MessageDef *msg_delete_tunnels_p = NULL; - uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; - - if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0 - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0, - "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", - eNB_ue_s1ap_id); - msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); - S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p); - } - - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); - memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); - // do not wait response - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; - - for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = - ue_context_p->ue_context.enb_gtp_ebi[e_rab]; - // erase data - ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; - memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); - ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; - } - - itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); - struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; - rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); - - if (rrc_ue_s1ap_ids != NULL) { - rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids); - } - -#endif -#endif - rrc_release_info.RRC_release_ctrl[release_num].flag = 0; - rrc_release_info.num_UEs--; - break; // break for (release_num) - } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ... - - if (release_total >= rrc_release_info.num_UEs) { - break; // break for (release_num) - } - } // end for (release_num) - } // end if (rrc_release_info.num_UEs > 0) - - pthread_mutex_unlock(&rrc_release_freelist); - - if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { - ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer - - if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) { - LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", - ue_context_p->ue_context.rnti); - ue_to_be_removed = ue_context_p; - break; // break RB_FOREACH - } - } - - if (ue_context_p->ue_context.ue_reestablishment_timer > 0) { - ue_context_p->ue_context.ue_reestablishment_timer++; - - if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) { - LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n", - ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ - ue_to_be_removed = ue_context_p; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - break; // break RB_FOREACH - } - } - - if (ue_context_p->ue_context.ue_release_timer > 0) { - ue_context_p->ue_context.ue_release_timer++; - - if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) { - LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n", - ue_context_p->ue_context.rnti); - /* - * TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent. - * It is no more the case. - * The timer should be renamed. - */ - ue_to_be_removed = ue_context_p; - ue_context_p->ue_context.ue_release_timer = 0; - break; // break RB_FOREACH - } - } - } // end RB_FOREACH - - if (ue_to_be_removed) { - if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) || - ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && - (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) { - ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; - ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; - ue_to_be_removed->ue_context.ue_release_timer = 0; - ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; - } - - rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed); - - if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { - ue_to_be_removed->ue_context.ul_failure_timer = 0; - } - - if ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && - (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { - ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent - } - } - -#ifdef RRC_LOCALIZATION - /* for the localization, only primary CC_id might be relevant*/ - gettimeofday(&ts, NULL); - current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000; - ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms; - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { - ctxt = *ctxt_pP; - ctxt.rnti = ue_context_p->ue_context.rnti; - estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type); - - if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) && - estimated_distance != -1) { - LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n", - ctxt.rnti, - ctxt_pP->module_id, - current_timestamp_ms, - ctxt_pP->frame, - estimated_distance); - LOG_D(LOCALIZE, "RRC status %d\n", - ue_context_p->ue_context.Status); - push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance); - RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms; - } // end if - } // end RB_FOREACH -#endif - (void)ts; /* remove gcc warning "unused variable" */ - (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */ - (void)current_timestamp_ms; /* remove gcc warning "unused variable" */ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT); + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_SUBFRAME_PROCESS); + RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt_pP; + RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; + itti_send_msg_to_task(TASK_RRC_ENB, ctxt_pP->module_id, message_p); return RRC_OK; } - diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index 135c6fea8d82e5279036ad7c11ae08df8d3d8683..ff8f455d6cb5d1c88e6b884984e6db5b46563e3d 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -27,53 +27,41 @@ * \email: lionel.gauthier@eurecom.fr */ -#if defined(ENABLE_USE_MME) # include "rrc_defs.h" # include "rrc_extern.h" # include "RRC/LTE/MESSAGES/asn1_msg.h" # include "rrc_eNB_GTPV1U.h" # include "rrc_eNB_UE_context.h" # include "msc.h" - -# if defined(ENABLE_ITTI) # include "asn1_conversions.h" # include "intertask_interface.h" -# endif - # include "common/ran_context.h" extern RAN_CONTEXT_t RC; int rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( - const protocol_ctxt_t* const ctxt_pP, - const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP, + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, uint8_t *inde_list -) -{ +) { rnti_t rnti; int i; - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; if (create_tunnel_resp_pP) { LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->num_tunnels); - rnti = create_tunnel_resp_pP->rnti; ue_context_p = rrc_eNB_get_ue_context( RC.rrc[ctxt_pP->module_id], ctxt_pP->rnti); for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) { - -// ue_context_p->ue_context.enb_gtp_teid[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->enb_S1u_teid[i]; -// ue_context_p->ue_context.enb_gtp_addrs[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->enb_addr; -// ue_context_p->ue_context.enb_gtp_ebi[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->eps_bearer_id[i]; ue_context_p->ue_context.enb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i]; ue_context_p->ue_context.enb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr; ue_context_p->ue_context.enb_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i]; - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), create_tunnel_resp_pP->enb_S1u_teid[i], @@ -83,6 +71,7 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( create_tunnel_resp_pP->eps_bearer_id[i], create_tunnel_resp_pP->enb_addr.length); } + MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, MSC_GTPU_ENB, @@ -98,4 +87,28 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( return -1; } } -#endif + +void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( + module_id_t enb_mod_idP, + const rrc_eNB_ue_context_t* const ue_context_pP +) +{ + if (!ue_context_pP) { + LOG_W(RRC, "[eNB] In %s: invalid UE\n", __func__); + return; + } + + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL, 0, + "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", + ue_context_pP->ue_context.eNB_ue_s1ap_id); + + MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg))); + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).rnti = ue_context_pP->ue_context.rnti; + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).num_erab = ue_context_pP->ue_context.nb_of_e_rabs; + for (int e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs; e_rab++) { + const rb_id_t gtp_ebi = ue_context_pP->ue_context.enb_gtp_ebi[e_rab]; + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).eps_bearer_id[e_rab] = gtp_ebi; + } + itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg); +} diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h index aedbdeac5e12bdd510ad5d286f3d82bf4cab83f2..23806f6a0482544ee0bb8845dc89d043760422d5 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h @@ -30,10 +30,6 @@ #ifndef RRC_ENB_GTPV1U_H_ #define RRC_ENB_GTPV1U_H_ -# if defined(ENABLE_USE_MME) - - -# if defined(ENABLE_ITTI) /*! \fn rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(const protocol_ctxt_t* const ctxt_pP, const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP) *\brief Process GTPV1U_ENB_CREATE_TUNNEL_RESP message received from GTPV1U, retrieve the enb teid created. @@ -42,11 +38,19 @@ *\return 0 when successful, -1 if the UE index can not be retrieved. */ int rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( - const protocol_ctxt_t* const ctxt_pP, - const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP, + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, uint8_t *inde_list ); -# endif -# endif /* defined(ENABLE_USE_MME) */ +/*! \fn rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(module_id_t enb_mod_idP, const rrc_eNB_ue_context_t* const ue_context_pP) + *\brief Send GTPV1U_ENB_DELETE_TUNNEL_REQ message to GTPV1U to destroy all UE-related tunnels. + *\param module_id Instance ID of eNB. + *\param ue_context_pP UE context in the eNB. + */ +void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( + module_id_t enb_mod_idP, + const rrc_eNB_ue_context_t* const ue_context_pP +); + #endif /* RRC_ENB_GTPV1U_H_ */ diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index ebacfc838119b779badc14625022513390247db5..b26e2c1cb06a6246a68c895a8f0c98f81800a10a 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -27,7 +27,7 @@ * \company Eurecom * \email: navid.nikaein@eurecom.fr */ -#if defined(ENABLE_USE_MME) + # include "rrc_defs.h" # include "rrc_extern.h" # include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" @@ -36,24 +36,19 @@ # include "rrc_eNB_S1AP.h" # include "enb_config.h" # include "common/ran_context.h" +# include "gtpv1u.h" # include "s1ap_eNB_defs.h" # include "s1ap_eNB_management_procedures.h" # include "s1ap_eNB_ue_context.h" +#include "asn1_conversions.h" +#include "intertask_interface.h" +#include "pdcp.h" +#include "pdcp_primitives.h" +#include "s1ap_eNB.h" -#if defined(ENABLE_ITTI) - #include "asn1_conversions.h" - #include "intertask_interface.h" - #include "pdcp.h" - #include "pdcp_primitives.h" - #include "s1ap_eNB.h" -#else - #include "../../S1AP/s1ap_eNB.h" -#endif -#if defined(ENABLE_SECURITY) - #include "UTIL/OSA/osa_defs.h" -#endif +#include "UTIL/OSA/osa_defs.h" #include "msc.h" #include "LTE_UERadioAccessCapabilityInformation.h" @@ -67,6 +62,11 @@ extern RAN_CONTEXT_t RC; +extern int +gtpv1u_delete_s1u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_delete_tunnel_req_t *const req_pP); + /* Value to indicate an invalid UE initial id */ static const uint16_t UE_INITIAL_ID_INVALID = 0; @@ -158,7 +158,7 @@ void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_c } } -# if defined(ENABLE_ITTI) + //------------------------------------------------------------------------------ /* * Get the UE S1 struct containing hashtables S1_id/UE_id. @@ -216,8 +216,7 @@ rrc_eNB_S1AP_get_ue_ids( result2->ue_initial_id, result->eNB_ue_s1ap_id, result2->eNB_ue_s1ap_id); - - // Still return *result + // Still return *result } } } // end if if (eNB_ue_s1ap_id > 0) @@ -225,7 +224,6 @@ rrc_eNB_S1AP_get_ue_ids( LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in initial_id2_s1ap_ids ue_initial_id %"PRIu16"\n", rrc_instance_pP - RC.rrc[0], ue_initial_id); - return NULL; /* * At the moment this is written, this case shouldn't (cannot) happen and is equivalent to an error. @@ -255,7 +253,6 @@ rrc_eNB_S1AP_get_ue_ids( } else { LOG_E(S1AP, "[eNB instance %d] Couldn't find the eNB S1AP context\n", instance); - return NULL; } @@ -270,7 +267,7 @@ rrc_eNB_S1AP_get_ue_ids( } else { LOG_E(RRC, "[eNB %ld] Incoherence between RRC context and S1AP context (%d != %d) for UE RNTI %d or UE RRC context doesn't exist\n", rrc_instance_pP - RC.rrc[0], - ue_context_p->ue_context.eNB_ue_s1ap_id, + (ue_context_p==NULL)?99999:ue_context_p->ue_context.eNB_ue_s1ap_id, eNB_ue_s1ap_id, result->ue_rnti); } @@ -279,7 +276,6 @@ rrc_eNB_S1AP_get_ue_ids( LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", even when looking at S1AP context\n", rrc_instance_pP - RC.rrc[0], eNB_ue_s1ap_id); - return NULL; } } // end if (h_rc != HASH_TABLE_OK) @@ -300,8 +296,6 @@ rrc_eNB_S1AP_remove_ue_ids( ) //------------------------------------------------------------------------------ { - const uint16_t ue_initial_id = ue_ids_pP->ue_initial_id; - const uint32_t eNB_ue_s1ap_id = ue_ids_pP->eNB_ue_s1ap_id; hashtable_rc_t h_rc; if (rrc_instance_pP == NULL) { @@ -314,6 +308,9 @@ rrc_eNB_S1AP_remove_ue_ids( return; } + const uint16_t ue_initial_id = ue_ids_pP->ue_initial_id; + const uint32_t eNB_ue_s1ap_id = ue_ids_pP->eNB_ue_s1ap_id; + if (eNB_ue_s1ap_id > 0) { h_rc = hashtable_remove(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id); @@ -429,7 +426,7 @@ static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_inte *\param security_capabilities The security capabilities received from S1AP. *\return TRUE if at least one algorithm has been changed else FALSE. */ -static int +int rrc_eNB_process_security( const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, @@ -480,14 +477,13 @@ rrc_eNB_process_security( *\param security_key_pP The security key received from S1AP. */ //------------------------------------------------------------------------------ -static void process_eNB_security_key ( +void process_eNB_security_key ( const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP ) //------------------------------------------------------------------------------ { -#if defined(ENABLE_SECURITY) char ascii_buffer[65]; uint8_t i; /* Saves the security key */ @@ -501,7 +497,6 @@ static void process_eNB_security_key ( ascii_buffer[2 * i] = '\0'; LOG_I (RRC, "[eNB %d][UE %x] Saved security key %s\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ascii_buffer); -#endif } @@ -514,7 +509,6 @@ rrc_pdcp_config_security( ) //------------------------------------------------------------------------------ { -#if defined(ENABLE_SECURITY) LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; @@ -572,8 +566,6 @@ rrc_pdcp_config_security( PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), DCCH); } - -#endif } //------------------------------------------------------------------------------ @@ -622,7 +614,6 @@ rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP( S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed; itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } -# endif //------------------------------------------------------------------------------ void @@ -633,7 +624,6 @@ rrc_eNB_send_S1AP_UPLINK_NAS( ) //------------------------------------------------------------------------------ { -#if defined(ENABLE_ITTI) { LTE_ULInformationTransfer_t *ulInformationTransfer = &ul_dcch_msg->message.choice.c1.choice.ulInformationTransfer; @@ -660,36 +650,6 @@ rrc_eNB_send_S1AP_UPLINK_NAS( itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } } -#else - { - LTE_ULInformationTransfer_t *ulInformationTransfer; - ulInformationTransfer = - &ul_dcch_msg->message.choice.c1.choice. - ulInformationTransfer; - - if (ulInformationTransfer->criticalExtensions.present == - LTE_ULInformationTransfer__criticalExtensions_PR_c1) { - if (ulInformationTransfer->criticalExtensions.choice.c1.present == - LTE_ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) { - ULInformationTransfer_r8_IEs_t - *ulInformationTransferR8; - ulInformationTransferR8 = - &ulInformationTransfer->criticalExtensions.choice. - c1.choice.ulInformationTransfer_r8; - - if (ulInformationTransferR8->dedicatedInfoType.present == - LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) { - extract_imsi(ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, - ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size, - ue_context_pP); - s1ap_eNB_new_data_request (mod_id, ue_index, - ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, - ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size); - } - } - } - } -#endif } //------------------------------------------------------------------------------ @@ -752,7 +712,6 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( //------------------------------------------------------------------------------ { eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; -#if defined(ENABLE_ITTI) { MessageDef *message_p = NULL; rrc_ue_s1ap_ids_t *rrc_ue_s1ap_ids_p = NULL; @@ -840,6 +799,11 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code = BIT_STRING_to_uint8 (&r_mme->mmec); S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id = BIT_STRING_to_uint16 (&r_mme->mmegi); + ue_context_pP->ue_context.ue_gummei.mcc = S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc; + ue_context_pP->ue_context.ue_gummei.mnc = S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc; + ue_context_pP->ue_context.ue_gummei.mnc_len = S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len; + ue_context_pP->ue_context.ue_gummei.mme_code = S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code; + ue_context_pP->ue_context.ue_gummei.mme_group_id = S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id; MSC_LOG_TX_MESSAGE(MSC_S1AP_ENB, MSC_S1AP_MME, (const char *)&message_p->ittiMsg.s1ap_nas_first_req, @@ -857,20 +821,9 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( } // end "Fill UE identities with available information" sub-part itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, message_p); } -#else - { - s1ap_eNB_new_data_request ( - ctxt_pP->module_id, - ue_context_pP, - rrcConnectionSetupComplete->dedicatedInfoNAS. - buf, - rrcConnectionSetupComplete->dedicatedInfoNAS. - size); - } -#endif } -# if defined(ENABLE_ITTI) + //------------------------------------------------------------------------------ int rrc_eNB_process_S1AP_DOWNLINK_NAS( @@ -996,6 +949,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char } else { PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); ue_context_p->ue_context.eNB_ue_s1ap_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).eNB_ue_s1ap_id; + ue_context_p->ue_context.mme_ue_s1ap_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).mme_ue_s1ap_id; /* Save e RAB information for later */ { int i; @@ -1067,6 +1021,35 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char rrc_eNB_generate_UECapabilityEnquiry (&ctxt, ue_context_p); } } + + // in case, send the S1SP initial context response if it is not sent with the attach complete message + if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) { + LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause); + //if(ue_context_p->ue_context.reestablishment_cause == ReestablishmentCause_spare1){} + rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(&ctxt,ue_context_p); + } +/* + if ((RC.rrc[ctxt.module_id]->node_type == ngran_eNB_CU) || + (RC.rrc[ctxt.module_id]->node_type == ngran_ng_eNB_CU) || + (RC.rrc[ctxt.module_id]->node_type == ngran_gNB_CU) ){ + + message_p = itti_alloc_new_message (TASK_RRC_ENB, F1AP_UE_CONTEXT_SETUP_REQ); + F1AP_UE_CONTEXT_SETUP_REQ (message_p).rrc_container = ue_p->Srb0.Tx_buffer.Payload; + + F1AP_UE_CONTEXT_SETUP_REQ (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size; + F1AP_UE_CONTEXT_SETUP_REQ (message_p).gNB_CU_ue_id = 0; + F1AP_UE_CONTEXT_SETUP_REQ (message_p).gNB_DU_ue_id = 0; + F1AP_UE_CONTEXT_SETUP_REQ (message_p).old_gNB_DU_ue_id = 0xFFFFFFFF; // unknown + F1AP_UE_CONTEXT_SETUP_REQ (message_p).rnti = ue_p->rnti; + F1AP_UE_CONTEXT_SETUP_REQ (message_p).srb_id = CCCH; + F1AP_UE_CONTEXT_SETUP_REQ (message_p).execute_duplication = 1; + F1AP_UE_CONTEXT_SETUP_REQ (message_p).RAT_frequency_priority_information.en_dc = 0; + itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); + LOG_D(RRC, "Send F1AP_UE_CONTEXT_SETUP_REQ with ITTI\n"); + + } +*/ + return (0); } } @@ -1189,6 +1172,20 @@ rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ( } } +void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT( + module_id_t enb_mod_idP, + uint32_t eNB_ue_s1ap_id +) +{ + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0, + "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", + eNB_ue_s1ap_id); + + MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); + S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg).eNB_ue_s1ap_id = eNB_ue_s1ap_id; + itti_send_msg_to_task(TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg); +} + //----------------------------------------------------------------------------- /* @@ -1784,7 +1781,6 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance uint32_t T; /* DRX cycle */ for (uint16_t tai_size = 0; tai_size < S1AP_PAGING_IND(msg_p).tai_size; tai_size++) { - LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]); @@ -1807,6 +1803,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance T = Tc < Tue ? Ttab[Tc] : Ttab[Tue]; /* set pcch_nB = PCCH-Config->nB */ pcch_nB = (uint32_t)RC.rrc[instance]->configuration.radioresourceconfig[CC_id].pcch_nB; + switch (pcch_nB) { case LTE_PCCH_Config__nB_fourT: Ns = 4; @@ -1931,5 +1928,261 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance return (0); } -# endif /* defined(ENABLE_ITTI) */ -#endif /* defined(ENABLE_USE_MME) */ +/*NN: careful about the typcast of xid (long -> uint8_t*/ +int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP) { + MessageDef *msg_p = NULL; + int e_rab = 0; + int e_rabs_done = 0; + rrc_ue_s1ap_ids_t *rrc_ue_s1ap_ids_p = NULL; + hashtable_rc_t h_rc; + gtpv1u_enb_create_tunnel_req_t create_tunnel_req; + gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; + uint8_t inde_list[ue_context_pP->ue_context.nb_of_e_rabs]; + memset(inde_list, 0, ue_context_pP->ue_context.nb_of_e_rabs*sizeof(uint8_t)); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_PATH_SWITCH_REQ); + ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id (ctxt_pP->module_id); + S1AP_PATH_SWITCH_REQ (msg_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id; + rrc_ue_s1ap_ids_p = malloc(sizeof(*rrc_ue_s1ap_ids_p)); + rrc_ue_s1ap_ids_p->ue_initial_id = ue_context_pP->ue_context.ue_initial_id; + rrc_ue_s1ap_ids_p->eNB_ue_s1ap_id = UE_INITIAL_ID_INVALID; + rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; + h_rc = hashtable_insert(RC.rrc[ctxt_pP->module_id]->initial_id2_s1ap_ids, + (hash_key_t)ue_context_pP->ue_context.ue_initial_id, + rrc_ue_s1ap_ids_p); + + if (h_rc != HASH_TABLE_OK) { + LOG_E(S1AP, "[eNB %d] Error while hashtable_insert in initial_id2_s1ap_ids ue_initial_id %u\n", + ctxt_pP->module_id, ue_context_pP->ue_context.ue_initial_id); + } + + S1AP_PATH_SWITCH_REQ (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; + S1AP_PATH_SWITCH_REQ (msg_p).mme_ue_s1ap_id = ue_context_pP->ue_context.mme_ue_s1ap_id; + S1AP_PATH_SWITCH_REQ (msg_p).ue_gummei.mcc = ue_context_pP->ue_context.ue_gummei.mcc; + S1AP_PATH_SWITCH_REQ (msg_p).ue_gummei.mnc = ue_context_pP->ue_context.ue_gummei.mnc; + S1AP_PATH_SWITCH_REQ (msg_p).ue_gummei.mnc_len = ue_context_pP->ue_context.ue_gummei.mnc_len; + S1AP_PATH_SWITCH_REQ (msg_p).ue_gummei.mme_code = ue_context_pP->ue_context.ue_gummei.mme_code; + S1AP_PATH_SWITCH_REQ (msg_p).ue_gummei.mme_group_id = ue_context_pP->ue_context.ue_gummei.mme_group_id; + S1AP_PATH_SWITCH_REQ (msg_p).security_capabilities.encryption_algorithms=ue_context_pP->ue_context.security_capabilities.encryption_algorithms; + S1AP_PATH_SWITCH_REQ (msg_p).security_capabilities.integrity_algorithms=ue_context_pP->ue_context.security_capabilities.integrity_algorithms; + LOG_I (RRC,"Path switch request: nb nb_of_e_rabs %u status %u\n", + ue_context_pP->ue_context.nb_of_e_rabs, + ue_context_pP->ue_context.e_rab[e_rab].status); + memset(&create_tunnel_req, 0, sizeof(create_tunnel_req)); + + // the context for UE to be handovered is obtained through ho_req message + for (e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs ; e_rab++) { + if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_ESTABLISHED) { + create_tunnel_req.eps_bearer_id[e_rabs_done] = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; + create_tunnel_req.sgw_S1u_teid[e_rabs_done] = ue_context_pP->ue_context.e_rab[e_rab].param.gtp_teid; + memcpy(&create_tunnel_req.sgw_addr[e_rabs_done], + &ue_context_pP->ue_context.e_rab[e_rab].param.sgw_addr, + sizeof(transport_layer_addr_t)); + inde_list[e_rabs_done] = e_rab; + e_rabs_done++; + } + } + + S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs = e_rabs_done; + create_tunnel_req.rnti = ue_context_pP->ue_context.rnti; + create_tunnel_req.num_tunnels = e_rabs_done; + gtpv1u_create_s1u_tunnel( + ctxt_pP->instance, + &create_tunnel_req, + &create_tunnel_resp); + rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( + ctxt_pP, + &create_tunnel_resp, + &inde_list[0]); + + for (e_rab = 0; e_rab < e_rabs_done; e_rab++) { + S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].e_rab_id = create_tunnel_resp.eps_bearer_id[e_rab]; + S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].gtp_teid = create_tunnel_resp.enb_S1u_teid[e_rab]; + S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr = create_tunnel_resp.enb_addr; + LOG_I (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d): nb_of_e_rabs %d, e_rab_id %d, teid: %u, addr: %d.%d.%d.%d \n ", + e_rabs_done, e_rab, ue_context_pP->ue_context.e_rab[inde_list[e_rab]].status, + S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs, + S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].e_rab_id, + S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].gtp_teid, + S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[0], + S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[1], + S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[2], + S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[3]); + } + + // NN: add conditions for e_rabs_failed + if (e_rabs_done > 0) { + LOG_I(RRC,"S1AP_PATH_SWITCH_REQ: sending the message: nb_of_erabstobeswitched %d, total e_rabs %d, index %d\n", + S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab); + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_S1AP_ENB, + (const char *)&S1AP_PATH_SWITCH_REQ (msg_p), + sizeof(s1ap_path_switch_req_t), + MSC_AS_TIME_FMT" PATH_SWITCH_REQ UE %X eNB_ue_s1ap_id %u e_rabs:%u succ", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_id_rnti, + S1AP_PATH_SWITCH_REQ (msg_p).eNB_ue_s1ap_id, + e_rabs_done); + itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); + } + + return 0; +} + +int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg_name, instance_t instance) { + uint16_t ue_initial_id; + uint32_t eNB_ue_s1ap_id; + //gtpv1u_enb_create_tunnel_req_t create_tunnel_req; + //gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; + gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + protocol_ctxt_t ctxt; + int i; + ue_initial_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).ue_initial_id; + eNB_ue_s1ap_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).eNB_ue_s1ap_id; + ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); + LOG_I(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", + instance, msg_name, ue_initial_id, eNB_ue_s1ap_id, S1AP_E_RAB_SETUP_REQ (msg_p).nb_e_rabs_tosetup); + + if (ue_context_p == NULL) { + /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ + //MessageDef *msg_fail_p = NULL; + LOG_W(RRC, "[eNB %d] In S1AP_PATH_SWITCH_REQ_ACK: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); + //msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_PATH_SWITCH_REQ_ACK_FAIL); + //S1AP_PATH_SWITCH_REQ_ACK (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; + // TODO add failure cause when defined! + //itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p); + return (-1); + } else { + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + ue_context_p->ue_context.eNB_ue_s1ap_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).eNB_ue_s1ap_id; + ue_context_p->ue_context.mme_ue_s1ap_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).mme_ue_s1ap_id; + /* Save e RAB information for later */ + { + ue_context_p->ue_context.nb_release_of_e_rabs = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobereleased; + + for (i = 0; + i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg + i++) { + // assume that we are releasing all the DRBs + ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_REESTABLISHED; + if (ue_context_p->ue_context.nb_release_of_e_rabs==0) { + LOG_I(RRC,"Bearer re-established with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id); + } + } + + //memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req)); + uint8_t nb_e_rabs_tobeswitched = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobeswitched; + + // keep the previous bearer + // the index for the rec + if (nb_e_rabs_tobeswitched>0) { + int e_rab_switch_index=0; + for (i = 0; + i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg + i++) { + /* Harmonize with enb_gtp_teid, enb_gtp_addrs, and enb_gtp_rbi vars in the top level structure */ + if (ue_context_p->ue_context.e_rab[i].param.e_rab_id == S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].e_rab_id) { + ue_context_p->ue_context.e_rab[i].param.e_rab_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].e_rab_id; + ue_context_p->ue_context.e_rab[i].param.sgw_addr= S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].sgw_addr; + ue_context_p->ue_context.e_rab[i].param.gtp_teid = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].gtp_teid; + e_rab_switch_index++; + } + } + } + } + ue_context_p->ue_context.ue_ambr=S1AP_PATH_SWITCH_REQ_ACK (msg_p).ue_ambr; + + ue_context_p->ue_context.setup_e_rabs = ue_context_p->ue_context.setup_e_rabs - ue_context_p->ue_context.nb_release_of_e_rabs; + ue_context_p->ue_context.nb_of_e_rabs = ue_context_p->ue_context.nb_of_e_rabs - ue_context_p->ue_context.nb_release_of_e_rabs; + + memset(&delete_tunnel_req, 0 , sizeof(delete_tunnel_req)); + + if (ue_context_p->ue_context.nb_release_of_e_rabs>0) { + int e_rab_release_index=0; + for (i = 0; + i < ue_context_p->ue_context.setup_e_rabs; + i++) { + if (ue_context_p->ue_context.e_rab[i].param.e_rab_id == S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id) { + LOG_I(RRC,"Bearer released with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id); + ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE; + ue_context_p->ue_context.e_rabs_tobereleased[e_rab_release_index]=S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id; + delete_tunnel_req.eps_bearer_id[e_rab_release_index] = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id; + e_rab_release_index++; + } + else { + LOG_I(RRC,"Bearer re-established with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id); + } + } + } + + if (ue_context_p->ue_context.nb_release_of_e_rabs>0){ + delete_tunnel_req.rnti= ue_context_p->ue_context.rnti; + delete_tunnel_req.num_erab= ue_context_p->ue_context.nb_release_of_e_rabs; + /* this could also be done through ITTI message */ + gtpv1u_delete_s1u_tunnel(instance, + &delete_tunnel_req); + /* TBD: release the DRB not admitted */ + //rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(&ctxt, ue_context_p, 0); + } + + /* Security key */ + ue_context_p->ue_context.next_hop_chain_count=S1AP_PATH_SWITCH_REQ_ACK (msg_p).next_hop_chain_count; + memcpy ( ue_context_p->ue_context.next_security_key, + S1AP_PATH_SWITCH_REQ_ACK (msg_p).next_security_key, + SECURITY_KEY_LENGTH); + + rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(&ctxt, ue_context_p); + + return (0); + } +} + +int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP) { + + MessageDef *msg_p = NULL; + + msg_p = itti_alloc_new_message (TASK_RRC_ENB, X2AP_UE_CONTEXT_RELEASE); + + X2AP_UE_CONTEXT_RELEASE (msg_p).rnti = ue_context_pP->ue_context.rnti; + X2AP_UE_CONTEXT_RELEASE (msg_p).source_assoc_id = ue_context_pP->ue_context.handover_info->assoc_id; + itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p); + return (0); +} + +int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id){ + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + DevAssert(s1ap_eNB_instance_p != NULL); + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + eNB_ue_s1ap_id)) == NULL) { + /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ + LOG_W(RRC,"Failed to find ue context associated with eNB ue s1ap id: %u\n", + eNB_ue_s1ap_id); + return -1; + } + + // release UE context + struct s1ap_eNB_ue_context_s *ue_context2_p = NULL; + + if ((ue_context2_p = RB_REMOVE(s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head, ue_context_p)) + != NULL) { + LOG_W(RRC,"Removed UE context eNB_ue_s1ap_id %u\n", + ue_context2_p->eNB_ue_s1ap_id); + s1ap_eNB_free_ue_context(ue_context2_p); + } else { + LOG_W(RRC,"Removing UE context eNB_ue_s1ap_id %u: did not find context\n", + ue_context_p->eNB_ue_s1ap_id); + } + /*RB_FOREACH(ue_context_p, s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head) { + S1AP_WARN("in s1ap_ue_map: UE context eNB_ue_s1ap_id %u mme_ue_s1ap_id %u state %u\n", + ue_context_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id, + ue_context_p->ue_state); + }*/ + + return 0; +} diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h index eb427bc7bd9e474cac11326d4241947408bdfd10..5feb55d635c63461b237b439f5f1654d9e2882dc 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.h +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h @@ -31,13 +31,10 @@ #ifndef RRC_ENB_S1AP_H_ #define RRC_ENB_S1AP_H_ -# if defined(ENABLE_USE_MME) - #include "LTE_UL-DCCH-Message.h" /* Up link procedures */ -# if defined(ENABLE_ITTI) typedef struct rrc_ue_s1ap_ids_s { /* Tree related data */ RB_ENTRY(rrc_ue_s1ap_ids_s) entries; @@ -52,36 +49,36 @@ typedef struct rrc_ue_s1ap_ids_s { int rrc_eNB_S1AP_compare_ue_ids( - struct rrc_ue_s1ap_ids_s* c1_pP, - struct rrc_ue_s1ap_ids_s* c2_pP + struct rrc_ue_s1ap_ids_s *c1_pP, + struct rrc_ue_s1ap_ids_s *c2_pP ); struct rrc_rnti_tree_s; RB_PROTOTYPE(rrc_rnti_tree_s, rrc_ue_s1ap_ids_s, entries, rrc_eNB_S1AP_compare_ue_ids); -struct rrc_ue_s1ap_ids_s* +struct rrc_ue_s1ap_ids_s * rrc_eNB_S1AP_get_ue_ids( - eNB_RRC_INST* const rrc_instance_pP, + eNB_RRC_INST *const rrc_instance_pP, const uint16_t ue_initial_id, const uint32_t eNB_ue_s1ap_id ); void rrc_eNB_S1AP_remove_ue_ids( - eNB_RRC_INST* const rrc_instance_pP, - struct rrc_ue_s1ap_ids_s* const ue_ids_pP + eNB_RRC_INST *const rrc_instance_pP, + struct rrc_ue_s1ap_ids_s *const ue_ids_pP ); void -rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, +rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const uint8_t ho_state ); int -rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, +rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const uint8_t ho_state ); @@ -92,8 +89,8 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons */ void rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP ); /*! \fn void rrc_eNB_send_S1AP_UPLINK_NAS(const protocol_ctxt_t * const ctxt_pP, eNB_RRC_UE_t * const ue_context_pP, UL_DCCH_Message_t * const ul_dcch_msg) @@ -104,9 +101,9 @@ rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP( */ void rrc_eNB_send_S1AP_UPLINK_NAS( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - LTE_UL_DCCH_Message_t* const ul_dcch_msg + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + LTE_UL_DCCH_Message_t *const ul_dcch_msg ); /*! \fn void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(const protocol_ctxt_t * const ctxt_pP, eNB_RRC_UE_t * const ue_context_pP, UL_DCCH_Message_t *ul_dcch_msg) @@ -116,9 +113,9 @@ rrc_eNB_send_S1AP_UPLINK_NAS( *\param ul_dcch_msg The message receive by RRC holding the NAS message. */ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - LTE_UL_DCCH_Message_t* ul_dcch_msg + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + LTE_UL_DCCH_Message_t *ul_dcch_msg ); /*! \fn rrc_eNB_send_S1AP_NAS_FIRST_REQ(const protocol_ctxt_t* const ctxt_pP,eNB_RRC_UE_t *const ue_context_pP, RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete) @@ -130,9 +127,9 @@ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( */ void rrc_eNB_send_S1AP_NAS_FIRST_REQ( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - LTE_RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + LTE_RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete ); @@ -146,11 +143,21 @@ the UE-associated S1-logical connection over the S1 interface. . */ void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ ( const module_id_t enb_mod_idP, - const rrc_eNB_ue_context_t* const ue_context_pP, + const rrc_eNB_ue_context_t *const ue_context_pP, const s1ap_Cause_t causeP, const long cause_valueP ); +/*! \fn rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(const module_id_t enb_mod_idP, const struct rrc_eNB_ue_context_s *const ue_context_pP) + *\brief create a S1AP_UE_CONTEXT_RELEASE_COMPLETE message, the message is sent by the eNB to S1AP task to acknowledge/complete the release of the UE-associated S1-logical connection over the S1 interface. . + *\param enb_mod_idP Instance ID of eNB. + *\param eNB_ue_s1ap_id UE's S1AP ID in the eNB. + */ +void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT( + module_id_t enb_mod_idP, + uint32_t eNB_ue_s1ap_id +); + /* Down link procedures */ /*! \fn rrc_eNB_process_S1AP_DOWNLINK_NAS(MessageDef *msg_p, const char *msg_name, instance_t instance, mui_t *rrc_eNB_mui) @@ -189,7 +196,7 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name *\param xid transaction identifier *\return 0 when successful, -1 if the UE index can not be retrieved. */ -int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, uint8_t xid ); +int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t xid ); /*! \fn rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance); *\brief process a S1AP dedicated E_RAB modify request message received from S1AP. @@ -207,7 +214,7 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam *\param xid transaction identifier *\return 0 when successful, -1 if the UE index can not be retrieved. */ -int rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, uint8_t xid ); +int rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t xid ); /*! \fn rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance) *\brief process a S1AP_UE_CTXT_MODIFICATION_REQ message received from S1AP. @@ -247,8 +254,8 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance void rrc_pdcp_config_security( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const uint8_t send_security_mode_command ); /*! \fn rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *msg_name, instance_t instance); @@ -267,8 +274,14 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms *\param xid transaction identifier *\return 0 when successful, -1 if the UE index can not be retrieved. */ -int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, uint8_t xid ); +int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t xid ); + +int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP); +int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg_name, instance_t instance); + +int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP); + +int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id); -# endif -# endif /* defined(ENABLE_USE_MME) */ #endif /* RRC_ENB_S1AP_H_ */ diff --git a/openair2/RRC/LTE/rrc_eNB_UE_context.c b/openair2/RRC/LTE/rrc_eNB_UE_context.c index 646939b8dc451335523b7de646fd93afcd1f641c..197aedae51756a886ad591bc4166d093e82cc705 100644 --- a/openair2/RRC/LTE/rrc_eNB_UE_context.c +++ b/openair2/RRC/LTE/rrc_eNB_UE_context.c @@ -41,7 +41,7 @@ //------------------------------------------------------------------------------ void uid_linear_allocator_init( - uid_allocator_t* const uid_pP + uid_allocator_t *const uid_pP ) //------------------------------------------------------------------------------ { @@ -51,14 +51,14 @@ uid_linear_allocator_init( //------------------------------------------------------------------------------ uid_t uid_linear_allocator_new( - eNB_RRC_INST* const rrc_instance_pP + eNB_RRC_INST *const rrc_instance_pP ) //------------------------------------------------------------------------------ { unsigned int i; unsigned int bit_index = 1; uid_t uid = 0; - uid_allocator_t* uia_p = &rrc_instance_pP->uid_allocator; + uid_allocator_t *uia_p = &rrc_instance_pP->uid_allocator; for (i=0; i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE; i++) { if (uia_p->bitmap[i] != UINT_MAX) { @@ -82,7 +82,7 @@ uid_linear_allocator_new( //------------------------------------------------------------------------------ void uid_linear_allocator_free( - eNB_RRC_INST* rrc_instance_pP, + eNB_RRC_INST *rrc_instance_pP, uid_t uidP ) //------------------------------------------------------------------------------ @@ -99,7 +99,7 @@ uid_linear_allocator_free( //------------------------------------------------------------------------------ int rrc_eNB_compare_ue_rnti_id( - struct rrc_eNB_ue_context_s* c1_pP, struct rrc_eNB_ue_context_s* c2_pP) + struct rrc_eNB_ue_context_s *c1_pP, struct rrc_eNB_ue_context_s *c2_pP) //------------------------------------------------------------------------------ { if (c1_pP->ue_id_rnti > c2_pP->ue_id_rnti) { @@ -120,14 +120,14 @@ RB_GENERATE(rrc_ue_tree_s, rrc_eNB_ue_context_s, entries, //------------------------------------------------------------------------------ -struct rrc_eNB_ue_context_s* +struct rrc_eNB_ue_context_s * rrc_eNB_allocate_new_UE_context( - eNB_RRC_INST* rrc_instance_pP + eNB_RRC_INST *rrc_instance_pP ) //------------------------------------------------------------------------------ { - struct rrc_eNB_ue_context_s* new_p; - new_p = (struct rrc_eNB_ue_context_s* )malloc(sizeof(struct rrc_eNB_ue_context_s)); + struct rrc_eNB_ue_context_s *new_p; + new_p = (struct rrc_eNB_ue_context_s * )malloc(sizeof(struct rrc_eNB_ue_context_s)); if (new_p == NULL) { LOG_E(RRC, "Cannot allocate new ue context\n"); @@ -136,18 +136,20 @@ rrc_eNB_allocate_new_UE_context( memset(new_p, 0, sizeof(struct rrc_eNB_ue_context_s)); new_p->local_uid = uid_linear_allocator_new(rrc_instance_pP); + for(int i = 0; i < NB_RB_MAX; i++) { - new_p->ue_context.e_rab[i].xid = -1; - new_p->ue_context.modify_e_rab[i].xid = -1; + new_p->ue_context.e_rab[i].xid = -1; + new_p->ue_context.modify_e_rab[i].xid = -1; } + return new_p; } //------------------------------------------------------------------------------ -struct rrc_eNB_ue_context_s* +struct rrc_eNB_ue_context_s * rrc_eNB_get_ue_context( - eNB_RRC_INST* rrc_instance_pP, + eNB_RRC_INST *rrc_instance_pP, rnti_t rntiP) //------------------------------------------------------------------------------ { @@ -157,6 +159,7 @@ rrc_eNB_get_ue_context( temp.ue_id_rnti = rntiP; struct rrc_eNB_ue_context_s *ue_context_p = NULL; ue_context_p = RB_FIND(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp); + if ( ue_context_p != NULL) { return ue_context_p; } else { @@ -172,9 +175,9 @@ rrc_eNB_get_ue_context( //------------------------------------------------------------------------------ void rrc_eNB_remove_ue_context( - const protocol_ctxt_t* const ctxt_pP, - eNB_RRC_INST* rrc_instance_pP, - struct rrc_eNB_ue_context_s* ue_context_pP) + const protocol_ctxt_t *const ctxt_pP, + eNB_RRC_INST *rrc_instance_pP, + struct rrc_eNB_ue_context_s *ue_context_pP) //------------------------------------------------------------------------------ { if (rrc_instance_pP == NULL) { @@ -190,12 +193,10 @@ void rrc_eNB_remove_ue_context( } RB_REMOVE(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); - MSC_LOG_EVENT( MSC_RRC_ENB, "0 Removed UE %"PRIx16" ", ue_context_pP->ue_context.rnti); - rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_pP); uid_linear_allocator_free(rrc_instance_pP, ue_context_pP->local_uid); free(ue_context_pP); diff --git a/openair2/RRC/LTE/rrc_eNB_ral.c b/openair2/RRC/LTE/rrc_eNB_ral.c index db20eb4a28bfe587d3427a40525b11c673e5f262..4820e84dc0d43e89cd8a71af61085b14f6e19253 100644 --- a/openair2/RRC/LTE/rrc_eNB_ral.c +++ b/openair2/RRC/LTE/rrc_eNB_ral.c @@ -46,8 +46,7 @@ int rrc_enb_ral_delete_all_thresholds_type(unsigned int mod_idP, ral_link_param_ rrc_ral_threshold_key_t *keys = NULL; unsigned int num_keys = 0; int return_code = 0; - - rc = obj_hashtable_get_keys(eNB_rrc_inst[mod_idP].ral_meas_thresholds, (void*)&keys, &num_keys); + rc = obj_hashtable_get_keys(eNB_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&keys, &num_keys); if (rc == HASH_TABLE_OK) { key = keys; @@ -82,10 +81,9 @@ int rrc_enb_ral_delete_threshold(unsigned int mod_idP, ral_link_param_type_t *pa { hashtable_rc_t rc; rrc_ral_threshold_key_t ref_key; - memcpy(&ref_key.link_param_type, param_type_pP, sizeof(ral_link_param_type_t)); memcpy(&ref_key.threshold, threshold_pP, sizeof(ral_threshold_t)); - rc = obj_hashtable_remove (eNB_rrc_inst[mod_idP].ral_meas_thresholds, (void*)&ref_key, sizeof(rrc_ral_threshold_key_t)); + rc = obj_hashtable_remove (eNB_rrc_inst[mod_idP].ral_meas_thresholds, (void *)&ref_key, sizeof(rrc_ral_threshold_key_t)); if (rc == HASH_TABLE_OK) { return 0; @@ -106,134 +104,130 @@ int rrc_enb_ral_handle_configure_threshold_request(unsigned int mod_idP, Message MessageDef *message_p = NULL; unsigned int ix_param = 0; unsigned int ix_thresholds = 0; - DevAssert(msg_pP != NULL); - LOG_I(RRC, "[eNB %d] Received %s\n", mod_idP, ITTI_MSG_NAME (msg_pP)); configure_threshold_req_p = &RRC_RAL_CONFIGURE_THRESHOLD_REQ(msg_pP); - transaction_id = configure_threshold_req_p->transaction_id; for (ix_param = 0; ix_param < configure_threshold_req_p->num_link_cfg_params; ix_param++) { link_cfg_param_p = &configure_threshold_req_p->link_cfg_params[ix_param]; switch (link_cfg_param_p->th_action) { - case RAL_TH_ACTION_SET_NORMAL_THRESHOLD: - case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD: - switch (link_cfg_param_p->link_param_type.choice) { - - case RAL_LINK_PARAM_TYPE_CHOICE_GEN: - switch (link_cfg_param_p->link_param_type._union.link_param_gen) { - case RAL_LINK_PARAM_GEN_DATA_RATE: - case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH: - case RAL_LINK_PARAM_GEN_SINR: - case RAL_LINK_PARAM_GEN_THROUGHPUT: - case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE: - message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; - - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_gen %d\n", link_cfg_param_p->link_param_type._union.link_param_gen); - return -1; - } + case RAL_TH_ACTION_SET_NORMAL_THRESHOLD: + case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD: + switch (link_cfg_param_p->link_param_type.choice) { + case RAL_LINK_PARAM_TYPE_CHOICE_GEN: + switch (link_cfg_param_p->link_param_type._union.link_param_gen) { + case RAL_LINK_PARAM_GEN_DATA_RATE: + case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH: + case RAL_LINK_PARAM_GEN_SINR: + case RAL_LINK_PARAM_GEN_THROUGHPUT: + case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE: + message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; + + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_gen %d\n", link_cfg_param_p->link_param_type._union.link_param_gen); + return -1; + } + + break; + + case RAL_LINK_PARAM_TYPE_CHOICE_QOS: + switch (link_cfg_param_p->link_param_type._union.link_param_qos) { + case RAL_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED: + case RAL_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS: + case RAL_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY: + case RAL_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO: + message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; + + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_qos %d\n", link_cfg_param_p->link_param_type._union.link_param_qos); + return -1; + } + + break; + + case RAL_LINK_PARAM_TYPE_CHOICE_LTE: + switch (link_cfg_param_p->link_param_type._union.link_param_lte) { + // group by dest task id + case RAL_LINK_PARAM_LTE_UE_RSRP: + case RAL_LINK_PARAM_LTE_UE_RSRQ: + case RAL_LINK_PARAM_LTE_UE_CQI: + message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; + + case RAL_LINK_PARAM_LTE_AVAILABLE_BW: + case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE: + case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS: + case RAL_LINK_PARAM_LTE_PACKET_DELAY: + message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); + PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; + memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); + itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + break; + + case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: + case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY: + case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY: + case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS: + case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW: +#warning "TO DO MIH LTE LINK PARAMS IN RRC ENB" + break; - break; + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_lte %d\n", link_cfg_param_p->link_param_type._union.link_param_lte); + return -1; + } + + break; - case RAL_LINK_PARAM_TYPE_CHOICE_QOS: - switch (link_cfg_param_p->link_param_type._union.link_param_qos) { - case RAL_LINK_PARAM_QOS_MAX_NUM_DIF_COS_SUPPORTED: - case RAL_LINK_PARAM_QOS_MIN_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_AVG_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_MAX_PACKET_TRANSFER_DELAY_ALL_COS: - case RAL_LINK_PARAM_QOS_STD_DEVIATION_PACKET_TRANSFER_DELAY: - case RAL_LINK_PARAM_QOS_PACKET_LOSS_RATE_ALL_COS_FRAME_RATIO: - message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; - - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_qos %d\n", link_cfg_param_p->link_param_type._union.link_param_qos); - return -1; + default: + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_type choice %d\n", link_cfg_param_p->link_param_type.choice); + return -1; } - break; + for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { + threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; + } - case RAL_LINK_PARAM_TYPE_CHOICE_LTE: - switch (link_cfg_param_p->link_param_type._union.link_param_lte) { - // group by dest task id - case RAL_LINK_PARAM_LTE_UE_RSRP: - case RAL_LINK_PARAM_LTE_UE_RSRQ: - case RAL_LINK_PARAM_LTE_UE_CQI: - message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; - - case RAL_LINK_PARAM_LTE_AVAILABLE_BW: - case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE: - case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS: - case RAL_LINK_PARAM_LTE_PACKET_DELAY: - message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); - PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; - memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); - break; - - case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: - case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY: - case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY: - case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS: - case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW: -#warning "TO DO MIH LTE LINK PARAMS IN RRC ENB" - break; + break; - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_lte %d\n", link_cfg_param_p->link_param_type._union.link_param_lte); - return -1; + case RAL_TH_ACTION_CANCEL_THRESHOLD: + + // IEEE Std 802.21-2008, Table F4, Data type name=LINK_CFG_PARAM (page 228): + // When “Cancel threshold†is selected and no thresholds are specified, then all + // currently configured thresholds for the given LINK_PARAM_TYPE are cancelled. + if (link_cfg_param_p->num_thresholds == 0) { + rrc_enb_ral_delete_all_thresholds_type(mod_idP, &link_cfg_param_p->link_param_type); + } else { + // + // When “Cancel threshold†is selected and thresholds are specified only those + // configured thresholds for the given LINK_PARAM_TYPE and whose threshold value match what was + // specified are cancelled. + for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { + threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; + rrc_enb_ral_delete_threshold(mod_idP, &link_cfg_param_p->link_param_type, threshold_p); + } } break; default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown link_param_type choice %d\n", link_cfg_param_p->link_param_type.choice); + LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown th_action %d\n", link_cfg_param_p->th_action); return -1; - } - - for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { - threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; - } - - break; - - case RAL_TH_ACTION_CANCEL_THRESHOLD: - - // IEEE Std 802.21-2008, Table F4, Data type name=LINK_CFG_PARAM (page 228): - // When “Cancel threshold†is selected and no thresholds are specified, then all - // currently configured thresholds for the given LINK_PARAM_TYPE are cancelled. - if (link_cfg_param_p->num_thresholds == 0) { - rrc_enb_ral_delete_all_thresholds_type(mod_idP, &link_cfg_param_p->link_param_type); - } else { - // - // When “Cancel threshold†is selected and thresholds are specified only those - // configured thresholds for the given LINK_PARAM_TYPE and whose threshold value match what was - // specified are cancelled. - for (ix_thresholds=0; ix_thresholds < link_cfg_param_p->num_thresholds; ix_thresholds++) { - threshold_p = &link_cfg_param_p->thresholds[ix_thresholds]; - rrc_enb_ral_delete_threshold(mod_idP, &link_cfg_param_p->link_param_type, threshold_p); - } - } - - break; - - default: - LOG_E(RRC, "Message RRC_RAL_CONFIGURE_THRESHOLD_REQ malformed, unknown th_action %d\n", link_cfg_param_p->th_action); - return -1; } } diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h index 22a583c25c94b90c969c567320dafb637f35b6d5..34439753d8f5ab796267940e159a62ca04beee75 100644 --- a/openair2/RRC/LTE/rrc_proto.h +++ b/openair2/RRC/LTE/rrc_proto.h @@ -32,20 +32,20 @@ */ #include "RRC/LTE/rrc_defs.h" - +#include "x2ap_messages_types.h" #include "flexran_agent_extern.h" //main.c int rrc_init_global_param(void); int L3_xface_init(void); void openair_rrc_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,uint8_t HO_enabled); -#if defined(ENABLE_ITTI) + char openair_rrc_eNB_configuration( const module_id_t enb_mod_idP, - RrcConfigurationReq* configuration + RrcConfigurationReq *configuration ); -#endif + char openair_rrc_eNB_init( const module_id_t module_idP); @@ -55,10 +55,10 @@ char openair_rrc_ue_init( void rrc_config_buffer(SRB_INFO *srb_info, uint8_t Lchan_type, uint8_t Role); void openair_rrc_on( - const protocol_ctxt_t* const ctxt_pP); + const protocol_ctxt_t *const ctxt_pP); void openair_rrc_on_ue( - const protocol_ctxt_t* const ctxt_pP); + const protocol_ctxt_t *const ctxt_pP); void rrc_top_cleanup(void); @@ -69,7 +69,7 @@ void rrc_top_cleanup(void); */ RRC_status_t rrc_rx_tx( - protocol_ctxt_t* const ctxt_pP, + protocol_ctxt_t *const ctxt_pP, const int CC_id ); @@ -80,7 +80,7 @@ rrc_rx_tx( */ RRC_status_t rrc_rx_tx_ue( - protocol_ctxt_t* const ctxt_pP, + protocol_ctxt_t *const ctxt_pP, const uint8_t enb_index, const int CC_id ); @@ -91,7 +91,7 @@ rrc_rx_tx_ue( \param ctxt_pP Running context \param Srb_info Pointer to SRB_INFO structure (SRB0) \param eNB_index Index of corresponding eNB/CH*/ -int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* const Srb_info, const uint8_t eNB_index ); +int rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const SRB_INFO *const Srb_info, const uint8_t eNB_index ); /** \brief Decodes a DL-DCCH message and invokes appropriate routine to handle the message \param ctxt_pP Running context @@ -100,17 +100,17 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* co \param eNB_index Index of corresponding eNB/CH*/ void rrc_ue_decode_dcch( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, - const uint8_t* const Buffer, + const uint8_t *const Buffer, const uint8_t eNB_indexP ); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int decode_SL_Discovery_Message( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, - const uint8_t* Sdu, + const uint8_t *Sdu, const uint8_t Sdu_len); #endif @@ -119,7 +119,7 @@ int decode_SL_Discovery_Message( \param eNB_index Index of corresponding eNB/CH*/ void rrc_ue_generate_RRCConnectionRequest( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ); @@ -129,8 +129,8 @@ rrc_ue_generate_RRCConnectionRequest( \param eNB_index Index of corresponding eNB/CH*/ void rrc_ue_process_rrcConnectionReconfiguration( - const protocol_ctxt_t* const ctxt_pP, - LTE_RRCConnectionReconfiguration_t* rrcConnectionReconfiguration, + const protocol_ctxt_t *const ctxt_pP, + LTE_RRCConnectionReconfiguration_t *rrcConnectionReconfiguration, uint8_t eNB_index ); @@ -164,9 +164,9 @@ int32_t rrc_ue_establish_drb(module_id_t module_idP,frame_t frameP,uint8_t eNB_ */ void rrc_ue_process_mobilityControlInfo( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, - struct LTE_MobilityControlInfo* const mobilityControlInfo + struct LTE_MobilityControlInfo *const mobilityControlInfo ); /** \brief Process a measConfig Message and configure PHY/MAC @@ -175,9 +175,9 @@ rrc_ue_process_mobilityControlInfo( \param measConfig Pointer to MeasConfig IE from configuration*/ void rrc_ue_process_measConfig( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, - LTE_MeasConfig_t* const measConfig + LTE_MeasConfig_t *const measConfig ); /** \brief Process a RadioResourceConfigDedicated Message and configure PHY/MAC @@ -185,7 +185,7 @@ rrc_ue_process_measConfig( \param eNB_index Index of corresponding CH/eNB \param radioResourceConfigDedicated Pointer to RadioResourceConfigDedicated IE from configuration*/ void rrc_ue_process_radioResourceConfigDedicated( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, uint8_t eNB_index, LTE_RadioResourceConfigDedicated_t *radioResourceConfigDedicated); @@ -202,8 +202,8 @@ void rrc_ue_process_sidelink_radioResourceConfig( uint8_t eNB_index, LTE_SystemInformationBlockType18_r12_t *sib18, LTE_SystemInformationBlockType19_r12_t *sib19, - LTE_SL_CommConfig_r12_t* sl_CommConfig, - LTE_SL_DiscConfig_r12_t* sl_DiscConfig); + LTE_SL_CommConfig_r12_t *sl_CommConfig, + LTE_SL_DiscConfig_r12_t *sl_DiscConfig); /** \brief Init control socket to listen to incoming packets from ProSe App * @@ -220,13 +220,13 @@ uint8_t rrc_eNB_get_next_transaction_identifier(module_id_t module_idP); /**\brief Entry routine to decode a UL-CCCH-Message. Invokes PER decoder and parses message. \param ctxt_pP Running context - \param Srb_info Pointer to SRB0 information structure (buffer, etc.)*/ -int -rrc_eNB_decode_ccch( - protocol_ctxt_t* const ctxt_pP, - const SRB_INFO* const Srb_info, - const int CC_id -); + \param buffer Pointer to SDU + \param buffer_length length of SDU in bytes + \param CC_id component carrier index*/ +int rrc_eNB_decode_ccch(protocol_ctxt_t* const ctxt_pP, + const uint8_t *buffer, + int buffer_length, + const int CC_id); /**\brief Entry routine to decode a UL-DCCH-Message. Invokes PER decoder and parses message. \param ctxt_pP Context @@ -234,9 +234,9 @@ rrc_eNB_decode_ccch( \param sdu_size Size of incoming SDU*/ int rrc_eNB_decode_dcch( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, - const uint8_t* const Rx_sdu, + const uint8_t *const Rx_sdu, const sdu_size_t sdu_sizeP ); @@ -245,8 +245,8 @@ rrc_eNB_decode_dcch( \param ue_context_pP UE context*/ void rrc_eNB_generate_RRCConnectionSetup( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const int CC_id ); @@ -256,8 +256,8 @@ rrc_eNB_generate_RRCConnectionSetup( \param CC_id Component Carrier ID*/ void rrc_eNB_generate_RRCConnectionReestablishmentReject( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const int CC_id ); @@ -267,9 +267,9 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( \param rrcConnectionSetupComplete Pointer to RRCConnectionSetupComplete message*/ void rrc_eNB_process_RRCConnectionSetupComplete( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* ue_context_pP, - LTE_RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *ue_context_pP, + LTE_RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete ); /**\brief Process the RRCConnectionReconfigurationComplete based on information coming from UE @@ -280,8 +280,8 @@ rrc_eNB_process_RRCConnectionSetupComplete( */ void rrc_eNB_process_RRCConnectionReconfigurationComplete( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *ue_context_pP, const uint8_t xid ); @@ -290,32 +290,41 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( \param ue_context_pP UE context of UE receiving the message*/ void rrc_eNB_generate_RRCConnectionRelease( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP ); void rrc_eNB_generate_defaultRRCConnectionReconfiguration( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const uint8_t ho_state ); void flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const uint8_t ho_state, - agent_reconf_rrc * trig_param - ); + agent_reconf_rrc *trig_param +); +void +rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t *buffer, + int *_size + //const uint8_t ho_state + ); +void +rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protocol_ctxt_t *const ctxt_pP); int freq_to_arfcn10(int band, unsigned long freq); void rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const uint8_t ho_state ); @@ -324,18 +333,18 @@ rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration( \param ue_context_pP UE context of UE receiving the message*/ void rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, uint8_t xid, uint32_t nas_length, - uint8_t* nas_buffer + uint8_t *nas_buffer ); void -rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* ue_context_pP); +rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *ue_context_pP); + -#if defined(ENABLE_ITTI) void rrc_enb_init(void); void *rrc_enb_process_itti_msg(void *); @@ -347,7 +356,9 @@ void *rrc_enb_task(void *args_p); /**\brief RRC UE task. \param void *args_p Pointer on arguments to start the task. */ void *rrc_ue_task(void *args_p); -#endif + + +void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m); /**\brief Generate/decode the handover RRCConnectionReconfiguration at eNB \param module_idP Instance ID for eNB/CH @@ -355,9 +366,9 @@ void *rrc_ue_task(void *args_p); \param ue_module_idP Index of UE transmitting the messages*/ void rrc_eNB_generate_RRCConnectionReconfiguration_handover( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - uint8_t* const nas_pdu, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t *const nas_pdu, const uint32_t nas_length ); @@ -368,8 +379,8 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( \param n_discoveryMessages Number of discovery messages*/ int rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, LTE_SL_DestinationInfoList_r12_t *destinationInfoList, int n_discoveryMessages ); @@ -379,9 +390,9 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( \param sidelinkUEInformation sidelinkUEInformation message from UE*/ uint8_t rrc_eNB_process_SidelinkUEInformation( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* ue_context_pP, - LTE_SidelinkUEInformation_r12_t* sidelinkUEInformation + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *ue_context_pP, + LTE_SidelinkUEInformation_r12_t *sidelinkUEInformation ); /** \brief Get a Resource Pool to transmit SL communication @@ -389,8 +400,8 @@ rrc_eNB_process_SidelinkUEInformation( \param ue_context_pP UE context \param destinationInfoList Pointer to the list of SL destinations*/ LTE_SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, LTE_SL_DestinationInfoList_r12_t *destinationInfoList ); @@ -399,8 +410,8 @@ LTE_SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( \param ue_context_pP UE context \param n_discoveryMessages Number of discovery messages*/ LTE_SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, int n_discoveryMessages ); @@ -416,20 +427,22 @@ mac_rrc_data_req( const int CC_id, const frame_t frameP, const rb_id_t Srb_id, + const rnti_t rnti, const uint8_t Nb_tb, - uint8_t* const buffer_pP, + uint8_t *const buffer_pP, const uint8_t mbsfn_sync_area ); int8_t mac_rrc_data_ind( const module_id_t module_idP, - const int CC_id, + const int CC_id, const frame_t frameP, const sub_frame_t sub_frameP, + const int UE_id, const rnti_t rntiP, const rb_id_t srb_idP, - const uint8_t* sduP, + const uint8_t *sduP, const sdu_size_t sdu_lenP, const uint8_t mbsfn_sync_areaP #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -444,7 +457,7 @@ mac_rrc_data_req_ue( const frame_t frameP, const rb_id_t Srb_id, const uint8_t Nb_tb, - uint8_t* const buffer_pP, + uint8_t *const buffer_pP, const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_area ); @@ -457,7 +470,7 @@ mac_rrc_data_ind_ue( const sub_frame_t sub_frameP, const rnti_t rntiP, const rb_id_t srb_idP, - const uint8_t* sduP, + const uint8_t *sduP, const sdu_size_t sdu_lenP, const mac_enb_index_t eNB_indexP, const uint8_t mbsfn_sync_areaP @@ -485,46 +498,46 @@ void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP, uint8_t rrc_data_req( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t rb_idP, const mui_t muiP, const confirm_t confirmP, const sdu_size_t sdu_size, - uint8_t* const buffer_pP, + uint8_t *const buffer_pP, const pdcp_transmission_mode_t modeP ); uint8_t rrc_data_req_ue( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t rb_idP, const mui_t muiP, const confirm_t confirmP, const sdu_size_t sdu_sizeP, - uint8_t* const buffer_pP, + uint8_t *const buffer_pP, const pdcp_transmission_mode_t modeP ); void rrc_data_ind( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, const sdu_size_t sdu_sizeP, - const uint8_t* const buffer_pP + const uint8_t *const buffer_pP ); void rrc_in_sync_ind(module_id_t module_idP, frame_t frameP, uint16_t eNB_index); void rrc_out_of_sync_ind(module_id_t module_idP, frame_t frameP, unsigned short eNB_index); -int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t* const Sdu, const uint8_t Sdu_len, const uint8_t mbsfn_sync_area ); +int decode_MCCH_Message( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t *const Sdu, const uint8_t Sdu_len, const uint8_t mbsfn_sync_area ); int decode_BCCH_DLSCH_Message( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, - uint8_t* const Sdu, + uint8_t *const Sdu, const uint8_t Sdu_len, const uint8_t rsrq, const uint8_t rsrp ); @@ -540,20 +553,20 @@ int decode_BCCH_MBMS_DLSCH_Message( #endif int decode_PCCH_DLSCH_Message( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, - uint8_t* const Sdu, + uint8_t *const Sdu, const uint8_t Sdu_len); void ue_meas_filtering( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ); void ue_measurement_report_triggering( - protocol_ctxt_t* const ctxt_pP, + protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ); @@ -571,33 +584,35 @@ mac_UE_get_rrc_status( void rrc_eNB_generate_UECapabilityEnquiry( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP ); void rrc_eNB_generate_SecurityModeCommand( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP ); void rrc_eNB_process_MeasurementReport( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* ue_context_pP, - const LTE_MeasResults_t* const measResults2 + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *ue_context_pP, + const LTE_MeasResults_t *const measResults2 ); void rrc_eNB_generate_HandoverPreparationInformation( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - LTE_PhysCellId_t targetPhyId + //const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t *buffer, + int *_size + //LTE_PhysCellId_t targetPhyId ); void check_handovers( - protocol_ctxt_t* const ctxt_pP + protocol_ctxt_t *const ctxt_pP ); //void rrc_ue_process_ueCapabilityEnquiry(uint8_t module_idP,uint32_t frame,UECapabilityEnquiry_t *UECapabilityEnquiry,uint8_t eNB_index); @@ -609,7 +624,6 @@ rrc_ue_process_securityModeCommand( ); */ -#if !defined(ENABLE_USE_MME) void rrc_eNB_emulation_notify_ue_module_id( const module_id_t ue_module_idP, const rnti_t rntiP, @@ -617,20 +631,20 @@ void rrc_eNB_emulation_notify_ue_module_id( const uint8_t cell_identity_byte1P, const uint8_t cell_identity_byte2P, const uint8_t cell_identity_byte3P); -#endif + void rrc_eNB_free_mem_UE_context( - const protocol_ctxt_t* const ctxt_pP, - struct rrc_eNB_ue_context_s* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + struct rrc_eNB_ue_context_s *const ue_context_pP ); void rrc_eNB_free_UE( const module_id_t enb_mod_idP, - const struct rrc_eNB_ue_context_s* const ue_context_pP + const struct rrc_eNB_ue_context_s *const ue_context_pP ); long binary_search_int(int elements[], long numElem, int value); @@ -641,7 +655,7 @@ void openair_rrc_top_init_eNB(int eMBMS_active,uint8_t HO_active); void openair_rrc_top_init_ue( int eMBMS_active, - char* uecap_xer, + char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active ); diff --git a/openair2/RRC/LTE/rrc_rrm_interface.c b/openair2/RRC/LTE/rrc_rrm_interface.c index 9f4270be8941487cc8ffe55bd0f08f1a316a1865..fe15dae46d64a00caba79803873f6f07cfd10310 100644 --- a/openair2/RRC/LTE/rrc_rrm_interface.c +++ b/openair2/RRC/LTE/rrc_rrm_interface.c @@ -44,18 +44,18 @@ */ #ifndef RRC_RRM_FIFOS_XFACE -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> + #include <stdio.h> + #include <stdlib.h> + #include <errno.h> + #include <string.h> + #include <unistd.h> -#include <sys/socket.h> -#include <sys/un.h> + #include <sys/socket.h> + #include <sys/un.h> #else -#include<rtai_fifos.h> + #include<rtai_fifos.h> #endif @@ -78,12 +78,11 @@ \return The return value is a socket handle */ int open_socket( - sock_rrm_t *s , ///< socket descriptor + sock_rrm_t *s, ///< socket descriptor char *path_local, ///< local socket path if unix socket - char *path_dest , ///< host Socket path if unix socket + char *path_dest, ///< host Socket path if unix socket int rrm_inst ///< instance of the rrm entity -) -{ +) { /* Unix socket */ int socket_fd ; int len ; @@ -109,8 +108,6 @@ int open_socket( s->un_dest_addr.sun_family = AF_UNIX; sprintf(s->un_dest_addr.sun_path,"%s%d", path_dest, rrm_inst ); msg("Dest %s\n",s->un_dest_addr.sun_path); - - s->s = socket_fd ; return socket_fd ; } @@ -121,8 +118,7 @@ int open_socket( */ void close_socket( sock_rrm_t *sock ///< the socket handle -) -{ +) { shutdown(sock->s, SHUT_RDWR); close(sock->s); } @@ -134,10 +130,9 @@ void close_socket( */ char BUFF[2048]; int send_msg_sock( - sock_rrm_t *s ,///< socket descriptor + sock_rrm_t *s, ///< socket descriptor msg_t *smsg ///< the message to send -) -{ +) { /* Unix socket */ int ret = 0 ; // char *buf = NULL; @@ -156,13 +151,10 @@ int send_msg_sock( //buf = RRM_MALLOC(char, taille); //if (buf ==NULL) //return -1 ; - - memcpy( BUFF , &(smsg->head) , sizeof(msg_head_t) ) ; + memcpy( BUFF, &(smsg->head), sizeof(msg_head_t) ) ; memcpy( BUFF+sizeof(msg_head_t), smsg->data, smsg->head.size ) ; - iov.iov_base = (void *)BUFF; iov.iov_len = taille ; - msghd.msg_name = (void *)&(s->un_dest_addr); msghd.msg_namelen = sizeof(s->un_dest_addr); msghd.msg_iov = &iov; @@ -179,7 +171,6 @@ int send_msg_sock( //RRM_FREE(buf) ; //RRM_FREE(msg->data) ; //RRM_FREE(msg) ; - return ret ; } @@ -191,8 +182,7 @@ int send_msg_sock( */ char *recv_msg( sock_rrm_t *s ///< socket descriptor -) -{ +) { /* Unix socket */ char *buf = NULL; char *smsg = NULL; @@ -201,9 +191,7 @@ char *recv_msg( int size_msg ; msg_head_t *head ; int ret ; - int taille = SIZE_MAX_PAYLOAD ; - buf = RRM_CALLOC( char,taille); if ( buf == NULL ) { @@ -218,8 +206,7 @@ char *recv_msg( msghd.msg_iovlen = 1; msghd.msg_control = NULL ; msghd.msg_controllen= 0 ; - - ret = recvmsg(s->s, &msghd , 0 ) ; + ret = recvmsg(s->s, &msghd, 0 ) ; if ( ret <= 0 ) { // non-blocking socket @@ -236,22 +223,19 @@ char *recv_msg( head = (msg_head_t *) buf ; size_msg = sizeof(msg_head_t) + head->size ; - - smsg = RRM_CALLOC(char , size_msg ) ; + smsg = RRM_CALLOC(char, size_msg ) ; if ( smsg != NULL ) { - memcpy( smsg , buf , size_msg ) ; + memcpy( smsg, buf, size_msg ) ; } RRM_FREE( buf ) ; - return smsg ; } #else //XFACE -int send_msg_fifo(int *s, msg_t *fmsg) -{ +int send_msg_fifo(int *s, msg_t *fmsg) { int ret = 0, ret1; int taille = sizeof(msg_head_t) ; msg("write on fifos %d, msg %p\n",*s,fmsg); @@ -261,9 +245,7 @@ int send_msg_fifo(int *s, msg_t *fmsg) } // envoi le header - - - ret1 = rtf_put (*s,(char*) &(fmsg->head) , taille); + ret1 = rtf_put (*s,(char *) &(fmsg->head), taille); if(ret1 <0) { msg("rtf_put H ERR %d\n",ret1); @@ -275,7 +257,7 @@ int send_msg_fifo(int *s, msg_t *fmsg) // envoi les datas si elles sont definis if ( fmsg->data != NULL ) { - ret1 += rtf_put (*s,(char*) fmsg->data, fmsg->head.size); + ret1 += rtf_put (*s,(char *) fmsg->data, fmsg->head.size); if(ret1 <0) { msg("rtf_put D ERR %d\n",ret1); @@ -290,7 +272,6 @@ int send_msg_fifo(int *s, msg_t *fmsg) #endif //XFACE -int send_msg(void *s, msg_t *smsg) -{ +int send_msg(void *s, msg_t *smsg) { send_msg_sock((sock_rrm_t *)s, smsg); } diff --git a/openair2/RRC/LTE/rrm_2_rrc_msg.c b/openair2/RRC/LTE/rrm_2_rrc_msg.c index 3ed3a9d8594a3f4fbc6f583b0a08d7531cda551d..79cdc74e2ba157746cc0acf95349799bb61773c8 100644 --- a/openair2/RRC/LTE/rrm_2_rrc_msg.c +++ b/openair2/RRC/LTE/rrm_2_rrc_msg.c @@ -51,26 +51,22 @@ //#include "openair_rrc_utils.h" //#include "openair_rrc_main.h" #ifdef PHY_EMUL -#include "SIMULATION/simulation_defs.h" -extern EMULATION_VARS *Emul_vars; -extern CH_MAC_INST *CH_mac_inst; -extern UE_MAC_INST *UE_mac_inst; + #include "SIMULATION/simulation_defs.h" + extern EMULATION_VARS *Emul_vars; + extern CH_MAC_INST *CH_mac_inst; + extern UE_MAC_INST *UE_mac_inst; #endif /******************************************************************************/ -void fn_rrc (void) -{ +void fn_rrc (void) { /******************************************************************************/ - msg_head_t *Header ; char *Data; - L2_ID Mac_id; while(1) { - Header = (msg_head_t *) recv_msg(&S_rrc) ; if(Header==NULL) { @@ -86,118 +82,107 @@ void fn_rrc (void) msg("Got MSG of Type %d on Inst %d\n",Header->msg_type,Header->inst); switch ( Header->msg_type ) { - case RRM_INIT_CH_REQ: { - rrm_init_ch_req_t *p = (rrm_init_ch_req_t *) Data; - msg( "[RRM]>[RRC][Inst %d]:RRM_INIT_CH_REQ\n",Header->inst); - rrc_init_ch_req(Header->inst,p); - break; - } - - case RRCI_INIT_MR_REQ: { - rrci_init_mr_req_t *p = (rrci_init_mr_req_t *) Data; - msg( "[RRM]>[RRC][Inst %d]:RRCI_INIT_MR_REQ\n",Header->inst); - rrc_init_mr_req(Header->inst,p); - break; - } - - case RRM_RB_ESTABLISH_REQ: { - send_msg((void *)&S_rrc,msg_rrc_rb_establish_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_RB_ESTABLISH_REQ, size %d\n",Header->inst,sizeof(rrm_rb_establish_req_t)); - rrc_config_req(Header->inst,(void*)Data,Header->msg_type,Header->Trans_id); - break ; - } - - case RRM_RB_MODIFY_REQ: { - send_msg((void *)&S_rrc,msg_rrc_rb_modify_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_RB_MODIFY_REQ\n",Header->inst); - rrc_config_req(Header->inst,Data,Header->msg_type,Header->Trans_id); - } - - case RRM_RB_RELEASE_REQ: { - send_msg((void *)&S_rrc,msg_rrc_rb_release_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_RB_RELEASE_REQ\n",Header->inst); - rrc_config_req(Header->inst,Data,Header->msg_type,Header->Trans_id); - } - - case RRCI_CX_ESTABLISH_RESP: { - rrci_cx_establish_resp_t *p = (rrci_cx_establish_resp_t *) Data; - unsigned char CH_index,i; - msg( "[RRCI]>[RRC][Inst %d]:RRCI_CX_ESTABLISH_RESP\n",Header->inst); - - for(i=0; i<NB_SIG_CNX_UE; i++) - if(!bcmp(&UE_rrc_inst[Header->inst-NB_CH_INST].Info[i].CH_mac_id,&p->L2_id,sizeof(L2_ID))) { - CH_index=i; - break; - } - - if(i==NB_SIG_CNX_UE) { - msg("[RRC] FATAL: CH_INDEX NOT FOUND\n"); - return; + case RRM_INIT_CH_REQ: { + rrm_init_ch_req_t *p = (rrm_init_ch_req_t *) Data; + msg( "[RRM]>[RRC][Inst %d]:RRM_INIT_CH_REQ\n",Header->inst); + rrc_init_ch_req(Header->inst,p); + break; } - UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr_type=p->L3_info_t; - - if(p->L3_info_t == IPv4_ADDR) { - memcpy(&UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr,p->L3_info,4); + case RRCI_INIT_MR_REQ: { + rrci_init_mr_req_t *p = (rrci_init_mr_req_t *) Data; + msg( "[RRM]>[RRC][Inst %d]:RRCI_INIT_MR_REQ\n",Header->inst); + rrc_init_mr_req(Header->inst,p); + break; } - else { - memcpy(&UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr,p->L3_info,16); + case RRM_RB_ESTABLISH_REQ: { + send_msg((void *)&S_rrc,msg_rrc_rb_establish_resp(Header->inst,Header->Trans_id)); + msg( "[RRM]>[RRC][Inst %d]:RRM_RB_ESTABLISH_REQ, size %d\n",Header->inst,sizeof(rrm_rb_establish_req_t)); + rrc_config_req(Header->inst,(void *)Data,Header->msg_type,Header->Trans_id); + break ; } - } - break ; - case RRM_SENSING_MEAS_REQ: { - // rrm_sensing_meas_req_t *p = (rrm_sensing_meas_req_t *) sock_msg ; - send_msg((void *)&S_rrc,msg_rrc_sensing_meas_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_SENSING_MEAS_REQ\n",Header->inst); - // rrc_meas_req(header->inst,p,RRC_MEAS_ADD); - } - break ; - - - case RRM_SENSING_MEAS_RESP: { - msg( "[RRM]>[RRC][Inst %d]:RRM_SENSING_MEAS_RESP\n",Header->inst); - //rrm_rrc_meas_resp(header->inst,header->Trans_id); - } - break ; - - - case RRM_SCAN_ORD: - msg( "[RRM]>[RRC][Inst %d]:RRM_SCAN_ORD\n",Header->inst); - //memcpy(&CH_rrc_inst[0].Rrm_init_scan_req,(rrm_init_scan_req_t *) Data,sizeof(rrm_init_scan_req_t)); - //CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; - ///send over air + case RRM_RB_MODIFY_REQ: { + send_msg((void *)&S_rrc,msg_rrc_rb_modify_resp(Header->inst,Header->Trans_id)); + msg( "[RRM]>[RRC][Inst %d]:RRM_RB_MODIFY_REQ\n",Header->inst); + rrc_config_req(Header->inst,Data,Header->msg_type,Header->Trans_id); + } - break; + case RRM_RB_RELEASE_REQ: { + send_msg((void *)&S_rrc,msg_rrc_rb_release_resp(Header->inst,Header->Trans_id)); + msg( "[RRM]>[RRC][Inst %d]:RRM_RB_RELEASE_REQ\n",Header->inst); + rrc_config_req(Header->inst,Data,Header->msg_type,Header->Trans_id); + } - case RRM_INIT_SCAN_REQ: - msg( "[RRM]>[RRC][Inst %d]:RRM_INIT_SCAN_REQ\n",Header->inst); - memcpy(&CH_rrc_inst[0].Rrm_init_scan_req,(rrm_init_scan_req_t *) Data,sizeof(rrm_init_scan_req_t)); - CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; - ///send over air + case RRCI_CX_ESTABLISH_RESP: { + rrci_cx_establish_resp_t *p = (rrci_cx_establish_resp_t *) Data; + unsigned char CH_index,i; + msg( "[RRCI]>[RRC][Inst %d]:RRCI_CX_ESTABLISH_RESP\n",Header->inst); - break; + for(i=0; i<NB_SIG_CNX_UE; i++) + if(!bcmp(&UE_rrc_inst[Header->inst-NB_CH_INST].Info[i].CH_mac_id,&p->L2_id,sizeof(L2_ID))) { + CH_index=i; + break; + } - case RRM_END_SCAN_REQ: + if(i==NB_SIG_CNX_UE) { + msg("[RRC] FATAL: CH_INDEX NOT FOUND\n"); + return; + } - msg( "[RRM]>[RRC][Inst %d]:RRM_END_SCAN_REQ\n",Header->inst); - memcpy(&Mac_id.L2_id[0],Data,sizeof(L2_ID)); - unsigned char UE_index=Mac_id.L2_id[0]-NB_CH_MAX+1; + UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr_type=p->L3_info_t; + if(p->L3_info_t == IPv4_ADDR) { + memcpy(&UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr,p->L3_info,4); + } else { + memcpy(&UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr,p->L3_info,16); + } + } + break ; - UE_rrc_inst[0].Srb2[UE_index].Srb_info.Tx_buffer.Payload[0]=100; - msg("SRB_ID %d\n",CH_rrc_inst[0].Srb2[UE_index].Srb_info.Srb_id); - Mac_rlc_xface->rrc_rlc_data_req(0,CH_rrc_inst[0].Srb2[UE_index].Srb_info.Srb_id,0,0,1,CH_rrc_inst[0].Srb2[UE_index].Srb_info.Tx_buffer.Payload); - //CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; - ///send over air + case RRM_SENSING_MEAS_REQ: { + // rrm_sensing_meas_req_t *p = (rrm_sensing_meas_req_t *) sock_msg ; + send_msg((void *)&S_rrc,msg_rrc_sensing_meas_resp(Header->inst,Header->Trans_id)); + msg( "[RRM]>[RRC][Inst %d]:RRM_SENSING_MEAS_REQ\n",Header->inst); + // rrc_meas_req(header->inst,p,RRC_MEAS_ADD); + } + break ; - break; + case RRM_SENSING_MEAS_RESP: { + msg( "[RRM]>[RRC][Inst %d]:RRM_SENSING_MEAS_RESP\n",Header->inst); + //rrm_rrc_meas_resp(header->inst,header->Trans_id); + } + break ; - default : - msg("[L3_xface]WARNING: msg unknown %d\n",Header->msg_type) ; + case RRM_SCAN_ORD: + msg( "[RRM]>[RRC][Inst %d]:RRM_SCAN_ORD\n",Header->inst); + //memcpy(&CH_rrc_inst[0].Rrm_init_scan_req,(rrm_init_scan_req_t *) Data,sizeof(rrm_init_scan_req_t)); + //CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; + ///send over air + break; + + case RRM_INIT_SCAN_REQ: + msg( "[RRM]>[RRC][Inst %d]:RRM_INIT_SCAN_REQ\n",Header->inst); + memcpy(&CH_rrc_inst[0].Rrm_init_scan_req,(rrm_init_scan_req_t *) Data,sizeof(rrm_init_scan_req_t)); + CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; + ///send over air + break; + + case RRM_END_SCAN_REQ: + msg( "[RRM]>[RRC][Inst %d]:RRM_END_SCAN_REQ\n",Header->inst); + memcpy(&Mac_id.L2_id[0],Data,sizeof(L2_ID)); + unsigned char UE_index=Mac_id.L2_id[0]-NB_CH_MAX+1; + UE_rrc_inst[0].Srb2[UE_index].Srb_info.Tx_buffer.Payload[0]=100; + msg("SRB_ID %d\n",CH_rrc_inst[0].Srb2[UE_index].Srb_info.Srb_id); + Mac_rlc_xface->rrc_rlc_data_req(0,CH_rrc_inst[0].Srb2[UE_index].Srb_info.Srb_id,0,0,1,CH_rrc_inst[0].Srb2[UE_index].Srb_info.Tx_buffer.Payload); + //CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; + ///send over air + break; + + default : + msg("[L3_xface]WARNING: msg unknown %d\n",Header->msg_type) ; } - } } diff --git a/openair2/RRC/LTE/utils.c b/openair2/RRC/LTE/utils.c index bbf97046bf5a0baba7f8b1eda2f866076610863f..08637e0e6767e48eb94f298ad2a0fe9cb8e795c4 100644 --- a/openair2/RRC/LTE/utils.c +++ b/openair2/RRC/LTE/utils.c @@ -34,8 +34,7 @@ ________________________________________________________________*/ //------------------------------------------------------------------------------------------------------------------// -uint16_t find_free_dtch_position(uint8_t Mod_id, uint16_t UE_CH_index) -{ +uint16_t find_free_dtch_position(uint8_t Mod_id, uint16_t UE_CH_index) { uint16_t i,j; if(UE_CH_index==0) { @@ -45,22 +44,18 @@ uint16_t find_free_dtch_position(uint8_t Mod_id, uint16_t UE_CH_index) } for(i=j; i<NB_RAB_MAX; i++) { //first RAB IS BROADCAST DTCH - if(CH_rrc_inst[Mod_id].Rab[i][UE_CH_index].Active==0) { return( i); } } msg("NO FREE DTCH LCHAN, exit... \n"); - Mac_rlc_xface->macphy_exit("NO FREE DTCH LCHAN, exit"); - return 0; } //-------------------------------------------------------------------------------------------// -uint8_t rrc_find_free_ue_index(uint8_t Mod_id) -{ +uint8_t rrc_find_free_ue_index(uint8_t Mod_id) { //-------------------------------------------------------------------------------------------// uint16_t i; @@ -78,8 +73,7 @@ uint8_t rrc_find_free_ue_index(uint8_t Mod_id) //-------------------------------------------------------------------------------------------// -unsigned short rrc_find_ue_index(unsigned char Mod_id, L2_ID Mac_id) -{ +unsigned short rrc_find_ue_index(unsigned char Mod_id, L2_ID Mac_id) { //-------------------------------------------------------------------------------------------// unsigned char i; /* @@ -90,8 +84,7 @@ unsigned short rrc_find_ue_index(unsigned char Mod_id, L2_ID Mac_id) */ } //-------------------------------------------------------------------------------------------// -uint8_t rrc_is_node_isolated(uint8_t Mod_id) -{ +uint8_t rrc_is_node_isolated(uint8_t Mod_id) { //-------------------------------------------------------------------------------------------// /*uint8_t i; for(i=0;i<NB_CNX_UE;i++) @@ -102,8 +95,7 @@ uint8_t rrc_is_node_isolated(uint8_t Mod_id) } //-------------------------------------------------------------------------------------------// -uint8_t find_rrc_info_index(uint8_t Mod_id,uint8_t CH_id) -{ +uint8_t find_rrc_info_index(uint8_t Mod_id,uint8_t CH_id) { //-------------------------------------------------------------------------------------------// /*uint8_t i; @@ -170,8 +162,7 @@ RB_INFO* rrc_find_rb_info(uint8_t Mod_id,uint16_t Rb_id){ */ /*------------------------------------------------------------------------------*/ -unsigned char rrc_is_mobile_already_associated(uint8_t Mod_id, L2_ID Mac_id) -{ +unsigned char rrc_is_mobile_already_associated(uint8_t Mod_id, L2_ID Mac_id) { /*------------------------------------------------------------------------------*/ /* unsigned char i; @@ -184,8 +175,7 @@ unsigned char rrc_is_mobile_already_associated(uint8_t Mod_id, L2_ID Mac_id) //-------------------------------------------------------------------------------------------// -void rrc_reset_buffer(RRC_BUFFER *Rrc_buffer) -{ +void rrc_reset_buffer(RRC_BUFFER *Rrc_buffer) { //-------------------------------------------------------------------------------------------// // Rrc_buffer->Header->Rv_tb_idx=0; // Rrc_buffer->W_idx=0; diff --git a/openair2/RRC/NAS/nas_config.c b/openair2/RRC/NAS/nas_config.c index c0f6d622aad6e20d30d63541eb470b968339dd3c..aa6696c864aee344f6c2594b45fc7a579ee89686 100644 --- a/openair2/RRC/NAS/nas_config.c +++ b/openair2/RRC/NAS/nas_config.c @@ -44,48 +44,56 @@ #include "nas_config.h" #include "common/utils/LOG/log.h" - +#include "targets/RT/USER/lte-softmodem.h" +#include "common/config/config_userapi.h" //default values according to the examples, -char *baseNetAddress = "10.0" ; -char *netMask = "255.255.255.0" ; -char *broadcastAddr = "10.0.255.255" ; - +char *baseNetAddress ; +char *netMask ; +char *broadcastAddr ; +#define NASHLP_NETPREFIX "<NAS network prefix, two first bytes of network addresses>\n" +#define NASHLP_NETMASK "<NAS network mask>\n" +#define NASHLP_BROADCASTADDR "<NAS network broadcast address>\n" +void nas_getparams(void) { + paramdef_t nasoptions[] = { + /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + /* configuration parameters for netlink, includes network parameters when running in noS1 mode */ + /* optname helpstr paramflags XXXptr defXXXval type numelt */ + /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + {"NetworkPrefix", NASHLP_NETPREFIX, 0, strptr:&baseNetAddress, defstrval:"10.0", TYPE_STRING, 0 }, + {"NetworkMask", NASHLP_NETMASK, 0, strptr:&netMask, defstrval:"255.255.255.0", TYPE_STRING, 0 }, + {"BroadcastAddr", NASHLP_BROADCASTADDR, 0, strptr:&broadcastAddr, defstrval:"10.0.255.255", TYPE_STRING, 0 }, + }; + config_get( nasoptions,sizeof(nasoptions)/sizeof(paramdef_t),"nas.noS1"); +} -void setBaseNetAddress (char* baseAddr) -{ +void setBaseNetAddress (char *baseAddr) { strcpy(baseNetAddress,baseAddr); } -char* getBaseNetAddress (void) -{ +char *getBaseNetAddress (void) { return baseNetAddress; } -void setNetMask (char* baseAddr) -{ +void setNetMask (char *baseAddr) { strcpy(netMask,baseAddr); } -char* getNetMask (void) -{ +char *getNetMask (void) { return netMask; } -void setBroadcastAddress (char* baseAddr) -{ +void setBroadcastAddress (char *baseAddr) { strcpy(broadcastAddr, baseAddr); } -char* getBroadcastAddress (void) -{ +char *getBroadcastAddress (void) { return broadcastAddr; } //Add Gateway to the interface -int set_gateway(char *interfaceName, char *gateway) -{ +int set_gateway(char *interfaceName, char *gateway) { int sock_fd; struct rtentry rt; struct sockaddr_in addr; @@ -96,20 +104,16 @@ int set_gateway(char *interfaceName, char *gateway) } memset (&rt, 0, sizeof (rt)); - addr.sin_family = AF_INET; /*set Destination addr*/ inet_aton("0.0.0.0",&addr.sin_addr); memcpy(&rt.rt_dst, &addr, sizeof(struct sockaddr_in)); - /*set gateway addr*/ inet_aton(gateway,&addr.sin_addr); memcpy(&rt.rt_gateway, &addr, sizeof(struct sockaddr_in)); - /*set genmask addr*/ inet_aton("0.0.0.0",&addr.sin_addr); memcpy(&rt.rt_genmask, &addr, sizeof(struct sockaddr_in)); - rt.rt_dev = interfaceName; //rt.rt_flags = RTF_UP|RTF_GATEWAY|RTF_DEFAULT; /* SR: rt_flags on 16 bits but RTF_DEFAULT = 0x00010000 @@ -129,19 +133,16 @@ int set_gateway(char *interfaceName, char *gateway) LOG_I(OIP,"set_gateway OK!\n"); return 0; } - } close(sock_fd); - LOG_D(OIP,"Set Gateway OK!\n"); return 0; } // sets a genneric interface parameter // (SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS) -int setInterfaceParameter(char *interfaceName, char *settingAddress, int operation) -{ +int setInterfaceParameter(char *interfaceName, char *settingAddress, int operation) { int sock_fd; struct ifreq ifr; struct sockaddr_in addr; @@ -154,10 +155,8 @@ int setInterfaceParameter(char *interfaceName, char *settingAddress, int operati memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name)-1); - memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; - inet_aton(settingAddress,&addr.sin_addr); memcpy(&ifr.ifr_ifru.ifru_addr,&addr,sizeof(struct sockaddr_in)); @@ -169,15 +168,12 @@ int setInterfaceParameter(char *interfaceName, char *settingAddress, int operati } close(sock_fd); - - // printf("Set OK!\n"); return 0; } // sets a genneric interface parameter // (SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS) -int bringInterfaceUp(char *interfaceName, int up) -{ +int bringInterfaceUp(char *interfaceName, int up) { int sock_fd; struct ifreq ifr; @@ -213,8 +209,7 @@ int bringInterfaceUp(char *interfaceName, int up) return 0; } // non blocking full configuration of the interface (address, net mask, and broadcast mask) -int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) -{ +int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) { bringInterfaceUp(interfaceName, 0); // sets the machine address int returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR); @@ -229,26 +224,23 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br // if(!returnValue) // returnValue=set_gateway(interfaceName, broadcastAddress); - - bringInterfaceUp(interfaceName, 1); + if(!returnValue) + returnValue = bringInterfaceUp(interfaceName, 1); return returnValue; } // non blocking full configuration of the interface (address, and the two lest octets of the address) -int nas_config(int interface_id, int thirdOctet, int fourthOctet) -{ +int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname) { //char buf[5]; char ipAddress[20]; char broadcastAddress[20]; - char interfaceName[8]; + char interfaceName[20]; int returnValue; - sprintf(ipAddress, "10.0.%d.%d", thirdOctet,fourthOctet); - - sprintf(broadcastAddress, "10.0.%d.255", thirdOctet); - - sprintf(interfaceName, "oai%d", interface_id); - + sprintf(ipAddress, "%s.%d.%d", baseNetAddress,thirdOctet,fourthOctet); + sprintf(broadcastAddress, "%s.%d.255",baseNetAddress, thirdOctet); + sprintf(interfaceName, "%s%s%d", (UE_NAS_USE_TUN || ENB_NAS_USE_TUN)?"oaitun_":ifname, + UE_NAS_USE_TUN?"ue": (ENB_NAS_USE_TUN?"enb":""),interface_id); bringInterfaceUp(interfaceName, 0); // sets the machine address returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR); @@ -261,19 +253,23 @@ int nas_config(int interface_id, int thirdOctet, int fourthOctet) if(!returnValue) returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR); - bringInterfaceUp(interfaceName, 1); + if(!returnValue) + bringInterfaceUp(interfaceName, 1); - return returnValue; + if(!returnValue) + LOG_I(OIP,"Interface %s successfuly configured, ip address %s, mask %s broadcast address %s\n", + interfaceName, ipAddress, netMask, broadcastAddress); + else + LOG_E(OIP,"Interface %s couldn't be configured (ip address %s, mask %s broadcast address %s)\n", + interfaceName, ipAddress, netMask, broadcastAddress); + return returnValue; } // Blocking full configuration of the interface (address, net mask, and broadcast mask) -int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) -{ - +int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) { char command[200]; command[0]='\0'; - strcat(command, "ifconfig "); strncat(command, interfaceName, sizeof(command) - strlen(command) - 1); strncat(command, " ", sizeof(command) - strlen(command) - 1); @@ -282,16 +278,13 @@ int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask, strncat(command, networkMask, sizeof(command) - strlen(command) - 1); strncat(command, " broadcast ", sizeof(command) - strlen(command) - 1); strncat(command, broadcastAddress, sizeof(command) - strlen(command) - 1); - // ifconfig nasmesh0 10.0.1.1 networkMask 255.255.255.0 broadcast 10.0.1.255 int i = system (command); - return i; } // program help -void helpOptions(char **argv) -{ +void helpOptions(char **argv) { printf("Help for %s\n", argv[0]); printf(" -i <interfaceName>\n"); printf(" -a <IP address>\n"); @@ -303,13 +296,11 @@ void helpOptions(char **argv) printf(" IP Address: 10.0.1.1\n"); printf(" Net mask: 255.255.255.0\n"); printf(" Broadcast address: [Beginning of the IP address].255\n"); - exit(1); } // creates the broadcast address if it wasn't set before -void createBroadcast(char *broadcastAddress) -{ +void createBroadcast(char *broadcastAddress) { int pos=strlen(broadcastAddress)-1; while(broadcastAddress[pos]!='.') @@ -331,7 +322,6 @@ int main(int argc,char **argv) char ipAddress[100]; char networkMask[100]; char broadcastAddress[100]; - strcpy(interfaceName, "oai0"); strcpy(ipAddress, "10.0.1.1"); strcpy(networkMask, "255.255.255.0"); @@ -339,38 +329,38 @@ int main(int argc,char **argv) while ((c = getopt (argc, argv, "i:a:n:b:h")) != -1) switch (c) { - case 'h': - helpOptions(argv); - break; - - case 'i': - strcpy(interfaceName,optarg); - break; - - case 'a': - strcpy(ipAddress,optarg); - break; - - case 'n': - strcpy(networkMask,optarg); - break; - - case 'b': - strcpy(broadcastAddress,optarg); - break; - - case '?': - if (isprint (optopt)) - fprintf (stderr, "Unknown option `-%c'.\n", optopt); - else - fprintf (stderr, - "Unknown option character `\\x%x'.\n", - optopt); - - return 1; - - default: - abort (); + case 'h': + helpOptions(argv); + break; + + case 'i': + strcpy(interfaceName,optarg); + break; + + case 'a': + strcpy(ipAddress,optarg); + break; + + case 'n': + strcpy(networkMask,optarg); + break; + + case 'b': + strcpy(broadcastAddress,optarg); + break; + + case '?': + if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, + "Unknown option character `\\x%x'.\n", + optopt); + + return 1; + + default: + abort (); } if(strlen(broadcastAddress)==0) { @@ -383,7 +373,6 @@ int main(int argc,char **argv) //test // setBaseNetAddress("11.11"); // nas_config(interfaceName, 33, 44); - } #endif diff --git a/openair2/RRC/NAS/nas_config.h b/openair2/RRC/NAS/nas_config.h index 4426ca9a1aabfd2eb9be65ffb2bb9886f72534fe..fdc3c98f1b0a3ccef3dc881f95c0beca926c2112 100644 --- a/openair2/RRC/NAS/nas_config.h +++ b/openair2/RRC/NAS/nas_config.h @@ -31,6 +31,13 @@ #include <netinet/in.h> +/*! \fn void void nas_getparams(void)(void) + * \brief This function get parameters used to configure network interface when running in noS1 mode + * \note + * @ingroup ????? + */ +void nas_getparams(void); + /*! \fn int NAS_config(char*, char*, char*, char*) * \brief This function initializes the nasmesh interface * \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1 @@ -54,7 +61,7 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br * \note * @ingroup ????? */ -int nas_config(int interface_id, int thirdOctet, int fourthOctet); +int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix); /*! \fn int blocking_NAS_config(char*, char*, char*, char*) * \brief This function initializes the nasmesh interface, in a blocking way, @@ -98,7 +105,7 @@ int set_gateway(char *interfaceName, char *gateway); * \note * @ingroup ????? */ -void setBaseNetAddress(char* baseAddr); +void setBaseNetAddress(char *baseAddr); /*! \fn char* getBaseNetAddress() * \brief This function returns the basic network address used @@ -106,7 +113,7 @@ void setBaseNetAddress(char* baseAddr); * \note * @ingroup ????? */ -char* getBaseNetAddress(void); +char *getBaseNetAddress(void); /*! \fn void setNetMask(char*) * \brief This function sets the new default network mask used @@ -114,7 +121,7 @@ char* getBaseNetAddress(void); * \note * @ingroup ????? */ -void setNetMask(char* baseAddr); +void setNetMask(char *baseAddr); /*! \fn char* getNetMask() * \brief This function returns the network mask address in use @@ -122,7 +129,7 @@ void setNetMask(char* baseAddr); * \note * @ingroup ????? */ -char* getNetMask(void); +char *getNetMask(void); /*! \fn coid setBroadcastAddress(char*) * \brief This function sets the new broadcast address used @@ -130,7 +137,7 @@ char* getNetMask(void); * \note * @ingroup ????? */ -void setBroadcastAddress(char* baseAddr); +void setBroadcastAddress(char *baseAddr); /*! \fn char* getBroadcastAddress() * \brief This function returns the broadcast address in use @@ -138,7 +145,7 @@ void setBroadcastAddress(char* baseAddr); * \note * @ingroup ????? */ -char* getBroadcastAddress(void); +char *getBroadcastAddress(void); int bringInterfaceUp(char *interfaceName, int up); diff --git a/openair2/UTIL/ASYNC_IF/link_manager.c b/openair2/UTIL/ASYNC_IF/link_manager.c index c1ce742d0bbe6928623dfa5cea8abf8c194f8670..e9a8e98e0768b282975a3c3b5f9a3223d0535eaf 100644 --- a/openair2/UTIL/ASYNC_IF/link_manager.c +++ b/openair2/UTIL/ASYNC_IF/link_manager.c @@ -46,15 +46,10 @@ static void *link_manager_sender_thread(void *_manager) LOG_D(MAC, "starting link manager sender thread\n"); while (manager->run) { - while (message_get(manager->send_queue, &data, &size, &priority) == 0) { - link_send_packet(manager->socket_link, data, size); + while ((size = message_get(manager->send_queue, &data, &priority)) > 0) { + link_send_packet(manager->socket_link, data, size, manager->peer_addr, manager->peer_port); free(data); } - // if (message_get(manager->send_queue, &data, &size, &priority)) - // goto error; - //if (link_send_packet(manager->socket_link, data, size)) - // goto error; - //free(data); } LOG_D(MAC, "link manager sender thread quits\n"); @@ -124,9 +119,6 @@ link_manager_t *create_link_manager( pthread_attr_setschedpolicy(&attr, SCHED_RR); //#endif - if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) - goto error; - if (pthread_create(&t, &attr, link_manager_sender_thread, ret)) goto error; ret->sender = t; @@ -151,9 +143,11 @@ error: void destroy_link_manager(link_manager_t *manager) { - LOG_D(MAC, "destroying link manager\n"); manager->run = 0; - /* todo: force threads to stop (using a dummy message?) */ + message_get_unlock(manager->send_queue); + pthread_join(manager->sender, NULL); + /* cancel aborts the read performed in the receiver, then cancels the thread */ + pthread_cancel(manager->receiver); } #ifdef SERVER_TEST @@ -186,7 +180,7 @@ int main(void) data = strdup("hello"); if (data == NULL) goto error; if (message_put(send_queue, data, 6, 100)) goto error; - if (message_get(receive_queue, &data, &size, &priority)) goto error; + if ((size = message_get(receive_queue, &data, &priority)) <= 0) goto error; printf("received message:\n"); printf(" data: %s\n", (char *)data); printf(" size: %d\n", size); @@ -230,7 +224,7 @@ int main(void) manager = create_link_manager(send_queue, receive_queue, link); if (manager == NULL) goto error; - if (message_get(receive_queue, &data, &size, &priority)) goto error; + if ((size = message_get(receive_queue, &data, &priority)) <= 0) goto error; printf("received message:\n"); printf(" data: %s\n", (char *)data); printf(" size: %d\n", size); diff --git a/openair2/UTIL/ASYNC_IF/link_manager.h b/openair2/UTIL/ASYNC_IF/link_manager.h index 90ede6c3db61865692c72c4d2721da720cd9350c..4148392eecc9e8461c7445f6672349976fbfaae4 100644 --- a/openair2/UTIL/ASYNC_IF/link_manager.h +++ b/openair2/UTIL/ASYNC_IF/link_manager.h @@ -31,8 +31,8 @@ #ifndef LINK_MANAGER_H #define LINK_MANAGER_H -//#include "message_queue.h" -#include "ringbuffer_queue.h" +#include "message_queue.h" +//#include "ringbuffer_queue.h" #include "socket_link.h" #include <pthread.h> @@ -45,6 +45,8 @@ typedef struct { message_queue_t *send_queue; message_queue_t *receive_queue; socket_link_t *socket_link; + const char *peer_addr; /* for UDP server remote IP */ + int peer_port; /* for UDP server remote address */ pthread_t sender; pthread_t receiver; volatile int run; @@ -54,6 +56,7 @@ link_manager_t *create_link_manager( message_queue_t *send_queue, message_queue_t *receive_queue, socket_link_t *link); + void destroy_link_manager(link_manager_t *); #ifdef __cplusplus diff --git a/openair2/UTIL/ASYNC_IF/message_queue.c b/openair2/UTIL/ASYNC_IF/message_queue.c index 5a33fbfabe7c8a027e15a3dedb6d2e7da2cff67a..2279a067b4547e8bea6edbeda98bd3968b9ebb85 100644 --- a/openair2/UTIL/ASYNC_IF/message_queue.c +++ b/openair2/UTIL/ASYNC_IF/message_queue.c @@ -56,6 +56,10 @@ message_queue_t *new_message_queue(void) if (pthread_cond_init(ret->cond, NULL)) goto error; + ret->head = NULL; + ret->tail = NULL; + ret->exit = 0; + return ret; error: @@ -72,6 +76,8 @@ error: int message_put(message_queue_t *queue, void *data, int size, int priority) { message_t *m = NULL; + if (size <= 0) + goto error; m = calloc(1, sizeof(message_t)); if (m == NULL) @@ -106,12 +112,12 @@ int message_put(message_queue_t *queue, void *data, int size, int priority) return 0; error: - free(m); + if (m) free(m); LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); return -1; } -int message_get(message_queue_t *queue, void **data, int *size, int *priority) +int message_get(message_queue_t *queue, void **data, int *priority) { message_t *m; @@ -119,10 +125,15 @@ int message_get(message_queue_t *queue, void **data, int *size, int *priority) goto error; while (queue->count == 0) { - if (pthread_cond_wait(queue->cond, queue->mutex)) { + int rc = pthread_cond_wait(queue->cond, queue->mutex); + if (rc != 0) { pthread_mutex_unlock(queue->mutex); goto error; } + if (queue->exit) { + pthread_mutex_unlock(queue->mutex); + return 0; + } } m = queue->head; @@ -136,17 +147,24 @@ int message_get(message_queue_t *queue, void **data, int *size, int *priority) goto error; *data = m->data; - *size = m->size; + const int size = m->size; *priority = m->priority; free(m); - return 0; - + return size; error: LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); return -1; } +void message_get_unlock(message_queue_t *queue) +{ + pthread_mutex_lock(queue->mutex); + queue->exit = 1; + pthread_mutex_unlock(queue->mutex); + pthread_cond_signal(queue->cond); +} + /* when calling this function, the queue must not be used anymore (we don't lock it) */ /* we suppose that the data pointer in messages was allocated by malloc/calloc/realloc */ void destroy_message_queue(message_queue_t *queue) @@ -181,10 +199,10 @@ int main(void) if (message_put(q, "hello", 6, 0)) goto error; if (message_put(q, "world", 6, 1)) goto error; - if (message_get(q, &data, &size, &priority)) goto error; + if ((size = message_get(q, &data, &priority)) <= 0) goto error; printf("message:\n data: '%s'\n size: %d\n priority: %d\n", (char *)data, size, priority); - if (message_get(q, &data, &size, &priority)) goto error; + if ((size = message_get(q, &data, &priority)) <= 0) goto error; printf("message:\n data: '%s'\n size: %d\n priority: %d\n", (char *)data, size, priority); @@ -193,10 +211,11 @@ int main(void) sprintf(s, "hello"); if (message_put(q, s, 6, 0)) goto error; destroy_message_queue(q); - + free(s); return 0; error: + free(s); printf("error\n"); return 1; } diff --git a/openair2/UTIL/ASYNC_IF/message_queue.h b/openair2/UTIL/ASYNC_IF/message_queue.h index 8fedddcc7751fa0233dcd5fbf133df88d6581062..656f3db28e3d87a271c2db0516a645631d62c0b6 100644 --- a/openair2/UTIL/ASYNC_IF/message_queue.h +++ b/openair2/UTIL/ASYNC_IF/message_queue.h @@ -41,6 +41,7 @@ typedef struct message_t { void *data; int size; int priority; + struct message_t *next; } message_t; @@ -50,11 +51,13 @@ typedef struct { volatile int count; pthread_mutex_t *mutex; pthread_cond_t *cond; + int exit; } message_queue_t; message_queue_t *new_message_queue(void); int message_put(message_queue_t *queue, void *data, int size, int priority); -int message_get(message_queue_t *queue, void **data, int *size, int *priority); +int message_get(message_queue_t *queue, void **data, int *priority); +void message_get_unlock(message_queue_t *queue); void destroy_message_queue(message_queue_t *queue); #ifdef __cplusplus diff --git a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c index 201603e0c57f327541c7aa0da91ba076a9393ced..7bcd3b564747b143ca31fc0f8ac9251120aba5d1 100644 --- a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c +++ b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.c @@ -67,6 +67,9 @@ int message_put(message_queue_t *queue, void *data, int size, int priority) { message_t *overwritten_msg; message_t *m = NULL; + if (size <= 0) + goto error; + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; lfds700_misc_prng_init(&ls); @@ -94,12 +97,11 @@ int message_put(message_queue_t *queue, void *data, int size, int priority) { return 0; error: - free(m); LOG_E(MAC, "%s: an error occured\n", __FUNCTION__); return -1; } -int message_get(message_queue_t *queue, void **data, int *size, int *priority) { +int message_get(message_queue_t *queue, void **data, int *priority) { message_t *m; struct lfds700_misc_prng_state ls; @@ -111,10 +113,15 @@ int message_get(message_queue_t *queue, void **data, int *size, int *priority) { } *data = m->data; - *size = m->size; + const int size = m->size; *priority = m->priority; free(m); - return 0; + return size; +} + +void message_get_unlock(message_queue_t *queue) { + /* don't do anything, this function exists to unlock a message_queue but is + * not needed in the case of the ringbuffer_queue */ } void destroy_message_queue(message_queue_t *queue) { diff --git a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h index 04414cbbb2b9618379ad1284a056943e04539c23..bb65612e6bfcfbee4f76ec79737158c268801a11 100644 --- a/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h +++ b/openair2/UTIL/ASYNC_IF/ringbuffer_queue.h @@ -47,7 +47,8 @@ typedef struct { message_queue_t * new_message_queue(int size); int message_put(message_queue_t *queue, void *data, int size, int priority); -int message_get(message_queue_t *queue, void **data, int *size, int *priority); +int message_get(message_queue_t *queue, void **data, int *priority); +void message_get_unlock(message_queue_t *queue); void destroy_message_queue(message_queue_t *queue); #endif /* RINGBUFFER_QUEUE_H */ diff --git a/openair2/UTIL/ASYNC_IF/socket_link.c b/openair2/UTIL/ASYNC_IF/socket_link.c index edfa2bde81948b29df2bf7c3cbce808db3f5843e..e40fba4a04da35bce9fd12ff173b65d0e9f286c3 100644 --- a/openair2/UTIL/ASYNC_IF/socket_link.c +++ b/openair2/UTIL/ASYNC_IF/socket_link.c @@ -51,6 +51,7 @@ socket_link_t *new_link_server(int port) socklen_t addrlen; int socket_server = -1; int no_delay; + ret = calloc(1, sizeof(socket_link_t)); if (ret == NULL) { @@ -59,22 +60,26 @@ socket_link_t *new_link_server(int port) } ret->socket_fd = -1; - LOG_D(MAC, "create a new link server socket at port %d\n", port); + + //printf("MAC create a new link server socket at port %d\n", port); socket_server = socket(AF_INET, SOCK_STREAM, 0); if (socket_server == -1) { LOG_E(MAC, "%s:%d: socket: %s\n", __FILE__, __LINE__, strerror(errno)); goto error; } + ret->type = SOCK_STREAM; reuse = 1; if (setsockopt(socket_server, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) { + LOG_E(MAC, "%s:%d: setsockopt: %s\n", __FILE__, __LINE__, strerror(errno)); goto error; } no_delay = 1; if (setsockopt(socket_server, IPPROTO_TCP, TCP_NODELAY, &no_delay, sizeof(no_delay)) == -1) { + LOG_E(MAC, "%s:%d: setsockopt: %s\n", __FILE__, __LINE__, strerror(errno)); goto error; } @@ -99,20 +104,19 @@ socket_link_t *new_link_server(int port) goto error; } - close(socket_server); - - LOG_D(MAC, "connection from %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); + //printf("MAC connection from %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); return ret; error: close(socket_server); if (ret != NULL) close(ret->socket_fd); free(ret); + LOG_E(MAC, "ERROR in new_link_server (see above), returning NULL\n"); return NULL; } -socket_link_t *new_link_client(char *server, int port) +socket_link_t *new_link_client(const char *server, int port) { socket_link_t *ret = NULL; struct sockaddr_in addr; @@ -132,6 +136,7 @@ socket_link_t *new_link_client(char *server, int port) LOG_E(MAC, "%s:%d: socket: %s\n", __FILE__, __LINE__, strerror(errno)); goto error; } + ret->type = SOCK_STREAM; no_delay = 1; if (setsockopt(ret->socket_fd, SOL_TCP, TCP_NODELAY, &no_delay, sizeof(no_delay)) == -1) { @@ -160,6 +165,263 @@ error: return NULL; } +socket_link_t *new_link_udp_server(const char *bind_addr, int bind_port) +{ + socket_link_t *ret = NULL; + + struct sockaddr_in si_me; + int socket_server = -1; + + ret = calloc(1, sizeof(socket_link_t)); + if (ret == NULL) { + LOG_D(PROTO_AGENT, "%s:%d: out of memory\n", __FILE__, __LINE__); + goto error; + } + ret->socket_fd = -1; + + //printf("PROTO_AGENT: create a new udp link server socket at port %d\n", port); + + //create a UDP socket + if ((socket_server=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { + goto error; + } + ret->type = SOCK_DGRAM; + + // zero out the structure + memset((char *) &si_me, 0, sizeof(si_me)); + + si_me.sin_family = AF_INET; + si_me.sin_port = htons(bind_port); + if (bind_addr) { + if (!inet_aton(bind_addr, &si_me.sin_addr)) + goto error; + } else { + si_me.sin_addr.s_addr = INADDR_ANY; + } + + //bind socket to port + if( bind(socket_server , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1) { + fprintf(stderr, "could not bind to address %s: %s\n", bind_addr, strerror(errno)); + goto error; + } + ret->socket_fd = socket_server; + return ret; + +error: + if (socket_server != -1) close(socket_server); + if (ret != NULL) close(ret->socket_fd); + free(ret); + //printf("\n\n\nERROR PROTO_AGENT: ERROR in new_link_udp_server (see above), returning NULL\n"); + return NULL; +} + + +socket_link_t *new_link_udp_client(const char *server, int port){ + + socket_link_t *ret = NULL; + ret = calloc(1, sizeof(socket_link_t)); + if (ret == NULL) { + LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__); + goto error; + } + ret->socket_fd = -1; + + struct sockaddr_in si_other; + int s; + socklen_t slen; + + if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ + goto error; + } + ret->type = SOCK_DGRAM; + + memset((char *) &si_other, 0, sizeof(si_other)); + si_other.sin_family = AF_INET; + si_other.sin_port = 0; //htons(port); + + + + if (inet_aton(server, &si_other.sin_addr) == 0){ + fprintf(stderr, "inet_aton() failed\n"); + goto error; + } + connect(s, (struct sockaddr *)&si_other, sizeof(si_other)); + + getsockname(s, (struct sockaddr *)&si_other, &slen); + + ret->socket_fd = s; + + return ret; +error: + if (ret != NULL) { + close(ret->socket_fd); + free(ret); + } + LOG_E(MAC, "ERROR in new_link_udp_client (see above), returning NULL\n"); + return NULL; +} + + +socket_link_t *new_link_sctp_server(int port) +{ + + socket_link_t *ret = NULL; + + int listenSock = -1, temp; + struct sockaddr_in servaddr; + + listenSock = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if(listenSock == -1) + { + perror("socket()"); + exit(1); + } + + bzero ((void *) &servaddr, sizeof (servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = INADDR_ANY; + servaddr.sin_port = htons(port); + + temp = bind (listenSock, (struct sockaddr *) &servaddr, sizeof (servaddr)); + + if(temp == -1 ) + { + perror("bind()"); + close(listenSock); + exit(1); + } + + temp = listen (listenSock, 5); + if(temp == -1 ) + { + perror("listen()"); + close(listenSock); + exit(1); + } + ret = calloc(1, sizeof(socket_link_t)); + if (ret == NULL) { + LOG_D(PROTO_AGENT, "%s:%d: out of memory\n", __FILE__, __LINE__); + goto error; + } + ret->socket_fd = -1; + + ret->socket_fd = accept (listenSock, NULL, NULL); + ret->type = SOCK_STREAM; + + return ret; + +error: + if (listenSock != -1) close(listenSock); + if (ret != NULL) close(ret->socket_fd); + free(ret); + LOG_E(MAC,"ERROR in new_link_sctp_server (see above), returning NULL\n"); + return NULL; +} + +socket_link_t *new_link_sctp_client(const char *server, int port) +{ + + socket_link_t *ret = NULL; + ret = calloc(1, sizeof(socket_link_t)); + if (ret == NULL) { + LOG_D(PROTO_AGENT, "%s:%d: out of memory\n", __FILE__, __LINE__); + goto error; + } + ret->socket_fd = -1; + + int temp; + struct sockaddr_in servaddr; + + ret->socket_fd = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP); + + if (ret->socket_fd == -1) + { + perror("socket()"); + exit(1); + } + ret->type = SOCK_STREAM; + + bzero ((void *) &servaddr, sizeof (servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons (port); + + if (inet_aton(server, &servaddr.sin_addr) == 0) { + LOG_E(MAC,"invalid IP address '%s', use a.b.c.d notation\n", server); + goto error; + } + + temp = connect (ret->socket_fd, (struct sockaddr *) &servaddr, sizeof (servaddr)); + + if (temp == -1) + { + perror("connect()"); + close(ret->socket_fd); + exit(1); + } + + return ret; + +error: + if (ret != NULL) close(ret->socket_fd); + free(ret); + LOG_E(MAC, "ERROR in new_link_sctp_client (see above), returning NULL\n"); + return NULL; +} + +static int socket_udp_send(int socket_fd, void *buf, int size, const char *peer_addr, int port) +{ + struct sockaddr_in si_other; + int slen = sizeof(si_other); + int l; + int my_socket; + + LOG_D(PROTO_AGENT,"UDP send\n"); + + my_socket = socket_fd; + memset((char *) &si_other, 0, sizeof(si_other)); + si_other.sin_family = AF_INET; + si_other.sin_port = htons(port); + + if (inet_aton(peer_addr , &si_other.sin_addr) == 0) + { + fprintf(stderr, "inet_aton() failed\n"); + exit(1); + } + + l = sendto(my_socket, buf, size, 0, (struct sockaddr *) &si_other, slen); + if (l == -1) goto error; + + return l; +error: + LOG_E(MAC,"socket_udp_send: ERROR: %s\n", strerror(errno)); + return -1; +} + +static int socket_udp_receive(int socket_fd, void *buf, int size) +{ + LOG_D(PROTO_AGENT,"UDP RECEIVE\n"); + + struct sockaddr_in client; + socklen_t slen; + int l; + + l = recvfrom(socket_fd, buf, size, 0, (struct sockaddr *) &client, &slen); + //getsockname(socket_fd, (struct sockaddr *)&client, &slen); + if (l == -1) goto error; + if (l == 0) goto socket_closed; + + return l; + +error: + LOG_E(MAC, "socket_udp_receive: ERROR: %s\n", strerror(errno)); + return -1; + +socket_closed: + LOG_E(MAC, "socket_udp_receive: socket closed\n"); + return -1; +} + + /* * return -1 on error and 0 if the sending was fine */ @@ -213,63 +475,92 @@ socket_closed: /* * return -1 on error and 0 if the sending was fine */ -int link_send_packet(socket_link_t *link, void *data, int size) +int link_send_packet(socket_link_t *link, void *data, int size, const char *peer_addr, int peer_port) { char sizebuf[4]; int32_t s = size; - - /* send the size first, maximum is 2^31 bytes */ - sizebuf[0] = (s >> 24) & 255; - sizebuf[1] = (s >> 16) & 255; - sizebuf[2] = (s >> 8) & 255; - sizebuf[3] = s & 255; - - if (socket_send(link->socket_fd, sizebuf, 4) == -1) - goto error; - - link->bytes_sent += 4; - - if (socket_send(link->socket_fd, data, size) == -1) - goto error; + switch (link->type) { + case SOCK_STREAM: + /* send the size first, maximum is 2^31 bytes */ + sizebuf[0] = (s >> 24) & 255; + sizebuf[1] = (s >> 16) & 255; + sizebuf[2] = (s >> 8) & 255; + sizebuf[3] = s & 255; + if (socket_send(link->socket_fd, sizebuf, 4) == -1) + return -1; + + link->bytes_sent += 4; + + if (socket_send(link->socket_fd, data, size) == -1) + return -1; + break; + case SOCK_DGRAM: + /* UDP is connectionless -> only send the data */ + if (socket_udp_send(link->socket_fd, data, size, peer_addr, peer_port) == -1) + return -1; + break; + default: + LOG_E(MAC, "unknown socket type %d\n", link->type); + return -1; + } link->bytes_sent += size; link->packets_sent++; return 0; - -error: - return -1; } /* * return -1 on error and 0 if the sending was fine */ + int link_receive_packet(socket_link_t *link, void **ret_data, int *ret_size) { unsigned char sizebuf[4]; - int32_t size; + int32_t size = 0; void *data = NULL; - + /* received the size first, maximum is 2^31 bytes */ - if (socket_receive(link->socket_fd, sizebuf, 4) == -1) - goto error; - - size = (sizebuf[0] << 24) | - (sizebuf[1] << 16) | - (sizebuf[2] << 8) | - sizebuf[3]; - - link->bytes_received += 4; - - data = malloc(size); - if (data == NULL) { - LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__); + switch (link->type) { + case SOCK_STREAM: + if (socket_receive(link->socket_fd, sizebuf, 4) == -1) + goto error; + + size = (sizebuf[0] << 24) | + (sizebuf[1] << 16) | + (sizebuf[2] << 8) | + sizebuf[3]; + + link->bytes_received += 4; + + data = malloc(size); + if (data == NULL) { + LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__); + goto error; + } + + if (socket_receive(link->socket_fd, data, size) == -1) + goto error; + break; + case SOCK_DGRAM: + /* we get a single packet (no size, UDP could lose it). Therefore, prepare + * for the maximum UDP packet size */ + size = 65535; + data = malloc(size); + if (data == NULL) { + LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__); + goto error; + } + + size = socket_udp_receive(link->socket_fd, data, size); + if (size < 0) + goto error; + break; + default: + LOG_E(MAC, "unknown socket type %d\n", link->type); goto error; } - if (socket_receive(link->socket_fd, data, size) == -1) - goto error; - link->bytes_received += size; link->packets_received++; @@ -313,8 +604,8 @@ int main(void) */ sleep(1); printf("... done\n"); - if (link_send_packet(l, "hello\n", 6+1) || - link_send_packet(l, "world\n", 6+1)) return 1; + if (link_send_packet(l, "hello\n", 6+1, NULL, 0) || + link_send_packet(l, "world\n", 6+1, NULL, 0)) return 1; if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data); if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data); printf("stats:\n"); @@ -342,8 +633,8 @@ int main(void) printf("link is up\n"); if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data); if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data); - if (link_send_packet(l, "bye\n", 4+1) || - link_send_packet(l, "server\n", 7+1)) return 1; + if (link_send_packet(l, "bye\n", 4+1, NULL, 0) || + link_send_packet(l, "server\n", 7+1, NULL, 0)) return 1; printf("stats:\n"); printf(" sent packets %"PRIu64"\n", l->packets_sent); printf(" sent bytes %"PRIu64"\n", l->bytes_sent); diff --git a/openair2/UTIL/ASYNC_IF/socket_link.h b/openair2/UTIL/ASYNC_IF/socket_link.h index dbe0a6937055e53c16e7a3bedcfecc8772c0cc79..b466721e084953fd24c5cc577a35fe3f3cbcb048 100644 --- a/openair2/UTIL/ASYNC_IF/socket_link.h +++ b/openair2/UTIL/ASYNC_IF/socket_link.h @@ -37,8 +37,10 @@ extern "C" { #endif + typedef struct { int socket_fd; + int type; uint64_t bytes_sent; uint64_t packets_sent; uint64_t bytes_received; @@ -46,11 +48,17 @@ typedef struct { } socket_link_t; socket_link_t *new_link_server(int port); -socket_link_t *new_link_client(char *server, int port); -int link_send_packet(socket_link_t *link, void *data, int size); +socket_link_t *new_link_client(const char *server, int port); +/* setting bind_addr to NULL binds server to INADDR_ANY */ +socket_link_t *new_link_udp_server(const char *bind_addr, int bind_port); +socket_link_t *new_link_udp_client(const char *server, int port); +socket_link_t *new_link_sctp_server(int port); +socket_link_t *new_link_sctp_client(const char *server, int port); +int link_send_packet(socket_link_t *link, void *data, int size, const char *peer_addr, int port); int link_receive_packet(socket_link_t *link, void **data, int *size); int close_link(socket_link_t *link); + #ifdef __cplusplus } #endif diff --git a/openair2/UTIL/FIFO/pad_list.c b/openair2/UTIL/FIFO/pad_list.c index 32a9f3519640a020df52ebc60add66f9a0fb3bac..e15041118d0f182492d34f596c829c988c0dd371 100644 --- a/openair2/UTIL/FIFO/pad_list.c +++ b/openair2/UTIL/FIFO/pad_list.c @@ -35,25 +35,19 @@ //#include <mpi.h> -void job_list_init (Job_List_t * listP) -{ - +void job_list_init (Job_List_t *listP) { listP->tail = NULL; listP->head = NULL; listP->nb_elements = 0; } -void event_list_init (Event_List_t * listP) -{ - +void event_list_init (Event_List_t *listP) { listP->tail = NULL; listP->head = NULL; listP->nb_elements = 0; } -void pkt_list_init (Packet_OTG_List_t * listP) -{ - +void pkt_list_init (Packet_OTG_List_t *listP) { listP->tail = NULL; listP->head = NULL; listP->nb_elements = 0; @@ -61,8 +55,7 @@ void pkt_list_init (Packet_OTG_List_t * listP) //----------------------------------------------------------------------------- -void job_list_free (Job_List_t * listP) -{ +void job_list_free (Job_List_t *listP) { Job_elt_t *le; while ((le = job_list_remove_head (listP))) { @@ -70,8 +63,7 @@ void job_list_free (Job_List_t * listP) } } -void event_list_free (Event_List_t * listP) -{ +void event_list_free (Event_List_t *listP) { Event_elt_t *le; while ((le = event_list_remove_head (listP))) { @@ -79,8 +71,7 @@ void event_list_free (Event_List_t * listP) } } -void pkt_list_free (Packet_OTG_List_t * listP) -{ +void pkt_list_free (Packet_OTG_List_t *listP) { Packet_otg_elt_t *le; while ((le = pkt_list_remove_head (listP))) { @@ -90,18 +81,15 @@ void pkt_list_free (Packet_OTG_List_t * listP) //----------------------------------------------------------------------------- -Job_elt_t * job_list_get_head (Job_List_t * listP) -{ +Job_elt_t *job_list_get_head (Job_List_t *listP) { return listP->head; } -Event_elt_t * event_list_get_head (Event_List_t * listP) -{ +Event_elt_t *event_list_get_head (Event_List_t *listP) { return listP->head; } -Packet_otg_elt_t * pkt_list_get_head (Packet_OTG_List_t * listP) -{ +Packet_otg_elt_t *pkt_list_get_head (Packet_OTG_List_t *listP) { return listP->head; } @@ -112,9 +100,7 @@ Packet_otg_elt_t * pkt_list_get_head (Packet_OTG_List_t * listP) * @param pointer on targeted list * @return pointer on removed Job_elt_t */ -Job_elt_t * job_list_remove_head (Job_List_t * listP) -{ - +Job_elt_t *job_list_remove_head (Job_List_t *listP) { // access optimisation Job_elt_t *head; head = listP->head; @@ -137,9 +123,7 @@ Job_elt_t * job_list_remove_head (Job_List_t * listP) return head; } -Event_elt_t * event_list_remove_head (Event_List_t * listP) -{ - +Event_elt_t *event_list_remove_head (Event_List_t *listP) { // access optimisation Event_elt_t *head; head = listP->head; @@ -162,9 +146,7 @@ Event_elt_t * event_list_remove_head (Event_List_t * listP) return head; } -Packet_otg_elt_t * pkt_list_remove_head (Packet_OTG_List_t * listP) -{ - +Packet_otg_elt_t *pkt_list_remove_head (Packet_OTG_List_t *listP) { // access optimisation Packet_otg_elt_t *head; head = listP->head; @@ -189,9 +171,7 @@ Packet_otg_elt_t * pkt_list_remove_head (Packet_OTG_List_t * listP) //----------------------------------------------------------------------------- -Job_elt_t * job_list_remove_element (Job_elt_t * elementP, Job_List_t * listP) -{ - +Job_elt_t *job_list_remove_element (Job_elt_t *elementP, Job_List_t *listP) { // access optimisation; Job_elt_t *head; @@ -233,9 +213,7 @@ Job_elt_t * job_list_remove_element (Job_elt_t * elementP, Job_List_t * listP) return elementP; } -Event_elt_t * event_list_remove_element (Event_elt_t * elementP, Event_List_t * listP) -{ - +Event_elt_t *event_list_remove_element (Event_elt_t *elementP, Event_List_t *listP) { // access optimisation; Event_elt_t *head; @@ -277,9 +255,7 @@ Event_elt_t * event_list_remove_element (Event_elt_t * elementP, Event_List_t * return elementP; } -Packet_otg_elt_t * pkt_list_remove_element (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP) -{ - +Packet_otg_elt_t *pkt_list_remove_element (Packet_otg_elt_t *elementP, Packet_OTG_List_t *listP) { // access optimisation; Packet_otg_elt_t *head; @@ -328,9 +304,7 @@ Packet_otg_elt_t * pkt_list_remove_element (Packet_otg_elt_t * elementP, Packet_ * @return pointer on removed Job_elt_t */ -void job_list_add_head (Job_elt_t * elementP, Job_List_t * listP) -{ - +void job_list_add_head (Job_elt_t *elementP, Job_List_t *listP) { // access optimisation; Job_elt_t *head; @@ -349,9 +323,7 @@ void job_list_add_head (Job_elt_t * elementP, Job_List_t * listP) } } -void event_list_add_head (Event_elt_t * elementP, Event_List_t * listP) -{ - +void event_list_add_head (Event_elt_t *elementP, Event_List_t *listP) { // access optimisation; Event_elt_t *head; @@ -370,9 +342,7 @@ void event_list_add_head (Event_elt_t * elementP, Event_List_t * listP) } } -void pkt_list_add_head (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP) -{ - +void pkt_list_add_head (Packet_otg_elt_t *elementP, Packet_OTG_List_t *listP) { // access optimisation; Packet_otg_elt_t *head; @@ -391,14 +361,12 @@ void pkt_list_add_head (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP) } } -void event_list_add_element (Event_elt_t * elementP, Event_elt_t * previous, Event_List_t * listP) -{ - +void event_list_add_element (Event_elt_t *elementP, Event_elt_t *previous, Event_List_t *listP) { // access optimisation; Event_elt_t *next; - elementP->next = NULL; if (elementP != NULL && previous != NULL) { + elementP->next = NULL; next = previous->next; listP->nb_elements = listP->nb_elements + 1; @@ -420,8 +388,7 @@ void event_list_add_element (Event_elt_t * elementP, Event_elt_t * previous, Eve * @param pointer on targeted list * @return pointer on removed Job_elt_t */ -void job_list_add_tail_eurecom (Job_elt_t * elementP, Job_List_t * listP) -{ +void job_list_add_tail_eurecom (Job_elt_t *elementP, Job_List_t *listP) { Job_elt_t *tail; if (elementP != NULL) { @@ -443,8 +410,7 @@ void job_list_add_tail_eurecom (Job_elt_t * elementP, Job_List_t * listP) } } -void event_list_add_tail_eurecom (Event_elt_t * elementP, Event_List_t * listP) -{ +void event_list_add_tail_eurecom (Event_elt_t *elementP, Event_List_t *listP) { Event_elt_t *tail; if (elementP != NULL) { @@ -466,8 +432,7 @@ void event_list_add_tail_eurecom (Event_elt_t * elementP, Event_List_t * listP) } } -void pkt_list_add_tail_eurecom (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP) -{ +void pkt_list_add_tail_eurecom (Packet_otg_elt_t *elementP, Packet_OTG_List_t *listP) { Packet_otg_elt_t *tail; if (elementP != NULL) { @@ -490,14 +455,11 @@ void pkt_list_add_tail_eurecom (Packet_otg_elt_t * elementP, Packet_OTG_List_t * } //----------------------------------------------------------------------------- -void job_list_add_list (Job_List_t * sublistP, Job_List_t * listP) -{ - +void job_list_add_list (Job_List_t *sublistP, Job_List_t *listP) { if (sublistP) { if (sublistP->head) { // access optimisation Job_elt_t *tail; - tail = listP->tail; // almost one element @@ -517,14 +479,11 @@ void job_list_add_list (Job_List_t * sublistP, Job_List_t * listP) } } -void event_list_add_list (Event_List_t * sublistP, Event_List_t * listP) -{ - +void event_list_add_list (Event_List_t *sublistP, Event_List_t *listP) { if (sublistP) { if (sublistP->head) { // access optimisation Event_elt_t *tail; - tail = listP->tail; // almost one element @@ -544,14 +503,11 @@ void event_list_add_list (Event_List_t * sublistP, Event_List_t * listP) } } -void pkt_list_add_list (Packet_OTG_List_t * sublistP, Packet_OTG_List_t * listP) -{ - +void pkt_list_add_list (Packet_OTG_List_t *sublistP, Packet_OTG_List_t *listP) { if (sublistP) { if (sublistP->head) { // access optimisation Packet_otg_elt_t *tail; - tail = listP->tail; // almost one element @@ -572,11 +528,8 @@ void pkt_list_add_list (Packet_OTG_List_t * sublistP, Packet_OTG_List_t * listP) } //----------------------------------------------------------------------------- -void job_list_display (Job_List_t * listP) -{ - +void job_list_display (Job_List_t *listP) { //Correct the output once the content of struct Job is fixed - /*Job_elt_t *cursor; unsigned short nb_elements = 0; @@ -605,8 +558,7 @@ void job_list_display (Job_List_t * listP) }*/ } -void event_list_display (Event_List_t * listP) -{ +void event_list_display (Event_List_t *listP) { Event_elt_t *cursor; unsigned short nb_elements = 0; @@ -630,8 +582,7 @@ void event_list_display (Event_List_t * listP) } } -void pkt_list_display (Packet_OTG_List_t * listP) -{ +void pkt_list_display (Packet_OTG_List_t *listP) { Packet_otg_elt_t *cursor; unsigned short nb_elements = 0; diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c index 8ab44e46b5d52040062926c2a5ea93a72b3e2387..11852859e860144c33c7460c07ec2345cd9770f2 100644 --- a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c +++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c @@ -31,8 +31,6 @@ void lfds700_ringbuffer_cleanup( struct lfds700_ringbuffer_state *rs, /****************************************************************************/ -//#pragma warning( disable : 4100 ) - static void lfds700_ringbuffer_internal_queue_element_cleanup_callback( struct lfds700_queue_state *qs, struct lfds700_queue_element *qe, enum lfds700_misc_flag dummy_element_flag ) { struct lfds700_ringbuffer_element @@ -57,9 +55,6 @@ static void lfds700_ringbuffer_internal_queue_element_cleanup_callback( struct l //#pragma warning( default : 4100 ) - - - /****************************************************************************/ //#pragma warning( disable : 4100 ) diff --git a/openair2/UTIL/LISTS/list.h b/openair2/UTIL/LISTS/list.h index 818df2be26d0c74c4e862ceaf660fd6be8708929..b88c581deab6ecb65ee6c0e251d4abbf034184cf 100644 --- a/openair2/UTIL/LISTS/list.h +++ b/openair2/UTIL/LISTS/list.h @@ -112,9 +112,9 @@ typedef struct { size_t atomSize; size_t increment; } varArray_t; - + static inline varArray_t * initVarArray(size_t increment, size_t atomSize) { - varArray_t * tmp=malloc(sizeof(varArray_t)+increment*atomSize); + varArray_t * tmp=(varArray_t *)malloc(sizeof(varArray_t)+increment*atomSize); tmp->size=0; tmp->atomSize=atomSize; tmp->mallocedSize=increment; @@ -129,7 +129,7 @@ static inline void * dataArray(varArray_t * input) { static inline void appendVarArray(varArray_t * input, void* data) { if (input->size>=input->mallocedSize) { input->mallocedSize+=input->increment; - input=realloc(input,sizeof(varArray_t)+input->mallocedSize*input->atomSize); + input=(varArray_t *)realloc(input,sizeof(varArray_t)+input->mallocedSize*input->atomSize); } memcpy((uint8_t*)(input+1)+input->atomSize*input->size++, data, input->atomSize); } diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c new file mode 100644 index 0000000000000000000000000000000000000000..faff4fcfb964de838392eee955903ed614322681 --- /dev/null +++ b/openair2/UTIL/LOG/log.c @@ -0,0 +1,1832 @@ +/* + * 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 log.c +* \brief log implementaion +* \author Navid Nikaein +* \date 2009 - 2014 +* \version 0.5 +* @ingroup util + +*/ + +#define _GNU_SOURCE /* required for pthread_getname_np */ +//#define LOG_TEST 1 + +#define COMPONENT_LOG +#define COMPONENT_LOG_IF +#include <ctype.h> +#define LOG_MAIN +#include "log.h" +#include "vcd_signal_dumper.h" +#include "assertions.h" + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + +# include <pthread.h> +# include <string.h> +#include "common/config/config_userapi.h" +// main log variables + + +mapping log_level_names[] = { + {"emerg", LOG_EMERG}, + {"alert", LOG_ALERT}, + {"crit", LOG_CRIT}, + {"error", LOG_ERR}, + {"warn", LOG_WARNING}, + {"notice", LOG_NOTICE}, + {"info", LOG_INFO}, + {"debug", LOG_DEBUG}, + {"file", LOG_FILE}, + {"trace", LOG_TRACE}, + {NULL, -1} +}; +mapping log_verbosity_names[] = { + {"none", 0x0}, + {"low", 0x5}, + {"medium", 0x15}, + {"high", 0x35}, + {"full", 0x75}, + {NULL, -1} +}; + +// vars for the log thread +LOG_params log_list[2000]; +int log_list_tail = 0; +int log_list_nb_elements = 0; + +pthread_mutex_t log_lock; +pthread_cond_t log_notify; + + +#if !defined(LOG_NO_THREAD) +int log_list_head = 0; +int log_shutdown; +#endif + +static int gfd; + +static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_ORANGE, LOG_BLUE, "", ""}; /*!< \brief Optional start-format strings for highlighting */ +static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET,LOG_RESET, "",""}; /*!< \brief Optional end-format strings for highlighting */ + +#if defined(ENABLE_ITTI) +static log_instance_type_t log_instance_type; +#endif + +/* get log parameters from configuration file */ +void log_getconfig(log_t *g_log) { + char *gloglevel = NULL; + char *glogverbo = NULL; + int level,verbosity; + paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC; + paramdef_t logparams_level[MAX_LOG_COMPONENTS]; + paramdef_t logparams_verbosity[MAX_LOG_COMPONENTS]; + paramdef_t logparams_logfile[MAX_LOG_COMPONENTS]; + + int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX); + if (ret <0) { + fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed"); + return; + } + memset(logparams_level, 0, sizeof(paramdef_t)*MAX_LOG_COMPONENTS); + memset(logparams_verbosity,0, sizeof(paramdef_t)*MAX_LOG_COMPONENTS); + memset(logparams_logfile, 0, sizeof(paramdef_t)*MAX_LOG_COMPONENTS); + for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + if(g_log->log_component[i].name == NULL) { + g_log->log_component[i].name = malloc(16); + sprintf((char *)g_log->log_component[i].name,"comp%i?",i); + logparams_logfile[i].paramflags = PARAMFLAG_DONOTREAD; + logparams_level[i].paramflags = PARAMFLAG_DONOTREAD; + logparams_verbosity[i].paramflags = PARAMFLAG_DONOTREAD; + } + sprintf(logparams_level[i].optname, LOG_CONFIG_LEVEL_FORMAT, g_log->log_component[i].name); + sprintf(logparams_verbosity[i].optname,LOG_CONFIG_VERBOSITY_FORMAT, g_log->log_component[i].name); + sprintf(logparams_logfile[i].optname, LOG_CONFIG_LOGFILE_FORMAT, g_log->log_component[i].name); +/* workaround: all log options in existing configuration files use lower case component names + where component names include uppercase char in log.h.... */ + for (int j=0 ; j<strlen(logparams_level[i].optname); j++) + logparams_level[i].optname[j] = tolower(logparams_level[i].optname[j]); + for (int j=0 ; j<strlen(logparams_level[i].optname); j++) + logparams_verbosity[i].optname[j] = tolower(logparams_verbosity[i].optname[j]); + for (int j=0 ; j<strlen(logparams_level[i].optname); j++) + logparams_logfile[i].optname[j] = tolower(logparams_logfile[i].optname[j]); +/* */ + logparams_level[i].defstrval = gloglevel; + logparams_verbosity[i].defstrval = glogverbo; + + logparams_level[i].type = TYPE_STRING; + logparams_verbosity[i].type = TYPE_STRING; + logparams_logfile[i].type = TYPE_UINT; + + logparams_logfile[i].paramflags = logparams_logfile[i].paramflags|PARAMFLAG_BOOL; + } + config_get( logparams_level, MAX_LOG_COMPONENTS,CONFIG_STRING_LOG_PREFIX); + config_get( logparams_verbosity,MAX_LOG_COMPONENTS,CONFIG_STRING_LOG_PREFIX); + config_get( logparams_logfile, MAX_LOG_COMPONENTS,CONFIG_STRING_LOG_PREFIX); + for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + verbosity = map_str_to_int(log_verbosity_names,*(logparams_verbosity[i].strptr)); + level = map_str_to_int(log_level_names, *(logparams_level[i].strptr)); + set_comp_log(i, level,verbosity,1); + set_component_filelog(*(logparams_logfile[i].uptr)); + } +} + + +int logInit (void) +{ + int i; + g_log = calloc(1, sizeof(log_t)); + + if (g_log == NULL) { + perror ("cannot allocated memory for log generation module \n"); + exit(EXIT_FAILURE); + } + + +#if ! defined(CN_BUILD) + g_log->log_component[PHY].name = "PHY"; + g_log->log_component[PHY].level = LOG_EMERG; + g_log->log_component[PHY].flag = LOG_MED; + g_log->log_component[PHY].interval = 1; + g_log->log_component[PHY].fd = 0; + g_log->log_component[PHY].filelog = 0; + g_log->log_component[PHY].filelog_name = "/tmp/phy.log"; + + g_log->log_component[MAC].name = "MAC"; + g_log->log_component[MAC].level = LOG_EMERG; + g_log->log_component[MAC].flag = LOG_MED; + g_log->log_component[MAC].interval = 1; + g_log->log_component[MAC].fd = 0; + g_log->log_component[MAC].filelog = 0; + g_log->log_component[MAC].filelog_name = "/tmp/mac.log"; + + g_log->log_component[OPT].name = "OPT"; + g_log->log_component[OPT].level = LOG_EMERG; + g_log->log_component[OPT].flag = LOG_MED; + g_log->log_component[OPT].interval = 1; + g_log->log_component[OPT].fd = 0; + g_log->log_component[OPT].filelog = 0; + g_log->log_component[OPT].filelog_name = ""; + + g_log->log_component[RLC].name = "RLC"; + g_log->log_component[RLC].level = LOG_INFO; + g_log->log_component[RLC].flag = LOG_MED; + g_log->log_component[RLC].interval = 1; + g_log->log_component[RLC].fd = 0; + g_log->log_component[RLC].filelog = 0; + g_log->log_component[RLC].filelog_name = "/tmp/rlc.log"; + + g_log->log_component[PDCP].name = "PDCP"; + g_log->log_component[PDCP].level = LOG_INFO; + g_log->log_component[PDCP].flag = LOG_MED; + g_log->log_component[PDCP].interval = 1; + g_log->log_component[PDCP].fd = 0; + g_log->log_component[PDCP].filelog = 0; + g_log->log_component[PDCP].filelog_name = "/tmp/pdcp.log"; + + g_log->log_component[RRC].name = "RRC"; + g_log->log_component[RRC].level = LOG_TRACE; + g_log->log_component[RRC].flag = LOG_MED; + g_log->log_component[RRC].interval = 1; + g_log->log_component[RRC].fd = 0; + g_log->log_component[RRC].filelog = 0; + g_log->log_component[RRC].filelog_name = "/tmp/rrc.log"; + + g_log->log_component[EMU].name = "EMU"; + g_log->log_component[EMU].level = LOG_EMERG; + g_log->log_component[EMU].flag = LOG_MED; + g_log->log_component[EMU].interval = 1; + g_log->log_component[EMU].fd = 0; + g_log->log_component[EMU].filelog = 0; + g_log->log_component[EMU].filelog_name = ""; + + g_log->log_component[OMG].name = "OMG"; + g_log->log_component[OMG].level = LOG_EMERG; + g_log->log_component[OMG].flag = LOG_MED; + g_log->log_component[OMG].interval = 1; + g_log->log_component[OMG].fd = 0; + g_log->log_component[OMG].filelog = 0; + g_log->log_component[OMG].filelog_name = "/tmp/omg.csv"; + + g_log->log_component[OTG].name = "OTG"; + g_log->log_component[OTG].level = LOG_EMERG; + g_log->log_component[OTG].flag = LOG_MED; + g_log->log_component[OTG].interval = 1; + g_log->log_component[OTG].fd = 0; + g_log->log_component[OTG].filelog = 0; + g_log->log_component[OTG].filelog_name = "/tmp/otg.log"; + + g_log->log_component[OTG_LATENCY].name = "OTG_LATENCY"; + g_log->log_component[OTG_LATENCY].level = LOG_EMERG; + g_log->log_component[OTG_LATENCY].flag = LOG_MED; + g_log->log_component[OTG_LATENCY].interval = 1; + g_log->log_component[OTG_LATENCY].fd = 0; + g_log->log_component[OTG_LATENCY].filelog = 0; + g_log->log_component[OTG_LATENCY].filelog_name = "/tmp/otg_latency.dat"; + + g_log->log_component[OTG_LATENCY_BG].name = "OTG_LATENCY_BG"; + g_log->log_component[OTG_LATENCY_BG].level = LOG_EMERG; + g_log->log_component[OTG_LATENCY_BG].flag = LOG_MED; + g_log->log_component[OTG_LATENCY_BG].interval = 1; + g_log->log_component[OTG_LATENCY_BG].fd = 0; + g_log->log_component[OTG_LATENCY_BG].filelog = 0; + g_log->log_component[OTG_LATENCY_BG].filelog_name = "/tmp/otg_latency_bg.dat"; + + g_log->log_component[OTG_GP].name = "OTG_GP"; + g_log->log_component[OTG_GP].level = LOG_EMERG; + g_log->log_component[OTG_GP].flag = LOG_MED; + g_log->log_component[OTG_GP].interval = 1; + g_log->log_component[OTG_GP].fd = 0; + g_log->log_component[OTG_GP].filelog = 0; + g_log->log_component[OTG_GP].filelog_name = "/tmp/otg_goodput.dat"; + + g_log->log_component[OTG_GP_BG].name = "OTG_GP_BG"; + g_log->log_component[OTG_GP_BG].level = LOG_EMERG; + g_log->log_component[OTG_GP_BG].flag = LOG_MED; + g_log->log_component[OTG_GP_BG].interval = 1; + g_log->log_component[OTG_GP_BG].fd = 0; + g_log->log_component[OTG_GP_BG].filelog = 0; + g_log->log_component[OTG_GP_BG].filelog_name = "/tmp/otg_goodput_bg.dat"; + + g_log->log_component[OTG_JITTER].name = "OTG_JITTER"; + g_log->log_component[OTG_JITTER].level = LOG_EMERG; + g_log->log_component[OTG_JITTER].flag = LOG_MED; + g_log->log_component[OTG_JITTER].interval = 1; + g_log->log_component[OTG_JITTER].fd = 0; + g_log->log_component[OTG_JITTER].filelog = 0; + g_log->log_component[OTG_JITTER].filelog_name = "/tmp/otg_jitter.dat"; + + g_log->log_component[OCG].name = "OCG"; + g_log->log_component[OCG].level = LOG_EMERG; + g_log->log_component[OCG].flag = LOG_MED; + g_log->log_component[OCG].interval = 1; + g_log->log_component[OCG].fd = 0; + g_log->log_component[OCG].filelog = 0; + g_log->log_component[OCG].filelog_name = ""; + + g_log->log_component[PERF].name = "PERF"; + g_log->log_component[PERF].level = LOG_EMERG; + g_log->log_component[PERF].flag = LOG_MED; + g_log->log_component[PERF].interval = 1; + g_log->log_component[PERF].fd = 0; + g_log->log_component[PERF].filelog = 0; + g_log->log_component[PERF].filelog_name = ""; + + g_log->log_component[OIP].name = "OIP"; + g_log->log_component[OIP].level = LOG_EMERG; + g_log->log_component[OIP].flag = LOG_MED; + g_log->log_component[OIP].interval = 1; + g_log->log_component[OIP].fd = 0; + g_log->log_component[OIP].filelog = 0; + g_log->log_component[OIP].filelog_name = ""; + + g_log->log_component[CLI].name = "CLI"; + g_log->log_component[CLI].level = LOG_EMERG; + g_log->log_component[CLI].flag = LOG_MED; + g_log->log_component[CLI].interval = 1; + g_log->log_component[CLI].fd = 0; + g_log->log_component[CLI].filelog = 0; + g_log->log_component[CLI].filelog_name = ""; + + g_log->log_component[MSC].name = "MSC"; + g_log->log_component[MSC].level = LOG_EMERG; + g_log->log_component[MSC].flag = LOG_MED; + g_log->log_component[MSC].interval = 1; + g_log->log_component[MSC].fd = 0; + g_log->log_component[MSC].filelog = 0; + g_log->log_component[MSC].filelog_name = "/tmp/msc.log"; + + g_log->log_component[PROTO_AGENT].name = "PROTO_AGENT"; + g_log->log_component[PROTO_AGENT].level = LOG_EMERG; + g_log->log_component[PROTO_AGENT].flag = LOG_MED; + g_log->log_component[PROTO_AGENT].interval = 1; + g_log->log_component[PROTO_AGENT].fd = 0; + g_log->log_component[PROTO_AGENT].filelog = 0; + g_log->log_component[PROTO_AGENT].filelog_name = "/tmp/proto_agent.log"; + + + + g_log->log_component[PROTO_AGENT].name = "PROTO_AGENT"; + g_log->log_component[PROTO_AGENT].level = LOG_EMERG; + g_log->log_component[PROTO_AGENT].flag = LOG_MED; + g_log->log_component[PROTO_AGENT].interval = 1; + g_log->log_component[PROTO_AGENT].fd = 0; + g_log->log_component[PROTO_AGENT].filelog = 0; + g_log->log_component[PROTO_AGENT].filelog_name = "/tmp/proto_agent.log"; + + g_log->log_component[F1U].name = "F1U"; + g_log->log_component[F1U].level = LOG_EMERG; + g_log->log_component[F1U].flag = LOG_MED; + g_log->log_component[F1U].interval = 1; + g_log->log_component[F1U].fd = 0; + g_log->log_component[F1U].filelog = 0; + g_log->log_component[F1U].filelog_name = "/tmp/f1u.log"; + + g_log->log_component[OCM].name = "OCM"; + g_log->log_component[OCM].level = LOG_EMERG; + g_log->log_component[OCM].flag = LOG_MED; + g_log->log_component[OCM].interval = 1; + g_log->log_component[OCM].fd = 0; + g_log->log_component[OCM].filelog = 0; + g_log->log_component[OCM].filelog_name = "/tmp/ocm.log"; + + g_log->log_component[HW].name = "HW"; + g_log->log_component[HW].level = LOG_EMERG; + g_log->log_component[HW].flag = LOG_MED; + g_log->log_component[HW].interval = 1; + g_log->log_component[HW].fd = 0; + g_log->log_component[HW].filelog = 0; + g_log->log_component[HW].filelog_name = ""; + + g_log->log_component[OSA].name = "OSA"; + g_log->log_component[OSA].level = LOG_EMERG; + g_log->log_component[OSA].flag = LOG_MED; + g_log->log_component[OSA].interval = 1; + g_log->log_component[OSA].fd = 0; + g_log->log_component[OSA].filelog = 0; + g_log->log_component[OSA].filelog_name = ""; + + g_log->log_component[RAL_ENB].name = "eRAL"; + g_log->log_component[RAL_ENB].level = LOG_EMERG; + g_log->log_component[RAL_ENB].flag = LOG_MED; + g_log->log_component[RAL_ENB].interval = 1; + g_log->log_component[RAL_ENB].fd = 0; + g_log->log_component[RAL_ENB].filelog = 0; + g_log->log_component[RAL_ENB].filelog_name = ""; + + g_log->log_component[RAL_UE].name = "mRAL"; + g_log->log_component[RAL_UE].level = LOG_EMERG; + g_log->log_component[RAL_UE].flag = LOG_MED; + g_log->log_component[RAL_UE].interval = 1; + g_log->log_component[RAL_UE].fd = 0; + g_log->log_component[RAL_UE].filelog = 0; + g_log->log_component[RAL_UE].filelog_name = ""; + + g_log->log_component[ENB_APP].name = "ENB_APP"; + g_log->log_component[ENB_APP].level = LOG_EMERG; + g_log->log_component[ENB_APP].flag = LOG_MED; + g_log->log_component[ENB_APP].interval = 1; + g_log->log_component[ENB_APP].fd = 0; + g_log->log_component[ENB_APP].filelog = 0; + g_log->log_component[ENB_APP].filelog_name = ""; + + g_log->log_component[FLEXRAN_AGENT].name = "FLEXRAN_AGENT"; + g_log->log_component[FLEXRAN_AGENT].level = LOG_DEBUG; + g_log->log_component[FLEXRAN_AGENT].flag = LOG_MED; + g_log->log_component[FLEXRAN_AGENT].interval = 1; + g_log->log_component[FLEXRAN_AGENT].fd = 0; + g_log->log_component[FLEXRAN_AGENT].filelog = 0; + g_log->log_component[FLEXRAN_AGENT].filelog_name = ""; + + g_log->log_component[TMR].name = "TMR"; + g_log->log_component[TMR].level = LOG_EMERG; + g_log->log_component[TMR].flag = LOG_MED; + g_log->log_component[TMR].interval = 1; + g_log->log_component[TMR].fd = 0; + g_log->log_component[TMR].filelog = 0; + g_log->log_component[TMR].filelog_name = ""; + + g_log->log_component[USIM].name = "USIM"; + g_log->log_component[USIM].level = LOG_DEBUG; + g_log->log_component[USIM].flag = LOG_NONE; + g_log->log_component[USIM].interval = 1; + g_log->log_component[USIM].fd = 0; + g_log->log_component[USIM].filelog = 0; + g_log->log_component[USIM].filelog_name = "/tmp/usim.txt"; + + /* following log component are used for the localization*/ + g_log->log_component[LOCALIZE].name = "LOCALIZE"; + g_log->log_component[LOCALIZE].level = LOG_EMERG; + g_log->log_component[LOCALIZE].flag = LOG_MED; + g_log->log_component[LOCALIZE].interval = 1; + g_log->log_component[LOCALIZE].fd = 0; + g_log->log_component[LOCALIZE].filelog = 0; + g_log->log_component[LOCALIZE].filelog_name = "/tmp/localize.log"; +#endif // ! defined(CN_BUILD) + + g_log->log_component[NAS].name = "NAS"; + g_log->log_component[NAS].level = LOG_TRACE; + g_log->log_component[NAS].flag = LOG_MED; + g_log->log_component[NAS].interval = 1; + g_log->log_component[NAS].fd = 0; + g_log->log_component[NAS].filelog = 0; + g_log->log_component[NAS].filelog_name = "/tmp/nas.log"; + + g_log->log_component[UDP_].name = "UDP"; + g_log->log_component[UDP_].level = LOG_EMERG; + g_log->log_component[UDP_].flag = LOG_FULL; + g_log->log_component[UDP_].interval = 1; + g_log->log_component[UDP_].fd = 0; + g_log->log_component[UDP_].filelog = 0; + g_log->log_component[UDP_].filelog_name = ""; + + g_log->log_component[GTPU].name = "GTPV1U"; + g_log->log_component[GTPU].level = LOG_EMERG; + g_log->log_component[GTPU].flag = LOG_FULL; + g_log->log_component[GTPU].interval = 1; + g_log->log_component[GTPU].fd = 0; + g_log->log_component[GTPU].filelog = 0; + g_log->log_component[GTPU].filelog_name = ""; + + g_log->log_component[S1AP].name = "S1AP"; + g_log->log_component[S1AP].level = LOG_EMERG; + g_log->log_component[S1AP].flag = LOG_FULL; + g_log->log_component[S1AP].interval = 1; + g_log->log_component[S1AP].fd = 0; + g_log->log_component[S1AP].filelog = 0; + g_log->log_component[S1AP].filelog_name = ""; + + g_log->log_component[SCTP].name = "SCTP"; + g_log->log_component[SCTP].level = LOG_EMERG; + g_log->log_component[SCTP].flag = LOG_MED; + g_log->log_component[SCTP].interval = 1; + g_log->log_component[SCTP].fd = 0; + g_log->log_component[SCTP].filelog = 0; + g_log->log_component[SCTP].filelog_name = ""; + + g_log->log_component[RRH].name = "RRH"; + g_log->log_component[RRH].level = LOG_EMERG; + g_log->log_component[RRH].flag = LOG_MED; + g_log->log_component[RRH].interval = 1; + g_log->log_component[RRH].fd = 0; + g_log->log_component[RRH].filelog = 0; + g_log->log_component[RRH].filelog_name = ""; + + g_log->level2string[LOG_EMERG] = "G"; //EMERG + g_log->level2string[LOG_ALERT] = "A"; // ALERT + g_log->level2string[LOG_CRIT] = "C"; // CRITIC + g_log->level2string[LOG_ERR] = "E"; // ERROR + g_log->level2string[LOG_WARNING] = "W"; // WARNING + g_log->level2string[LOG_NOTICE] = "N"; // NOTICE + g_log->level2string[LOG_INFO] = "I"; //INFO + g_log->level2string[LOG_DEBUG] = "D"; // DEBUG + g_log->level2string[LOG_FILE] = "F"; // file + g_log->level2string[LOG_TRACE] = "T"; // TRACE + + g_log->onlinelog = 1; //online log file + g_log->syslog = 0; + g_log->filelog = 0; + g_log->level = LOG_TRACE; + g_log->flag = LOG_LOW; + + g_log->config.remote_ip = 0; + g_log->config.remote_level = LOG_EMERG; + g_log->config.facility = LOG_LOCAL7; + g_log->config.audit_ip = 0; + g_log->config.audit_facility = LOG_LOCAL6; + g_log->config.format = 0x00; // online debug inactive + + g_log->filelog_name = "/tmp/openair.log"; + + if (g_log->syslog) { +#if ! defined(CN_BUILD) + openlog(g_log->log_component[EMU].name, LOG_PID, g_log->config.facility); +#endif // ! defined(CN_BUILD) + } + log_getconfig(g_log); + if (g_log->filelog) { + gfd = open(g_log->filelog_name, O_WRONLY | O_CREAT, 0666); + } + + // could put a loop here to check for all comps + for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + if (g_log->log_component[i].filelog == 1 ) { + g_log->log_component[i].fd = open(g_log->log_component[i].filelog_name, + O_WRONLY | O_CREAT | O_APPEND, 0666); + } + } + + printf("log init done\n"); + + return 0; +} + +void nfapi_log(char *file, char *func, int line, int comp, int level, const char* format, va_list args) +{ + //logRecord_mt(file,func,line, pthread_self(), comp, level, format, ##args) + int len = 0; + log_component_t *c; + char *log_start; + char *log_end; + /* The main difference with the version above is the use of this local log_buffer. + * The other difference is the return value of snprintf which was not used + * correctly. It was not a big problem because in practice MAX_LOG_TOTAL is + * big enough so that the buffer is never full. + */ + char log_buffer[MAX_LOG_TOTAL]; + + /* for no gcc warnings */ + (void)log_start; + (void)log_end; + + c = &g_log->log_component[comp]; + + // do not apply filtering for LOG_F + // only log messages which are enabled and are below the global log level and component's level threshold + if ((level != LOG_FILE) && ((level > c->level) || (level > g_log->level))) { + /* if ((level != LOG_FILE) && + ((level > c->level) || + (level > g_log->level) || + ( c->level > g_log->level))) { + */ + return; + } + + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, VCD_FUNCTION_IN); + + // adjust syslog level for TRACE messages + if (g_log->syslog) { + if (g_log->level > LOG_DEBUG) { + g_log->level = LOG_DEBUG; + } + } + + // make sure that for log trace the extra info is only printed once, reset when the level changes + if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level == LOG_TRACE)) { + log_start = log_buffer; + len = vsnprintf(log_buffer, MAX_LOG_TOTAL, format, args); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + log_end = log_buffer + len; + } else { + if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", + log_level_highlight_start[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + log_start = log_buffer + len; + + if ( (g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", + g_log->log_component[comp].name); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", + g_log->level2string[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_THREAD) || (c->flag & FLAG_THREAD) ) { +# define THREAD_NAME_LEN 128 + char threadname[THREAD_NAME_LEN]; + if (pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN) != 0) + { + perror("pthread_getname_np : "); + } else { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", threadname); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } +# undef THREAD_NAME_LEN + } + + if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ", + func); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]", + file, line); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + //len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%08lx]", thread_id); + //if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + + len += vsnprintf(&log_buffer[len], MAX_LOG_TOTAL - len, format, args); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + log_end = log_buffer + len; + + if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", + log_level_highlight_end[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + } + + va_end(args); + + // OAI printf compatibility + if ((g_log->onlinelog == 1) && (level != LOG_FILE)) +#ifdef RTAI + if (len > MAX_LOG_TOTAL) { + rt_printk ("[OPENAIR] FIFO_PRINTF WROTE OUTSIDE ITS MEMORY BOUNDARY : ERRORS WILL OCCUR\n"); + } + + if (len > 0) { + rtf_put (FIFO_PRINTF_NO, log_buffer, len); + } + +#else + fwrite(log_buffer, len, 1, stdout); +#endif + +#ifndef RTAI + + if (g_log->syslog) { + syslog(g_log->level, "%s", log_buffer); + } + + if (g_log->filelog) { + if (write(gfd, log_buffer, len) < len) { + // TODO assert ? + } + } + + if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { + if (write(g_log->log_component[comp].fd, log_buffer, len) < len) { + // TODO assert ? + } + } + +#else + + // online print messges + if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { + printf(log_buffer); + } + +#endif + +#if defined(ENABLE_ITTI) + + if (level <= LOG_DEBUG) { + task_id_t origin_task_id = TASK_UNKNOWN; + MessagesIds messages_id; + MessageDef *message_p; + size_t message_string_size; + char *message_msg_p; + + message_string_size = log_end - log_start; + +#if !defined(DISABLE_ITTI_DETECT_SUB_TASK_ID) + + /* Try to identify sub task ID from log information (comp, log_instance_type) */ + switch (comp) { + case PHY: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_PHY_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_PHY_UE; + break; + + default: + break; + } + + break; + + case MAC: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_MAC_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_MAC_UE; + + default: + break; + } + + break; + + case RLC: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_RLC_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_RLC_UE; + + default: + break; + } + + break; + + case PDCP: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_PDCP_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_PDCP_UE; + + default: + break; + } + + break; + + default: + break; + } + +#endif + + switch (level) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + messages_id = ERROR_LOG; + break; + + case LOG_WARNING: + messages_id = WARNING_LOG; + break; + + case LOG_NOTICE: + messages_id = NOTICE_LOG; + break; + + case LOG_INFO: + messages_id = INFO_LOG; + break; + + default: + messages_id = DEBUG_LOG; + break; + } + + message_p = itti_alloc_new_message_sized(origin_task_id, messages_id, message_string_size); + + switch (level) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + message_msg_p = (char *) &message_p->ittiMsg.error_log; + break; + + case LOG_WARNING: + message_msg_p = (char *) &message_p->ittiMsg.warning_log; + break; + + case LOG_NOTICE: + message_msg_p = (char *) &message_p->ittiMsg.notice_log; + break; + + case LOG_INFO: + message_msg_p = (char *) &message_p->ittiMsg.info_log; + break; + + default: + message_msg_p = (char *) &message_p->ittiMsg.debug_log; + break; + } + + memcpy(message_msg_p, log_start, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + } + +#endif +#if 0 + LOG_params log_params; + int len; + + len = vsnprintf(log_params.l_buff_info, MAX_LOG_INFO-1, format, args); + + //2 first parameters must be passed as 'const' to the thread function + log_params.file = strdup(file); + log_params.func = strdup(func); + log_params.line = line; + log_params.comp = PHY;//comp; + log_params.level = 6; // INFO - level; + log_params.format = format; + log_params.len = len; + + if (pthread_mutex_lock(&log_lock) != 0) { + return; + } + + log_list_tail++; + log_list[log_list_tail - 1] = log_params; + + if (log_list_tail >= 1000) { + log_list_tail = 0; + } + + if (log_list_nb_elements < 1000) { + log_list_nb_elements++; + } + + if(pthread_cond_signal(&log_notify) != 0) { + pthread_mutex_unlock(&log_lock); + return; + } + + if(pthread_mutex_unlock(&log_lock) != 0) { + return; + } + +#endif +} + +//log record: add to a list +void logRecord(const char *file, const char *func, int line, int comp, + int level, const char *format, ...) +{ + va_list args; + LOG_params log_params; + int len; + + va_start(args, format); + len = vsnprintf(log_params.l_buff_info, MAX_LOG_INFO-1, format, args); + va_end(args); + + //2 first parameters must be passed as 'const' to the thread function + log_params.file = strdup(file); + log_params.func = strdup(func); + log_params.line = line; + log_params.comp = comp; + log_params.level = level; + log_params.format = format; + log_params.len = len; + + if (pthread_mutex_lock(&log_lock) != 0) { + return; + } + + log_list_tail++; + log_list[log_list_tail - 1] = log_params; + + if (log_list_tail >= 1000) { + log_list_tail = 0; + } + + if (log_list_nb_elements < 1000) { + log_list_nb_elements++; + } + + if(pthread_cond_signal(&log_notify) != 0) { + pthread_mutex_unlock(&log_lock); + return; + } + + if(pthread_mutex_unlock(&log_lock) != 0) { + return; + } + + //log = malloc(sizeof(LOG_elt)); + //log->next = NULL; + //log->log_params = log_params; + /* Add log task to queue */ + //log_list_add_tail_eurecom(log, &log_list); + +} + +void logRecord_thread_safe(const char *file, const char *func, + int line, int comp, int level, + int len, const char *params_string) +{ + log_component_t *c; + int total_len = 0; + char log_buffer[MAX_LOG_TOTAL]; + + c = &g_log->log_component[comp]; + + // do not apply filtering for LOG_F + // only log messages which are enabled and are below the global log level and component's level threshold + if ((level != LOG_FILE) && ((c->level > g_log->level) || + (level > c->level) || (level > g_log->level))) { + return; + } + + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, + VCD_FUNCTION_IN); + + // adjust syslog level for TRACE messages + if (g_log->syslog) { + if (g_log->level > LOG_DEBUG) { + g_log->level = LOG_DEBUG; + } + } + + // make sure that for log trace the extra info is only printed once, reset when the level changes + if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level ==LOG_TRACE )) { + total_len = snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - 1, "%s", + params_string); + } else { + if ((g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR)) { + total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "%s", + log_level_highlight_start[level]); + } + + if ((g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) { + total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s]", + g_log->log_component[comp].name); + } + + if ((g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL)) { + total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s]", + g_log->level2string[level]); + } + + if ((g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT)) { + total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s] ", + func); + } + + if ((g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) { + total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "[%s:%d]", + file, line); + } + + len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - len, "%s", + params_string); + + if ((g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR)) { + total_len += snprintf(&log_buffer[total_len], MAX_LOG_TOTAL - total_len, "%s", + log_level_highlight_end[level]); + } + } + + // OAI printf compatibility + if ((g_log->onlinelog == 1) && (level != LOG_FILE)) { + fprintf(stdout, "%s", log_buffer); + } + + if (g_log->syslog) { + syslog(g_log->level, "%s", log_buffer); + } + + if (g_log->filelog) { + if (write(gfd, log_buffer, total_len) < total_len) { + // TODO assert ? + } + } + + if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { + if (write(g_log->log_component[comp].fd, log_buffer, total_len) < total_len) { + // TODO assert ? + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, + VCD_FUNCTION_OUT); +} + +#if !defined(LOG_NO_THREAD) +void *log_thread_function(void *list) +{ + + LOG_params log_params; + + for(;;) { + + //log_elt = NULL; + + /* Lock must be taken to wait on conditional variable */ + pthread_mutex_lock(&log_lock); + + /* Wait on condition variable, check for spurious wakeups. + When returning from pthread_cond_wait(), we own the lock. */ + + // sleep + while((log_list_nb_elements == 0) && (log_shutdown == 0)) { + pthread_cond_wait(&log_notify, &log_lock); + } + + // exit + if ((log_shutdown==1) && (log_list_nb_elements == 0)) { + break; + } + + /* Grab our task */ + //log_elt = log_list_remove_head(&log_list); + log_params = log_list[log_list_head]; + log_list_head++; + log_list_nb_elements--; + + if (log_list_head >= 1000) { + log_list_head = 0; + } + + + /* Unlock */ + pthread_mutex_unlock(&log_lock); + + /* Get to work */ + logRecord_thread_safe(log_params.file, + log_params.func, + log_params.line, + log_params.comp, + log_params.level, + log_params.len, + log_params.l_buff_info); + + //free(log_elt); + } +} +#endif + +#if 0 +/* This function does not work. When multiple threads call it at the same time + * for the same component, both threads end up using the same buffer. + * The output is the completely messed up/wrong. + * Kept in case the fix below is not correct or acceptable. + */ +//log record, format, and print: executed in the main thread (mt) +void logRecord_mt(const char *file, const char *func, int line, int comp, + int level, const char *format, ...) +{ + int len = 0; + va_list args; + log_component_t *c; + char *log_start; + char *log_end; + + /* for no gcc warnings */ + (void)log_start; + (void)log_end; + + c = &g_log->log_component[comp]; + + // do not apply filtering for LOG_F + // only log messages which are enabled and are below the global log level and component's level threshold + if ((level != LOG_FILE) && ((level > c->level) || (level > g_log->level))) { + /* if ((level != LOG_FILE) && + ((level > c->level) || + (level > g_log->level) || + ( c->level > g_log->level))) { + */ + return; + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, + VCD_FUNCTION_IN); + + va_start(args, format); + + // adjust syslog level for TRACE messages + if (g_log->syslog) { + if (g_log->level > LOG_DEBUG) { + g_log->level = LOG_DEBUG; + } + } + + // make sure that for log trace the extra info is only printed once, reset when the level changes + if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level == LOG_TRACE)) { + log_start = c->log_buffer; + len = vsnprintf(c->log_buffer, MAX_LOG_TOTAL-1, format, args); + log_end = c->log_buffer + len; + } else { + if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { + len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "%s", + log_level_highlight_start[level]); + } + + log_start = c->log_buffer + len; + + if ( (g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) { + len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", + g_log->log_component[comp].name); + } + + if ( (g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL) ) { + len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", + g_log->level2string[level]); + } + + if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) { + len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ", + func); + } + + if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) { + len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]", + file, line); + } + + len += vsnprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, format, args); + log_end = c->log_buffer + len; + + if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { + len += snprintf(&c->log_buffer[len], MAX_LOG_TOTAL - len, "%s", + log_level_highlight_end[level]); + } + } + + va_end(args); + + // OAI printf compatibility + if ((g_log->onlinelog == 1) && (level != LOG_FILE)) + fwrite(c->log_buffer, len, 1, stdout); + + if (g_log->syslog) { + syslog(g_log->level, "%s", c->log_buffer); + } + + if (g_log->filelog) { + if (write(gfd, c->log_buffer, len) < len) { + // TODO assert ? + } + } + + if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { + if (write(g_log->log_component[comp].fd, c->log_buffer, len) < len) { + // TODO assert ? + } + } + +#if defined(ENABLE_ITTI) + + if (level <= LOG_DEBUG) { + task_id_t origin_task_id = TASK_UNKNOWN; + MessagesIds messages_id; + MessageDef *message_p; + size_t message_string_size; + char *message_msg_p; + + message_string_size = log_end - log_start; + +#if !defined(DISABLE_ITTI_DETECT_SUB_TASK_ID) + + /* Try to identify sub task ID from log information (comp, log_instance_type) */ + switch (comp) { + case PHY: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_PHY_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_PHY_UE; + break; + + default: + break; + } + + break; + + case MAC: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_MAC_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_MAC_UE; + + default: + break; + } + + break; + + case RLC: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_RLC_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_RLC_UE; + + default: + break; + } + + break; + + case PDCP: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_PDCP_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_PDCP_UE; + + default: + break; + } + + break; + + default: + break; + } + +#endif + + switch (level) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + messages_id = ERROR_LOG; + break; + + case LOG_WARNING: + messages_id = WARNING_LOG; + break; + + case LOG_NOTICE: + messages_id = NOTICE_LOG; + break; + + case LOG_INFO: + messages_id = INFO_LOG; + break; + + default: + messages_id = DEBUG_LOG; + break; + } + + message_p = itti_alloc_new_message_sized(origin_task_id, messages_id, message_string_size); + + switch (level) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + message_msg_p = (char *) &message_p->ittiMsg.error_log; + break; + + case LOG_WARNING: + message_msg_p = (char *) &message_p->ittiMsg.warning_log; + break; + + case LOG_NOTICE: + message_msg_p = (char *) &message_p->ittiMsg.notice_log; + break; + + case LOG_INFO: + message_msg_p = (char *) &message_p->ittiMsg.info_log; + break; + + default: + message_msg_p = (char *) &message_p->ittiMsg.debug_log; + break; + } + + memcpy(message_msg_p, log_start, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + } + +#endif + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, + VCD_FUNCTION_OUT); +} +#endif /* #if 0 */ + +//log record, format, and print: executed in the main thread (mt) +void logRecord_mt(const char *file, const char *func, int line, int comp, + int level, const char *format, ...) +{ + int len = 0; + va_list args; + log_component_t *c; + char *log_start; + char *log_end; + /* The main difference with the version above is the use of this local log_buffer. + * The other difference is the return value of snprintf which was not used + * correctly. It was not a big problem because in practice MAX_LOG_TOTAL is + * big enough so that the buffer is never full. + */ + char log_buffer[MAX_LOG_TOTAL]; + + /* for no gcc warnings */ + (void)log_start; + (void)log_end; + + c = &g_log->log_component[comp]; + + // do not apply filtering for LOG_F + // only log messages which are enabled and are below the global log level and component's level threshold + if ((level != LOG_FILE) && ((level > c->level) || (level > g_log->level))) { + /* if ((level != LOG_FILE) && + ((level > c->level) || + (level > g_log->level) || + ( c->level > g_log->level))) { + */ + return; + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, + VCD_FUNCTION_IN); + + va_start(args, format); + + // adjust syslog level for TRACE messages + if (g_log->syslog) { + if (g_log->level > LOG_DEBUG) { + g_log->level = LOG_DEBUG; + } + } + + // make sure that for log trace the extra info is only printed once, reset when the level changes + if ((level == LOG_FILE) || (c->flag == LOG_NONE) || (level == LOG_TRACE)) { + log_start = log_buffer; + len = vsnprintf(log_buffer, MAX_LOG_TOTAL, format, args); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + log_end = log_buffer + len; + } else { + if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", + log_level_highlight_start[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + log_start = log_buffer + len; + + if ( (g_log->flag & FLAG_COMP) || (c->flag & FLAG_COMP) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", + g_log->log_component[comp].name); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_LEVEL) || (c->flag & FLAG_LEVEL) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", + g_log->level2string[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_THREAD) || (c->flag & FLAG_THREAD) ) { +# define THREAD_NAME_LEN 128 + char threadname[THREAD_NAME_LEN]; + if (pthread_getname_np(pthread_self(), threadname, THREAD_NAME_LEN) != 0) + { + perror("pthread_getname_np : "); + } else { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s]", threadname); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } +# undef THREAD_NAME_LEN + } + + if ( (g_log->flag & FLAG_FUNCT) || (c->flag & FLAG_FUNCT) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s] ", + func); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + if ( (g_log->flag & FLAG_FILE_LINE) || (c->flag & FLAG_FILE_LINE) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%s:%d]", + file, line); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + + len += vsnprintf(&log_buffer[len], MAX_LOG_TOTAL - len, format, args); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + log_end = log_buffer + len; + + if ( (g_log->flag & FLAG_COLOR) || (c->flag & FLAG_COLOR) ) { + len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s", + log_level_highlight_end[level]); + if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL; + } + } + + va_end(args); + + // OAI printf compatibility + if ((g_log->onlinelog == 1) && (level != LOG_FILE)) + fwrite(log_buffer, len, 1, stdout); + + if (g_log->syslog) { + syslog(g_log->level, "%s", log_buffer); + } + + if (g_log->filelog) { + if (write(gfd, log_buffer, len) < len) { + // TODO assert ? + } + } + + if ((g_log->log_component[comp].filelog) && (level == LOG_FILE)) { + if (write(g_log->log_component[comp].fd, log_buffer, len) < len) { + // TODO assert ? + } + } + +#if defined(ENABLE_ITTI) + + if (level <= LOG_DEBUG) { + task_id_t origin_task_id = TASK_UNKNOWN; + MessagesIds messages_id; + MessageDef *message_p; + size_t message_string_size; + char *message_msg_p; + + message_string_size = log_end - log_start; + +#if !defined(DISABLE_ITTI_DETECT_SUB_TASK_ID) + + /* Try to identify sub task ID from log information (comp, log_instance_type) */ + switch (comp) { + case PHY: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_PHY_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_PHY_UE; + break; + + default: + break; + } + + break; + + case MAC: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_MAC_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_MAC_UE; + + default: + break; + } + + break; + + case RLC: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_RLC_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_RLC_UE; + + default: + break; + } + + break; + + case PDCP: + switch (log_instance_type) { + case LOG_INSTANCE_ENB: + origin_task_id = TASK_PDCP_ENB; + break; + + case LOG_INSTANCE_UE: + origin_task_id = TASK_PDCP_UE; + + default: + break; + } + + break; + + default: + break; + } + +#endif + + switch (level) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + messages_id = ERROR_LOG; + break; + + case LOG_WARNING: + messages_id = WARNING_LOG; + break; + + case LOG_NOTICE: + messages_id = NOTICE_LOG; + break; + + case LOG_INFO: + messages_id = INFO_LOG; + break; + + default: + messages_id = DEBUG_LOG; + break; + } + + message_p = itti_alloc_new_message_sized(origin_task_id, messages_id, message_string_size); + + switch (level) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + message_msg_p = (char *) &message_p->ittiMsg.error_log; + break; + + case LOG_WARNING: + message_msg_p = (char *) &message_p->ittiMsg.warning_log; + break; + + case LOG_NOTICE: + message_msg_p = (char *) &message_p->ittiMsg.notice_log; + break; + + case LOG_INFO: + message_msg_p = (char *) &message_p->ittiMsg.info_log; + break; + + default: + message_msg_p = (char *) &message_p->ittiMsg.debug_log; + break; + } + + memcpy(message_msg_p, log_start, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + } + +#endif + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, + VCD_FUNCTION_OUT); +} + +int set_log(int component, int level, int interval) +{ + /* Checking parameters */ + DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS), + component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); + DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE, + LOG_EMERG); + DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); + + g_log->log_component[component].level = level; + + switch (level) { + case LOG_TRACE: + g_log->log_component[component].flag = LOG_MED ; + break; + + case LOG_DEBUG: + g_log->log_component[component].flag = LOG_MED ; + break; + + case LOG_INFO: + g_log->log_component[component].flag = LOG_LOW ; + break; + + default: + g_log->log_component[component].flag = LOG_NONE ; + break; + } + + g_log->log_component[component].interval = interval; + + return 0; +} + +int set_comp_log(int component, int level, int verbosity, int interval) +{ + /* Checking parameters */ + DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS), + component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); + DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE, + LOG_EMERG); + DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); + +#if 0 + if ((verbosity == LOG_NONE) || (verbosity == LOG_LOW) || + (verbosity == LOG_MED) || (verbosity == LOG_FULL) || + (verbosity == LOG_HIGH)) { + g_log->log_component[component].flag = verbosity; + } +#else + g_log->log_component[component].flag = verbosity; +#endif + + g_log->log_component[component].level = level; + g_log->log_component[component].interval = interval; + + return 0; +} + +void set_glog(int level, int verbosity) +{ + if( g_log->level >= 0) g_log->level = level; + if( g_log->flag >= 0) g_log->flag = verbosity; +} +void set_glog_syslog(int enable) +{ + g_log->syslog = enable; +} +void set_glog_onlinelog(int enable) +{ + g_log->onlinelog = enable; +} +void set_glog_filelog(int enable) +{ + g_log->filelog = enable; +} + +void set_component_filelog(int comp) +{ + if (g_log->log_component[comp].filelog == 0) { + g_log->log_component[comp].filelog = 1; + + if (g_log->log_component[comp].fd == 0) { + g_log->log_component[comp].fd = open(g_log->log_component[comp].filelog_name, + O_WRONLY | O_CREAT | O_TRUNC, 0666); + } + } +} + +/* + * for the two functions below, the passed array must have a final entry + * with string value NULL + */ +/* map a string to an int. Takes a mapping array and a string as arg */ +int map_str_to_int(mapping *map, const char *str) +{ + while (1) { + if (map->name == NULL) { + return(-1); + } + + if (!strcmp(map->name, str)) { + return(map->value); + } + + map++; + } +} + +/* map an int to a string. Takes a mapping array and a value */ +char *map_int_to_str(mapping *map, int val) +{ + while (1) { + if (map->name == NULL) { + return NULL; + } + + if (map->value == val) { + return map->name; + } + + map++; + } +} + +int is_newline( char *str, int size) +{ + int i; + + for ( i = 0; i < size; i++ ) { + if ( str[i] == '\n' ) { + return 1; + } + } + + /* if we get all the way to here, there must not have been a newline! */ + return 0; +} + +void logClean (void) +{ + int i; + + if (g_log->syslog) { + closelog(); + } + + if (g_log->filelog) { + close(gfd); + } + + for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + if (g_log->log_component[i].filelog) { + close(g_log->log_component[i].fd); + } + } +} + +#if defined(ENABLE_ITTI) +void log_set_instance_type (log_instance_type_t instance) +{ + log_instance_type = instance; +} +#endif + +#ifdef LOG_TEST + +int main(int argc, char *argv[]) +{ + + logInit(); + + //set_log_syslog(1); + test_log(); + + return 1; +} + +int test_log(void) +{ + LOG_ENTER(MAC); // because the default level is DEBUG + LOG_I(EMU, "1 Starting OAI logs version %s Build date: %s on %s\n", + BUILD_VERSION, BUILD_DATE, BUILD_HOST); + LOG_D(MAC, "1 debug MAC \n"); + LOG_N(MAC, "1 notice MAC \n"); + LOG_W(MAC, "1 warning MAC \n"); + + set_comp_log(EMU, LOG_INFO, FLAG_ONLINE); + set_comp_log(MAC, LOG_WARNING, 0); + + LOG_I(EMU, "2 Starting OAI logs version %s Build date: %s on %s\n", + BUILD_VERSION, BUILD_DATE, BUILD_HOST); + LOG_E(MAC, "2 emerge MAC\n"); + LOG_D(MAC, "2 debug MAC \n"); + LOG_N(MAC, "2 notice MAC \n"); + LOG_W(MAC, "2 warning MAC \n"); + LOG_I(MAC, "2 info MAC \n"); + + + set_comp_log(MAC, LOG_NOTICE, 1); + + LOG_ENTER(MAC); + LOG_I(EMU, "3 Starting OAI logs version %s Build date: %s on %s\n", + BUILD_VERSION, BUILD_DATE, BUILD_HOST); + LOG_D(MAC, "3 debug MAC \n"); + LOG_N(MAC, "3 notice MAC \n"); + LOG_W(MAC, "3 warning MAC \n"); + LOG_I(MAC, "3 info MAC \n"); + + set_comp_log(MAC, LOG_DEBUG,1); + set_comp_log(EMU, LOG_DEBUG,1); + + LOG_ENTER(MAC); + LOG_I(EMU, "4 Starting OAI logs version %s Build date: %s on %s\n", + BUILD_VERSION, BUILD_DATE, BUILD_HOST); + LOG_D(MAC, "4 debug MAC \n"); + LOG_N(MAC, "4 notice MAC \n"); + LOG_W(MAC, "4 warning MAC \n"); + LOG_I(MAC, "4 info MAC \n"); + + + set_comp_log(MAC, LOG_DEBUG,0); + set_comp_log(EMU, LOG_DEBUG,0); + + LOG_I(LOG, "5 Starting OAI logs version %s Build date: %s on %s\n", + BUILD_VERSION, BUILD_DATE, BUILD_HOST); + LOG_D(MAC, "5 debug MAC \n"); + LOG_N(MAC, "5 notice MAC \n"); + LOG_W(MAC, "5 warning MAC \n"); + LOG_I(MAC, "5 info MAC \n"); + + + set_comp_log(MAC, LOG_TRACE,0X07F); + set_comp_log(EMU, LOG_TRACE,0X07F); + + LOG_ENTER(MAC); + LOG_I(LOG, "6 Starting OAI logs version %s Build date: %s on %s\n", + BUILD_VERSION, BUILD_DATE, BUILD_HOST); + LOG_D(MAC, "6 debug MAC \n"); + LOG_N(MAC, "6 notice MAC \n"); + LOG_W(MAC, "6 warning MAC \n"); + LOG_I(MAC, "6 info MAC \n"); + LOG_EXIT(MAC); + + return 0; +} +#endif diff --git a/openair2/UTIL/MATH/taus.c b/openair2/UTIL/MATH/taus.c index 632b1544dd0970b484fbe0a2ef4d585cae550604..6f1b2214e51b92ec07cbc21d9699664077f40633 100644 --- a/openair2/UTIL/MATH/taus.c +++ b/openair2/UTIL/MATH/taus.c @@ -41,9 +41,7 @@ unsigned int s0[MAX_NUM_COMPS], s1[MAX_NUM_COMPS], s2[MAX_NUM_COMPS], b[MAX_NUM_ -inline unsigned int taus(unsigned int comp) -{ - +inline unsigned int taus(unsigned int comp) { b[comp] = (((s0[comp] << 13) ^ s0[comp]) >> 19); s0[comp] = (((s0[comp] & 0xFFFFFFFE) << 12)^ b[comp]); b[comp] = (((s1[comp] << 2) ^ s1[comp]) >> 25); @@ -54,42 +52,36 @@ inline unsigned int taus(unsigned int comp) return r[comp]; } -void set_taus_seed(unsigned int seed_type) -{ - +void set_taus_seed(unsigned int seed_type) { unsigned int i; // i index of component for (i=MIN_NUM_COMPS; i < MAX_NUM_COMPS ; i ++) { - switch (seed_type) { - case 0: // use rand func - if (i == 0) srand(time(NULL)); - - s0[i] = ((unsigned int)rand()); - s1[i] = ((unsigned int)rand()); - s2[i] = ((unsigned int)rand()); - printf("Initial seeds use rand: s0[%d] = 0x%x, s1[%d] = 0x%x, s2[%d] = 0x%x\n", i, s0[i], i, s1[i], i, s2[i]); - break; - - case 1: // use rand with seed - if (i == 0) srand(0x1e23d851); - - s0[i] = ((unsigned int)rand()); - s1[i] = ((unsigned int)rand()); - s2[i] = ((unsigned int)rand()); - printf("Initial seeds use rand with seed : s0[%d] = 0x%x, s1[%d] = 0x%x, s2[%d] = 0x%x\n", i, s0[i], i, s1[i], i, s2[i]); - - break; - - default: - break; - + case 0: // use rand func + if (i == 0) srand(time(NULL)); + + s0[i] = ((unsigned int)rand()); + s1[i] = ((unsigned int)rand()); + s2[i] = ((unsigned int)rand()); + printf("Initial seeds use rand: s0[%u] = 0x%x, s1[%u] = 0x%x, s2[%u] = 0x%x\n", i, s0[i], i, s1[i], i, s2[i]); + break; + + case 1: // use rand with seed + if (i == 0) srand(0x1e23d851); + + s0[i] = ((unsigned int)rand()); + s1[i] = ((unsigned int)rand()); + s2[i] = ((unsigned int)rand()); + printf("Initial seeds use rand with seed : s0[%u] = 0x%x, s1[%u] = 0x%x, s2[%u] = 0x%x\n", i, s0[i], i, s1[i], i, s2[i]); + break; + + default: + break; } } } -int get_rand (unsigned int comp) -{ +int get_rand (unsigned int comp) { if ((comp > MIN_NUM_COMPS) && (comp < MAX_NUM_COMPS)) return r[comp]; else { @@ -98,9 +90,7 @@ int get_rand (unsigned int comp) } } -unsigned int dtaus(unsigned int comp, unsigned int a, unsigned b) -{ - +unsigned int dtaus(unsigned int comp, unsigned int a, unsigned b) { return (int) (((double)taus(comp)/(double)0xffffffff)* (double)(b-a) + (double)a); } /* diff --git a/openair2/UTIL/MEM/mem_block.h b/openair2/UTIL/MEM/mem_block.h index 18ded1a5990da3297c9abde96dc8615443fe329c..4d8ed4e89bc9e881ca0a6a346a3f2d97f36e0b61 100644 --- a/openair2/UTIL/MEM/mem_block.h +++ b/openair2/UTIL/MEM/mem_block.h @@ -130,6 +130,8 @@ void check_free_mem_block (mem_block_t * leP); # define MEM_MNGT_MB12_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*4096 // 262144 # define MEM_MNGT_MB12_NB_BLOCKS 32 * MEM_SCALE +//# define MEM_MNGT_MB12_NB_BLOCKS 4096 * MEM_SCALE + # define MEM_MNGT_POOL_ID12 12 diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h index 0495b139ce363e548346c83d9d22213ea32647e3..34190f7d15839e2a0c3a83e9bcc9d501fbf7fb25 100644 --- a/openair2/UTIL/OCG/OCG.h +++ b/openair2/UTIL/OCG/OCG.h @@ -39,10 +39,8 @@ #include "PHY/defs_common.h" #include "PHY/impl_defs_top.h" #include "platform_types.h" - -#if defined(ENABLE_USE_MME) # include "s1ap_eNB.h" -#endif + #ifdef __cplusplus extern "C" @@ -135,8 +133,7 @@ The following diagram is based on graphviz (http://www.graphviz.org/), you need * \enddot */ -enum -{ +enum { STATE_START_OCG, /*!< \brief initiate OCG */ STATE_GET_OPT, /*!< \brief get options of OCG command */ STATE_DETECT_FILE, /*!< \brief detect the configuration file in folder USER_XML_FOLDER */ @@ -571,7 +568,7 @@ typedef struct { } Layer; typedef struct { - char * level; + char *level; char *verbosity; int interval; } Log_Emu; @@ -598,8 +595,8 @@ typedef struct { Log_Emu log_emu; Packet_Trace packet_trace; Seed seed; - char * curve; - char * background_stats; + char *curve; + char *background_stats; // CLI tags are in Info //char g_log_level[20]; } Emulation_Config; @@ -677,7 +674,7 @@ typedef struct { unsigned char cba_group_active; unsigned char cba_backoff; unsigned char handover_active; - char * otg_traffic; + char *otg_traffic; unsigned char otg_bg_traffic_enabled; unsigned char omg_model_rn; unsigned char omg_model_enb; @@ -705,7 +702,7 @@ typedef struct { node_function_t node_function[MAX_NUM_CCs]; node_timing_t node_timing[MAX_NUM_CCs]; unsigned char frame_type[MAX_NUM_CCs]; //! LTE frame type (TDD=1, FDD=0). \note this should be converted to \ref lte_frame_type_t (header file reorganization needed) - char * frame_type_name[MAX_NUM_CCs]; + char *frame_type_name[MAX_NUM_CCs]; unsigned char tdd_config[MAX_NUM_CCs]; unsigned char tdd_config_S[MAX_NUM_CCs]; unsigned char extended_prefix_flag[MAX_NUM_CCs]; @@ -713,10 +710,7 @@ typedef struct { unsigned char transmission_mode[MAX_NUM_CCs]; int max_predefined_traffic_config_index; int max_customized_traffic_config_index; - -#if defined(ENABLE_USE_MME) s1ap_eNB_config_t s1ap_config; -#endif /* Per-Slot ISR * Interval between two ISR = 500usec diff --git a/openair2/UTIL/OCG/OCG_config_mobi.c b/openair2/UTIL/OCG/OCG_config_mobi.c index cef4c5543b0705f90c9122c0ec6e69dd8d208417..b3100a421463dbc6bc8d3c1e7222c7166b2907cb 100644 --- a/openair2/UTIL/OCG/OCG_config_mobi.c +++ b/openair2/UTIL/OCG/OCG_config_mobi.c @@ -39,84 +39,60 @@ #include "OCG_config_mobi.h" /*----------------------------------------------------------------------------*/ -int config_mobi(char mobigen_filename[FILENAME_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX]) -{ +int config_mobi(char mobigen_filename[FILENAME_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX]) { // for the xml writer, refer to http://xmlsoft.org/html/libxml-xmlwriter.html - - char dir_to_mobigen_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX] = ""; + char dir_to_mobigen_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX]; char mobi_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX] = ""; xmlTextWriterPtr writer; - strcpy(dir_to_mobigen_file, DIR_TO_MOBIGEN); strcat(dir_to_mobigen_file, mobigen_filename); /* Create a new XmlWriter for uri, with no compression. */ writer = xmlNewTextWriterFilename(dir_to_mobigen_file, 0); - // set the output format of the XML file xmlTextWriterSetIndent(writer, 1); xmlTextWriterSetIndentString(writer, " "); - /* Start the document with the xml default for the version, * encoding ISO 8859-1 and the default for the standalone * declaration. */ xmlTextWriterStartDocument(writer, NULL, NULL, NULL); - /* Start an element named "EXAMPLE". Since this is the first * element, this will be the root element of the document. */ xmlTextWriterStartElement(writer, "universe"); - /* Write an element named "X_ORDER_ID" as child of HEADER. */ xmlTextWriterWriteFormatElement(writer, "dimx", "%lf", oai_emulation.topo_config.area.x); - /* Write an element named "X_ORDER_ID" as child of HEADER. */ xmlTextWriterWriteFormatElement(writer, "dimy", "%lf", oai_emulation.topo_config.area.y); - xmlTextWriterWriteFormatElement(writer, "seed", "%d", 1); - xmlTextWriterStartElement(writer, "extension"); xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.mobisim.simulations.TimeSimulation"); xmlTextWriterWriteFormatAttribute(writer, "param", "%lf", oai_emulation.emu_config.emu_time); xmlTextWriterEndElement(writer); - xmlTextWriterStartElement(writer, "extension"); xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.spatialmodel.core.SpatialModel"); xmlTextWriterWriteFormatAttribute(writer, "max_x", "%lf", oai_emulation.topo_config.area.x); xmlTextWriterWriteFormatAttribute(writer, "max_y", "%lf", oai_emulation.topo_config.area.y); xmlTextWriterWriteAttribute(writer, "min_x", "0"); xmlTextWriterWriteAttribute(writer, "min_y", "0"); - xmlTextWriterWriteFormatElement(writer, "dump_boundary_points", "%s", "false"); - xmlTextWriterWriteFormatElement(writer, "separated_flow", "%s", "false"); - xmlTextWriterWriteFormatElement(writer, "max_traffic_lights", "%d", 500); - xmlTextWriterEndElement(writer); - xmlTextWriterStartElement(writer, "extension"); xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.mobisim.extensions.ReportNodeMobility"); - strcpy(mobi_file, MOBI_XML_FOLDER); strcat(mobi_file, filename); xmlTextWriterWriteAttribute(writer, "output", mobi_file); - xmlTextWriterWriteFormatElement(writer, "step", "%d", 1); - xmlTextWriterEndElement(writer); - xmlTextWriterStartElement(writer, "nodegroup"); xmlTextWriterWriteAttribute(writer, "car2x", "false"); xmlTextWriterWriteAttribute(writer, "id", ""); xmlTextWriterWriteAttribute(writer, "n", "50"); xmlTextWriterWriteAttribute(writer, "type", "car"); - xmlTextWriterStartElement(writer, "position"); xmlTextWriterWriteAttribute(writer, "random", "true"); - xmlTextWriterWriteFormatElement(writer, "z", "%s", "0.0"); - xmlTextWriterEndElement(writer); - xmlTextWriterStartElement(writer, "extension"); xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.mobisim.mobilitymodels.RandomWaypointWalk"); @@ -134,12 +110,8 @@ int config_mobi(char mobigen_filename[FILENAME_LENGTH_MAX], char filename[FILENA // Close the element named HEADER. xmlTextWriterEndElement(writer); - - xmlTextWriterEndDocument(writer); - xmlFreeTextWriter(writer); - return MODULE_OK; } diff --git a/openair2/UTIL/OCG/OCG_generate_report.c b/openair2/UTIL/OCG/OCG_generate_report.c index fa1ed191e62afa1cc9fa7cb1d9b8a5f38ac9dcc6..a48b3a7af7583bf46628dfe5053364ca65886dd8 100644 --- a/openair2/UTIL/OCG/OCG_generate_report.c +++ b/openair2/UTIL/OCG/OCG_generate_report.c @@ -42,39 +42,29 @@ /*----------------------------------------------------------------------------*/ -int generate_report(char dst_dir[DIR_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX]) -{ +int generate_report(char dst_dir[DIR_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX]) { // for the xml writer, refer to http://xmlsoft.org/html/libxml-xmlwriter.html - - char dst_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX] = ""; - strncat(dst_file, dst_dir, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(dst_file) - 1); - strncat(dst_file, filename, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(dst_file) - 1); - + char dst_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX]; + strncpy(dst_file, dst_dir, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(filename) - 1); + strcat(dst_file, filename); xmlTextWriterPtr writer; - writer = xmlNewTextWriterFilename(dst_file, 0); - // set the output format of the XML file xmlTextWriterSetIndent(writer, 1); - xmlTextWriterSetIndentString(writer,(unsigned char*) " "); - + xmlTextWriterSetIndentString(writer,(unsigned char *) " "); xmlTextWriterStartDocument(writer, NULL, NULL, NULL); - /* Write an element named "X_ORDER_ID" as child of HEADER. */ - xmlTextWriterWriteFormatElement(writer,(unsigned char*) "COMMENT ", " in this output file, %d means NOT_PROCESSED; %d means NO_FILE; %d means ERROR; %d means OK ", MODULE_NOT_PROCESSED, + xmlTextWriterWriteFormatElement(writer,(unsigned char *) "COMMENT ", " in this output file, %d means NOT_PROCESSED; %d means NO_FILE; %d means ERROR; %d means OK ", MODULE_NOT_PROCESSED, NO_FILE, MODULE_ERROR, MODULE_OK); - xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_GET_OPT ", " %d ", get_opt_OK); - xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_DETECT_FILE ", " %d ", detect_file_OK); - xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_PARSE_FILENAME", " %d ", parse_filename_OK); - xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_CREATE_DIR ", " %d ", create_dir_OK); - xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_PARSE_XML ", " %d ", parse_XML_OK); - xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_SAVE_XML ", " %d ", save_XML_OK); + xmlTextWriterWriteFormatElement(writer,(unsigned char *) "OCG_GET_OPT ", " %d ", get_opt_OK); + xmlTextWriterWriteFormatElement(writer,(unsigned char *) "OCG_DETECT_FILE ", " %d ", detect_file_OK); + xmlTextWriterWriteFormatElement(writer,(unsigned char *) "OCG_PARSE_FILENAME", " %d ", parse_filename_OK); + xmlTextWriterWriteFormatElement(writer,(unsigned char *) "OCG_CREATE_DIR ", " %d ", create_dir_OK); + xmlTextWriterWriteFormatElement(writer,(unsigned char *) "OCG_PARSE_XML ", " %d ", parse_XML_OK); + xmlTextWriterWriteFormatElement(writer,(unsigned char *) "OCG_SAVE_XML ", " %d ", save_XML_OK); // xmlTextWriterWriteFormatElement(writer, "OCG_CALL_EMU ", " %d ", call_emu_OK); - xmlTextWriterEndDocument(writer); - xmlFreeTextWriter(writer); - LOG_I(OCG, "A report of OCG is generated in directory \"%s\"\n\n", dst_dir); return MODULE_OK; } diff --git a/openair2/UTIL/OMG/omg.c b/openair2/UTIL/OMG/omg.c index 6a1ada01568b1d079b69f1e05264de868ff00fff..f13da86c9f7395f6d2076aa9325ae3f535239ac4 100644 --- a/openair2/UTIL/OMG/omg.c +++ b/openair2/UTIL/OMG/omg.c @@ -46,21 +46,20 @@ #include "grid.h" #include "steadystaterwp.h" #ifdef SUMO_IF -#include "sumo.h" -#endif + #include "sumo.h" +#endif #include "../OMV/structures.h" //#define STANDALONE float n_frames = 20.0; -int omv_write (int pfd, node_list * ue_node_list, Data_Flow_Unit omv_data); +int omv_write (int pfd, node_list *ue_node_list, Data_Flow_Unit omv_data); void omv_end (int pfd, Data_Flow_Unit omv_data); int omv_enabled; /*initialze global parameters*/ void -init_omg_global_params (void) -{ +init_omg_global_params (void) { int mob_t, node_t, i; xloc_div = 10.0; yloc_div = 10.0; @@ -86,92 +85,86 @@ init_omg_global_params (void) /*initiate mobility generator*/ void -init_mobility_generator (omg_global_param omg_param_list[]) -{ +init_mobility_generator (omg_global_param omg_param_list[]) { int node_t, mobility_t; for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++) { - mobility_t = omg_param_list[node_t].mobility_type; switch (mobility_t) { + case STATIC: + start_static_generator (omg_param_list[node_t]); + break; - case STATIC: - start_static_generator (omg_param_list[node_t]); - break; - - case RWP: - start_rwp_generator (omg_param_list[node_t]); - break; + case RWP: + start_rwp_generator (omg_param_list[node_t]); + break; - case RWALK: - start_rwalk_generator (omg_param_list[node_t]); - break; + case RWALK: + start_rwalk_generator (omg_param_list[node_t]); + break; - case TRACE: - start_trace_generator (omg_param_list[node_t]); - break; + case TRACE: + start_trace_generator (omg_param_list[node_t]); + break; #ifdef SUMO_IF - case SUMO: - start_sumo_generator (omg_param_list[node_t]); - break; -#endif - case STEADY_RWP: - start_steadystaterwp_generator (omg_param_list[node_t]); - break; - default: - LOG_W (OMG, "Unsupported generator\n"); - } + case SUMO: + start_sumo_generator (omg_param_list[node_t]); + break; +#endif + case STEADY_RWP: + start_steadystaterwp_generator (omg_param_list[node_t]); + break; + default: + LOG_W (OMG, "Unsupported generator\n"); + } } - } /**************************************************************************************/ /*stop sumo mobiity generator*/ void -stop_mobility_generator (omg_global_param * omg_param_list) -{ +stop_mobility_generator (omg_global_param *omg_param_list) { int i; for (i = 0; i < MAX_NUM_NODE_TYPES; i++) { switch (omg_param_list[i].mobility_type) { + case STATIC: + break; - case STATIC: - break; - - case RWP: - break; + case RWP: + break; - case RWALK: - break; + case RWALK: + break; - case TRACE: - clear_list (); - break; + case TRACE: + clear_list (); + break; - case STEADY_RWP: - break; + case STEADY_RWP: + break; #ifdef SUMO_IF - case SUMO: - stop_sumo_generator (); - //LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n"); - break; -#endif - default: - LOG_W (OMG, "Unsupported generator\n"); + + case SUMO: + stop_sumo_generator (); + //LOG_D(OMG," --------OMG will interface with SUMO for mobility generation-------- \n"); + break; +#endif + + default: + LOG_W (OMG, "Unsupported generator\n"); } } - } /*****************************************************************************/ void -update_nodes (double cur_time) -{ +update_nodes (double cur_time) { //LOG_D(OMG, "UPDATE NODES" ); int i = 0; @@ -180,38 +173,38 @@ update_nodes (double cur_time) update_node_vector (i, cur_time); } } - } void -update_node_vector (int mobility_type, double cur_time) -{ +update_node_vector (int mobility_type, double cur_time) { //set_time(cur_time); switch (mobility_type) { - case RWP: - update_rwp_nodes (cur_time); - break; + case RWP: + update_rwp_nodes (cur_time); + break; - case RWALK: - update_rwalk_nodes (cur_time); - break; + case RWALK: + update_rwalk_nodes (cur_time); + break; - case TRACE: - update_trace_nodes (cur_time); - break; + case TRACE: + update_trace_nodes (cur_time); + break; #ifdef SUMO_IF - case SUMO: - // printf("in SUMO case \n"); - update_sumo_nodes (cur_time); - break; -#endif - case STEADY_RWP: - update_steadystaterwp_nodes (cur_time); - break; - - default: - LOG_W (OMG, "STATIC or Unsupported generator\n"); + + case SUMO: + // printf("in SUMO case \n"); + update_sumo_nodes (cur_time); + break; +#endif + + case STEADY_RWP: + update_steadystaterwp_nodes (cur_time); + break; + + default: + LOG_W (OMG, "STATIC or Unsupported generator\n"); } } @@ -219,50 +212,45 @@ update_node_vector (int mobility_type, double cur_time) /*return updated node position for a given node type*/ node_list * -get_current_positions (int mobility_type, int node_type, double cur_time) -{ - - +get_current_positions (int mobility_type, int node_type, double cur_time) { get_nodes_positions (mobility_type, cur_time); return node_vector[node_type]; - } /*update current position of nodes for specific mobility type*/ void -get_nodes_positions (int mobility_type, double cur_time) -{ +get_nodes_positions (int mobility_type, double cur_time) { //printf("%d \n",mobility_type); - switch (mobility_type) { - case STATIC: - break; + case STATIC: + break; - case RWP: - get_rwp_positions_updated (cur_time); - break; + case RWP: + get_rwp_positions_updated (cur_time); + break; - case RWALK: - get_rwalk_positions_updated (cur_time); - break; + case RWALK: + get_rwalk_positions_updated (cur_time); + break; - case TRACE: - get_trace_positions_updated (cur_time); - break; + case TRACE: + get_trace_positions_updated (cur_time); + break; #ifdef SUMO_IF - case SUMO: - LOG_I (OMG, "getting positions from SUMO\n"); - get_sumo_positions_updated (cur_time); - break; -#endif - case STEADY_RWP: - get_steadystaterwp_positions_updated (cur_time); - break; - - default: - LOG_E (OMG, " Unsupported generator \n"); - } + case SUMO: + LOG_I (OMG, "getting positions from SUMO\n"); + get_sumo_positions_updated (cur_time); + break; +#endif + + case STEADY_RWP: + get_steadystaterwp_positions_updated (cur_time); + break; + + default: + LOG_E (OMG, " Unsupported generator \n"); + } } /***************************************************************/ @@ -270,10 +258,8 @@ get_nodes_positions (int mobility_type, double cur_time) // get the position for a specific node node_struct * -get_node_position (int node_type, int nid) -{ +get_node_position (int node_type, int nid) { node_list *tmp; - tmp = node_vector[node_type]; while (tmp != NULL) { @@ -289,15 +275,12 @@ get_node_position (int node_type, int nid) /*set new mobility for a node*/ void -set_new_mob_type (int id, int node_t, int mob_t, double cur_time) -{ - +set_new_mob_type (int id, int node_t, int mob_t, double cur_time) { int prev_mob; node_list *tmp; //job_list *tmp2, *prev_job; pair_struct *pair; double pause_p; - //find previous mobility type tmp = node_vector[node_t]; @@ -313,7 +296,6 @@ set_new_mob_type (int id, int node_t, int mob_t, double cur_time) //end if (tmp != NULL && prev_mob != mob_t) { - //initialize node position if (mob_t == STATIC || mob_t == RWP || mob_t == RWALK || mob_t == STEADY_RWP) { tmp->node->x_pos = @@ -341,61 +323,57 @@ set_new_mob_type (int id, int node_t, int mob_t, double cur_time) //end switch (mob_t) { - - case STATIC: - - break; - - case RWP: - pair = (pair_struct *) malloc (sizeof (struct pair_struct)); - pair->b = tmp->node; - sleep_rwp_node (pair, cur_time); - job_vector[RWP] = addjob (pair, job_vector[RWP]); - break; - - case RWALK: - pair = (pair_struct *) malloc (sizeof (struct pair_struct)); - pair->b = tmp->node; - sleep_rwalk_node (pair, cur_time); - job_vector[RWALK] = addjob (pair, job_vector[RWALK]); - break; - - case STEADY_RWP: - tmp->node->event_num = 0; - pair = (pair_struct *) malloc (sizeof (struct pair_struct)); - pair->b = tmp->node; - pause_p = pause_probability (omg_param_list[node_t]); - - if (randomgen (0, 1) < pause_p) - sleep_steadystaterwp_node (pair, cur_time); - else - move_steadystaterwp_node (pair, cur_time); - - break; + case STATIC: + break; + + case RWP: + pair = (pair_struct *) malloc (sizeof (struct pair_struct)); + pair->b = tmp->node; + sleep_rwp_node (pair, cur_time); + job_vector[RWP] = addjob (pair, job_vector[RWP]); + break; + + case RWALK: + pair = (pair_struct *) malloc (sizeof (struct pair_struct)); + pair->b = tmp->node; + sleep_rwalk_node (pair, cur_time); + job_vector[RWALK] = addjob (pair, job_vector[RWALK]); + break; + + case STEADY_RWP: + tmp->node->event_num = 0; + pair = (pair_struct *) malloc (sizeof (struct pair_struct)); + pair->b = tmp->node; + pause_p = pause_probability (omg_param_list[node_t]); + + if (randomgen (0, 1) < pause_p) + sleep_steadystaterwp_node (pair, cur_time); + else + move_steadystaterwp_node (pair, cur_time); + + break; #ifdef SUMO_IF - case SUMO: - LOG_E (OMG, "not possible to change mobility type to sumo \n"); - break; + + case SUMO: + LOG_E (OMG, "not possible to change mobility type to sumo \n"); + break; #endif - case TRACE: - LOG_E (OMG, "not possible to change mobility type to trace \n"); - break; - default: - LOG_E (OMG, " Unsupported generator \n"); - } + case TRACE: + LOG_E (OMG, "not possible to change mobility type to trace \n"); + break; + default: + LOG_E (OMG, " Unsupported generator \n"); + } } - - } #ifdef STANDALONE /************************** get options ************************************/ void -usage (void) -{ +usage (void) { fprintf (stderr, "\n\t-X: assign maximum width of the simulation area for UE nodes(X_max)" "\n\t-x: assign minimum width of the simulation area for UE nodes(X_min)" @@ -443,8 +421,7 @@ usage (void) int -get_options (int argc, char *argv[]) -{ +get_options (int argc, char *argv[]) { int node_t; char tag; @@ -452,345 +429,342 @@ get_options (int argc, char *argv[]) getopt (argc, argv, "U:u:E:e:R:r:A:a:B:b:C:c:D:d:f:g:hI:i:J:j:k:L:l:N:n:P:p:S:s:T:t:vW:w:X:x:Y:y:Z:z:")) != EOF) { - - switch (tag) { - - case 'U': - if (atoi (optarg) < 0) { - usage (); - exit (1); - } - - omg_param_list[UE].nodes = atoi (optarg); - LOG_D (OMG, "#Number of UE nodes : %d \n", - omg_param_list[UE].nodes); - break; - - case 'E': - if (atoi (optarg) < 0) { - usage (); - exit (1); - } - - omg_param_list[eNB].nodes = atoi (optarg); - LOG_D (OMG, "#Number of eNB nodes : %d \n", - omg_param_list[eNB].nodes); - break; - - case 'R': - if (atoi (optarg) < 0) { - usage (); - exit (1); - } - - omg_param_list[RELAY].nodes = atoi (optarg); - LOG_D (OMG, "#Number of relay nodes : %d \n", - omg_param_list[RELAY].nodes); - break; - - case 'k': - if (atof (optarg) < 0) - LOG_E (OMG, "#Number of frames can not be negative \n"); - - n_frames = abs (atof (optarg)); - LOG_D (OMG, "#Number of frames : %f \n", n_frames); - break; - - case 'u': - if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) { - usage (); - exit (1); - } - - omg_param_list[UE].mobility_type = atoi (optarg); - LOG_D (OMG, "#UE nodes mobility type: %d \n", - omg_param_list[UE].mobility_type); - break; - - case 'e': - if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) { + case 'U': + if (atoi (optarg) < 0) { + usage (); + exit (1); + } + + omg_param_list[UE].nodes = atoi (optarg); + LOG_D (OMG, "#Number of UE nodes : %d \n", + omg_param_list[UE].nodes); + break; + + case 'E': + if (atoi (optarg) < 0) { + usage (); + exit (1); + } + + omg_param_list[eNB].nodes = atoi (optarg); + LOG_D (OMG, "#Number of eNB nodes : %d \n", + omg_param_list[eNB].nodes); + break; + + case 'R': + if (atoi (optarg) < 0) { + usage (); + exit (1); + } + + omg_param_list[RELAY].nodes = atoi (optarg); + LOG_D (OMG, "#Number of relay nodes : %d \n", + omg_param_list[RELAY].nodes); + break; + + case 'k': + if (atof (optarg) < 0) + LOG_E (OMG, "#Number of frames can not be negative \n"); + + n_frames = abs (atof (optarg)); + LOG_D (OMG, "#Number of frames : %f \n", n_frames); + break; + + case 'u': + if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) { + usage (); + exit (1); + } + + omg_param_list[UE].mobility_type = atoi (optarg); + LOG_D (OMG, "#UE nodes mobility type: %d \n", + omg_param_list[UE].mobility_type); + break; + + case 'e': + if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) { + usage (); + exit (1); + } + + omg_param_list[eNB].mobility_type = atoi (optarg); + LOG_D (OMG, "#eNB nodes mobility type: %d \n", + omg_param_list[eNB].mobility_type); + break; + + case 'r': + if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) { + usage (); + exit (1); + } + + omg_param_list[RELAY].mobility_type = atoi (optarg); + LOG_D (OMG, "#relay nodes mobility type: %d \n", + omg_param_list[RELAY].mobility_type); + break; + + case 's': + if (atof (optarg) < 0) + LOG_E (OMG, "#min sleep can not be negative \n"); + + omg_param_list[UE].min_sleep = fabs (atof (optarg)); + LOG_D (OMG, "#UE min sleep is set to: %.2f \n", + omg_param_list[UE].min_sleep); + break; + + case 'S': + if (atof (optarg) < 0) + LOG_E (OMG, "#max_sleep can not be negative \n"); + + omg_param_list[UE].max_sleep = fabs (atof (optarg)); + LOG_D (OMG, "#UE max_sleep is set to : %.2f \n", + omg_param_list[UE].max_sleep); + break; + + case 'l': + if (atof (optarg) < 0) + LOG_E (OMG, "#min sleep can not be negative or zero \n"); + + if (atof (optarg) != 0) + omg_param_list[eNB].min_sleep = fabs (atof (optarg)); + + LOG_D (OMG, "#eNB min sleep is set to : %.2f \n", + omg_param_list[eNB].min_sleep); + break; + + case 'L': + if (atof (optarg) <= 0) + LOG_E (OMG, "#max_sleep can not be negative or zero \n"); + + if (atof (optarg) != 0) + omg_param_list[eNB].max_sleep = fabs (atof (optarg)); + + LOG_D (OMG, "#eNB max_sleep is set to : %.2f \n", + omg_param_list[eNB].max_sleep); + break; + + case 'p': + if (atof (optarg) < 0) + LOG_E (OMG, "#min sleep can not be negative \n"); + + omg_param_list[RELAY].min_sleep = fabs (atof (optarg)); + LOG_D (OMG, "#relay min sleep is set to: %.2f \n", + omg_param_list[RELAY].min_sleep); + break; + + case 'P': + if (atof (optarg) < 0) + LOG_E (OMG, "#max_sleep can not be negative \n"); + + omg_param_list[RELAY].max_sleep = fabs (atof (optarg)); + LOG_D (OMG, "#relay max_sleep is set to : %.2f \n", + omg_param_list[RELAY].max_sleep); + break; + + case 'd': + if (atof (optarg) < 0) + LOG_E (OMG, "#min_speed can not be negative \n"); + + if (atof (optarg) != 0) + omg_param_list[UE].min_speed = fabs (atof (optarg)); + + LOG_D (OMG, "#UE min_speed is set to: %.2f \n", + omg_param_list[UE].min_speed); + break; + + case 'D': + if (atof (optarg) < 0) + LOG_E (OMG, "#max_speed can not be negative \n"); + + omg_param_list[UE].max_speed = fabs (atof (optarg)); + LOG_D (OMG, "#UE max_speed is set to: %.2f \n", + omg_param_list[UE].max_speed); + break; + + case 'i': + if (atof (optarg) < 0) + LOG_E (OMG, "#min_speed can not be negative \n"); + + if (atof (optarg) != 0) + omg_param_list[eNB].min_speed = fabs (atof (optarg)); + + LOG_D (OMG, "#eNB min_speed is set to: %.2f \n", + omg_param_list[eNB].min_speed); + break; + + case 'I': + if (atof (optarg) < 0) + LOG_E (OMG, "#max_speed can not be negative \n"); + + omg_param_list[eNB].max_speed = fabs (atof (optarg)); + LOG_D (OMG, "#eNB max_speed is set to : %.2f \n", + omg_param_list[eNB].max_speed); + break; + + case 'a': + if (atof (optarg) < 0) + LOG_E (OMG, "#min_speed can not be negative \n"); + + if (atof (optarg) != 0) + omg_param_list[RELAY].min_speed = fabs (atof (optarg)); + + LOG_D (OMG, "#relay min_speed is set to : %.2f \n", + omg_param_list[RELAY].min_speed); + break; + + case 'A': + if (atof (optarg) < 0) + LOG_E (OMG, "#max_speed can not be negative \n"); + + omg_param_list[RELAY].max_speed = fabs (atof (optarg)); + LOG_D (OMG, "#relay max_speed is set to: %.2f \n", + omg_param_list[RELAY].max_speed); + break; + + case 'v': + omv_enabled = 1; + break; + + case 'X': + omg_param_list[UE].max_x = fabs (atof (optarg)); + LOG_D (OMG, "#UE X_max : %.2f \n", omg_param_list[UE].max_x); + break; + + case 'x': + omg_param_list[UE].min_x = fabs (atof (optarg)); + LOG_D (OMG, "#UE X_min : %.2f \n", omg_param_list[UE].min_x); + break; + + case 'C': + omg_param_list[eNB].max_x = fabs (atof (optarg)); + LOG_D (OMG, "#eNB X_max : %.2f \n", omg_param_list[eNB].max_x); + break; + + case 'c': + omg_param_list[eNB].min_x = fabs (atof (optarg)); + LOG_D (OMG, "#eNB X_min : %.2f \n", omg_param_list[eNB].min_x); + break; + + case 'B': + omg_param_list[RELAY].max_x = fabs (atof (optarg)); + LOG_D (OMG, "#relay X_max : %.2f \n", omg_param_list[RELAY].max_x); + break; + + case 'b': + omg_param_list[RELAY].min_x = fabs (atof (optarg)); + LOG_D (OMG, "#relay X_min : %.2f \n", omg_param_list[RELAY].min_x); + break; + + case 'Y': + omg_param_list[UE].max_y = fabs (atof (optarg)); + LOG_D (OMG, "#UE Y_max : %.2f \n", omg_param_list[UE].max_y); + break; + + case 'y': + omg_param_list[UE].min_y = fabs (atof (optarg)); + LOG_D (OMG, "#UE Y_min : %.2f \n", omg_param_list[UE].min_y); + break; + + case 'Z': + omg_param_list[eNB].max_y = fabs (atof (optarg)); + LOG_D (OMG, "#eNB Y_max : %.2f \n", omg_param_list[eNB].max_y); + break; + + case 'z': + omg_param_list[eNB].min_y = fabs (atof (optarg)); + LOG_D (OMG, "#eNB Y_min : %.2f \n", omg_param_list[eNB].min_y); + break; + + case 'W': + omg_param_list[RELAY].max_y = fabs (atof (optarg)); + LOG_D (OMG, "#relay Y_max : %.2f \n", omg_param_list[RELAY].max_y); + break; + + case 'w': + omg_param_list[RELAY].min_y = fabs (atof (optarg)); + LOG_D (OMG, "#relay Y_min : %.2f \n", omg_param_list[RELAY].min_y); + break; + + case 'J': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_max can not be negative \n"); + + omg_param_list[UE].max_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "UE Journey_time_max : %.2f \n", + omg_param_list[UE].max_journey_time); + break; + + case 'j': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_min can not be negative \n"); + + omg_param_list[UE].min_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "#UE Journey_time_min : %.2f \n", + omg_param_list[UE].min_journey_time); + break; + + case 'T': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_max can not be negative \n"); + + omg_param_list[eNB].max_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "#eNB Journey_time_max : %.2f \n", + omg_param_list[eNB].max_journey_time); + break; + + case 't': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_min can not be negative \n"); + + omg_param_list[eNB].min_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "#eNB Journey_time_min : %.2f \n", + omg_param_list[eNB].min_journey_time); + break; + + case 'N': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_max can not be negative \n"); + + omg_param_list[RELAY].max_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "#relay Journey_time_max : %.2f \n", + omg_param_list[RELAY].max_journey_time); + break; + + case 'n': + if (atof (optarg) < 0) + LOG_E (OMG, "#Journey_time_min can not be negative \n"); + + omg_param_list[RELAY].min_journey_time = fabs (atof (optarg)); + LOG_D (OMG, "#relay Journey_time_min : %.2f \n", + omg_param_list[RELAY].min_journey_time); + break; + + case 'f': + for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++) { + omg_param_list[node_t].seed = atoi (optarg); + LOG_D (OMG, "#Seed is %d \n", omg_param_list[node_t].seed); + } + + break; + + case 'g': + if (atoi (optarg) < 1 || atoi (optarg) > 2) { + LOG_E (OMG, "#value given for graph should be 1 or 2 \n"); + exit (-1); + } + + grid = abs (atof (optarg)); + LOG_D (OMG, "#graph value is %d \n", grid); + break; + + case 'h': usage (); - exit (1); - } - - omg_param_list[eNB].mobility_type = atoi (optarg); - LOG_D (OMG, "#eNB nodes mobility type: %d \n", - omg_param_list[eNB].mobility_type); - break; + break; - case 'r': - if (atoi (optarg) < 0 || atoi (optarg) >= MAX_NUM_MOB_TYPES) { + default: usage (); exit (1); - } - - omg_param_list[RELAY].mobility_type = atoi (optarg); - LOG_D (OMG, "#relay nodes mobility type: %d \n", - omg_param_list[RELAY].mobility_type); - break; - - case 's': - if (atof (optarg) < 0) - LOG_E (OMG, "#min sleep can not be negative \n"); - - omg_param_list[UE].min_sleep = fabs (atof (optarg)); - LOG_D (OMG, "#UE min sleep is set to: %.2f \n", - omg_param_list[UE].min_sleep); - break; - - case 'S': - if (atof (optarg) < 0) - LOG_E (OMG, "#max_sleep can not be negative \n"); - - omg_param_list[UE].max_sleep = fabs (atof (optarg)); - LOG_D (OMG, "#UE max_sleep is set to : %.2f \n", - omg_param_list[UE].max_sleep); - break; - - case 'l': - if (atof (optarg) < 0) - LOG_E (OMG, "#min sleep can not be negative or zero \n"); - - if (atof (optarg) != 0) - omg_param_list[eNB].min_sleep = fabs (atof (optarg)); - - LOG_D (OMG, "#eNB min sleep is set to : %.2f \n", - omg_param_list[eNB].min_sleep); - break; - - case 'L': - if (atof (optarg) <= 0) - LOG_E (OMG, "#max_sleep can not be negative or zero \n"); - - if (atof (optarg) != 0) - omg_param_list[eNB].max_sleep = fabs (atof (optarg)); - - LOG_D (OMG, "#eNB max_sleep is set to : %.2f \n", - omg_param_list[eNB].max_sleep); - break; - - case 'p': - if (atof (optarg) < 0) - LOG_E (OMG, "#min sleep can not be negative \n"); - - omg_param_list[RELAY].min_sleep = fabs (atof (optarg)); - LOG_D (OMG, "#relay min sleep is set to: %.2f \n", - omg_param_list[RELAY].min_sleep); - break; - - case 'P': - if (atof (optarg) < 0) - LOG_E (OMG, "#max_sleep can not be negative \n"); - - omg_param_list[RELAY].max_sleep = fabs (atof (optarg)); - LOG_D (OMG, "#relay max_sleep is set to : %.2f \n", - omg_param_list[RELAY].max_sleep); - break; - - case 'd': - if (atof (optarg) < 0) - LOG_E (OMG, "#min_speed can not be negative \n"); - - if (atof (optarg) != 0) - omg_param_list[UE].min_speed = fabs (atof (optarg)); - - LOG_D (OMG, "#UE min_speed is set to: %.2f \n", - omg_param_list[UE].min_speed); - break; - - case 'D': - if (atof (optarg) < 0) - LOG_E (OMG, "#max_speed can not be negative \n"); - - omg_param_list[UE].max_speed = fabs (atof (optarg)); - LOG_D (OMG, "#UE max_speed is set to: %.2f \n", - omg_param_list[UE].max_speed); - break; - - case 'i': - if (atof (optarg) < 0) - LOG_E (OMG, "#min_speed can not be negative \n"); - - if (atof (optarg) != 0) - omg_param_list[eNB].min_speed = fabs (atof (optarg)); - - LOG_D (OMG, "#eNB min_speed is set to: %.2f \n", - omg_param_list[eNB].min_speed); - break; - - case 'I': - if (atof (optarg) < 0) - LOG_E (OMG, "#max_speed can not be negative \n"); - - omg_param_list[eNB].max_speed = fabs (atof (optarg)); - LOG_D (OMG, "#eNB max_speed is set to : %.2f \n", - omg_param_list[eNB].max_speed); - break; - - case 'a': - if (atof (optarg) < 0) - LOG_E (OMG, "#min_speed can not be negative \n"); - - if (atof (optarg) != 0) - omg_param_list[RELAY].min_speed = fabs (atof (optarg)); - - LOG_D (OMG, "#relay min_speed is set to : %.2f \n", - omg_param_list[RELAY].min_speed); - break; - - case 'A': - if (atof (optarg) < 0) - LOG_E (OMG, "#max_speed can not be negative \n"); - - omg_param_list[RELAY].max_speed = fabs (atof (optarg)); - LOG_D (OMG, "#relay max_speed is set to: %.2f \n", - omg_param_list[RELAY].max_speed); - break; - - case 'v': - omv_enabled = 1; - break; - - case 'X': - omg_param_list[UE].max_x = fabs (atof (optarg)); - LOG_D (OMG, "#UE X_max : %.2f \n", omg_param_list[UE].max_x); - break; - - case 'x': - omg_param_list[UE].min_x = fabs (atof (optarg)); - LOG_D (OMG, "#UE X_min : %.2f \n", omg_param_list[UE].min_x); - break; - - case 'C': - omg_param_list[eNB].max_x = fabs (atof (optarg)); - LOG_D (OMG, "#eNB X_max : %.2f \n", omg_param_list[eNB].max_x); - break; - - case 'c': - omg_param_list[eNB].min_x = fabs (atof (optarg)); - LOG_D (OMG, "#eNB X_min : %.2f \n", omg_param_list[eNB].min_x); - break; - - case 'B': - omg_param_list[RELAY].max_x = fabs (atof (optarg)); - LOG_D (OMG, "#relay X_max : %.2f \n", omg_param_list[RELAY].max_x); - break; - - case 'b': - omg_param_list[RELAY].min_x = fabs (atof (optarg)); - LOG_D (OMG, "#relay X_min : %.2f \n", omg_param_list[RELAY].min_x); - break; - - case 'Y': - omg_param_list[UE].max_y = fabs (atof (optarg)); - LOG_D (OMG, "#UE Y_max : %.2f \n", omg_param_list[UE].max_y); - break; - - case 'y': - omg_param_list[UE].min_y = fabs (atof (optarg)); - LOG_D (OMG, "#UE Y_min : %.2f \n", omg_param_list[UE].min_y); - break; - - case 'Z': - omg_param_list[eNB].max_y = fabs (atof (optarg)); - LOG_D (OMG, "#eNB Y_max : %.2f \n", omg_param_list[eNB].max_y); - break; - - case 'z': - omg_param_list[eNB].min_y = fabs (atof (optarg)); - LOG_D (OMG, "#eNB Y_min : %.2f \n", omg_param_list[eNB].min_y); - break; - - case 'W': - omg_param_list[RELAY].max_y = fabs (atof (optarg)); - LOG_D (OMG, "#relay Y_max : %.2f \n", omg_param_list[RELAY].max_y); - break; - - case 'w': - omg_param_list[RELAY].min_y = fabs (atof (optarg)); - LOG_D (OMG, "#relay Y_min : %.2f \n", omg_param_list[RELAY].min_y); - break; - - case 'J': - if (atof (optarg) < 0) - LOG_E (OMG, "#Journey_time_max can not be negative \n"); - - omg_param_list[UE].max_journey_time = fabs (atof (optarg)); - LOG_D (OMG, "UE Journey_time_max : %.2f \n", - omg_param_list[UE].max_journey_time); - break; - - case 'j': - if (atof (optarg) < 0) - LOG_E (OMG, "#Journey_time_min can not be negative \n"); - - omg_param_list[UE].min_journey_time = fabs (atof (optarg)); - LOG_D (OMG, "#UE Journey_time_min : %.2f \n", - omg_param_list[UE].min_journey_time); - break; - - case 'T': - if (atof (optarg) < 0) - LOG_E (OMG, "#Journey_time_max can not be negative \n"); - - omg_param_list[eNB].max_journey_time = fabs (atof (optarg)); - LOG_D (OMG, "#eNB Journey_time_max : %.2f \n", - omg_param_list[eNB].max_journey_time); - break; - - case 't': - if (atof (optarg) < 0) - LOG_E (OMG, "#Journey_time_min can not be negative \n"); - - omg_param_list[eNB].min_journey_time = fabs (atof (optarg)); - LOG_D (OMG, "#eNB Journey_time_min : %.2f \n", - omg_param_list[eNB].min_journey_time); - break; - - case 'N': - if (atof (optarg) < 0) - LOG_E (OMG, "#Journey_time_max can not be negative \n"); - - omg_param_list[RELAY].max_journey_time = fabs (atof (optarg)); - LOG_D (OMG, "#relay Journey_time_max : %.2f \n", - omg_param_list[RELAY].max_journey_time); - break; - - case 'n': - if (atof (optarg) < 0) - LOG_E (OMG, "#Journey_time_min can not be negative \n"); - - omg_param_list[RELAY].min_journey_time = fabs (atof (optarg)); - LOG_D (OMG, "#relay Journey_time_min : %.2f \n", - omg_param_list[RELAY].min_journey_time); - break; - - case 'f': - for (node_t = eNB; node_t < MAX_NUM_NODE_TYPES; node_t++) { - omg_param_list[node_t].seed = atoi (optarg); - LOG_D (OMG, "#Seed is %d \n", omg_param_list[node_t].seed); - } - - break; - - case 'g': - if (atoi (optarg) < 1 || atoi (optarg) > 2) { - LOG_E (OMG, "#value given for graph should be 1 or 2 \n"); - exit (-1); - } - - grid = abs (atof (optarg)); - LOG_D (OMG, "#graph value is %d \n", grid); - break; - - case 'h': - usage (); - break; - - default: - usage (); - exit (1); } } @@ -800,8 +774,7 @@ get_options (int argc, char *argv[]) /**************************** main **********************************/ int -main (int argc, char *argv[]) -{ +main (int argc, char *argv[]) { int i, node_type; double cur_time = 0.0; double ms = 0.0; @@ -824,8 +797,6 @@ main (int argc, char *argv[]) //default parameters for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++) { - - if (node_type == UE) omg_param_list[node_type].nodes = 5; else @@ -857,22 +828,16 @@ main (int argc, char *argv[]) omg_param_list[node_type].sumo_port = 8890; } - init_omg_global_params (); //initialize global paramaters - get_options (argc, argv); // overwrite the default params if any input parameter for (node_type = eNB; node_type < MAX_NUM_NODE_TYPES; node_type++) { omg_param_list[node_type].max_vertices = max_vertices_ongrid (omg_param_list[node_type]); - omg_param_list[node_type].max_block_num = max_connecteddomains_ongrid (omg_param_list[node_type]); - } - - init_mobility_generator (omg_param_list); //initialize choosen mobility generator // ****************init omv******************** @@ -884,30 +849,25 @@ main (int argc, char *argv[]) LOG_I (EMU, "Stating the OMV path %s pfd[0] %d pfd[1] %d \n", full_name, pfd[0], pfd[1]); - - - - switch (fork ()) { - case -1: - perror ("fork failed \n"); - break; - - case 0: - if (close (pfd[1]) == -1) - perror ("close on write\n"); - - sprintf (fdstr, "%d", pfd[0]); - sprintf (num_enb, "%d", 1); - sprintf (num_ue, "%d", omg_param_list[UE].nodes); - sprintf (x_area, "%f", omg_param_list[UE].max_x); - sprintf (y_area, "%f", omg_param_list[UE].max_y); - sprintf (z_area, "%f", 200.0); - sprintf (frames, "%d", (int) n_frames); - - execl (full_name, "OMV", fdstr, frames, num_enb, num_ue, x_area, - y_area, z_area, NULL); - perror ("error in execl the OMV"); + case -1: + perror ("fork failed \n"); + break; + + case 0: + if (close (pfd[1]) == -1) + perror ("close on write\n"); + + sprintf (fdstr, "%d", pfd[0]); + sprintf (num_enb, "%d", 1); + sprintf (num_ue, "%d", omg_param_list[UE].nodes); + sprintf (x_area, "%f", omg_param_list[UE].max_x); + sprintf (y_area, "%f", omg_param_list[UE].max_y); + sprintf (z_area, "%f", 200.0); + sprintf (frames, "%d", (int) n_frames); + execl (full_name, "OMV", fdstr, frames, num_enb, num_ue, x_area, + y_area, z_area, NULL); + perror ("error in execl the OMV"); } //parent @@ -918,7 +878,6 @@ main (int argc, char *argv[]) //****************************** for (emu_info_time = 0.0; emu_info_time <= n_frames; emu_info_time += 0.1) { - update_nodes (emu_info_time); time_s = round (emu_info_time * 1000.0); @@ -929,7 +888,6 @@ main (int argc, char *argv[]) node_type, emu_info_time); if (current_positions != NULL) - display_job_list (emu_info_time, job_vector[omg_param_list [node_type].mobility_type]); @@ -939,12 +897,9 @@ main (int argc, char *argv[]) nodes_avgspeed(job_vector[omg_param_list [node_type].mobility_type])); */ } - //display current postion of nodes if (omv_enabled == 1) omv_write (pfd[1], node_vector[SUMO], omv_data); - - } /*LOG_I(OMG,"#-----event average-----\n"); @@ -953,22 +908,19 @@ main (int argc, char *argv[]) if(events[i]!=0) LOG_D(OMG,"%d %d \n",i,event_sum[i]/events[i]); } */ - stop_mobility_generator (omg_param_list); if (omv_enabled == 1) omv_end (pfd[1], omv_data); //clear_mem(); - return 0; } /**********************************sumo****************************/ int -omv_write (int pfd, node_list * ue_node_list, Data_Flow_Unit omv_data) -{ +omv_write (int pfd, node_list *ue_node_list, Data_Flow_Unit omv_data) { int i = 0, j; omv_data.end = 0; // enb @@ -979,7 +931,7 @@ omv_write (int pfd, node_list * ue_node_list, Data_Flow_Unit omv_data) omv_data.geo[i].node_type = 0; //eNB omv_data.geo[i].Neighbors = 0; - for (i = 1; i < omg_param_list[SUMO].nodes + 1; i++) { + for (i = 1; i < omg_param_list[SUMO-1].nodes + 1; i++) { if (ue_node_list != NULL) { omv_data.geo[i].x = (int) (ue_node_list->node->x_pos < @@ -988,7 +940,7 @@ omv_write (int pfd, node_list * ue_node_list, Data_Flow_Unit omv_data) (int) (ue_node_list->node->y_pos < 0.0) ? 0.0 : ue_node_list->node->y_pos; omv_data.geo[i].z = 1.0; - omv_data.geo[i].mobility_type = omg_param_list[SUMO].mobility_type; + omv_data.geo[i].mobility_type = omg_param_list[SUMO-1].mobility_type; omv_data.geo[i].node_type = 1; //UE ue_node_list = ue_node_list->next; omv_data.geo[i].Neighbors = 0; @@ -1004,8 +956,7 @@ omv_write (int pfd, node_list * ue_node_list, Data_Flow_Unit omv_data) } void -omv_end (int pfd, Data_Flow_Unit omv_data) -{ +omv_end (int pfd, Data_Flow_Unit omv_data) { omv_data.end = 1; if (write (pfd, &omv_data, sizeof (struct Data_Flow_Unit)) == -1) diff --git a/openair2/UTIL/OMG/omg_hashtable.c b/openair2/UTIL/OMG/omg_hashtable.c index 32b3840af3966e51dc32469e1dce68e04a51beaa..a545c5fc6227da90c08bc11310d10a9f51b83dd9 100644 --- a/openair2/UTIL/OMG/omg_hashtable.c +++ b/openair2/UTIL/OMG/omg_hashtable.c @@ -43,8 +43,7 @@ * @returns hash_table_element_t object when success * @returns NULL when no memory */ -hash_table_element_t * hash_table_element_new(void) -{ +hash_table_element_t *hash_table_element_new(void) { //INFO("creating a new hash table element"); return calloc(1, hash_table_element_s); } @@ -54,8 +53,7 @@ hash_table_element_t * hash_table_element_new(void) * @param table table from which element has to be deleted * @param element hash table element to be deleted */ -void hash_table_element_delete(omg_hash_table_t * table, hash_table_element_t * element) -{ +void hash_table_element_delete(omg_hash_table_t *table, hash_table_element_t *element) { //INFO("Deleting an hash table element"); if (table->mode == MODE_COPY) { free(element->value); @@ -74,8 +72,7 @@ void hash_table_element_delete(omg_hash_table_t * table, hash_table_element_t * * @returns omg_hash_table_t object which references the hash table * @returns NULL when no memory */ -omg_hash_table_t * hash_table_new(hash_table_mode_t mode) -{ +omg_hash_table_t *hash_table_new(hash_table_mode_t mode) { //INFO("Creating a new hash table"); omg_hash_table_t *table = calloc(1, SIZEOF_HASH_TABLE); @@ -102,14 +99,13 @@ omg_hash_table_t * hash_table_new(hash_table_mode_t mode) * Function to delete the hash table * @param table hash table to be deleted */ -void hash_table_delete(omg_hash_table_t * table) -{ +void hash_table_delete(omg_hash_table_t *table) { //INFO("Deleating a hash table"); size_t i=0; for (; i<HASH_LEN; i++) { while (table->store_house[i]) { - hash_table_element_t * temp = table->store_house[i]; + hash_table_element_t *temp = table->store_house[i]; table->store_house[i] = table->store_house[i]->next; hash_table_element_delete(table, temp); } @@ -129,8 +125,7 @@ void hash_table_delete(omg_hash_table_t * table) * @returns 0 on sucess * @returns -1 when no memory */ -int hash_table_add(omg_hash_table_t * table, void * key, size_t key_len, void * value, size_t value_len) -{ +int hash_table_add(omg_hash_table_t *table, void *key, size_t key_len, void *value, size_t value_len) { if ((table->key_count / table->key_num) >= table->key_ratio) { //LOG("Ratio(%d) reached the set limit %d\nExpanding hash_table", (table->key_count / table->key_num), table->key_ratio); hash_table_resize(table, table->key_num*2); @@ -138,7 +133,7 @@ int hash_table_add(omg_hash_table_t * table, void * key, size_t key_len, void * } size_t hash = HASH(key, key_len); - hash_table_element_t * element = hash_table_element_new(); + hash_table_element_t *element = hash_table_element_new(); if (!element) { //INFO("Cannot allocate memory for element"); @@ -197,7 +192,7 @@ int hash_table_add(omg_hash_table_t * table, void * key, size_t key_len, void * table->key_count++; } else { //LOG("Conflicts adding element at %d", (int)hash); - hash_table_element_t * temp = table->store_house[hash]; + hash_table_element_t *temp = table->store_house[hash]; while(temp->next) { while(temp->next && temp->next->key_len!=key_len) { @@ -234,8 +229,7 @@ int hash_table_add(omg_hash_table_t * table, void * key, size_t key_len, void * * @returns 0 on sucess * @returns -1 when key is not found */ -int hash_table_remove(omg_hash_table_t * table, void * key, size_t key_len) -{ +int hash_table_remove(omg_hash_table_t *table, void *key, size_t key_len) { //INFO("Deleting a key-value pair from the hash table"); if ((table->key_num/ table->key_count) >= table->key_ratio) { //LOG("Ratio(%d) reached the set limit %d\nContracting hash_table", (table->key_num / table->key_count), table->key_ratio); @@ -290,8 +284,7 @@ int hash_table_remove(omg_hash_table_t * table, void * key, size_t key_len) * @returns NULL when key is not found in the hash table * @returns void* pointer to the value in the table */ -void * hash_table_lookup(omg_hash_table_t * table, void * key, size_t key_len) -{ +void *hash_table_lookup(omg_hash_table_t *table, void *key, size_t key_len) { size_t hash = HASH(key, key_len); //LOG("Looking up a key-value pair for hash -> %d", (int)hash); @@ -328,8 +321,7 @@ void * hash_table_lookup(omg_hash_table_t * table, void * key, size_t key_len) * @returns 0 when key is not found * @returns 1 when key is found */ -int hash_table_has_key(omg_hash_table_t * table, void * key, size_t key_len) -{ +int hash_table_has_key(omg_hash_table_t *table, void *key, size_t key_len) { size_t hash = HASH(key, key_len); //LOG("Searching for key with hash -> %d", (int)hash); @@ -365,11 +357,10 @@ int hash_table_has_key(omg_hash_table_t * table, void * key, size_t key_len) * @param keys a void** pointer where keys are filled in (memory allocated internally and must be freed) * @return total number of keys filled in keys */ -size_t hash_table_get_keys(omg_hash_table_t * table, void ** keys) -{ +size_t hash_table_get_keys(omg_hash_table_t *table, void **keys) { size_t i = 0; size_t count = 0; - keys = calloc(table->key_count, sizeof(void *)); + keys = calloc(table->key_count, sizeof(void *)*HASH_LEN); for(i=0; i<HASH_LEN; i++) { if (table->store_house[i]) { @@ -403,8 +394,7 @@ size_t hash_table_get_keys(omg_hash_table_t * table, void ** keys) * @returns 1 when no memory * @returns count of elements */ -size_t hash_table_get_elements(omg_hash_table_t * table, hash_table_element_t *** elements) -{ +size_t hash_table_get_elements(omg_hash_table_t *table, hash_table_element_t *** elements) { size_t i = 0; size_t count = 0; (*elements) = (hash_table_element_t **) calloc(table->key_count, sizeof(hash_table_element_t *)); @@ -446,8 +436,7 @@ size_t hash_table_get_elements(omg_hash_table_t * table, hash_table_element_t ** * @param max_key max value of the hash to be returned by the function * @returns hash value belonging to [0, max_key) */ -uint16_t hash_table_do_hash(void * key, size_t key_len, uint16_t max_key) -{ +uint16_t hash_table_do_hash(void *key, size_t key_len, uint16_t max_key) { uint16_t *ptr = (uint16_t *) key; uint16_t hash = 0xbabe; // WHY NOT size_t i = 0; @@ -469,10 +458,9 @@ uint16_t hash_table_do_hash(void * key, size_t key_len, uint16_t max_key) * @returns -2 when no emmory for new store house * @returns 0 when sucess */ -int hash_table_resize(omg_hash_table_t *table, size_t len) -{ +int hash_table_resize(omg_hash_table_t *table, size_t len) { //LOG("resizing hash table from %d to %d", table->key_num, len); - hash_table_element_t ** elements; + hash_table_element_t **elements; size_t count; // FIXME traversing the elements twice, change it some time soon count = hash_table_get_elements(table, &elements); @@ -483,7 +471,7 @@ int hash_table_resize(omg_hash_table_t *table, size_t len) } // keep the current store house in case we dont get more memory - hash_table_element_t ** temp = table->store_house; + hash_table_element_t **temp = table->store_house; table->store_house = calloc(len, sizeof(hash_table_element_t *)); if (!table->store_house) { diff --git a/openair2/UTIL/OTG/main.c b/openair2/UTIL/OTG/main.c index 1ee9b0edd7600df62ccd4acb8d9c1a2cc6194ecc..023033c45fbc603820b7890bddac690000fc275d 100644 --- a/openair2/UTIL/OTG/main.c +++ b/openair2/UTIL/OTG/main.c @@ -53,9 +53,7 @@ int simu_time=0, duration=0, seed=0, simu_mode=0; // init OTG with config parameters -void init_config_otg(char *protocol, char *ip_version) -{ - +void init_config_otg(char *protocol, char *ip_version) { int i, j, k; if (simu_time>0) @@ -70,25 +68,19 @@ void init_config_otg(char *protocol, char *ip_version) printf("duration %d, seeds %d \n", duration, g_otg->seed); - for (i=0; i<(NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX); i++) { - - - if (duration>0) g_otg->duration[i]=duration; else g_otg->duration[i]=10000; - g_otg->dst_port[i]=DST_PORT; - g_otg->dst_ip[i]=(char*)malloc(100*sizeof(char*)); + g_otg->dst_ip[i]=(char *)malloc(100*sizeof(char *)); g_otg->dst_ip[i]=DST_IP; g_otg->dst_ip[i]=DST_IP; //config ip version - if (ip_version !=NULL) { if ((strcmp(ip_version,"IP4")==0) ||(strcmp(ip_version,"ip4")==0)) g_otg->ip_v[i]=IPV4; @@ -97,7 +89,6 @@ void init_config_otg(char *protocol, char *ip_version) } else g_otg->ip_v[i]=IPV4; - //config transport protocol version if (protocol!=NULL) { if ((strcmp(protocol,"TCP")==0) ||(strcmp(protocol,"tcp")==0)) @@ -123,20 +114,13 @@ void init_config_otg(char *protocol, char *ip_version) g_otg->size_std_dev[i][j][k]=PKTS_SIZE_STD_DEV; g_otg->size_lambda[i][j][k]=PKTS_SIZE_LAMBDA; } - } - - } - - - } -int main_below_ip() -{ +int main_below_ip() { int i, j, k, l, rtt_owd ,rx_otg=0, simu_time=0, ctime=0, nb_round=0; float p; char *packet; @@ -145,25 +129,17 @@ int main_below_ip() printf(" max enb %d, max ue %d \n", NUMBER_OF_eNB_MAX, NUMBER_OF_UE_MAX); do { - nb_round=nb_round+1; // for (stime=0; stime < SIMU_TIME; stime++) // discrete event generation : tick, stime generate the ctime for (i=0; i<(NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX); i++) { - for (j=0; j<(NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX); j++) { - for (k=0; k<MAX_NUM_TRAFFIC_STATE; k++) { LOG_I(OTG,"OTG emulation src=%d, dst=%d, state=%d \n", i, j, k); - - - ctime=0; // set the ctime to 0 do { - if (simu_time> SIMU_TIME) { - otg_info->ctime=SIMU_TIME; return(0); } @@ -172,21 +148,16 @@ int main_below_ip() char *packet=NULL; /*packet=packet_gen(i, j, k, ctime);*/ packet=packet_gen(i, j, ctime, &pkt_size); - - if (packet!=NULL) { if ((ceil(g_otg->duration[i]*uniform_rng()))==ctime) { - printf("DROP PACKET (i=%d,j=%d) seq num=%d\n",i, j, otg_info->seq_num[i][j]); - + printf("DROP PACKET (i=%d,j=%d) seq num=%d\n",i, j, (int)otg_info->seq_num[i][j]); } else { - printf("SEND PACKET (i=%d,j=%d) seq num=%d\n",i, j, otg_info->seq_num[i][j]); - + printf("SEND PACKET (i=%d,j=%d) seq num=%d\n",i, j, (int)otg_info->seq_num[i][j]); rtt_owd=ceil(uniform_rng()*8.56); LOG_I(OTG,"one way delay= %d , (src=%d, dst=%d, state=%d)\n", rtt_owd, i, j, k); ctime+=rtt_owd; otg_info->rx_pkt_owd[i][j]=rtt_owd; simu_time+=rtt_owd; - //rx_packet_out=check_packet(i, j, ctime, packet); rx_packet_out=otg_rx_pkt(i,j, ctime, packet, pkt_size); //if (rx_packet_out==NULL) @@ -196,18 +167,15 @@ int main_below_ip() // rx_packet_out=NULL; free(packet); // } - //} - //Do not increase the ctime and simu_time with the one way delay. ctime-=rtt_owd; simu_time-=rtt_owd; - - - LOG_I(OTG,"PKTS INFO:: (src=%d, dst=%d, state=%d),NB PKTS=%d ,sequence NB=%d, RTT (one way)ms= %d \n ",i, j, k, otg_info->tx_num_pkt[i][j], otg_info->seq_num[i][j], otg_info->rx_pkt_owd[i][j]); + LOG_I(OTG,"PKTS INFO:: (src=%d, dst=%d, state=%d),NB PKTS=%d ,sequence NB=%d, RTT (one way)ms= %d \n ", + i, j, k, (int)otg_info->tx_num_pkt[i][j], (int)otg_info->seq_num[i][j], (int)otg_info->rx_pkt_owd[i][j]); } } else - printf("Node (i=%d,j=%d) seq num=%d, ctime %d, prb %lf\n",i, j, otg_info->seq_num[i][j], ctime,(ceil(g_otg->duration[i]*uniform_rng()))); + printf("Node (i=%d,j=%d) seq num=%d, ctime %d, prb %lf\n",i, j, (int)otg_info->seq_num[i][j], ctime,(ceil(g_otg->duration[i]*uniform_rng()))); LOG_I(OTG,"Time:: ctime=%d, duration=%d, simu_time=%d, max=%d, (src=%d, dst=%d, state=%d) \n", ctime, g_otg->duration[i],simu_time, SIMU_TIME, i, j,k); ctime+=1; @@ -215,27 +183,19 @@ int main_below_ip() } while (ctime<=g_otg->duration[i]) ; } - - if (otg_info->tx_num_pkt[i][j]>otg_info->rx_num_pkt[i][j]) - LOG_I(OTG,"STAT: (LOSS):: (src=%d, dst=%d) NB packet TX= %d, NB packet RX = %d, seq NUM=%d\n ",i, j, otg_info->tx_num_pkt[i][j], otg_info->rx_num_pkt[i][j],otg_info->seq_num[i][j] ); + LOG_I(OTG,"STAT: (LOSS):: (src=%d, dst=%d) NB packet TX= %d, NB packet RX = %d, seq NUM=%d\n ", + i, j, (int)otg_info->tx_num_pkt[i][j], (int)otg_info->rx_num_pkt[i][j],(int)otg_info->seq_num[i][j] ); else - LOG_I(OTG,"STAT: :: (src=%d, dst=%d) NB packet TX= %d, NB packet RX= %d, seq NUM=%d \n ",i, j, otg_info->tx_num_pkt[i][j], otg_info->rx_num_pkt[i][j], otg_info->seq_num[i][j]); - - - + LOG_I(OTG,"STAT: :: (src=%d, dst=%d) NB packet TX= %d, NB packet RX= %d, seq NUM=%d \n ", + i, j, (int)otg_info->tx_num_pkt[i][j], (int)otg_info->rx_num_pkt[i][j], (int)otg_info->seq_num[i][j]); } } - - - } while (simu_time<=SIMU_TIME); - } -int main_above_ip() -{ +int main_above_ip() { int i, j, k, simu_time=0, ctime=0, nb_round=0; char *packet=NULL; printf(" max enb %d, max ue %d \n", NUMBER_OF_eNB_MAX, NUMBER_OF_UE_MAX); @@ -244,9 +204,7 @@ int main_above_ip() nb_round=nb_round+1; for (i=0; i<(NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX); i++) { - for (j=0; j<(NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX); j++) { - for (k=0; k<MAX_NUM_TRAFFIC_STATE; k++) { LOG_I(OTG,"SOCKET:: OTG emulation src=%d, dst=%d, state=%d \n", i, j, k); ctime=0; @@ -255,57 +213,44 @@ int main_above_ip() } } - ctime+=1; simu_time+=1; } while (simu_time<=SIMU_TIME); - } -void config_traffic_type(char *traffic) -{ +void config_traffic_type(char *traffic) { Application application; int i,j; if (strcmp(traffic, "SCBR")==0) application=SCBR; - else if (strcmp(traffic, "OPENARENA")==0) application=OPENARENA; - else if (strcmp(traffic, "BICYCLE_RACE")==0) application=BICYCLE_RACE; - else if (strcmp(traffic, "AUTO_PILOT")==0) application=AUTO_PILOT; - else if (strcmp(traffic, "TEAM_FORTRESS")==0) application=TEAM_FORTRESS; - else application=NO_PREDEFINED_TRAFFIC; printf("Config Application: %d \n", application); for (i=0; i<(NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX); i++) { - for (j=0; j<(NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX); j++) { - g_otg->application_type[i][j] =application; - } } - } -cunstom_config(simu_time, duration) -{ +cunstom_config(simu_time, duration) { int i; //--config introduced Global simulation time for each node @@ -321,37 +266,23 @@ cunstom_config(simu_time, duration) -int main (int argc, char **argv) -{ - - +int main (int argc, char **argv) { int i,j, tx; - char *protocol=NULL; char *ip_version=NULL; char *traffic=NULL; - - - - init_all_otg(); otg_info->ctime=0; LOG_I(OTG,"Emulation time %d \n ", otg_info->ctime); g_otg->num_nodes=NUMBER_OF_eNB_MAX + NUMBER_OF_UE_MAX; LOG_I(OTG,"OTG emulation number of nodes= %d \n", g_otg->num_nodes); - - for (i = 1; i <argc ; i ++) { if ('-' == argv[i][0]) { - if(('h' == argv[i][1]) || ('H' == argv[i][1])) { printf("Help OTG: \n./otg [-M [s (socket mode)] [b (Below IP)]] [-T (Simu Time)] [-d (duration per node)] [-s (seed)] [-P (protocol: TCP or UDP)] [-I (ip version: IP4 or IP6)] -A [(application: CBR, AUTO_PILOT, BICYCLE_RACE, OPENARENA, TEAM_FORTRESS)]\n"); return(0); - - } - - else if ('M' == argv[i][1]) { + } else if ('M' == argv[i][1]) { if (strcmp("s",argv[i+1])==0) { printf("Above IP: SOCKET MODE \n"); simu_mode=1; @@ -359,89 +290,53 @@ int main (int argc, char **argv) printf("Below IP: IPC/RPC MODE\n"); simu_mode=0; } - - } - - else if ('T' == argv[i][1]) { + } else if ('T' == argv[i][1]) { simu_time=atoi(argv[i+1]); printf("simu_time=%d\n", simu_time); - } - - - else if ('d' == argv[i][1]) { + } else if ('d' == argv[i][1]) { duration=atoi(argv[i+1]); printf("duration node=%d\n", duration); - } - - else if ('s' == argv[i][1]) { + } else if ('s' == argv[i][1]) { seed=atoi(argv[i+1]); printf("seed val =%d\n", seed); - } - - - else if ('P' == argv[i][1]) { + } else if ('P' == argv[i][1]) { protocol=argv[i+1]; if ((strcmp(argv[i+1],"TCP")==0) || (strcmp(argv[i+1],"UDP")==0) || (strcmp(argv[i+1],"tcp")==0) || (strcmp(argv[i+1],"udp")==0)) { protocol=argv[i+1]; printf("Protocol=%s\n", protocol); } - } - - else if ('I' == argv[i][1]) { + } else if ('I' == argv[i][1]) { if ((strcmp(argv[i+1],"IP4")==0) || (strcmp(argv[i+1],"IP6")==0) || (strcmp(argv[i+1],"ip4")==0) || (strcmp(argv[i+1],"ip6")==0)) { ip_version=argv[i+1]; printf("IP version=%s\n", ip_version); } - - - } - - else if ('A' == argv[i][1]) { + } else if ('A' == argv[i][1]) { if ((strcmp(argv[i+1],"CBR")==0) || (strcmp(argv[i+1],"AUTO_PILOT")==0) || (strcmp(argv[i+1],"BICYCLE_RACE")==0) || (strcmp(argv[i+1],"OPENARENA")==0) || (strcmp(argv[i+1],"TEAM_FORTRESS")==0)) traffic=argv[i+1]; config_traffic_type(traffic); - } - - } - - - } - - if (traffic!=NULL) init_predef_traffic(); else init_config_otg(protocol, ip_version); - init_seeds(g_otg->seed); cunstom_config(simu_time, duration); - - if (simu_mode==0) tx=main_below_ip(); - else if (simu_mode==1) tx=main_above_ip(); - - // Compute KPI after the end of the simu kpi_gen(); - free_otg(); - - - return 0; - } diff --git a/openair2/UTIL/OTG/otg_form.c b/openair2/UTIL/OTG/otg_form.c index 6994e658961b9ec76795320b24c66f8b908ea631..aea5d3888277edf14c94aa2bfcd25217b453c001 100644 --- a/openair2/UTIL/OTG/otg_form.c +++ b/openair2/UTIL/OTG/otg_form.c @@ -38,31 +38,25 @@ extern unsigned char NB_eNB_INST; extern unsigned char NB_UE_INST; -FD_otg * form_dl, *form_ul; +FD_otg *form_dl, *form_ul; FL_FORM *fclock; unsigned int clear_cmpt_ul=0; unsigned int clear_cmpt_dl=0; -FD_otg *create_form_otg(void) -{ +FD_otg *create_form_otg(void) { FL_OBJECT *obj; FD_otg *fdui = (FD_otg *) fl_calloc(1, sizeof(*fdui)); - fdui->otg = fl_bgn_form(FL_NO_BOX, 550, 550); obj = fl_add_box(FL_UP_BOX,0,0,900,700,""); fdui->owd = fl_add_xyplot(FL_NORMAL_XYPLOT,50,30,450,190,"Delay(ms)"); fl_set_object_color(fdui->owd,FL_BLACK,FL_YELLOW); fdui->throughput = fl_add_xyplot(FL_NORMAL_XYPLOT,50,300,450,190,"Throughput(Kbit/s)"); fl_set_object_color(fdui->throughput,FL_BLACK,FL_YELLOW); - - obj = fl_add_button(FL_NORMAL_BUTTON,250,510,50,30,"Exit"); fl_set_object_callback(obj, exit_cb, 0); fdui->loss_ratio=fl_add_text(FL_NORMAL_TEXT,5,510,220,20,"NB Loss pkts"); fdui->simu_time=fl_add_text(FL_NORMAL_TEXT,370,510,250,30,"Simulation Time"); - - fl_end_form(); fdui->otg->fdui = fdui; return fdui; @@ -70,18 +64,15 @@ FD_otg *create_form_otg(void) //For more details about object parameters, refer to: http://xforms-toolkit.org/doc/xforms_25.html -void show_otg_form() -{ +void show_otg_form() { int eNB_id; char title[255]; char *tArgv[] = { "OTG", "OTG" }; int tArgc = 2; - int major_owd = 6; int minor_owd = 3; int major_thr = 5; int minor_thr = 2; - fl_initialize(&tArgc,tArgv,"OTG",0,0); for (eNB_id = 0; eNB_id < NB_eNB_INST; eNB_id++) { //NB_eNB_INST @@ -98,9 +89,6 @@ void show_otg_form() fl_set_xyplot_ytics(form_dl->throughput,major_thr, minor_thr); fl_set_xyplot_ybounds(form_dl->throughput,0,1000); - - - form_ul= create_form_otg (); sprintf (title, "LTE UE->eNB (UL)"); fl_show_form (form_ul->otg, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); @@ -116,20 +104,15 @@ void show_otg_form() //fl_set_xyplot_xgrid (form_ul->throughput, FL_GRID_MAJOR); fl_set_xyplot_ytics(form_ul->throughput,major_thr, minor_thr); fl_set_xyplot_ybounds(form_ul->throughput,0,1000); - - } //create_form_clock(); //fl_show_form(fclock, FL_PLACE_CENTER,FL_TRANSIENT,"clocks"); //fl_do_forms(); - fl_check_forms(); } -void add_tab_metric(int src, int dst, float owd, float throughput, int ctime) -{ - +void add_tab_metric(int src, int dst, float owd, float throughput, int ctime) { if (otg_forms_info->init_forms==0) { show_otg_form(); otg_forms_info->init_forms=1; @@ -158,9 +141,7 @@ void add_tab_metric(int src, int dst, float owd, float throughput, int ctime) } -void plot_graphes_ul(int src, int dst, int ctime) //UE -->eNB -{ - +void plot_graphes_ul(int src, int dst, int ctime) { //UE -->eNB int i, src_idx=1, curve_id=1; char loss_rate[100]; char simu_time[100]; @@ -169,12 +150,8 @@ void plot_graphes_ul(int src, int dst, int ctime) //UE -->eNB int y_key_position=75; if (otg_forms_info->idx_ul[src][dst]==MAX_SAMPLES-1) { - fl_update_display(1); //the function flushes the X buffer so the drawing requests are on their way to the server - - - if (otg_forms_info->is_data_plot_ul == -1) otg_forms_info->is_data_plot_ul=src; @@ -184,17 +161,13 @@ void plot_graphes_ul(int src, int dst, int ctime) //UE -->eNB sprintf(curve_label, "%d%s%d", src,"-->", dst); fl_set_xyplot_key(form_ul->owd, 0, curve_label); fl_set_xyplot_key_position(form_ul->owd, x_key_position,y_key_position, FL_ALIGN_BOTTOM_LEFT); - fl_set_xyplot_data (form_ul->throughput, otg_forms_info->data_ctime_ul[src][dst], otg_forms_info->data_throughput_ul[src][dst], otg_forms_info->idx_ul[src][dst], "", "time", "kbit/s"); fl_set_xyplot_key(form_ul->throughput, 0, curve_label); fl_set_xyplot_key_font(form_ul->throughput, FL_BOLD_STYLE, FL_HUGE_SIZE); fl_set_xyplot_key_position(form_ul->throughput, x_key_position,y_key_position , FL_ALIGN_BOTTOM_LEFT); - - - otg_kpi_nb_loss_pkts(); - sprintf(loss_rate, "%s%d","NB Loss pkts UL=", otg_info->total_loss_ul); + sprintf(loss_rate, "%s%u","NB Loss pkts UL=", otg_info->total_loss_ul); fl_set_object_label(form_ul->loss_ratio, loss_rate); sprintf(simu_time, "%s%d","Simulation Time(ms)=", ctime); fl_set_object_label(form_ul->simu_time, simu_time); @@ -204,20 +177,16 @@ void plot_graphes_ul(int src, int dst, int ctime) //UE -->eNB sprintf(curve_label, "%d%s%d", otg_forms_info->is_data_plot_ul,"-->", dst); fl_set_xyplot_key(form_ul->owd, 0, curve_label); fl_set_xyplot_key_position(form_ul->owd, x_key_position,y_key_position, FL_ALIGN_BOTTOM_LEFT); - - fl_set_xyplot_data (form_ul->throughput, otg_forms_info->data_ctime_ul[otg_forms_info->is_data_plot_ul][dst], otg_forms_info->data_throughput_ul[otg_forms_info->is_data_plot_ul][dst], otg_forms_info->idx_ul[otg_forms_info->is_data_plot_ul][dst], "", "time", "kbit/s"); sprintf(curve_label, "%d%s%d", otg_forms_info->is_data_plot_ul,"-->", dst); fl_set_xyplot_key(form_ul->throughput, 0, curve_label); fl_set_xyplot_key_position(form_ul->throughput, x_key_position,y_key_position , FL_ALIGN_BOTTOM_LEFT); - otg_kpi_nb_loss_pkts(); - sprintf(loss_rate, "%s%d","NB Loss pkts UL=",otg_info->total_loss_ul); + sprintf(loss_rate, "%s%u","NB Loss pkts UL=",otg_info->total_loss_ul); fl_set_object_label(form_ul->loss_ratio, loss_rate); sprintf(simu_time, "%s%d","Simulation Time(ms)=", ctime); fl_set_object_label(form_ul->simu_time, simu_time); - } for (src_idx=1; src_idx<=NB_UE_INST; src_idx++) { @@ -229,9 +198,6 @@ void plot_graphes_ul(int src, int dst, int ctime) //UE -->eNB sprintf(curve_label, "%d%s%d", src_idx,"-->", dst); fl_set_xyplot_key(form_ul->owd, curve_id-1, curve_label); fl_set_xyplot_key_position(form_ul->owd, x_key_position,y_key_position, FL_ALIGN_BOTTOM_LEFT); - - - fl_add_xyplot_overlay(form_ul->throughput,curve_id++, otg_forms_info->data_ctime_ul[src_idx][dst], otg_forms_info->data_throughput_ul[src_idx][dst], @@ -242,7 +208,6 @@ void plot_graphes_ul(int src, int dst, int ctime) //UE -->eNB } } - for (i=0; i<otg_forms_info->idx_ul[src][dst]; i++) { otg_forms_info->data_ctime_ul[src][dst][otg_forms_info->idx_ul[src][dst]]=i; otg_forms_info->data_owd_ul[src][dst][i]= otg_forms_info->data_owd_ul[src][dst][i+1]; @@ -253,14 +218,11 @@ void plot_graphes_ul(int src, int dst, int ctime) //UE -->eNB } fl_check_forms(); - } -void plot_graphes_dl(int src, int dst, int ctime) //eNB -->UE -{ - +void plot_graphes_dl(int src, int dst, int ctime) { //eNB -->UE int i, dst_idx=1, curve_id=1; char loss_rate[100]; char curve_label[100]; @@ -269,11 +231,8 @@ void plot_graphes_dl(int src, int dst, int ctime) //eNB -->UE int y_key_position=75; if (otg_forms_info->idx_dl[src][dst]==MAX_SAMPLES-1) { - fl_update_display(1); //the function flushes the X buffer so the drawing requests are on their way to the server - - if (otg_forms_info->is_data_plot_dl == -1) otg_forms_info->is_data_plot_dl=dst; @@ -289,12 +248,10 @@ void plot_graphes_dl(int src, int dst, int ctime) //eNB -->UE fl_set_xyplot_key(form_dl->throughput, 0, curve_label); fl_set_xyplot_key_position(form_dl->throughput, x_key_position,y_key_position, FL_ALIGN_BOTTOM_LEFT); otg_kpi_nb_loss_pkts(); - sprintf(loss_rate, "%s%d","NB Loss pkts DL=",otg_info->total_loss_dl); + sprintf(loss_rate, "%s%u","NB Loss pkts DL=",otg_info->total_loss_dl); fl_set_object_label(form_dl->loss_ratio, loss_rate); - sprintf(simu_time, "%s%d","Simulation Time(ms)=", ctime); fl_set_object_label(form_dl->simu_time, simu_time); - } else { fl_set_xyplot_data (form_dl->owd, otg_forms_info->data_ctime_dl[src][otg_forms_info->is_data_plot_dl], otg_forms_info->data_owd_dl[src][otg_forms_info->is_data_plot_dl], otg_forms_info->idx_dl[src][otg_forms_info->is_data_plot_dl], "", "time", "ms"); @@ -306,9 +263,8 @@ void plot_graphes_dl(int src, int dst, int ctime) //eNB -->UE sprintf(curve_label, "%d%s%d", src,"-->",otg_forms_info->is_data_plot_dl); fl_set_xyplot_key(form_dl->throughput, 0, curve_label); fl_set_xyplot_key_position(form_dl->throughput,x_key_position,y_key_position, FL_ALIGN_BOTTOM_LEFT); - otg_kpi_nb_loss_pkts(); - sprintf(loss_rate, "%s%d","NB Loss pkts DL=",otg_info->total_loss_dl); + sprintf(loss_rate, "%s%u","NB Loss pkts DL=",otg_info->total_loss_dl); fl_set_object_label(form_dl->loss_ratio, loss_rate); sprintf(simu_time, "%s%d","Simulation Time(ms)=", ctime); fl_set_object_label(form_dl->simu_time, simu_time); @@ -323,7 +279,6 @@ void plot_graphes_dl(int src, int dst, int ctime) //eNB -->UE sprintf(curve_label, "%d%s%d", src,"-->", dst_idx); fl_set_xyplot_key(form_dl->owd, curve_id-1, curve_label); fl_set_xyplot_key_position(form_dl->owd, x_key_position,y_key_position, FL_ALIGN_BOTTOM_LEFT); - fl_add_xyplot_overlay(form_dl->throughput,curve_id++, otg_forms_info->data_ctime_dl[src][dst_idx], otg_forms_info->data_throughput_dl[src][dst_idx], @@ -331,8 +286,6 @@ void plot_graphes_dl(int src, int dst, int ctime) //eNB -->UE sprintf(curve_label, "%d%s%d", src,"-->", dst_idx); fl_set_xyplot_key(form_dl->throughput, curve_id-1, curve_label); fl_set_xyplot_key_position(form_dl->throughput, x_key_position,y_key_position, FL_ALIGN_BOTTOM_LEFT); - - } } @@ -346,7 +299,6 @@ void plot_graphes_dl(int src, int dst, int ctime) //eNB -->UE } fl_check_forms(); - } @@ -354,14 +306,12 @@ void plot_graphes_dl(int src, int dst, int ctime) //eNB -->UE -void exit_cb(FL_OBJECT *ob, long q) -{ +void exit_cb(FL_OBJECT *ob, long q) { fl_finish(); exit(0); } -void create_form_clock(void) -{ +void create_form_clock(void) { FL_OBJECT *obj; if (fclock) @@ -369,22 +319,18 @@ void create_form_clock(void) fclock = fl_bgn_form(FL_NO_BOX,500,350); obj = fl_add_box(FL_UP_BOX,0,0,500,350,""); - obj = fl_add_clock(FL_DIGITAL_CLOCK,185,20,150,35,""); fl_set_object_boxtype(obj,FL_ROUNDED_BOX); fl_set_object_color(obj,FL_COL1,FL_BLACK); fl_set_object_lsize(obj,FL_MEDIUM_SIZE); fl_set_object_lstyle(obj,FL_BOLD_STYLE); - obj = fl_add_clock(FL_ANALOG_CLOCK,30,70,220,200,""); fl_set_object_boxtype(obj,FL_UP_BOX); - obj = fl_add_clock(FL_ANALOG_CLOCK,260,70,220,200,""); fl_set_object_boxtype(obj,FL_OVAL3D_UPBOX); obj = fl_add_button(FL_NORMAL_BUTTON,375,300,110,35,"Exit"); fl_set_object_callback(obj, exit_cb, 0); fl_end_form(); - fl_scale_form(fclock, 0.7, 0.7); } diff --git a/openair2/UTIL/OTG/otg_kpi.c b/openair2/UTIL/OTG/otg_kpi.c index 94a0a53d5c54025b6e7c340cfa2a3dbe8af69010..3af84adc8b303275048733b9255a6f3c92be52c9 100644 --- a/openair2/UTIL/OTG/otg_kpi.c +++ b/openair2/UTIL/OTG/otg_kpi.c @@ -43,23 +43,22 @@ unsigned int start_log_jitter=0; extern unsigned char NB_eNB_INST; extern unsigned char NB_UE_INST; -void tx_throughput(int src, int dst, int application) -{ - +void tx_throughput(int src, int dst, int application) { if (otg_info->tx_num_bytes[src][dst][application]>0) { // otg_info->tx_throughput[src][dst][application]=((double)otg_info->tx_num_bytes[src][dst][application] *1000*8)/ (get_ctime()*1024); // unit Kbit/sec, if ctime in ms if ((g_otg->flow_start[src][dst][application]+g_otg->flow_duration[src][dst][application]) < get_ctime() ) - otg_info->tx_throughput[src][dst][application]=((double)otg_info->tx_num_bytes[src][dst][application] *1000*8)/ ((g_otg->flow_start[src][dst][application]+g_otg->flow_duration[src][dst][application])*1024); // unit Kbit/sec, if ctime in ms + otg_info->tx_throughput[src][dst][application]=((double)otg_info->tx_num_bytes[src][dst][application] *1000*8)/ ((g_otg->flow_start[src][dst][application]+g_otg->flow_duration[src][dst][application]) + *1024); // unit Kbit/sec, if ctime in ms else if (g_otg->flow_start[src][dst][application] < get_ctime() ) otg_info->tx_throughput[src][dst][application]=((double)otg_info->tx_num_bytes[src][dst][application] *1000*8)/ ((get_ctime() - g_otg->flow_start[src][dst][application])*1024); - else + else LOG_W(OTG, "[src %d][dst %d][app %d] flow start time less than the simu time (start %d, duration %d, ctime %d)\n", - src, dst, application, - g_otg->flow_start[src][dst][application], - g_otg->flow_duration[src][dst][application], - get_ctime()); + src, dst, application, + g_otg->flow_start[src][dst][application], + g_otg->flow_duration[src][dst][application], + get_ctime()); } - + if (otg_info->tx_num_bytes_background[src][dst]>0) otg_info->tx_throughput_background[src][dst]=((double)otg_info->tx_num_bytes_background[src][dst]*1000*8)/ (get_ctime()*1024); // unit Kbit/sec, if ctime in ms @@ -71,26 +70,24 @@ void tx_throughput(int src, int dst, int application) // LOG_I(OTG,"DUY, get_ctime() [i=%d,j=%d,k=%d] = %.d\n", src,dst,application,get_ctime()); LOG_I(OTG,"otg_multicast_info->tx_num_bytes[i=%d,j=%d,k=%d] = %.d\n", src,dst,application,otg_multicast_info->tx_num_bytes[src][dst][application]); } - } -void rx_goodput(int src, int dst, int application) -{ - +void rx_goodput(int src, int dst, int application) { if (otg_info->rx_num_bytes[src][dst][application]>0) { // otg_info->rx_goodput[src][dst][application]=((double)otg_info->rx_num_bytes[src][dst][application]*1000*8)/(get_ctime()*1024); // unit kB/sec, if ctime in ms -if ((g_otg->flow_start[src][dst][application]+g_otg->flow_duration[src][dst][application]) < get_ctime() ) - otg_info->rx_goodput[src][dst][application]=((double)otg_info->rx_num_bytes[src][dst][application] *1000*8)/ ((g_otg->flow_start[src][dst][application]+g_otg->flow_duration[src][dst][application])*1024); // unit Kbit/sec, if ctime in ms + if ((g_otg->flow_start[src][dst][application]+g_otg->flow_duration[src][dst][application]) < get_ctime() ) + otg_info->rx_goodput[src][dst][application]=((double)otg_info->rx_num_bytes[src][dst][application] *1000*8)/ ((g_otg->flow_start[src][dst][application]+g_otg->flow_duration[src][dst][application]) + *1024); // unit Kbit/sec, if ctime in ms else if (g_otg->flow_start[src][dst][application] < get_ctime() ) otg_info->rx_goodput[src][dst][application]=((double)otg_info->rx_num_bytes[src][dst][application] *1000*8)/ ((get_ctime() - g_otg->flow_start[src][dst][application])*1024); - else + else LOG_W(OTG, "[src %d][dst %d][app %d] flow start time less than the simu time (start %d, duration %d, ctime %d)\n", - src, dst, application, - g_otg->flow_start[src][dst][application], - g_otg->flow_duration[src][dst][application], - get_ctime()); + src, dst, application, + g_otg->flow_start[src][dst][application], + g_otg->flow_duration[src][dst][application], + get_ctime()); } if (otg_info->rx_num_bytes_background[src][dst]>0) @@ -105,9 +102,7 @@ if ((g_otg->flow_start[src][dst][application]+g_otg->flow_duration[src][dst][app -void rx_loss_rate_pkts(int src, int dst, int application) -{ - +void rx_loss_rate_pkts(int src, int dst, int application) { if (otg_info->rx_num_pkt[src][dst][application]<otg_info->tx_num_pkt[src][dst][application]) otg_info->rx_loss_rate[src][dst][application]= 1 - ((double)otg_info->rx_num_pkt[src][dst][application]/otg_info->tx_num_pkt[src][dst][application]); else @@ -127,26 +122,20 @@ void rx_loss_rate_pkts(int src, int dst, int application) otg_multicast_info->rx_loss_rate[src][dst]= 1 - ((double)otg_multicast_info->rx_num_pkt[src][dst][application]/otg_multicast_info->tx_num_pkt[src][dst][0]); else otg_multicast_info->rx_loss_rate[src][dst]=0; - } -void rx_loss_rate_bytes(int src, int dst, int application) -{ - +void rx_loss_rate_bytes(int src, int dst, int application) { if (otg_info->rx_num_pkt[src][dst][application]<otg_info->tx_num_pkt[src][dst][application]) otg_info->rx_loss_rate[src][dst][application]= 1 - ((double)otg_info->rx_num_bytes[src][dst][application]/otg_info->tx_num_bytes[src][dst][application]); else otg_info->rx_loss_rate[src][dst][application]=0; LOG_I(OTG, "loss rate (src=%d, dst=%d, appli %d ):: = %lf(bytes) \n",src, dst, application, otg_info->rx_loss_rate[src][dst][application]); - } -void otg_kpi_nb_loss_pkts(void) -{ +void otg_kpi_nb_loss_pkts(void) { unsigned int i,j,k; - otg_info->total_loss_dl=0; otg_info->total_loss_ul=0; @@ -162,9 +151,7 @@ void otg_kpi_nb_loss_pkts(void) } } -void average_pkt_jitter(int src, int dst, int application) -{ - +void average_pkt_jitter(int src, int dst, int application) { if (otg_info->rx_jitter_sample[src][dst][application] > 0 ) { otg_info->rx_jitter_avg[src][dst][application]/= otg_info->rx_jitter_sample[src][dst][application]; otg_info->rx_jitter_avg_e2e[src][dst][application]/= otg_info->rx_jitter_sample[src][dst][application]; @@ -189,13 +176,10 @@ void average_pkt_jitter(int src, int dst, int application) LOG_T(OTG,"average_jitter_dl %lf average_jitter_ul %lf \n",otg_info->average_jitter_dl_e2e,otg_info->average_jitter_ul_e2e); } - } -void average_total_jitter(void) -{ +void average_total_jitter(void) { unsigned int i,j,k; - otg_info->average_jitter_dl=0; otg_info->average_jitter_ul=0; otg_info->average_jitter_dl_e2e=0; @@ -207,7 +191,6 @@ void average_total_jitter(void) if (i<NB_eNB_INST) { otg_info->average_jitter_dl+=otg_info->rx_jitter_avg[i][j][k]; otg_info->average_jitter_dl_e2e+=otg_info->rx_jitter_avg_e2e[i][j][k]; - } else { otg_info->average_jitter_ul+=otg_info->rx_jitter_avg[i][j][k]; otg_info->average_jitter_ul_e2e+=otg_info->rx_jitter_avg_e2e[i][j][k]; @@ -221,10 +204,8 @@ void average_total_jitter(void) // otg_info->average_jitter_ul/= (float)NB_UE_INST; } -void kpi_gen() -{ +void kpi_gen() { int i, j,k; - int tx_total_bytes_dl=0; int tx_total_pkts_dl=0; int rx_total_bytes_dl=0; @@ -233,13 +214,10 @@ void kpi_gen() int tx_total_pkts_ul=0; int rx_total_bytes_ul=0; int rx_total_pkts_ul=0; - float min_owd_dl=0; float max_owd_dl=0; - float min_owd_dl_e2e=0; float max_owd_dl_e2e=0; - int tx_total_bytes_dl_background=0; int tx_total_pkts_dl_background=0; int rx_total_bytes_dl_background=0; @@ -248,27 +226,18 @@ void kpi_gen() int tx_total_pkts_ul_background=0; int rx_total_bytes_ul_background=0; int rx_total_pkts_ul_background=0; - float min_owd_ul=0; float max_owd_ul=0; float min_owd_ul_e2e=0; float max_owd_ul_e2e=0; - - int tx_total_bytes_dl_multicast=0; int tx_total_pkts_dl_multicast=0; int rx_total_bytes_dl_multicast=0; int rx_total_pkts_dl_multicast=0; - - int num_active_source=0; - - int dl_ok=1,ul_ok=1; - char traffic_type[12]; char traffic[30]; - #ifdef STANDALONE FILE *file; file = fopen("log_OTG.txt", "w"); @@ -281,11 +250,8 @@ void kpi_gen() #endif - - for (i=0; i<(NB_eNB_INST + NB_UE_INST); i++) { for (j=0; j<(NB_eNB_INST + NB_UE_INST); j++) { - /*background stats*/ if (i<NB_eNB_INST) { tx_total_bytes_dl_background+=otg_info->tx_num_bytes_background[i][j]; @@ -300,7 +266,6 @@ void kpi_gen() } for (k=0; k<MAX_NUM_APPLICATION; k++) { - tx_throughput(i,j,k); rx_goodput(i,j,k); rx_loss_rate_pkts(i,j,k); @@ -319,7 +284,6 @@ void kpi_gen() tx_total_pkts_dl_multicast+=otg_multicast_info->tx_num_pkt[i][j][k]; rx_total_bytes_dl_multicast+=otg_multicast_info->rx_num_bytes[i][j][k]; rx_total_pkts_dl_multicast+=otg_multicast_info->rx_num_pkt[i][j][k]; - #ifdef STANDALONE LOG_I(OTG,"No stats for multicast "); // do nothing #else @@ -329,21 +293,17 @@ void kpi_gen() if (otg_multicast_info->tx_num_bytes[i][j][k]>0) { LOG_I(OTG,"----------------------------------------------------------\n"); LOG_I(OTG,"Total Time (multicast) (ms)= %d \n", otg_info->ctime+1); - // LOG_I(OTG,"[%s] Multicast [eNB:%d -> UE:%d] \n",traffic_type, i, j); - LOG_I(OTG,"[MULTICAST] Total packets(TX)= %d \n", otg_multicast_info->tx_num_pkt[i][j][k]); LOG_I(OTG,"[MULTICAST] Total bytes(TX)= %d \n", otg_multicast_info->tx_num_bytes[i][j][k]); LOG_I(OTG,"[MULTICAST] Total packets(RX)= %d \n", otg_multicast_info->rx_num_pkt[i][j][k]); LOG_I(OTG,"[MULTICAST] Total bytes(RX)= %d \n", otg_multicast_info->rx_num_bytes[i][j][k]); - LOG_I(OTG,"[MULTICAST] TX throughput = %.7f (Kbit/s) \n", otg_multicast_info->tx_throughput[i][j]); LOG_I(OTG,"[MULTICAST] RX goodput = %.7f (Kbit/s) \n", otg_multicast_info->rx_goodput[i][j]); // if (otg_multicast_info->rx_loss_rate[i][j]>0){ // LOG_I(OTG,"[MULTICAST] Loss rate = %lf \n", (otg_multicast_info->rx_loss_rate[i][j])); // LOG_I(OTG,"[MULTICAST] NB Lost packets=%d \n", (otg_multicast_info->tx_num_pkt[i][j][k]-otg_multicast_info->rx_num_pkt[i][j][k])); //} - // if ((g_otg->background_stats==1)&&(otg_info->tx_num_bytes_background[i][j]>0)){ LOG_F(OTG,"----------------------------------------------------------\n"); LOG_F(OTG,"Total Time (multicast) (ms)= %d \n", otg_info->ctime+1); @@ -363,12 +323,9 @@ void kpi_gen() } #endif - }// end for multicast - if ((otg_info->tx_throughput[i][j][k]>0)||((otg_info->tx_throughput_background[i][j]>0) && (otg_info->tx_num_bytes[i][j][k]>0))) { - num_active_source+=1; if (i<NB_eNB_INST) { // DL @@ -392,7 +349,6 @@ void kpi_gen() if ((max_owd_dl_e2e<otg_info->rx_owd_max_e2e[i][j][k]) || (max_owd_dl_e2e==0)) max_owd_dl_e2e=otg_info->rx_owd_max_e2e[i][j][k]; - } else { // UL tx_total_bytes_ul+=otg_info->tx_num_bytes[i][j][k]; tx_total_pkts_ul+=otg_info->tx_num_pkt[i][j][k]; @@ -414,7 +370,6 @@ void kpi_gen() if ((max_owd_ul_e2e<otg_info->rx_owd_max_e2e[i][j][k]) || (max_owd_ul_e2e==0)) max_owd_ul_e2e=otg_info->rx_owd_max_e2e[i][j][k]; - } //LOG_D(OTG,"KPI: (src=%d, dst=%d, appli %d) NB packet TX= %d, NB packet RX= %d\n ",i, j, otg_info->tx_num_pkt[i][j][k], otg_info->rx_num_pkt[i][j][k]); @@ -432,9 +387,7 @@ void kpi_gen() traffic[sizeof(traffic) - 1] = 0; // terminate string } - #ifdef STANDALONE - fprintf(file,"----------------------------------------------------------\n"); fprintf(file,"Total Time (ms)= %d \n", otg_info->ctime+1); @@ -467,8 +420,6 @@ void kpi_gen() } } */ - - #else LOG_I(OTG,"----------------------------------------------------------\n"); LOG_I(OTG,"Total Time (ms)= %d \n", otg_info->ctime+1); @@ -555,15 +506,11 @@ void kpi_gen() } */ #endif - } // if ((otg_multicast_info->tx_throughput[i][j]>0) && (otg_info->tx_num_bytes[i][j][k]>0)) { - }// end loop of k - - #ifdef STANDALONE if ((g_otg->background_stats==1)&&(otg_info->tx_num_bytes_background[i][j]>0)) { @@ -629,14 +576,10 @@ void kpi_gen() } #endif - - }// end loop of j }// end loop of i - // average_total_jitter(); - #ifdef STANDALONE fprintf (file,"**************** TOTAL DL RESULTS ******************\n"); fprintf(file,"Total Time= %d \n", otg_info->ctime+1); @@ -723,7 +666,6 @@ void kpi_gen() LOG_I(OTG,"[MULTICAST] RX throughput = %.7f(Kbit/s) \n", ((double)rx_total_bytes_dl_multicast*1000*8)/(otg_info->ctime*1024)); } - LOG_F(OTG,"**************** TOTAL DL RESULTS ******************\n"); LOG_F(OTG,"Total Time (ms)= %d \n", otg_info->ctime+1); LOG_F(OTG,"[DATA] Total packets(TX)= %d \n", tx_total_pkts_dl); @@ -762,8 +704,6 @@ void kpi_gen() LOG_F(OTG,"[MULTICAST] RX throughput = %.7f(Kbit/s) \n", ((double)rx_total_bytes_dl_multicast*1000*8)/(otg_info->ctime*1024)); } - - LOG_I(OTG,"**************** TOTAL UL RESULTS ******************\n"); LOG_I(OTG,"Total Time (ms)= %d \n", otg_info->ctime+1); LOG_I(OTG,"[DATA] Total packets(TX)= %d \n", tx_total_pkts_ul); @@ -795,7 +735,6 @@ void kpi_gen() LOG_I(OTG,"[BACKGROUND] Total bytes(RX)= %d \n", rx_total_bytes_ul_background); LOG_I(OTG,"[BACKGROUND] TX throughput = %.7f(Kbit/s) \n", ((double)tx_total_bytes_ul_background*1000*8)/(otg_info->ctime*1024)); LOG_I(OTG,"[BACKGROUND] RX throughput = %.7f(Kbit/s) \n", ((double)rx_total_bytes_ul_background*1000*8)/(otg_info->ctime*1024)); - } LOG_F(OTG,"**************** TOTAL UL RESULTS ******************\n"); @@ -825,7 +764,6 @@ void kpi_gen() LOG_F(OTG,"[BACKGROUND] Total bytes(RX)= %d \n", rx_total_bytes_ul_background); LOG_F(OTG,"[BACKGROUND] TX throughput = %.7f(Kbit/s) \n", ((double)tx_total_bytes_ul_background*1000*8)/(otg_info->ctime*1024)); LOG_F(OTG,"[BACKGROUND] RX throughput = %.7f(Kbit/s) \n", ((double)rx_total_bytes_ul_background*1000*8)/(otg_info->ctime*1024)); - } if ((dl_ok == 1 ) && (ul_ok ==1)) @@ -837,8 +775,7 @@ void kpi_gen() } -void add_log_metric(int src, int dst, int ctime, double metric, unsigned int label) -{ +void add_log_metric(int src, int dst, int ctime, double metric, unsigned int label) { unsigned int i; unsigned int j; unsigned int node_actif=0; @@ -846,28 +783,27 @@ void add_log_metric(int src, int dst, int ctime, double metric, unsigned int lab //LOG_I(OTG,"[%d][%d] LOGG_ADDED ctime=%d, metric=%.2f \n", src, dst, ctime, metric); switch (label) { - case OTG_LATENCY: - add_log_label(label, &start_log_latency); - break; - - case OTG_LATENCY_BG: - add_log_label(label, &start_log_latency_bg); - break; - - case OTG_GP: - add_log_label(label, &start_log_GP); - break; - - case OTG_GP_BG: - add_log_label(label, &start_log_GP_bg); - break; - - case OTG_JITTER: - add_log_label(label, &start_log_GP_bg); - break; - - default: - LOG_E(OTG, "File label unknown %d \n", label); + case OTG_LATENCY: + add_log_label(label, &start_log_latency); + break; + + case OTG_LATENCY_BG: + add_log_label(label, &start_log_latency_bg); + break; + + case OTG_GP: + add_log_label(label, &start_log_GP); + break; + + case OTG_GP_BG: + add_log_label(label, &start_log_GP_bg); + break; + + case OTG_JITTER: + add_log_label(label, &start_log_GP_bg); + break; + default: + LOG_E(OTG, "File label unknown %u \n", label); } LOG_F(label,"%d ", ctime); @@ -892,8 +828,7 @@ void add_log_metric(int src, int dst, int ctime, double metric, unsigned int lab -void add_log_label(unsigned int label, unsigned int * start_log_metric) -{ +void add_log_label(unsigned int label, unsigned int *start_log_metric) { unsigned int i; unsigned int j; unsigned int node_actif=0; @@ -910,7 +845,7 @@ void add_log_label(unsigned int label, unsigned int * start_log_metric) node_actif++; if (node_actif>0) - LOG_F(label,"%d->%d ", i, j); + LOG_F(label,"%u->%u ", i, j); } } diff --git a/openair2/UTIL/OTG/otg_rx.c b/openair2/UTIL/OTG/otg_rx.c index 46cad30cb8b78a5d16b5264e8e8d0826b76da9a4..a8b18e23b7aa5f6f84b84ae7d5f2fe449ca93d69 100644 --- a/openair2/UTIL/OTG/otg_rx.c +++ b/openair2/UTIL/OTG/otg_rx.c @@ -38,9 +38,9 @@ #include "otg_kpi.h" #ifdef ENABLE_DB_STATS -#include <mysql.h> -#include <m_ctype.h> -#include <sql_common.h> + #include <mysql.h> + #include <m_ctype.h> + #include <sql_common.h> #endif extern unsigned char NB_eNB_INST; @@ -54,12 +54,10 @@ extern unsigned char NB_UE_INST; #define MIN(x,y) ((x)<(y)?(x):(y)) // Check if the packet is well received or not and extract data -int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buffer_tx, const unsigned int size) -{ - +int otg_rx_pkt(const int dst_instanceP, const int ctime, const char *const buffer_tx, const unsigned int size) { int bytes_read = 0; - otg_hdr_info_t * otg_hdr_info_rx; - otg_hdr_t * otg_hdr_rx; + otg_hdr_info_t *otg_hdr_info_rx; + otg_hdr_t *otg_hdr_rx; int is_size_ok = 0; unsigned int seq_num_rx; unsigned int nb_loss_pkts; @@ -70,26 +68,22 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff if (buffer_tx!=NULL) { otg_hdr_info_rx = (otg_hdr_info_t *) (&buffer_tx[bytes_read]); bytes_read += sizeof (otg_hdr_info_t); - - LOG_D(OTG,"otg_rx_pkt functions: destination %d, size %d, otg_hdr_info_rx->flag %.4x, otg_hdr_info_rx->size %d \n", + LOG_D(OTG,"otg_rx_pkt functions: destination %d, size %u, otg_hdr_info_rx->flag %.4x, otg_hdr_info_rx->size %u \n", dst_instanceP, size, otg_hdr_info_rx->flag, otg_hdr_info_rx->size); - if (((otg_hdr_info_rx->flag == 0xffff) || (otg_hdr_info_rx->flag == 0xbbbb) || (otg_hdr_info_rx->flag == 0x1000)) && (otg_hdr_info_rx->size == size )) { //data traffic - LOG_I(OTG,"MAX_RX_INFO %d %d \n",NB_eNB_INST, NB_UE_INST); - /*is_size_ok= 0; if (( otg_hdr_info_rx->size ) == size ) {*/ is_size_ok= 1; otg_hdr_rx = (otg_hdr_t *) (&buffer_tx[bytes_read]); - LOG_I(OTG,"[SRC %d][DST %d] [FLOW_idx %d][APP TYPE %d] RX INFO pkt at time %d: flag 0x %x, seq number %d, tx time %d, size (hdr %d, pdcp %d) \n", + LOG_I(OTG,"[SRC %u][DST %u] [FLOW_idx %u][APP TYPE %u] RX INFO pkt at time %d: flag 0x %x, seq number %u, tx time %u, size (hdr %u, pdcp %u) \n", otg_hdr_rx->src_instance, otg_hdr_rx->dst_instance, otg_hdr_rx->flow_id, @@ -99,14 +93,12 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_hdr_rx->seq_num, otg_hdr_rx->time, otg_hdr_info_rx->size, size); - bytes_read += sizeof (otg_hdr_t); - src_instance = otg_hdr_rx->src_instance; dst_instance = otg_hdr_rx->dst_instance; if (dst_instance != dst_instanceP) { -//#warning "LG: TODO think about multicast traffic" + //#warning "LG: TODO think about multicast traffic" /* TODO: fix this LOG, a lot of missing parameters, replaced by a simple basic version */ /*LOG_W(OTG,"[SRC %d][DST %d] [FLOW_idx %d][APP TYPE %d] RX INFO pkt at time %d: flag 0x %x, seq number %d, tx time %d, size (hdr %d, pdcp %d) not for dest instance %u\n", dst_instanceP);*/ @@ -114,7 +106,7 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff } if(otg_hdr_rx->traffic_type > MAX_NUM_APPLICATION) { - LOG_W(OTG,"RX packet: application type out of range %d for the pair of (src %d, dst %d) \n", + LOG_W(OTG,"RX packet: application type out of range %u for the pair of (src %u, dst %u) \n", otg_hdr_rx->traffic_type, src_instance, dst_instance); otg_hdr_rx->traffic_type=0; } @@ -135,7 +127,7 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff // rx_check_loss(src_instance, dst_instance, otg_hdr_info_rx->flag, otg_hdr_rx->seq_num, &seq_num_rx, &nb_loss_pkts); // otg_multicast_info->loss_rate[src_instance][dst_instance][otg_hdr_rx->traffic_type]=nb_loss_pkts; //otg_multicast_info->rx_sn[src_instance][dst_instance][otg_hdr_rx->traffic_type]=seq_num_rx; - LOG_I(OTG,"received a multicast packet with size %d sn %d ran owd %d loss rate %d\n", + LOG_I(OTG,"received a multicast packet with size %u sn %u ran owd %u loss rate %u\n", otg_hdr_info_rx->size, seq_num_rx, ctime- otg_hdr_rx->time, nb_loss_pkts); //return 0; } /** background traffic **/ @@ -148,10 +140,8 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff nb_loss_pkts=otg_info->nb_loss_pkts_background_ul[src_instance][dst_instance]; } - - LOG_D(OTG,"[%d][%d] AGGREGATION LEVEL (RX) %d \n", src_instance, dst_instance, otg_hdr_rx->aggregation_level); + LOG_D(OTG,"[%u][%u] AGGREGATION LEVEL (RX) %u \n", src_instance, dst_instance, otg_hdr_rx->aggregation_level); otg_info->aggregation_level[src_instance][dst_instance]=otg_hdr_rx->aggregation_level; - /* Loss and out of sequence data management */ lost_packet= rx_check_loss( src_instance, @@ -161,11 +151,9 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff &seq_num_rx, &nb_loss_pkts); - if (otg_info->owd_const[src_instance][dst_instance][otg_hdr_rx->flow_id]==0) owd_const_gen(src_instance,dst_instance,otg_hdr_rx->flow_id, otg_hdr_rx->traffic_type); - /******/ /* float owd_const_capillary_v=owd_const_capillary()/2; @@ -185,7 +173,7 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_info->radio_access_delay[src_instance][dst_instance]=(float) (ctime- otg_hdr_rx->time); otg_multicast_info->radio_access_delay[src_instance][dst_instance]=(float) (ctime- otg_hdr_rx->time); } else { - LOG_I(OTG,"received packet has tx time %d greater than the current time %d\n",otg_hdr_rx->time,ctime ); + LOG_I(OTG,"received packet has tx time %u greater than the current time %d\n",otg_hdr_rx->time,ctime ); otg_info->radio_access_delay[src_instance][dst_instance] = 0; otg_multicast_info->radio_access_delay[src_instance][dst_instance]=0; } @@ -196,8 +184,7 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_info->rx_pkt_owd_e2e[src_instance][dst_instance]= otg_info->owd_const[src_instance][dst_instance][otg_hdr_rx->flow_id] + otg_info->radio_access_delay[src_instance][dst_instance]; otg_multicast_info->rx_pkt_owd[src_instance][dst_instance]=otg_multicast_info->radio_access_delay[src_instance][dst_instance]; - - LOG_D(OTG, "[src %d][dst %d] ctime %d tx time %d: OWD %lf E2E OWD %lf \n", + LOG_D(OTG, "[src %u][dst %u] ctime %d tx time %u: OWD %lf E2E OWD %lf \n", src_instance, dst_instance, ctime, @@ -217,7 +204,7 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_info->rx_pkt_jitter[src_instance][dst_instance]= abs(otg_info->rx_pkt_owd_history[src_instance][dst_instance][0] - otg_info->rx_pkt_owd_history[src_instance][dst_instance][1]); - LOG_D(OTG,"The packet jitter for the pair (src %d, dst %d)) at %d is %lf (current %lf, previous %lf) \n", + LOG_D(OTG,"The packet jitter for the pair (src %u, dst %u)) at %d is %lf (current %lf, previous %lf) \n", src_instance, dst_instance, ctime, otg_info->rx_pkt_jitter[src_instance][dst_instance], otg_info->rx_pkt_owd_history[src_instance][dst_instance][0], otg_info->rx_pkt_owd_history[src_instance][dst_instance][1]); // e2e @@ -230,26 +217,24 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance]= abs(otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][0] - otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][1]); - LOG_D(OTG,"The packet jitter for the pair (src %d, dst %d)) at %d is %lf (current %lf, previous %lf) \n", + LOG_D(OTG,"The packet jitter for the pair (src %u, dst %u)) at %d is %lf (current %lf, previous %lf) \n", src_instance, dst_instance, ctime, otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance], otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][0], otg_info->rx_pkt_owd_history_e2e[src_instance][dst_instance][1]); - } if (otg_hdr_info_rx->flag == 0x1000) { - LOG_I(OTG,"[SRC%d -> DST %d] Received a multicast packet at time %d with size %d, seq num %d, ran owd %d number loss packet %d\n", + LOG_I(OTG,"[SRC%u -> DST %u] Received a multicast packet at time %d with size %u, seq num %u, ran owd %u number loss packet %u\n", src_instance, dst_instance, ctime,otg_hdr_info_rx->size, otg_hdr_rx->seq_num, ctime - otg_hdr_rx->time, nb_loss_pkts); - - LOG_I(OTG,"INFO LATENCY :: [SRC %d][DST %d] radio access %.2f (tx time %d, ctime %d), OWD:%d (ms):\n", + LOG_I(OTG,"INFO LATENCY :: [SRC %u][DST %u] radio access %.2f (tx time %u, ctime %d), OWD:%d (ms):\n", src_instance, dst_instance, otg_multicast_info->radio_access_delay[src_instance][dst_instance], @@ -286,8 +271,7 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_multicast_info->rx_total_bytes_dl+=otg_hdr_info_rx->size; } else { - - LOG_I(OTG,"[SRC %d][DST %d] Stats :: radio access latency %.2f (tx time %d, ctime %d) jitter %.2f, Estimated E2E OWD:%.2f (ms):\n", + LOG_I(OTG,"[SRC %u][DST %u] Stats :: radio access latency %.2f (tx time %u, ctime %d) jitter %.2f, Estimated E2E OWD:%.2f (ms):\n", src_instance, dst_instance, otg_info->radio_access_delay[src_instance][dst_instance], @@ -296,7 +280,6 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_info->rx_pkt_owd_e2e[src_instance][dst_instance]); if (otg_hdr_info_rx->flag == 0xffff) { - if (otg_info->rx_owd_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]==0) { otg_info->rx_owd_max[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_info->rx_pkt_owd[src_instance][dst_instance]; otg_info->rx_owd_min[src_instance][dst_instance][otg_hdr_rx->traffic_type]=otg_info->rx_pkt_owd[src_instance][dst_instance]; @@ -332,7 +315,6 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_info->rx_jitter_avg_e2e[src_instance][dst_instance][otg_hdr_rx->traffic_type] += otg_info->rx_pkt_jitter_e2e[src_instance][dst_instance]; otg_info->rx_jitter_sample[src_instance][dst_instance][otg_hdr_rx->traffic_type] +=1; } - } if (g_otg->curve==1) { @@ -355,15 +337,12 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_info->rx_total_bytes_dl+=otg_hdr_info_rx->size; else otg_info->rx_total_bytes_ul+=otg_hdr_info_rx->size; - } //LOG_I(OTG,"RX INFO :: RTT MIN(one way) ms: %.2f, RTT MAX(one way) ms: %.2f \n", otg_info->rx_owd_min[src][dst], otg_info->rx_owd_max[src][dst]); - /* xforms part: add metrics */ - //printf("payload_size %d, header_size %d \n", otg_hdr_rx->pkts_size, otg_hdr_rx->hdr_type); - LOG_I(OTG,"[RX] OTG packet, PACKET SIZE [SRC %d][DST %d]: Flag (0x%x), Traffic %d, time(%d), Seq num (%d), Total size (%d)\n", + LOG_I(OTG,"[RX] OTG packet, PACKET SIZE [SRC %u][DST %u]: Flag (0x%x), Traffic %u, time(%d), Seq num (%u), Total size (%u)\n", src_instance, dst_instance, otg_hdr_info_rx->flag, @@ -372,7 +351,6 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_hdr_rx->seq_num, size); /*LOG_I(OTG,"details::RX [SRC %d][DST %d]: Flag (0x%x), time(%d), Seq num (%d), Total size (%d), header(%d), payload (%d) \n", src, dst, otg_hdr_info_rx->flag, ctime, otg_hdr_rx->seq_num, size, strlen(packet_rx->header), strlen(packet_rx->payload));*/ - if (otg_hdr_info_rx->flag == 0xffff) { otg_info->rx_num_pkt[src_instance][dst_instance][otg_hdr_rx->traffic_type]+=1; otg_info->rx_num_bytes[src_instance][dst_instance][otg_hdr_rx->traffic_type]+=otg_hdr_info_rx->size; @@ -402,7 +380,6 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff otg_hdr_rx->time, ((otg_hdr_info_rx->size*1000*8)/(otg_info->rx_pkt_owd[src_instance][dst_instance]*1024 )), OTG_GP); /* compute the throughput in Kbit/s */ - } else if (otg_hdr_info_rx->flag == 0x1000) { otg_multicast_info->rx_num_pkt[src_instance][dst_instance][otg_hdr_rx->traffic_type]+=1; otg_multicast_info->rx_num_bytes[src_instance][dst_instance][otg_hdr_rx->traffic_type]+=otg_hdr_info_rx->size; @@ -446,18 +423,17 @@ int otg_rx_pkt(const int dst_instanceP, const int ctime, const char * const buff if (is_size_ok == 0) { otg_hdr_rx = (otg_hdr_t *) (&buffer_tx[bytes_read]); - LOG_W(OTG,"[SRC %d][DST %d] RX pkt: seq number %d size mis-matche (hdr %d, pdcp %d) \n", + LOG_W(OTG,"[SRC %u][DST %u] RX pkt: seq number %u size mis-matche (hdr %u, pdcp %u) \n", src_instance, dst_instance, otg_hdr_rx->seq_num, otg_hdr_info_rx->size, size); otg_info->nb_loss_pkts_otg[src_instance][dst_instance]++; } return(0); } else { - LOG_W(OTG,"RX: Not an OTG pkt, forward to upper layer (flag %x, size %d, pdcp_size %d) FIX ME \n", + LOG_W(OTG,"RX: Not an OTG pkt, forward to upper layer (flag %x, size %u, pdcp_size %u) FIX ME \n", otg_hdr_info_rx->flag, otg_hdr_info_rx->size, size); return(1); //to be fixed on the real case to one } - } return(0); @@ -471,10 +447,8 @@ int rx_check_loss( const int dst, const unsigned int flag, const int seq_num, - unsigned int * const seq_num_rx, - unsigned int * const nb_loss_pkts) -{ - + unsigned int *const seq_num_rx, + unsigned int *const nb_loss_pkts) { /* Loss and out of sequence data management, we have 3 case : */ /* (1) Receieved packet corresponds to the expected one, in terms of the sequence number*/ int lost_packet=0; @@ -509,8 +483,7 @@ void owd_const_gen( const int src, const int dst, const int flow_id, - const unsigned int flag) -{ + const unsigned int flag) { otg_info->owd_const[src][dst][flow_id]=(owd_const_mobile_core()+owd_const_IP_backbone()+owd_const_application())/2; if ((flag==M2M)||(flag==M2M_TRAFFIC)||(flag==AUTO_PILOT_L)||(flag==AUTO_PILOT_M)||(flag==AUTO_PILOT_H)||(flag==VIRTUAL_GAME_L)||(flag==VIRTUAL_GAME_M)|| (flag==VIRTUAL_GAME_H)||(flag==VIRTUAL_GAME_F) @@ -523,8 +496,7 @@ void owd_const_gen( -float owd_const_capillary(void) -{ +float owd_const_capillary(void) { /*return (uniform_dist(MIN_APPLICATION_PROCESSING_GATEWAY_DELAY, MAX_APPLICATION_PROCESSING_GATEWAY_DELAY) + uniform_dist(MIN_FORMATING_TRANSFERRING_DELAY, MAX_FORMATING_TRANSFERRING_DELAY) + uniform_dist(MIN_ACCESS_DELAY, MAX_ACCESS_DELAY) + @@ -534,8 +506,7 @@ float owd_const_capillary(void) } -float owd_const_mobile_core(void) -{ +float owd_const_mobile_core(void) { /*double delay; // this is a delay model for a loaded GGSN according to //"M. Laner, P. Svoboda and M. Rupp, Latency Analysis of 3G Network Components, EW'12, Poznan, Poland, 2012", table 2, page 6. @@ -559,15 +530,12 @@ float owd_const_mobile_core(void) return ((double)MIN_U_PLANE_CORE_IP_ACCESS_DELAY+ (double)MAX_U_PLANE_CORE_IP_ACCESS_DELAY + (double)MIN_FW_PROXY_DELAY + (double)MAX_FW_PROXY_DELAY)/2; } -float owd_const_IP_backbone(void) -{ +float owd_const_IP_backbone(void) { /*return uniform_dist(MIN_NETWORK_ACCESS_DELAY,MAX_NETWORK_ACCESS_DELAY);*/ return ((double)MIN_NETWORK_ACCESS_DELAY+(double)MAX_NETWORK_ACCESS_DELAY)/2; - } -float owd_const_application(void) -{ +float owd_const_application(void) { /*return uniform_dist(MIN_APPLICATION_ACESS_DELAY, MAX_APPLICATION_ACESS_DELAY);*/ return ((double)MIN_APPLICATION_ACESS_DELAY+(double)MAX_APPLICATION_ACESS_DELAY)/2; } diff --git a/openair2/UTIL/OTG/otg_tx.c b/openair2/UTIL/OTG/otg_tx.c index ac3ffd0fb29b0bfdf7666c13e7122b9d7b76d6b8..2459bb7338860747e488f1edfc98d98ca407cbfa 100644 --- a/openair2/UTIL/OTG/otg_tx.c +++ b/openair2/UTIL/OTG/otg_tx.c @@ -305,10 +305,10 @@ unsigned char *packet_gen( otg_info->tx_num_pkt[src_instance][dst_instance][otg_info->traffic_type[src_instance][dst_instance]]+=1; if (size!=strlen(payload)) - LOG_E(OTG,"[%d][%d] [0x %x] The expected packet size does not match the payload size : size %d, strlen %zu, seq_num %d packet: |%s|%s| \n", + LOG_E(OTG,"[%d][%d] [0x %x] The expected packet size does not match the payload size : size %u, strlen %zu, seq_num %u packet: |%s|%s| \n", src_instance, dst_instance, flag, size, strlen(payload), seq_num, header, payload); else - LOG_D(OTG,"[%d][%d] 0x %x][m2m Aggre %d][Flow %d][Type %d/%s] TX INFO pkt at time %d Size= [payload %d] [Total %zu] with seq num %d, state=%d : |%s|%s| \n", + LOG_D(OTG,"[%d][%d] 0x %x][m2m Aggre %u][Flow %u][Type %u/%s] TX INFO pkt at time %d Size= [payload %u] [Total %zu] with seq num %u, state=%u : |%s|%s| \n", src_instance, dst_instance, flag, otg_info->m2m_aggregation[src_instance][dst_instance], otg_info->flow_id[src_instance][dst_instance], @@ -316,7 +316,7 @@ unsigned char *packet_gen( map_int_to_str(otg_app_type_names,otg_info->traffic_type[src_instance][dst_instance]), ctime, size, header_size+strlen(payload), seq_num,state, header, payload); - LOG_D(OTG, "[%d]MY_SEQ %d \n", otg_info->traffic_type[src_instance][dst_instance], otg_info->seq_num[src_instance][dst_instance][otg_info->traffic_type[src_instance][dst_instance]] ); + LOG_D(OTG, "[%u]MY_SEQ %d \n", otg_info->traffic_type[src_instance][dst_instance], otg_info->seq_num[src_instance][dst_instance][otg_info->traffic_type[src_instance][dst_instance]] ); } else { if ((g_otg->aggregation_level[src_instance][dst_instance][application]*otg_info->size_background[src_instance][dst_instance])<=PAYLOAD_MAX) otg_info->size_background[src_instance][dst_instance]=g_otg->aggregation_level[src_instance][dst_instance][application]*otg_info->size_background[src_instance][dst_instance]; @@ -335,7 +335,7 @@ unsigned char *packet_gen( otg_info->seq_num_background[src_instance][dst_instance]+=1; if (otg_info->size_background[src_instance][dst_instance]!=strlen(payload)) - LOG_E(OTG,"[%d][%d] [0x %x] The expected packet size does not match the payload size : size %d, strlen %zu, seq num %d, packet |%s|%s| \n", + LOG_E(OTG,"[%d][%d] [0x %x] The expected packet size does not match the payload size : size %d, strlen %zu, seq num %u, packet |%s|%s| \n", src_instance, dst_instance, flag, @@ -345,7 +345,7 @@ unsigned char *packet_gen( header, payload); else - LOG_D(OTG,"[%d][%d][0x %x][%d] TX INFO pkt at time %s size is %d with seq num %d, state=%d : |%s|%s| \n", + LOG_D(OTG,"[%d][%d][0x %x][%d] TX INFO pkt at time %s size is %d with seq num %u, state=%u : |%s|%s| \n", src_instance, dst_instance, flag, @@ -367,7 +367,7 @@ unsigned char *packet_gen( otg_info->tx_total_bytes_ul+=buffer_size; if (otg_info->traffic_type[src_instance][dst_instance] > MAX_NUM_APPLICATION) { - LOG_W(OTG,"application type out of range %d for the pair of (src %d, dst %d) \n", + LOG_W(OTG,"application type out of range %u for the pair of (src %d, dst %d) \n", otg_info->traffic_type[src_instance][dst_instance], src_instance, dst_instance); otg_info->traffic_type[src_instance][dst_instance]=0; } @@ -425,7 +425,7 @@ unsigned char *packet_gen_multicast( g_otg_multicast->idt_max[src_instance][dst_instance][app])); size = ceil(uniform_dist(g_otg_multicast->size_min[src_instance][dst_instance][app], g_otg_multicast->size_max[src_instance][dst_instance][app])); - LOG_D(OTG, "ptime %d, ctime %d idt %d (min %d, max %d) size %d (min %d, max %d)\n", + LOG_D(OTG, "ptime %d, ctime %d idt %d (min %d, max %d) size %u (min %d, max %d)\n", otg_multicast_info->ptime[src_instance][dst_instance][application], ctime, otg_multicast_info->idt[src_instance][dst_instance][app], @@ -459,10 +459,10 @@ unsigned char *packet_gen_multicast( otg_multicast_info->tx_num_bytes[src_instance][dst_instance][app]); if (size!=strlen(payload)) - LOG_E(OTG,"[src %d][dst %d] The expected packet size does not match the payload size : size %d, strlen %zu \n", + LOG_E(OTG,"[src %d][dst %d] The expected packet size does not match the payload size : size %u, strlen %zu \n", src_instance, dst_instance, size, strlen(payload)); else { - LOG_I(OTG,"[src %d][dst %d]TX INFO pkt at time %d Size= [payload %d] [Total %zu] with seq num %d: |%s|%s| \n", + LOG_I(OTG,"[src %d][dst %d]TX INFO pkt at time %d Size= [payload %u] [Total %zu] with seq num %d: |%s|%s| \n", src_instance, dst_instance, ctime, @@ -557,7 +557,7 @@ int check_data_transmit( // for (application=0; application<g_otg->application_idx[src_instance][dst_instance]; application++){ otg_info->gen_pkts=0; - LOG_T(OTG,"FLOW_INFO [src %d][dst %d] [IDX %d] [APPLICATION TYPE %d] MAX %d [M2M %d ]\n", + LOG_T(OTG,"FLOW_INFO [src %d][dst %d] [IDX %d] [APPLICATION TYPE %d] MAX %u [M2M %u ]\n", src_instance, dst_instance, app, g_otg->application_type[src_instance][dst_instance][app], g_otg->application_idx[src_instance][dst_instance], @@ -605,7 +605,7 @@ int check_data_transmit( if (((state==PU_STATE)||(state==ED_STATE))|| (otg_info->idt[src_instance][dst_instance][app]==0) || (( (ctime-otg_info->ptime[src_instance][dst_instance][app]) >= otg_info->idt[src_instance][dst_instance][app] ) )) { - LOG_D(OTG,"[TX] OTG packet: Time To Transmit::OK (Source= %d, Destination= %d, Application %d, State= %d) , (IDT= %d ,ctime= %d, ptime= %d) \n", + LOG_D(OTG,"[TX] OTG packet: Time To Transmit::OK (Source= %d, Destination= %d, Application %d, State= %u) , (IDT= %d ,ctime= %d, ptime= %d) \n", src_instance, dst_instance , app, @@ -654,7 +654,7 @@ int check_data_transmit( if (g_otg->m2m[src_instance][dst_instance][app]==M2M) otg_info->traffic_type[src_instance][dst_instance]=app;//g_otg->application_idx[src_instance][dst_instance];//M2M; - LOG_D(OTG,"[BACKGROUND=%d] Time To Transmit [SRC %d][DST %d][APPLI %d] \n", otg_info->traffic_type_background[src_instance][dst_instance], src_instance, dst_instance, app); + LOG_D(OTG,"[BACKGROUND=%u] Time To Transmit [SRC %d][DST %d][APPLI %d] \n", otg_info->traffic_type_background[src_instance][dst_instance], src_instance, dst_instance, app); } } @@ -720,7 +720,7 @@ void header_size_gen( if ((g_otg->application_type[src_instance][dst_instance][application]==VOIP_G711)||(g_otg->application_type[src_instance][dst_instance][application]==VOIP_G729)) size_header+=RTP_HEADER; - LOG_D(OTG,"Header size is %d [IP V=%d][PROTO=%d]\n", size_header, g_otg->ip_v[src_instance][dst_instance][application],g_otg->trans_proto[src_instance][dst_instance][application]); + LOG_D(OTG,"Header size is %u [IP V=%d][PROTO=%d]\n", size_header, g_otg->ip_v[src_instance][dst_instance][application],g_otg->trans_proto[src_instance][dst_instance][application]); otg_info->header_size_app[src_instance][dst_instance][application]=size_header; } } @@ -889,7 +889,7 @@ unsigned char * serialize_buffer( otg_hdr_p->traffic_type=traffic_type; byte_tx_count += sizeof(otg_hdr_t); - LOG_I(OTG,"traffic type %d\n",otg_hdr_p->traffic_type); + LOG_I(OTG,"traffic type %u\n",otg_hdr_p->traffic_type); // copy the header first memcpy(&tx_buffer[byte_tx_count], header, strlen(header)); byte_tx_count += strlen(header); @@ -1953,7 +1953,7 @@ int header_size_gen_background( otg_info->header_size_background[src_instance][dst_instance]=size_header; } - LOG_D(OTG," [SRC %d][DST %d] BACKGROUND TRAFFIC:: size header %d \n", src_instance, dst_instance, otg_info->header_size_background[src_instance][dst_instance]); + LOG_D(OTG," [SRC %d][DST %d] BACKGROUND TRAFFIC:: size header %u \n", src_instance, dst_instance, otg_info->header_size_background[src_instance][dst_instance]); return otg_info->header_size_background[src_instance][dst_instance]; } @@ -1987,7 +1987,7 @@ void state_management( if (ctime>otg_info->start_holding_time_off[src_instance][dst_instance][application]) { otg_info->c_holding_time_off[src_instance][dst_instance][application]= ctime - otg_info->start_holding_time_off[src_instance][dst_instance][application]; - LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%d] STATE:: OFF Holding Time %d (%d, %d)\n", src_instance, dst_instance,application , g_otg->aggregation_level[src_instance][dst_instance][application], + LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%u] STATE:: OFF Holding Time %u (%d, %u)\n", src_instance, dst_instance,application , g_otg->aggregation_level[src_instance][dst_instance][application], otg_info->c_holding_time_off[src_instance][dst_instance][application], ctime, otg_info->start_holding_time_off[src_instance][dst_instance][application]); } @@ -1997,7 +1997,7 @@ void state_management( +g_otg->prob_off_pe[src_instance][dst_instance][application]))) && (otg_info->c_holding_time_off[src_instance][dst_instance][application]>=g_otg->holding_time_off_pu[src_instance][dst_instance][application])) { otg_info->state[src_instance][dst_instance][application]=PU_STATE; - LOG_I(OTG,"[%d][%d][Appli id %d][Agg Level=%d] NEW STATE:: OFF-->PU %d (ctime %d, start %d )\n", src_instance, dst_instance,application, + LOG_I(OTG,"[%d][%d][Appli id %d][Agg Level=%u] NEW STATE:: OFF-->PU %u (ctime %d, start %u )\n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application], otg_info->c_holding_time_off[src_instance][dst_instance][application], ctime, otg_info->start_holding_time_off[src_instance][dst_instance][application]); otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); @@ -2007,7 +2007,7 @@ void state_management( && (otg_info->state_transition_prob[src_instance][dst_instance][application]< 1-g_otg->prob_off_pe[src_instance][dst_instance][application])) && (otg_info->c_holding_time_off[src_instance][dst_instance][application]>=g_otg->holding_time_off_ed[src_instance][dst_instance][application])) { otg_info->state[src_instance][dst_instance][application]=ED_STATE; - LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%d] NEW STATE:: OFF-->ED \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); + LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%u] NEW STATE:: OFF-->ED \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); } @@ -2015,13 +2015,13 @@ void state_management( && (otg_info->state_transition_prob[src_instance][dst_instance][application]<=1)) && (otg_info->c_holding_time_off[src_instance][dst_instance]>=g_otg->holding_time_off_pe[src_instance][dst_instance])) { otg_info->state[src_instance][dst_instance][application]=PE_STATE; - LOG_I(OTG,"[%d][%d][Appli id %d][Agg Level=%d] NEW STATE:: OFF-->PE \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); + LOG_I(OTG,"[%d][%d][Appli id %d][Agg Level=%u] NEW STATE:: OFF-->PE \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); } else { otg_info->c_holding_time_off[src_instance][dst_instance][application]= ctime - otg_info->start_holding_time_off[src_instance][dst_instance][application]; otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); - LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%d] STATE:: OFF\n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); + LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%u] STATE:: OFF\n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); } break; @@ -2033,20 +2033,20 @@ void state_management( otg_info->state[src_instance][dst_instance][application]=OFF_STATE; otg_info->start_holding_time_off[src_instance][dst_instance][application]=ctime; otg_info->c_holding_time_off[src_instance][dst_instance][application]=0; - LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%d] NEW STATE:: PU-->OFF \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); + LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%u] NEW STATE:: PU-->OFF \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); } else if ((otg_info->state_transition_prob[src_instance][dst_instance][application]<=1-g_otg->prob_pu_pe[src_instance][dst_instance][application]) && (otg_info->state_transition_prob[src_instance][dst_instance][application]>1-(g_otg->prob_pu_ed[src_instance][dst_instance][application] +g_otg->prob_pu_pe[src_instance][dst_instance][application]))) { //otg_info->state[src_instance][dst_instance]=ON_STATE; otg_info->state[src_instance][dst_instance][application]=ED_STATE; - LOG_I(OTG,"[%d][%d][Appli id %d][Agg Level=%d] NEW STATE:: PU-->ED \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); + LOG_I(OTG,"[%d][%d][Appli id %d][Agg Level=%u] NEW STATE:: PU-->ED \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); } else { /*if (otg_info->state_transition_prob[src_instance][dst_instance]>=g_otg->prob_pu_ed)*/ //otg_info->state[src_instance][dst_instance]=ON_STATE; otg_info->state[src_instance][dst_instance][application]=PE_STATE; otg_info->start_holding_time_pe_off[src_instance][dst_instance][application]=ctime; - LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%d] NEW STATE:: PU-->PE \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); + LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%u] NEW STATE:: PU-->PE \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); } @@ -2059,20 +2059,20 @@ void state_management( otg_info->state[src_instance][dst_instance][application]=OFF_STATE; otg_info->start_holding_time_off[src_instance][dst_instance][application]=ctime; otg_info->c_holding_time_off[src_instance][dst_instance][application]=0; - LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%d] NEW STATE:: ED-->OFF \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); + LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%u] NEW STATE:: ED-->OFF \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); } else if ((otg_info->state_transition_prob[src_instance][dst_instance][application]>=1-(g_otg->prob_ed_pu[src_instance][dst_instance][application] + g_otg->prob_ed_pe[src_instance][dst_instance][application] )) && (otg_info->state_transition_prob[src_instance][dst_instance][application]<1-g_otg->prob_ed_pe[src_instance][dst_instance][application])) { //otg_info->state[src_instance][dst_instance]=ON_STATE; otg_info->state[src_instance][dst_instance][application]=PE_STATE; - LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%d] NEW STATE:: ED-->PU \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); + LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%u] NEW STATE:: ED-->PU \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); } else { /*if ((otg_info->state_transition_prob[src_instance][dst_instance]>=1-g_otg->prob_ed_pe)&&(otg_info->state_transition_prob[src_instance][dst_instance]<=1)) */ //otg_info->state[src_instance][dst_instance]=ON_STATE; otg_info->state[src_instance][dst_instance][application]=PE_STATE; otg_info->start_holding_time_pe_off[src_instance][dst_instance][application]=ctime; - LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%d] NEW STATE:: ED-->PE \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); + LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%u] NEW STATE:: ED-->PE \n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); } @@ -2082,7 +2082,7 @@ void state_management( if (g_otg->holding_time_pe_off[src_instance][dst_instance][application]<=otg_info->c_holding_time_pe_off[src_instance][dst_instance][application]) { //otg_info->state[src_instance][dst_instance]=OFF_STATE; otg_info->state[src_instance][dst_instance][application]=OFF_STATE; - LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%d] NEW STATE:: PE->OFF\n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); + LOG_D(OTG,"[%d][%d][Appli id %d][Agg Level=%u] NEW STATE:: PE->OFF\n", src_instance, dst_instance,application, g_otg->aggregation_level[src_instance][dst_instance][application]); otg_info->c_holding_time_pe_off[src_instance][dst_instance][application]=0; otg_info->state_transition_prob[src_instance][dst_instance][application]=uniform_dist(0,1); otg_info->start_holding_time_off[src_instance][dst_instance][application]=ctime; @@ -2097,7 +2097,7 @@ void state_management( break; default: - LOG_W(OTG,"Unknown state(%d) \n", otg_info->state[src_instance][dst_instance][application]); + LOG_W(OTG,"Unknown state(%u) \n", otg_info->state[src_instance][dst_instance][application]); otg_info->state[src_instance][dst_instance][application]= OFF_STATE; // switch to default state break; @@ -2145,13 +2145,13 @@ void voip_traffic( if (ctime>otg_info->start_voip_silence[src_instance][dst_instance][application]) otg_info->c_holding_time_silence[src_instance][dst_instance][application]= ctime - otg_info->start_voip_silence[src_instance][dst_instance][application]; - LOG_D(OTG,"[%d][%d][Appli id %d] VOIP STATE:: SILENCE %d (ctime=%d, start=%d)\n", src_instance, dst_instance,application, + LOG_D(OTG,"[%d][%d][Appli id %d] VOIP STATE:: SILENCE %u (ctime=%d, start=%u)\n", src_instance, dst_instance,application, otg_info->c_holding_time_silence[src_instance][dst_instance][application], ctime, otg_info->start_voip_silence[src_instance][dst_instance][application]); } if (otg_info->c_holding_time_silence[src_instance][dst_instance][application]>=otg_info->silence_time[src_instance][dst_instance][application]) { otg_info->voip_state[src_instance][dst_instance][application]=SIMPLE_TALK; - LOG_I(OTG,"[%d][%d][Appli id %d] NEW VOIP STATE :: SILENCE-->TALK %d (ctime=%d, start=%d )\n", src_instance, dst_instance,application , + LOG_I(OTG,"[%d][%d][Appli id %d] NEW VOIP STATE :: SILENCE-->TALK %u (ctime=%d, start=%u )\n", src_instance, dst_instance,application , otg_info->c_holding_time_silence[src_instance][dst_instance][application], ctime, otg_info->start_voip_silence[src_instance][dst_instance][application]); otg_info->start_voip_talk[src_instance][dst_instance][application]=ctime; otg_info->c_holding_time_talk[src_instance][dst_instance][application]=0; @@ -2160,7 +2160,7 @@ void voip_traffic( if (ctime>otg_info->start_voip_silence[src_instance][dst_instance][application]) otg_info->c_holding_time_silence[src_instance][dst_instance][application]= ctime - otg_info->start_voip_silence[src_instance][dst_instance][application]; - LOG_I(OTG,"[%d][%d][Appli id %d] STATE:: SILENCE [timer:%d] \n", src_instance, dst_instance,application, otg_info->c_holding_time_silence[src_instance][dst_instance][application]); + LOG_I(OTG,"[%d][%d][Appli id %d] STATE:: SILENCE [timer:%u] \n", src_instance, dst_instance,application, otg_info->c_holding_time_silence[src_instance][dst_instance][application]); } break; @@ -2168,7 +2168,7 @@ void voip_traffic( case SIMPLE_TALK: if (otg_info->c_holding_time_talk[src_instance][dst_instance][application]>=otg_info->simple_talk_time[src_instance][dst_instance][application]) { otg_info->voip_state[src_instance][dst_instance][application]=SILENCE; - LOG_I(OTG,"[%d][%d][Appli id %d] NEW VOIP STATE:: TALK-->SILENCE %d (ctime=%d, start=%d )\n", src_instance, dst_instance,application , + LOG_I(OTG,"[%d][%d][Appli id %d] NEW VOIP STATE:: TALK-->SILENCE %u (ctime=%d, start=%u )\n", src_instance, dst_instance,application , otg_info->c_holding_time_talk[src_instance][dst_instance][application], ctime, otg_info->start_voip_talk[src_instance][dst_instance][application]); otg_info->start_voip_silence[src_instance][dst_instance][application]=ctime; otg_info->c_holding_time_silence[src_instance][dst_instance][application]=0; @@ -2177,15 +2177,15 @@ void voip_traffic( if (ctime>otg_info->start_voip_talk[src_instance][dst_instance][application]) otg_info->c_holding_time_talk[src_instance][dst_instance][application]= ctime - otg_info->start_voip_talk[src_instance][dst_instance][application]; - LOG_I(OTG,"[%d][%d][Appli id %d] VOIP STATE:: TALK [timer:%d]\n", src_instance, dst_instance,application, otg_info->c_holding_time_talk[src_instance][dst_instance][application]); - LOG_I(OTG, "test_talk [ctime %d] [start talk %d] [%d] \n",ctime, otg_info->start_voip_talk[src_instance][dst_instance][application], + LOG_I(OTG,"[%d][%d][Appli id %d] VOIP STATE:: TALK [timer:%u]\n", src_instance, dst_instance,application, otg_info->c_holding_time_talk[src_instance][dst_instance][application]); + LOG_I(OTG, "test_talk [ctime %d] [start talk %u] [%u] \n",ctime, otg_info->start_voip_talk[src_instance][dst_instance][application], otg_info->c_holding_time_talk[src_instance][dst_instance][application] ); } break; default: - LOG_W(OTG,"Unknown VOIP state(%d) \n", otg_info->voip_state[src_instance][dst_instance][application]); + LOG_W(OTG,"Unknown VOIP state(%u) \n", otg_info->voip_state[src_instance][dst_instance][application]); otg_info->voip_state[src_instance][dst_instance][application]= SILENCE; // switch to default state break; diff --git a/openair2/UTIL/OTG/otg_tx_socket.c b/openair2/UTIL/OTG/otg_tx_socket.c index 026dc3e8b836344ea81099aa7b59a4df829acf3b..073b9b6ddd83f1fb22579ffea539ca6a823f1e34 100644 --- a/openair2/UTIL/OTG/otg_tx_socket.c +++ b/openair2/UTIL/OTG/otg_tx_socket.c @@ -36,28 +36,28 @@ #ifdef WIN32 /* si vous êtes sous Windows */ -#include <winsock2.h> + #include <winsock2.h> #elif defined (linux) /* si vous êtes sous Linux */ -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <unistd.h> /* close */ -#include <netdb.h> /* gethostbyname */ -#include <errno.h> - -#define INVALID_SOCKET -1 -#define SOCKET_ERROR -1 -#define closesocket(s) close(s) -typedef int SOCKET; -typedef struct sockaddr_in SOCKADDR_IN; -typedef struct sockaddr SOCKADDR; -typedef struct in_addr IN_ADDR; + #include <sys/types.h> + #include <sys/socket.h> + #include <netinet/in.h> + #include <arpa/inet.h> + #include <unistd.h> /* close */ + #include <netdb.h> /* gethostbyname */ + #include <errno.h> + + #define INVALID_SOCKET -1 + #define SOCKET_ERROR -1 + #define closesocket(s) close(s) + typedef int SOCKET; + typedef struct sockaddr_in SOCKADDR_IN; + typedef struct sockaddr SOCKADDR; + typedef struct in_addr IN_ADDR; #else /* sinon vous êtes sur une plateforme non supportée */ -#error not defined for this platform + #error not defined for this platform #endif @@ -67,11 +67,8 @@ control_hdr_t *control_hdr; -void socket_packet_send(int src, int dst, int state,int ctime) -{ - +void socket_packet_send(int src, int dst, int state,int ctime) { init_control_header(); - LOG_I(OTG,"SOCKET:: IP version %d, Transport Protocol %d \n", g_otg->ip_v[src], g_otg->trans_proto[src]); if ((g_otg->ip_v[src]==1) && (g_otg->trans_proto[src]==2)) @@ -85,29 +82,20 @@ void socket_packet_send(int src, int dst, int state,int ctime) if ((g_otg->ip_v[src]==2) && (g_otg->trans_proto[src]==1)) client_socket_udp_ip6(src, dst, state, ctime); - - - } -void client_socket_tcp_ip4(int src, int dst, int state, int ctime) -{ - +void client_socket_tcp_ip4(int src, int dst, int state, int ctime) { #define PORT 7777 - - LOG_I(OTG,"SOCKET:: TCP-IP4 :: src= %d , dst= %d , state= %d \n", src, dst, state); - #if defined (WIN32) WSADATA WSAData; int erreur = WSAStartup(MAKEWORD(2,2), &WSAData); #else int erreur = 0; #endif - SOCKET sock; SOCKADDR_IN sin; int sock_err; @@ -118,94 +106,69 @@ void client_socket_tcp_ip4(int src, int dst, int state, int ctime) if(!erreur) { /* Create socket */ sock = socket(AF_INET, SOCK_STREAM, 0); - /* Configure the connection */ sin.sin_addr.s_addr = inet_addr(g_otg->dst_ip[src]); sin.sin_family = AF_INET; sin.sin_port = htons(PORT); - /* connection is ok */ - printf("SOCKET:: TCP-IP4 :: \n"); - if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) { + if(connect(sock, (SOCKADDR *)&sin, sizeof(sin)) != SOCKET_ERROR) { LOG_I(OTG,"SOCKET:: TCP-IP4 :: Create socket %s with dst port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port)); ctime=0; LOG_I(OTG,"SOCKET:: TCP-IP4 :: ctime=%d, duration=%d \n", ctime, g_otg->duration[src]); - init_control_header(); - do { //payload=NULL; //payload=packet_gen_socket(src, dst, state, ctime); //payload="CCCCC"; - char *payload_rest; payload_rest=packet_gen_socket(src, dst, state, ctime); if (payload_rest!=NULL) { - - - payload_t *payload; payload= malloc(sizeof(payload_t)); // Data serialization char *tx_buffer; tx_buffer= (char *)malloc(PAYLOAD_MAX); - payload->control_hdr=otg_info_hdr_gen(src, dst, TCP, IPV4); - payload->payload_rest=payload_rest; memcpy(tx_buffer, payload->control_hdr, sizeof (control_hdr_t)); memcpy(tx_buffer+ sizeof (control_hdr_t), payload->payload_rest, strlen(payload_rest)); - - int total_size=sizeof(control_hdr_t) + strlen(payload_rest); - if((sock_err = send(sock, tx_buffer, total_size, 0)) != SOCKET_ERROR) LOG_I(OTG,"SOCKET:: TCP-IP4 :: Payload to send size :: %d \n",sock_err); else LOG_I(OTG,"SOCKET:: TCP-IP4 :: Transmission Error\n"); - + free(payload); + free(tx_buffer); } ctime+=1; - - } while (ctime<=g_otg->duration[src]) ; - - } /* connection is not possible..." */ else LOG_I(OTG,"SOCKET:: TCP-IP4 :: connection is not possible to connect \n"); - /* close the socket */ closesocket(sock); - } } -void client_socket_udp_ip4(int src, int dst, int state,int ctime) -{ - +void client_socket_udp_ip4(int src, int dst, int state,int ctime) { char *payload_rest; signed int udp_send; - - - int sockfd, ok, addr_in_size; u_short portnum = 12345; struct sockaddr_in *to; struct hostent *toinfo; char *htoname = "127.0.0.1"; u_long toaddr; - LOG_I(OTG,"SOCKET:: UDP-IP4 :: src= %d , dst= %d , state= %d \n", src, dst, state); to = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); @@ -226,7 +189,6 @@ void client_socket_udp_ip4(int src, int dst, int state,int ctime) to->sin_port = portnum; - // /* @@ -238,8 +200,6 @@ void client_socket_udp_ip4(int src, int dst, int state,int ctime) memset(control_hdr, 0, sizeof(control_hdr_t)); */ // - - if((sockfd = socket (PF_INET, SOCK_DGRAM, 0)) == -1) { LOG_W(OTG,"SOCKET:: UDP-IP4 :: Error %d in socket: %s\n",errno,sys_errlist[errno]); exit(errno); @@ -249,21 +209,20 @@ void client_socket_udp_ip4(int src, int dst, int state,int ctime) payload_rest=packet_gen_socket(src, dst, state, ctime); if (payload_rest!=NULL) { - payload_t *payload; payload= malloc(sizeof(payload_t)); // Data serialization char *tx_buffer; tx_buffer= (char *)malloc(PAYLOAD_MAX); - - + if (tx_buffer == NULL || payload == NULL) { + LOG_E(OTG,"Memory allocation failed\n"); + return; + } payload->control_hdr=otg_info_hdr_gen(src, dst, UDP, IPV4); payload->payload_rest=payload_rest; memcpy(tx_buffer, payload->control_hdr, sizeof (control_hdr_t)); memcpy(tx_buffer+ sizeof (control_hdr_t), payload->payload_rest, strlen(payload_rest)); int total_size=sizeof(control_hdr_t) + strlen(payload_rest); - - udp_send=sendto(sockfd, tx_buffer,total_size ,0,(struct sockaddr *)to,addr_in_size); LOG_I(OTG,"SOCKET:: UDP-IP4 :: Payload to send :: data sent:%d \n", udp_send); // Update TX OTG info @@ -271,69 +230,42 @@ void client_socket_udp_ip4(int src, int dst, int state,int ctime) //otg_info->rx_num_bytes[src][dst]+= udp_send + (HDR_IP_v4 + HDR_UDP); // - if (NULL != payload) { - payload=NULL; - free(payload); - } - - if (NULL != tx_buffer) { - tx_buffer=NULL; - free(tx_buffer); - } - - - + free(payload); + free(tx_buffer); } if(udp_send == -1) { LOG_I(OTG,"SOCKET:: UDP-IP4 :: Transmission Error\n"); exit(errno); - } - - else + } else LOG_I(OTG,"SOCKET:: UDP-IP4 :: No data to transmit\n"); ctime+=1; - - } while (ctime<=g_otg->duration[src]) ; closesocket(sockfd); - } -void client_socket_tcp_ip6(int src, int dst, int state,int ctime) -{ +void client_socket_tcp_ip6(int src, int dst, int state,int ctime) { printf("client TCP IPv6\n"); - } -void client_socket_udp_ip6(int src, int dst, int state,int ctime) -{ +void client_socket_udp_ip6(int src, int dst, int state,int ctime) { printf("client UDP IPv6\n"); - } -char* packet_gen_socket(int src, int dst, int state, int ctime) -{ - +char *packet_gen_socket(int src, int dst, int state, int ctime) { int size; char *payload=NULL; - - set_ctime(ctime); LOG_I(OTG,"SOCKET :: num_nodes_tx:: %d , seed:: %d \n", g_otg->num_nodes, g_otg->seed); - LOG_I(OTG,"SOCKET :: NODE_INFO (Source= %d, Destination= %d,State= %d) ctime %d \n", src, dst, state, otg_info->ctime); - - LOG_I(OTG,"SOCKET :: INFO_SIM (src=%d, dst=%d, state=%d) application=%d, idt dist =%d, pkts dist= %d\n", src, dst, state, g_otg->application_type[src][dst], g_otg->idt_dist[src][dst][state], g_otg->size_dist[src][dst][state]); - LOG_I(OTG,"SOCKET :: Transmission info: idt=%d, simulation time=%d \n", otg_info->idt[src][dst], ctime); // do not generate packet for this pair of src, dst : no app type and/or idt are defined @@ -352,7 +284,6 @@ char* packet_gen_socket(int src, int dst, int state, int ctime) //end pre-config if ((otg_info->idt[src][dst]==(ctime-otg_info->ptime[src][dst][state])) || (otg_info->idt[src][dst]==0)) { - LOG_I(OTG,"SOCKET :: Time To Transmit (Source= %d, Destination= %d,State= %d) , (IDT= %d ,simu time= %d, previous packet time= %d) \n", src, dst, state ,otg_info->idt[src][dst], ctime, otg_info->ptime[src][dst][state]); otg_info->ptime[src][dst][state]=ctime; @@ -362,8 +293,6 @@ char* packet_gen_socket(int src, int dst, int state, int ctime) return 0; // do not generate the packet, and keep the idt } - - size=size_dist(src, dst, state); LOG_I(OTG,"SOCKET :: Generate Packet for (Source= %d, Destination= %d,State= %d) , pkt size dist= %d, simu time= %d ,packet size=%d \n", src, dst, state, g_otg->size_dist[src][dst][state], otg_info->ctime, size); @@ -374,15 +303,12 @@ char* packet_gen_socket(int src, int dst, int state, int ctime) size=(5* sizeof(int))+10; payload=payload_pkts(size); - return(payload); - } -control_hdr_t *otg_info_hdr_gen(int src, int dst, int trans_proto, int ip_v) -{ +control_hdr_t *otg_info_hdr_gen(int src, int dst, int trans_proto, int ip_v) { control_hdr->src=src; control_hdr->dst=dst; control_hdr->trans_proto=trans_proto; @@ -391,15 +317,11 @@ control_hdr_t *otg_info_hdr_gen(int src, int dst, int trans_proto, int ip_v) LOG_I(OTG,"SOCKET :: control header src %d\n",control_hdr->dst); LOG_I(OTG,"SOCKET :: control header src %d\n",control_hdr->trans_proto); LOG_I(OTG,"SOCKET :: control header src %d\n",control_hdr->ip_v); - - return control_hdr; - } -void init_control_header() -{ +void init_control_header() { //set otg header to 0 control_hdr = calloc(1, sizeof(control_hdr_t)); diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 13f6989f1cbe9749f3c5b727e3f20ecb4acc0409..8b11e469b2d03f1e86b74c8a94bf55778ab9a1d6 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB.c + * \brief x2ap tasks for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #include <pthread.h> #include <stdio.h> #include <stdlib.h> @@ -33,6 +40,8 @@ #include "x2ap_eNB_handler.h" #include "x2ap_eNB_generate_messages.h" #include "x2ap_common.h" +#include "x2ap_ids.h" +#include "x2ap_timers.h" #include "queue.h" #include "assertions.h" @@ -64,6 +73,18 @@ void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p, uint32_t enb_port_for_X2C, int multi_sd); +static +void x2ap_eNB_handle_handover_req(instance_t instance, + x2ap_handover_req_t *x2ap_handover_req); + +static +void x2ap_eNB_handle_handover_req_ack(instance_t instance, + x2ap_handover_req_ack_t *x2ap_handover_req_ack); + +static +void x2ap_eNB_ue_context_release(instance_t instance, + x2ap_ue_context_release_t *x2ap_ue_context_release); + static void x2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { @@ -116,7 +137,7 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); - x2ap_handle_x2_setup_message(x2ap_enb_data_p, + x2ap_handle_x2_setup_message(instance_p, x2ap_enb_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); return; } @@ -280,6 +301,11 @@ void x2ap_eNB_handle_register_eNB(instance_t instance, new_instance->mnc_digit_length = x2ap_register_eNB->mnc_digit_length; new_instance->num_cc = x2ap_register_eNB->num_cc; + x2ap_id_manager_init(&new_instance->id_manager); + x2ap_timers_init(&new_instance->timers, + x2ap_register_eNB->t_reloc_prep, + x2ap_register_eNB->tx2_reloc_overall); + for (int i = 0; i< x2ap_register_eNB->num_cc; i++) { new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i]; new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i]; @@ -353,6 +379,99 @@ void x2ap_eNB_handle_sctp_init_msg_multi_cnf( } } +static +void x2ap_eNB_handle_handover_req(instance_t instance, + x2ap_handover_req_t *x2ap_handover_req) +{ + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *target; + x2ap_id_manager *id_manager; + int ue_id; + + int target_pci = x2ap_handover_req->target_physCellId; + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + target = x2ap_is_eNB_pci_in_list(target_pci); + DevAssert(target != NULL); + + /* allocate x2ap ID */ + id_manager = &instance_p->id_manager; + ue_id = x2ap_allocate_new_id(id_manager); + if (ue_id == -1) { + X2AP_ERROR("could not allocate a new X2AP UE ID\n"); + /* TODO: cancel handover: send (to be defined) message to RRC */ + exit(1); + } + /* id_source is ue_id, id_target is unknown yet */ + x2ap_set_ids(id_manager, ue_id, x2ap_handover_req->rnti, ue_id, -1); + x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_SOURCE_PREPARE); + x2ap_set_reloc_prep_timer(id_manager, ue_id, + x2ap_timer_get_tti(&instance_p->timers)); + x2ap_id_set_target(id_manager, ue_id, target); + + x2ap_eNB_generate_x2_handover_request(instance_p, target, x2ap_handover_req, ue_id); +} + +static +void x2ap_eNB_handle_handover_req_ack(instance_t instance, + x2ap_handover_req_ack_t *x2ap_handover_req_ack) +{ + /* TODO: remove this hack (the goal is to find the correct + * eNodeB structure for the other end) - we need a proper way for RRC + * and X2AP to identify eNodeBs + * RRC knows about mod_id and X2AP knows about eNB_id (eNB_ID in + * the configuration file) + * as far as I understand.. CROUX + */ + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *target; + int source_assoc_id = x2ap_handover_req_ack->source_assoc_id; + int ue_id; + int id_source; + int id_target; + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + target = x2ap_get_eNB(NULL, source_assoc_id, 0); + DevAssert(target != NULL); + + /* rnti is a new information, save it */ + ue_id = x2ap_handover_req_ack->x2_id_target; + id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + id_target = ue_id; + x2ap_set_ids(&instance_p->id_manager, ue_id, x2ap_handover_req_ack->rnti, id_source, id_target); + + x2ap_eNB_generate_x2_handover_request_ack(instance_p, target, x2ap_handover_req_ack); +} + +static +void x2ap_eNB_ue_context_release(instance_t instance, + x2ap_ue_context_release_t *x2ap_ue_context_release) +{ + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *target; + int source_assoc_id = x2ap_ue_context_release->source_assoc_id; + int ue_id; + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + target = x2ap_get_eNB(NULL, source_assoc_id, 0); + DevAssert(target != NULL); + + x2ap_eNB_generate_x2_ue_context_release(instance_p, target, x2ap_ue_context_release); + + /* free the X2AP UE ID */ + ue_id = x2ap_find_id_from_rnti(&instance_p->id_manager, x2ap_ue_context_release->rnti); + if (ue_id == -1) { + X2AP_ERROR("could not find UE %x\n", x2ap_ue_context_release->rnti); + exit(1); + } + x2ap_release_id(&instance_p->id_manager, ue_id); +} + void *x2ap_task(void *arg) { MessageDef *received_msg = NULL; int result; @@ -369,11 +488,30 @@ void *x2ap_task(void *arg) { itti_exit_task(); break; + case X2AP_SUBFRAME_PROCESS: + x2ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg)); + break; + case X2AP_REGISTER_ENB_REQ: x2ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), &X2AP_REGISTER_ENB_REQ(received_msg)); break; + case X2AP_HANDOVER_REQ: + x2ap_eNB_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &X2AP_HANDOVER_REQ(received_msg)); + break; + + case X2AP_HANDOVER_REQ_ACK: + x2ap_eNB_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &X2AP_HANDOVER_REQ_ACK(received_msg)); + break; + + case X2AP_UE_CONTEXT_RELEASE: + x2ap_eNB_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &X2AP_UE_CONTEXT_RELEASE(received_msg)); + break; + case SCTP_INIT_MSG_MULTI_CNF: x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_init_msg_multi_cnf); @@ -408,4 +546,38 @@ void *x2ap_task(void *arg) { return NULL; } +#include "common/config/config_userapi.h" + +int is_x2ap_enabled(void) +{ + static volatile int config_loaded = 0; + static volatile int enabled = 0; + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + if (pthread_mutex_lock(&mutex)) goto mutex_error; + + if (config_loaded) { + if (pthread_mutex_unlock(&mutex)) goto mutex_error; + return enabled; + } + + char *enable_x2 = NULL; + paramdef_t p[] = { + { "enable_x2", "yes/no", 0, strptr:&enable_x2, defstrval:"", TYPE_STRING, 0 } + }; + + /* TODO: do it per module - we check only first eNB */ + config_get(p, sizeof(p)/sizeof(paramdef_t), "eNBs.[0]"); + if (enable_x2 != NULL && strcmp(enable_x2, "yes") == 0) + enabled = 1; + + config_loaded = 1; + if (pthread_mutex_unlock(&mutex)) goto mutex_error; + + return enabled; + +mutex_error: + LOG_E(X2AP, "mutex error\n"); + exit(1); +} diff --git a/openair2/X2AP/x2ap_eNB.h b/openair2/X2AP/x2ap_eNB.h index 1a19416122d0918fa20896b6f580c858758db90e..afa6f11b8e0a9839c98eecf728551766b022440c 100644 --- a/openair2/X2AP/x2ap_eNB.h +++ b/openair2/X2AP/x2ap_eNB.h @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB.h + * \brief x2ap tasks for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #include <stdio.h> #include <stdint.h> @@ -39,6 +46,8 @@ int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p, void *x2ap_task(void *arg); +int is_x2ap_enabled(void); + #endif /* X2AP_H_ */ /** diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c index f156d96d175beab05523d01625cd34324bc1e1a5..3604aa03c8a75420b4638dd70967ddba52745e00 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.c +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_decoder.c + * \brief x2ap decoder procedures for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #include <stdio.h> #include "assertions.h" @@ -33,7 +40,22 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu) switch(pdu->choice.initiatingMessage.procedureCode) { case X2AP_ProcedureCode_id_x2Setup: - asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + X2AP_INFO("x2ap_eNB_decode_initiating_message!\n"); + break; + + case X2AP_ProcedureCode_id_handoverPreparation: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + X2AP_INFO("x2ap_eNB_decode_initiating_message!\n"); + break; + + case X2AP_ProcedureCode_id_uEContextRelease: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + X2AP_INFO("x2ap_eNB_decode_initiating_message!\n"); + break; + + case X2AP_ProcedureCode_id_handoverCancel: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); X2AP_INFO("x2ap_eNB_decode_initiating_message!\n"); break; @@ -54,7 +76,12 @@ static int x2ap_eNB_decode_successful_outcome(X2AP_X2AP_PDU_t *pdu) switch(pdu->choice.successfulOutcome.procedureCode) { case X2AP_ProcedureCode_id_x2Setup: - asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n"); + break; + + case X2AP_ProcedureCode_id_handoverPreparation: + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n"); break; @@ -73,7 +100,7 @@ static int x2ap_eNB_decode_unsuccessful_outcome(X2AP_X2AP_PDU_t *pdu) switch(pdu->choice.unsuccessfulOutcome.procedureCode) { case X2AP_ProcedureCode_id_x2Setup: - asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); + //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu); X2AP_INFO("x2ap_eNB_decode_unsuccessfuloutcome_message!\n"); break; @@ -99,8 +126,9 @@ int x2ap_eNB_decode_pdu(X2AP_X2AP_PDU_t *pdu, const uint8_t *const buffer, uint3 length, 0, 0); - - xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, pdu); + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, pdu); + } if (dec_ret.code != RC_OK) { X2AP_ERROR("Failed to decode pdu\n"); diff --git a/openair2/X2AP/x2ap_eNB_decoder.h b/openair2/X2AP/x2ap_eNB_decoder.h index 9ce9ea3d40ef039a9c36c45163bdeb2969b0b9fb..e3fa8b44e88ad15393ea103b687efec6be5d7f32 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.h +++ b/openair2/X2AP/x2ap_eNB_decoder.h @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_decoder.h + * \brief x2ap decoder procedures for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #ifndef X2AP_ENB_DECODER_H_ #define X2AP_ENB_DECODER_H_ @@ -26,4 +33,3 @@ int x2ap_eNB_decode_pdu(X2AP_X2AP_PDU_t *pdu, const uint8_t *const buffer, uint3 __attribute__ ((warn_unused_result)); #endif /* X2AP_ENB_DECODER_H_ */ - diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h index 3014290206913e516b046bfc5dbab94fa64397b1..e1a8b506bcabeea022da333856c3b0a03626b481 100644 --- a/openair2/X2AP/x2ap_eNB_defs.h +++ b/openair2/X2AP/x2ap_eNB_defs.h @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_defs.h + * \brief x2ap struct definitions for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #include <stdint.h> #include "queue.h" @@ -26,6 +33,9 @@ #include "sctp_eNB_defs.h" +#include "x2ap_ids.h" +#include "x2ap_timers.h" + #ifndef X2AP_ENB_DEFS_H_ #define X2AP_ENB_DEFS_H_ @@ -34,27 +44,26 @@ typedef enum { /* Disconnected state: initial state for any association. */ X2AP_ENB_STATE_DISCONNECTED = 0x0, - + /* State waiting for x2 Setup response message if the target eNB accepts or * X2 Setup failure if rejects the eNB. */ X2AP_ENB_STATE_WAITING = 0x1, - + /* The eNB is successfully connected to another eNB. */ X2AP_ENB_STATE_CONNECTED = 0x2, - + /* X2AP is ready, and the eNB is successfully connected to another eNB. */ X2AP_ENB_STATE_READY = 0x3, X2AP_ENB_STATE_OVERLOAD = 0x4, X2AP_ENB_STATE_RESETTING = 0x5, - + /* Max number of states available */ X2AP_ENB_STATE_MAX, } x2ap_eNB_state_t; - /* Served PLMN identity element */ struct plmn_identity_s { uint16_t mcc; @@ -84,13 +93,13 @@ typedef struct x2ap_eNB_data_s { /* This is the optional name provided by the MME */ char *eNB_name; - - /* target eNB ID */ + + /* target eNB ID */ uint32_t eNB_id; - + /* Current eNB load information (if any). */ //x2ap_load_state_t overload_state; - + /* Current eNB->eNB X2AP association state */ x2ap_eNB_state_t state; @@ -107,6 +116,10 @@ typedef struct x2ap_eNB_data_s { /* SCTP association id */ int32_t assoc_id; + /* Nid cells */ + uint32_t Nid_cell[MAX_NUM_CCs]; + int num_cc; + /* Only meaningfull in virtual mode */ struct x2ap_eNB_instance_s *x2ap_eNB_instance; } x2ap_eNB_data_t; @@ -169,6 +182,9 @@ typedef struct x2ap_eNB_instance_s { uint16_t sctp_out_streams; uint32_t enb_port_for_X2C; int multi_sd; + + x2ap_id_manager id_manager; + x2ap_timers_t timers; } x2ap_eNB_instance_t; typedef struct { @@ -192,4 +208,3 @@ RB_PROTOTYPE(x2ap_eNB_map, x2ap_eNB_data_s, entry, x2ap_eNB_compare_assoc_id); #endif /* X2AP_ENB_DEFS_H_ */ - diff --git a/openair2/X2AP/x2ap_eNB_encoder.c b/openair2/X2AP/x2ap_eNB_encoder.c index 1eb617a7f1ddec817a88648fe25ddbef2ac9ad7c..8b1c030d35d0b14d588475cf317d450f2fa3e686 100644 --- a/openair2/X2AP/x2ap_eNB_encoder.c +++ b/openair2/X2AP/x2ap_eNB_encoder.c @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_encoder.c + * \brief x2ap encoder procedures for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #include <stdio.h> #include <string.h> #include <stdint.h> diff --git a/openair2/X2AP/x2ap_eNB_encoder.h b/openair2/X2AP/x2ap_eNB_encoder.h index 04c77583b4f27c05fcc723100784bf418bf26c3a..f451a3fb2626e6119b7a0158d4f4394a8f0cb9d1 100644 --- a/openair2/X2AP/x2ap_eNB_encoder.h +++ b/openair2/X2AP/x2ap_eNB_encoder.h @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_encoder.h + * \brief x2ap encoder procedures for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #ifndef X2AP_ENB_ENCODER_H_ #define X2AP_ENB_ENCODER_H_ diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 9c5a281506730409d8cf9b7048e4d68b90e826a7..53ec8574fd80e4305fc5e6744d5b8b7748d8f459 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -19,12 +19,23 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_generate_messages.c + * \brief x2ap procedures for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #include "intertask_interface.h" +#include "X2AP_LastVisitedCell-Item.h" + #include "x2ap_common.h" #include "x2ap_eNB.h" #include "x2ap_eNB_generate_messages.h" #include "x2ap_eNB_encoder.h" +#include "x2ap_eNB_decoder.h" +#include "x2ap_ids.h" #include "x2ap_eNB_itti_messaging.h" @@ -170,7 +181,7 @@ int x2ap_eNB_generate_x2_setup_request( return ret; } -int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data_t *x2ap_eNB_data_p) +int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p) { X2AP_X2AP_PDU_t pdu; X2AP_X2SetupResponse_t *out; @@ -179,18 +190,12 @@ int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data_t *x2ap_eNB_data_p) ServedCells__Member *servedCellMember; X2AP_GU_Group_ID_t *gu; - x2ap_eNB_instance_t *instance_p; - uint8_t *buffer; uint32_t len; int ret = 0; - DevAssert(x2ap_eNB_data_p != NULL); - - /* get the eNB instance */ - instance_p = x2ap_eNB_data_p->x2ap_eNB_instance; - DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); /* Prepare the X2AP message to encode */ memset(&pdu, 0, sizeof(pdu)); @@ -403,3 +408,397 @@ int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p, return 0; } + +int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + x2ap_handover_req_t *x2ap_handover_req, int ue_id) +{ + + X2AP_X2AP_PDU_t pdu; + X2AP_HandoverRequest_t *out; + X2AP_HandoverRequest_IEs_t *ie; + X2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; + X2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; + X2AP_LastVisitedCell_Item_t *lastVisitedCell_Item; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + /* Prepare the X2AP handover message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_handoverPreparation; + pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_HandoverRequest; + out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest; + + /* mandatory */ + ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_HandoverRequest_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_Cause; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_HandoverRequest_IEs__value_PR_Cause; + ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_TargetCell_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_HandoverRequest_IEs__value_PR_ECGI; + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &ie->value.choice.ECGI.pLMN_Identity); + MACRO_ENB_ID_TO_CELL_IDENTITY(x2ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_GUMMEI_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_HandoverRequest_IEs__value_PR_GUMMEI; + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity); + //@TODO: consider to update these values + INT16_TO_OCTET_STRING(x2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID); + MME_CODE_TO_OCTET_STRING(x2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_UE_ContextInformation; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation; + //@TODO: consider to update this value + ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = x2ap_handover_req->mme_ue_s1ap_id; + + KENB_STAR_TO_BIT_STRING(x2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star); + + if (x2ap_handover_req->kenb_ncc >=0) { // Check this condition + ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = x2ap_handover_req->kenb_ncc; + } + else { + ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1; + } + + ENCRALG_TO_BIT_STRING(x2ap_handover_req->security_capabilities.encryption_algorithms, + &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); + + INTPROTALG_TO_BIT_STRING(x2ap_handover_req->security_capabilities.integrity_algorithms, + &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); + + //@TODO: update with proper UEAMPR + UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink); + UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink); + { + for (int i=0;i<x2ap_handover_req->nb_e_rabs_tobesetup;i++) { + e_RABS_ToBeSetup_ItemIEs = (X2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_ToBeSetup_ItemIEs_t)); + e_RABS_ToBeSetup_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item; + e_RABS_ToBeSetup_ItemIEs->criticality = X2AP_Criticality_ignore; + e_RABS_ToBeSetup_ItemIEs->value.present = X2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item; + e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item; + { + e_RABs_ToBeSetup_Item->e_RAB_ID = x2ap_handover_req->e_rabs_tobesetup[i].e_rab_id; + e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = x2ap_handover_req->e_rab_param[i].qos.qci; + e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = x2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level; + e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = x2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability; + e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = x2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability; + e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(x2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length/8); + e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length%8; + e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf = + calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); + + memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf, + x2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.buffer, + e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); + + INT32_TO_OCTET_STRING(x2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID); + } + ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs); + } + } + + OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) x2ap_handover_req->rrc_buffer, x2ap_handover_req->rrc_buffer_size); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_UE_HistoryInformation; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation; + //@TODO: consider to update this value + { + lastVisitedCell_Item = (X2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(X2AP_LastVisitedCell_Item_t)); + lastVisitedCell_Item->present = X2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell; + MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, + &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity); + MACRO_ENB_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier); + lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = X2AP_Cell_Size_small; + lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2; + ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode X2 handover request\n"); + abort(); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1); + + return ret; +} + +int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + x2ap_handover_req_ack_t *x2ap_handover_req_ack) +{ + + X2AP_X2AP_PDU_t pdu; + X2AP_HandoverRequestAcknowledge_t *out; + X2AP_HandoverRequestAcknowledge_IEs_t *ie; + X2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs; + X2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item; + int ue_id; + int id_source; + int id_target; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + ue_id = x2ap_handover_req_ack->x2_id_target; + id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + id_target = ue_id; + + /* Prepare the X2AP handover message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_handoverPreparation; + pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge; + out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; + + /* mandatory */ + ie = (X2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = id_source; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1; + ie->value.choice.UE_X2AP_ID_1 = id_target; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_List; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List; + + { + for (int i=0;i<x2ap_handover_req_ack->nb_e_rabs_tobesetup;i++) { + e_RABS_Admitted_ItemIEs = (X2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(X2AP_E_RABs_Admitted_ItemIEs_t)); + e_RABS_Admitted_ItemIEs->id = X2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item; + e_RABS_Admitted_ItemIEs->criticality = X2AP_Criticality_ignore; + e_RABS_Admitted_ItemIEs->value.present = X2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item; + e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item; + { + e_RABs_Admitted_Item->e_RAB_ID = x2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id; + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs); + } + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_TargeteNBtoSource_eNBTransparentContainer; + + OCTET_STRING_fromBuf(&ie->value.choice.TargeteNBtoSource_eNBTransparentContainer, (char*) x2ap_handover_req_ack->rrc_buffer, x2ap_handover_req_ack->rrc_buffer_size); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode X2 handover response\n"); + abort(); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", x2ap_eNB_data_p->assoc_id); + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1); + + return ret; +} + +int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ue_context_release_t *x2ap_ue_context_release) +{ + + X2AP_X2AP_PDU_t pdu; + X2AP_UEContextRelease_t *out; + X2AP_UEContextRelease_IEs_t *ie; + int ue_id; + int id_source; + int id_target; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + ue_id = x2ap_find_id_from_rnti(&instance_p->id_manager, x2ap_ue_context_release->rnti); + if (ue_id == -1) { + X2AP_ERROR("could not find UE %x\n", x2ap_ue_context_release->rnti); + exit(1); + } + id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + id_target = ue_id; + + /* Prepare the X2AP ue context relase message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_uEContextRelease; + pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore; + pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_UEContextRelease; + out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease; + + /* mandatory */ + ie = (X2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(X2AP_UEContextRelease_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = id_source; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (X2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(X2AP_UEContextRelease_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID_1; + ie->value.choice.UE_X2AP_ID_1 = id_target; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode X2 UE Context Release\n"); + abort(); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1); + + return ret; +} + +int x2ap_eNB_generate_x2_handover_cancel (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + int x2_ue_id, + x2ap_handover_cancel_cause_t cause) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_HandoverCancel_t *out; + X2AP_HandoverCancel_IEs_t *ie; + int ue_id; + int id_source; + int id_target; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + ue_id = x2_ue_id; + id_source = ue_id; + id_target = x2ap_id_get_id_target(&instance_p->id_manager, ue_id); + + /* Prepare the X2AP handover cancel message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_handoverCancel; + pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore; + pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_HandoverCancel; + out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel; + + /* mandatory */ + ie = (X2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(X2AP_HandoverCancel_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID; + ie->criticality = X2AP_Criticality_reject; + ie->value.present = X2AP_HandoverCancel_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = id_source; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (id_target != -1) { + ie = (X2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(X2AP_HandoverCancel_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_HandoverCancel_IEs__value_PR_UE_X2AP_ID_1; + ie->value.choice.UE_X2AP_ID_1 = id_target; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + ie = (X2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(X2AP_HandoverCancel_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_Cause; + ie->criticality = X2AP_Criticality_ignore; + ie->value.present = X2AP_HandoverCancel_IEs__value_PR_Cause; + switch (cause) { + case X2AP_T_RELOC_PREP_TIMEOUT: + ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = + X2AP_CauseRadioNetwork_trelocprep_expiry; + break; + case X2AP_TX2_RELOC_OVERALL_TIMEOUT: + ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = + X2AP_CauseRadioNetwork_tx2relocoverall_expiry; + break; + default: + /* we can't come here */ + X2AP_ERROR("unhandled cancel cause\n"); + exit(1); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode X2 Handover Cancel\n"); + abort(); + return -1; + } + + MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 1); + + return ret; +} diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index a72b37e743da4ff24bdd8cd827ec0ffaeec47713..1fcdf31f121e033f08e08b16e13af5bf044170e2 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_generate_messages.h + * \brief x2ap procedures for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #ifndef X2AP_ENB_GENERATE_MESSAGES_H_ #define X2AP_ENB_GENERATE_MESSAGES_H_ @@ -26,9 +33,9 @@ #include "x2ap_common.h" int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p, - x2ap_eNB_data_t *x2ap_enb_data_p); + x2ap_eNB_data_t *x2ap_eNB_data_p); -int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data_t *x2ap_enb_data_p); +int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); int x2ap_eNB_generate_x2_setup_failure(instance_t instance, uint32_t assoc_id, @@ -40,5 +47,17 @@ int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p, X2AP_Cause_PR cause_type, long cause_value); -#endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ +int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + x2ap_handover_req_t *x2ap_handover_req, int ue_id); + +int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + x2ap_handover_req_ack_t *x2ap_handover_req_ack); +int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + x2ap_ue_context_release_t *x2ap_ue_context_release); + +int x2ap_eNB_generate_x2_handover_cancel (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + int x2_ue_id, + x2ap_handover_cancel_cause_t cause); + +#endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index a16a3da5a8ac9d3b5fd998875fed3e61cd8cc5fc..96ffac162ebc2e62c8d249a7b2c72b9d40e7d2eb 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -18,6 +18,14 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ + +/*! \file x2ap_eNB_handler.c + * \brief x2ap handler procedures for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #include <stdint.h> #include "intertask_interface.h" @@ -28,6 +36,7 @@ #include "x2ap_eNB_defs.h" #include "x2ap_eNB_handler.h" #include "x2ap_eNB_decoder.h" +#include "x2ap_ids.h" #include "x2ap_eNB_management_procedures.h" #include "x2ap_eNB_generate_messages.h" @@ -52,14 +61,37 @@ int x2ap_eNB_handle_x2_setup_failure (instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); +static +int x2ap_eNB_handle_handover_preparation (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); +static +int x2ap_eNB_handle_handover_response (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + +static +int x2ap_eNB_handle_ue_context_release (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + +static +int x2ap_eNB_handle_handover_cancel (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + /* Handlers matrix. Only eNB related procedure present here */ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { - { 0, 0, 0 }, /* handoverPreparation */ - { 0, 0, 0 }, /* handoverCancel */ + { x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */ + { x2ap_eNB_handle_handover_cancel, 0, 0 }, /* handoverCancel */ { 0, 0, 0 }, /* loadIndication */ { 0, 0, 0 }, /* errorIndication */ { 0, 0, 0 }, /* snStatusTransfer */ - { 0, 0, 0 }, /* uEContextRelease */ + { x2ap_eNB_handle_ue_context_release, 0, 0 }, /* uEContextRelease */ { x2ap_eNB_handle_x2_setup_request, x2ap_eNB_handle_x2_setup_response, x2ap_eNB_handle_x2_setup_failure }, /* x2Setup */ { 0, 0, 0 }, /* reset */ { 0, 0, 0 }, /* eNBConfigurationUpdate */ @@ -93,7 +125,7 @@ static char *x2ap_direction_String[] = { return(x2ap_direction_String[x2ap_dir]); } -void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown) +void x2ap_handle_x2_setup_message(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown) { if (sctp_shutdown) { /* A previously connected eNB has been shutdown */ @@ -102,38 +134,38 @@ void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown if (enb_desc_p->state == X2AP_ENB_STATE_CONNECTED) { enb_desc_p->state = X2AP_ENB_STATE_DISCONNECTED; - if (enb_desc_p->x2ap_eNB_instance-> x2_target_enb_associated_nb > 0) { + if (instance_p-> x2_target_enb_associated_nb > 0) { /* Decrease associated eNB number */ - enb_desc_p->x2ap_eNB_instance-> x2_target_enb_associated_nb --; + instance_p-> x2_target_enb_associated_nb --; } /* If there are no more associated eNB, inform eNB app */ - if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_associated_nb == 0) { + if (instance_p->x2_target_enb_associated_nb == 0) { MessageDef *message_p; message_p = itti_alloc_new_message(TASK_X2AP, X2AP_DEREGISTERED_ENB_IND); X2AP_DEREGISTERED_ENB_IND(message_p).nb_x2 = 0; - itti_send_msg_to_task(TASK_ENB_APP, enb_desc_p->x2ap_eNB_instance->instance, message_p); + itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p); } } } else { /* Check that at least one setup message is pending */ - DevCheck(enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb > 0, - enb_desc_p->x2ap_eNB_instance->instance, - enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb, 0); + DevCheck(instance_p->x2_target_enb_pending_nb > 0, + instance_p->instance, + instance_p->x2_target_enb_pending_nb, 0); - if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb > 0) { + if (instance_p->x2_target_enb_pending_nb > 0) { /* Decrease pending messages number */ - enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb --; + instance_p->x2_target_enb_pending_nb --; } /* If there are no more pending messages, inform eNB app */ - if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb == 0) { + if (instance_p->x2_target_enb_pending_nb == 0) { MessageDef *message_p; message_p = itti_alloc_new_message(TASK_X2AP, X2AP_REGISTER_ENB_CNF); - X2AP_REGISTER_ENB_CNF(message_p).nb_x2 = enb_desc_p->x2ap_eNB_instance->x2_target_enb_associated_nb; - itti_send_msg_to_task(TASK_ENB_APP, enb_desc_p->x2ap_eNB_instance->instance, message_p); + X2AP_REGISTER_ENB_CNF(message_p).nb_x2 = instance_p->x2_target_enb_associated_nb; + itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p); } } } @@ -143,41 +175,105 @@ int x2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stre const uint8_t *const data, const uint32_t data_length) { X2AP_X2AP_PDU_t pdu; - int ret; + int ret = 0; DevAssert(data != NULL); memset(&pdu, 0, sizeof(pdu)); + //printf("Data length received: %d\n", data_length); + if (x2ap_eNB_decode_pdu(&pdu, data, data_length) < 0) { X2AP_ERROR("Failed to decode PDU\n"); return -1; } - /* Checking procedure Code and direction of message */ - if (pdu.choice.initiatingMessage.procedureCode > sizeof(x2ap_messages_callback) / (3 * sizeof( - x2ap_message_decoded_callback)) - || (pdu.present > X2AP_X2AP_PDU_PR_unsuccessfulOutcome)) { - X2AP_ERROR("[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", - assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); - return -1; - } + switch (pdu.present) { - /* No handler present. - * This can mean not implemented or no procedure for eNB (wrong direction). - */ - if (x2ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { - X2AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", - assoc_id, pdu.choice.initiatingMessage.procedureCode, - x2ap_direction2String(pdu.present - 1)); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); - return -1; - } + case X2AP_X2AP_PDU_PR_initiatingMessage: + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage.procedureCode > sizeof(x2ap_messages_callback) / (3 * sizeof( + x2ap_message_decoded_callback))) { + //|| (pdu.present > X2AP_X2AP_PDU_PR_unsuccessfulOutcome)) { + X2AP_ERROR("[SCTP %d] Either procedureCode %ld exceed expected\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); + return -1; + } - /* Calling the right handler */ - ret = (*x2ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (x2ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) { + X2AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage.procedureCode, + x2ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); + return -1; + } + /* Calling the right handler */ + ret = (*x2ap_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) (instance, assoc_id, stream, &pdu); + break; + + case X2AP_X2AP_PDU_PR_successfulOutcome: + /* Checking procedure Code and direction of message */ + if (pdu.choice.successfulOutcome.procedureCode > sizeof(x2ap_messages_callback) / (3 * sizeof( + x2ap_message_decoded_callback))) { + //|| (pdu.present > X2AP_X2AP_PDU_PR_unsuccessfulOutcome)) { + X2AP_ERROR("[SCTP %d] Either procedureCode %ld exceed expected\n", + assoc_id, pdu.choice.successfulOutcome.procedureCode); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (x2ap_messages_callback[pdu.choice.successfulOutcome.procedureCode][pdu.present - 1] == NULL) { + X2AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.successfulOutcome.procedureCode, + x2ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); + return -1; + } + /* Calling the right handler */ + ret = (*x2ap_messages_callback[pdu.choice.successfulOutcome.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + break; + + case X2AP_X2AP_PDU_PR_unsuccessfulOutcome: + /* Checking procedure Code and direction of message */ + if (pdu.choice.unsuccessfulOutcome.procedureCode > sizeof(x2ap_messages_callback) / (3 * sizeof( + x2ap_message_decoded_callback))) { + //|| (pdu.present > X2AP_X2AP_PDU_PR_unsuccessfulOutcome)) { + X2AP_ERROR("[SCTP %d] Either procedureCode %ld exceed expected\n", + assoc_id, pdu.choice.unsuccessfulOutcome.procedureCode); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for eNB (wrong direction). + */ + if (x2ap_messages_callback[pdu.choice.unsuccessfulOutcome.procedureCode][pdu.present - 1] == NULL) { + X2AP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.unsuccessfulOutcome.procedureCode, + x2ap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); + return -1; + } + /* Calling the right handler */ + ret = (*x2ap_messages_callback[pdu.choice.unsuccessfulOutcome.procedureCode][pdu.present - 1]) + (instance, assoc_id, stream, &pdu); + break; + + default: + X2AP_ERROR("[SCTP %d] Direction %d exceed expected\n", + assoc_id, pdu.present); + break; + } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_X2AP_X2AP_PDU, &pdu); return ret; } @@ -191,7 +287,9 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance, X2AP_X2SetupRequest_t *x2SetupRequest; X2AP_X2SetupRequest_IEs_t *ie; + ServedCells__Member *servedCellMember; + x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; uint32_t eNB_id = 0; @@ -219,27 +317,31 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance, X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupRequest_IEs_t, ie, x2SetupRequest, X2AP_ProtocolIE_ID_id_GlobalENB_ID, true); - - if (ie->value.choice.GlobalENB_ID.eNB_ID.present == X2AP_ENB_ID_PR_home_eNB_ID) { + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } else { + if (ie->value.choice.GlobalENB_ID.eNB_ID.present == X2AP_ENB_ID_PR_home_eNB_ID) { // Home eNB ID = 28 bits - uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.home_eNB_ID.buf; + uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.home_eNB_ID.buf; - if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) { + if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 28) { //TODO: handle case were size != 28 -> notify ? reject ? - } + } - eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4); - X2AP_DEBUG("Home eNB id: %07x\n", eNB_id); - } else { + eNB_id = (eNB_id_buf[0] << 20) + (eNB_id_buf[1] << 12) + (eNB_id_buf[2] << 4) + ((eNB_id_buf[3] & 0xf0) >> 4); + X2AP_DEBUG("Home eNB id: %07x\n", eNB_id); + } else { // Macro eNB = 20 bits - uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; + uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf; - if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) { + if (ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.size != 20) { //TODO: handle case were size != 20 -> notify ? reject ? - } + } - eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4); - X2AP_DEBUG("macro eNB id: %05x\n", eNB_id); + eNB_id = (eNB_id_buf[0] << 12) + (eNB_id_buf[1] << 4) + ((eNB_id_buf[2] & 0xf0) >> 4); + X2AP_DEBUG("macro eNB id: %05x\n", eNB_id); + } } X2AP_DEBUG("Adding eNB to the list of associated eNBs\n"); @@ -270,8 +372,7 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance, */ X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id); - DevAssert(x2ap_eNB_data->x2ap_eNB_instance != NULL); - x2ap_eNB_generate_x2_setup_failure (x2ap_eNB_data->x2ap_eNB_instance->instance, + x2ap_eNB_generate_x2_setup_failure (instance, assoc_id, X2AP_Cause_PR_protocol, X2AP_CauseProtocol_unspecified, @@ -283,7 +384,25 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance, */ } - return x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data); + /* Set proper pci */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupRequest_IEs_t, ie, x2SetupRequest, + X2AP_ProtocolIE_ID_id_ServedCells, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + if (ie->value.choice.ServedCells.list.count > 0) { + x2ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count; + for (int i=0; i<ie->value.choice.ServedCells.list.count;i++) { + servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i]; + x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI; + } + } + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data); } static @@ -295,7 +414,9 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance, X2AP_X2SetupResponse_t *x2SetupResponse; X2AP_X2SetupResponse_IEs_t *ie; + ServedCells__Member *servedCellMember; + x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; uint32_t eNB_id = 0; @@ -322,6 +443,10 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance, X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupResponse_IEs_t, ie, x2SetupResponse, X2AP_ProtocolIE_ID_id_GlobalENB_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } if (ie->value.choice.GlobalENB_ID.eNB_ID.present == X2AP_ENB_ID_PR_home_eNB_ID) { // Home eNB ID = 28 bits uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.home_eNB_ID.buf; @@ -367,14 +492,34 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance, */ } + /* Set proper pci */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupResponse_IEs_t, ie, x2SetupResponse, + X2AP_ProtocolIE_ID_id_ServedCells, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + if (ie->value.choice.ServedCells.list.count > 0) { + x2ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count; + for (int i=0; i<ie->value.choice.ServedCells.list.count;i++) { + servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i]; + x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI; + } + } + /* Optionaly set the target eNB name */ /* The association is now ready as source and target eNBs know parameters of each other. * Mark the association as connected. */ x2ap_eNB_data->state = X2AP_ENB_STATE_READY; - x2ap_eNB_data->x2ap_eNB_instance->x2_target_enb_associated_nb ++; - x2ap_handle_x2_setup_message(x2ap_eNB_data, 0); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + instance_p->x2_target_enb_associated_nb ++; + x2ap_handle_x2_setup_message(instance_p, x2ap_eNB_data, 0); return 0; } @@ -389,6 +534,7 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance, X2AP_X2SetupFailure_t *x2SetupFailure; X2AP_X2SetupFailure_IEs_t *ie; + x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; DevAssert(pdu != NULL); @@ -416,7 +562,10 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance, X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupFailure_IEs_t, ie, x2SetupFailure, X2AP_ProtocolIE_ID_id_Cause, true); - + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } // need a FSM to handle all cases if ((ie->value.choice.Cause.present == X2AP_Cause_PR_misc) && (ie->value.choice.Cause.choice.misc == X2AP_CauseMisc_unspecified)) { @@ -426,7 +575,429 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance, } x2ap_eNB_data->state = X2AP_ENB_STATE_WAITING; - x2ap_handle_x2_setup_message(x2ap_eNB_data, 0); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + x2ap_handle_x2_setup_message(instance_p, x2ap_eNB_data, 0); + + return 0; +} + +static +int x2ap_eNB_handle_handover_preparation (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + + X2AP_HandoverRequest_t *x2HandoverRequest; + X2AP_HandoverRequest_IEs_t *ie; + + X2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs; + X2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + int ue_id; + + DevAssert (pdu != NULL); + x2HandoverRequest = &pdu->choice.initiatingMessage.value.choice.HandoverRequest; + + if (stream == 0) { + X2AP_ERROR ("Received new x2 handover request on stream == 0\n"); + /* TODO: send a x2 failure response */ + return 0; + } + + X2AP_DEBUG ("Received a new X2 handover request\n"); + + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, + X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + /* allocate a new X2AP UE ID */ + ue_id = x2ap_allocate_new_id(&instance_p->id_manager); + if (ue_id == -1) { + X2AP_ERROR("could not allocate a new X2AP UE ID\n"); + /* TODO: cancel handover: send HO preparation failure to source eNB */ + exit(1); + } + /* rnti is unknown yet, must not be set to -1, 0 is fine */ + x2ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.UE_X2AP_ID, ue_id); + x2ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_TARGET); + + X2AP_HANDOVER_REQ(msg).x2_id = ue_id; + + //X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice. + //measResultListEUTRA.list.array[ncell_index]->physCellId; + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, + X2AP_ProtocolIE_ID_id_GUMMEI_ID, true); + + TBCD_TO_MCC_MNC(&ie->value.choice.ECGI.pLMN_Identity, X2AP_HANDOVER_REQ(msg).ue_gummei.mcc, + X2AP_HANDOVER_REQ(msg).ue_gummei.mnc, X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len); + OCTET_STRING_TO_INT8(&ie->value.choice.GUMMEI.mME_Code, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code); + OCTET_STRING_TO_INT16(&ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_group_id); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, + X2AP_ProtocolIE_ID_id_UE_ContextInformation, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID; + + /* TODO: properly store Target Cell ID */ + + X2AP_HANDOVER_REQ(msg).target_assoc_id = assoc_id; + + X2AP_HANDOVER_REQ(msg).security_capabilities.encryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms); + X2AP_HANDOVER_REQ(msg).security_capabilities.integrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms); + + //X2AP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr; + + if ((ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.buf) && + (ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.size == 32)) { + memcpy(X2AP_HANDOVER_REQ(msg).kenb, ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star.buf, 32); + X2AP_HANDOVER_REQ(msg).kenb_ncc = ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount; + } else { + X2AP_WARN ("Size of eNB key star does not match the expected value\n"); + } + + if (ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count > 0) { + + X2AP_HANDOVER_REQ(msg).nb_e_rabs_tobesetup = ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count; + + for (int i=0;i<ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.count;i++) { + e_RABS_ToBeSetup_ItemIEs = (X2AP_E_RABs_ToBeSetup_ItemIEs_t *) ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list.array[i]; + e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item; + + X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].e_rab_id = e_RABs_ToBeSetup_Item->e_RAB_ID ; + + memcpy(X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr.buffer, + e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf, + e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size); + + X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].eNB_addr.length = + e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused; + + OCTET_STRING_TO_INT32(&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID, + X2AP_HANDOVER_REQ(msg).e_rabs_tobesetup[i].gtp_teid); + + X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.qci = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI; + X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel; + X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability; + X2AP_HANDOVER_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability; + } + + } + else { + X2AP_ERROR ("Can't decode the e_RABs_ToBeSetup_List \n"); + } + + X2AP_RRC_Context_t *c = &ie->value.choice.UE_ContextInformation.rRC_Context; + + if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s*/) + { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } + + memcpy(X2AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size); + X2AP_HANDOVER_REQ(msg).rrc_buffer_size = c->size; + + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + + return 0; +} + +static +int x2ap_eNB_handle_handover_response (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + X2AP_HandoverRequestAcknowledge_t *x2HandoverRequestAck; + X2AP_HandoverRequestAcknowledge_IEs_t *ie; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + int ue_id; + int id_source; + int id_target; + int rnti; + + DevAssert (pdu != NULL); + x2HandoverRequestAck = &pdu->choice.successfulOutcome.value.choice.HandoverRequestAcknowledge; + + if (stream == 0) { + X2AP_ERROR ("Received new x2 handover response on stream == 0\n"); + /* TODO: send a x2 failure response */ + return 0; + } + + X2AP_DEBUG ("Received a new X2 handover response\n"); + + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ_ACK); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, + X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + id_source = ie->value.choice.UE_X2AP_ID; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, + X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + id_target = ie->value.choice.UE_X2AP_ID_1; + + ue_id = id_source; + + if (ue_id != x2ap_find_id_from_id_source(&instance_p->id_manager, id_source)) { + X2AP_WARN("incorrect/unknown X2AP IDs for UE (old ID %d new ID %d), ignoring handover response\n", + id_source, id_target); + return 0; + } + + rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id); + + /* id_target is a new information, store it */ + x2ap_set_ids(&instance_p->id_manager, ue_id, rnti, id_source, id_target); + x2ap_id_set_state(&instance_p->id_manager, ue_id, X2ID_STATE_SOURCE_OVERALL); + x2ap_set_reloc_overall_timer(&instance_p->id_manager, ue_id, + x2ap_timer_get_tti(&instance_p->timers)); + + X2AP_HANDOVER_REQ_ACK(msg).rnti = rnti; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, + X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true); + + X2AP_TargeteNBtoSource_eNBTransparentContainer_t *c = &ie->value.choice.TargeteNBtoSource_eNBTransparentContainer; + + if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s*/) + { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } + + memcpy(X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, c->buf, c->size); + X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size = c->size; + + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + return 0; +} + + +static +int x2ap_eNB_handle_ue_context_release (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + X2AP_UEContextRelease_t *x2UEContextRelease; + X2AP_UEContextRelease_IEs_t *ie; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + int ue_id; + int id_source; + int id_target; + + DevAssert (pdu != NULL); + x2UEContextRelease = &pdu->choice.initiatingMessage.value.choice.UEContextRelease; + + if (stream == 0) { + X2AP_ERROR ("Received new x2 ue context release on stream == 0\n"); + /* TODO: send a x2 failure response */ + return 0; + } + + X2AP_DEBUG ("Received a new X2 ue context release\n"); + + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + msg = itti_alloc_new_message(TASK_X2AP, X2AP_UE_CONTEXT_RELEASE); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, + X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + id_source = ie->value.choice.UE_X2AP_ID; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, + X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + id_target = ie->value.choice.UE_X2AP_ID_1; + + ue_id = id_source; + if (ue_id != x2ap_find_id_from_id_source(&instance_p->id_manager, id_source)) { + X2AP_WARN("incorrect/unknown X2AP IDs for UE (old ID %d new ID %d), ignoring UE context release\n", + id_source, id_target); + return 0; + } + + if (id_target != x2ap_id_get_id_target(&instance_p->id_manager, ue_id)) { + X2AP_ERROR("UE context release: bad id_target for UE %x (id_source %d) expected %d got %d, ignoring message\n", + x2ap_id_get_rnti(&instance_p->id_manager, ue_id), + id_source, + x2ap_id_get_id_target(&instance_p->id_manager, ue_id), + id_target); + return 0; + } + + X2AP_UE_CONTEXT_RELEASE(msg).rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id); + + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + + x2ap_release_id(&instance_p->id_manager, ue_id); + + return 0; +} + +static +int x2ap_eNB_handle_handover_cancel (instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + X2AP_HandoverCancel_t *x2HandoverCancel; + X2AP_HandoverCancel_IEs_t *ie; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + int ue_id; + int id_source; + int id_target; + x2ap_handover_cancel_cause_t cause; + + DevAssert (pdu != NULL); + x2HandoverCancel = &pdu->choice.initiatingMessage.value.choice.HandoverCancel; + + if (stream == 0) { + X2AP_ERROR ("Received new x2 handover cancel on stream == 0\n"); + return 0; + } + + X2AP_DEBUG ("Received a new X2 handover cancel\n"); + + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverCancel_IEs_t, ie, x2HandoverCancel, + X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + id_source = ie->value.choice.UE_X2AP_ID; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverCancel_IEs_t, ie, x2HandoverCancel, + X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, false); + + if (ie == NULL ) { + X2AP_INFO("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + id_target = -1; + } else + id_target = ie->value.choice.UE_X2AP_ID_1; + + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverCancel_IEs_t, ie, x2HandoverCancel, + X2AP_ProtocolIE_ID_id_Cause, true); + + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + if (ie->value.present != X2AP_HandoverCancel_IEs__value_PR_Cause || + ie->value.choice.Cause.present != X2AP_Cause_PR_radioNetwork || + !(ie->value.choice.Cause.choice.radioNetwork == + X2AP_CauseRadioNetwork_trelocprep_expiry || + ie->value.choice.Cause.choice.radioNetwork == + X2AP_CauseRadioNetwork_tx2relocoverall_expiry)) { + X2AP_ERROR("%s %d: Cause not supported (only T_reloc_prep and TX2_reloc_overall handled)\n",__FILE__,__LINE__); + return -1; + } + + switch (ie->value.choice.Cause.choice.radioNetwork) { + case X2AP_CauseRadioNetwork_trelocprep_expiry: + cause = X2AP_T_RELOC_PREP_TIMEOUT; + break; + case X2AP_CauseRadioNetwork_tx2relocoverall_expiry: + cause = X2AP_TX2_RELOC_OVERALL_TIMEOUT; + break; + default: /* can't come here */ exit(1); + } + + ue_id = x2ap_find_id_from_id_source(&instance_p->id_manager, id_source); + if (ue_id == -1) { + X2AP_WARN("Handover cancel: UE not found (id_source = %d), ignoring message\n", id_source); + return 0; + } + + if (id_target != -1 && + id_target != x2ap_id_get_id_target(&instance_p->id_manager, ue_id)) { + X2AP_ERROR("Handover cancel: bad id_target for UE %x (id_source %d) expected %d got %d\n", + x2ap_id_get_rnti(&instance_p->id_manager, ue_id), + id_source, + x2ap_id_get_id_target(&instance_p->id_manager, ue_id), + id_target); + exit(1); + } + + msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_CANCEL); + + X2AP_HANDOVER_CANCEL(msg).rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id); + X2AP_HANDOVER_CANCEL(msg).cause = cause; + + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + + x2ap_release_id(&instance_p->id_manager, ue_id); return 0; } diff --git a/openair2/X2AP/x2ap_eNB_handler.h b/openair2/X2AP/x2ap_eNB_handler.h index 0f93859a84213e273c3a19eac0dd158d1616212e..65f411895fbb823a9c523826d06bdb15130821cb 100644 --- a/openair2/X2AP/x2ap_eNB_handler.h +++ b/openair2/X2AP/x2ap_eNB_handler.h @@ -19,15 +19,21 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_handler.h + * \brief x2ap handler procedures for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #ifndef X2AP_ENB_HANDLERS_H_ #define X2AP_ENB_HANDLERS_H_ #include "x2ap_eNB_defs.h" -void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); +void x2ap_handle_x2_setup_message(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown); int x2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, const uint8_t * const data, const uint32_t data_length); #endif /* X2AP_ENB_HANDLERS_H_ */ - diff --git a/openair2/X2AP/x2ap_eNB_itti_messaging.c b/openair2/X2AP/x2ap_eNB_itti_messaging.c index d8e1e19afeeae608e1d44b18784ca1ec0aa293a6..7573d9be898a8bd0643b9e5ffa4be85c9052ae89 100644 --- a/openair2/X2AP/x2ap_eNB_itti_messaging.c +++ b/openair2/X2AP/x2ap_eNB_itti_messaging.c @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_itti_messaging.c + * \brief x2ap tasks for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #include "intertask_interface.h" #include "x2ap_eNB_itti_messaging.h" @@ -53,4 +60,3 @@ void x2ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t asso itti_send_msg_to_task(TASK_SCTP, instance, message_p); } - diff --git a/openair2/X2AP/x2ap_eNB_itti_messaging.h b/openair2/X2AP/x2ap_eNB_itti_messaging.h index 55bf58b6605260c85c70b4d5887f768c42f3e49f..ee946880ac3c3b69ca51b58ee0c327260ea3ed6d 100644 --- a/openair2/X2AP/x2ap_eNB_itti_messaging.h +++ b/openair2/X2AP/x2ap_eNB_itti_messaging.h @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_itti_messaging.h + * \brief x2ap tasks for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #ifndef X2AP_ENB_ITTI_MESSAGING_H_ #define X2AP_ENB_ITTI_MESSAGING_H_ diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.c b/openair2/X2AP/x2ap_eNB_management_procedures.c index c2b128ffd312c4c042dc397b992dd62ff6641bc2..986ca10902ba678c30a1578c95a1aa0881dfd309 100644 --- a/openair2/X2AP/x2ap_eNB_management_procedures.c +++ b/openair2/X2AP/x2ap_eNB_management_procedures.c @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_management_procedures.c + * \brief x2ap tasks for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #include <stdio.h> #include <stdlib.h> #include <stdint.h> @@ -38,7 +45,7 @@ # define X2AP_eNB_LIST_OUT(x, args...) X2AP_DEBUG("[eNB]%*s"x"\n", 4*indent, "", ##args) #else # define X2AP_eNB_LIST_OUT(x, args...) -#endif +#endif static int indent = 0; @@ -116,7 +123,7 @@ printf("---------------------------------------------\n"); } struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p, - int32_t assoc_id, + int32_t assoc_id, uint16_t cnx_id) { struct x2ap_eNB_data_s temp; @@ -162,8 +169,7 @@ x2ap_eNB_instance_t *x2ap_eNB_get_instance(instance_t instance) return NULL; } - -/// utility functions +/// utility functions void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref); @@ -172,9 +178,9 @@ x2ap_dump_eNB_list (void) { x2ap_eNB_instance_t *inst = NULL; struct x2ap_eNB_data_s *found = NULL; struct x2ap_eNB_data_s temp; - + memset(&temp, 0, sizeof(struct x2ap_eNB_data_s)); - + STAILQ_FOREACH (inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) { found = RB_FIND(x2ap_enb_map, &inst->x2ap_enb_head, &temp); x2ap_dump_eNB (found); @@ -186,12 +192,12 @@ void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref) { if (eNB_ref == NULL) { return; } - + X2AP_eNB_LIST_OUT (""); X2AP_eNB_LIST_OUT ("eNB name: %s", eNB_ref->eNB_name == NULL ? "not present" : eNB_ref->eNB_name); X2AP_eNB_LIST_OUT ("eNB STATE: %07x", eNB_ref->state); X2AP_eNB_LIST_OUT ("eNB ID: %07x", eNB_ref->eNB_id); - indent++; + indent++; X2AP_eNB_LIST_OUT ("SCTP cnx id: %d", eNB_ref->cnx_id); X2AP_eNB_LIST_OUT ("SCTP assoc id: %d", eNB_ref->assoc_id); X2AP_eNB_LIST_OUT ("SCTP instreams: %d", eNB_ref->in_streams); @@ -199,6 +205,22 @@ void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref) { indent--; } +x2ap_eNB_data_t * x2ap_is_eNB_pci_in_list (const uint32_t pci) +{ + x2ap_eNB_instance_t *inst; + struct x2ap_eNB_data_s *elm; + + STAILQ_FOREACH(inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) { + RB_FOREACH(elm, x2ap_enb_map, &inst->x2ap_enb_head) { + for (int i = 0; i<elm->num_cc; i++) { + if (elm->Nid_cell[i] == pci) { + return elm; + } + } + } + } + return NULL; +} x2ap_eNB_data_t * x2ap_is_eNB_id_in_list (const uint32_t eNB_id) { @@ -233,4 +255,3 @@ x2ap_eNB_data_t * x2ap_is_eNB_assoc_id_in_list (const uint32_t sctp_assoc_id) } return NULL; } - diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.h b/openair2/X2AP/x2ap_eNB_management_procedures.h index b66a6d10356536508f5dad4d44a960da61a7f094..c5217341c514818f8abe81231cfd9b9600e03821 100644 --- a/openair2/X2AP/x2ap_eNB_management_procedures.h +++ b/openair2/X2AP/x2ap_eNB_management_procedures.h @@ -19,6 +19,13 @@ * contact@openairinterface.org */ +/*! \file x2ap_eNB_management_procedures.h + * \brief x2ap tasks for eNB + * \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr> + * \date 2018 + * \version 1.0 + */ + #ifndef X2AP_ENB_MANAGEMENT_PROCEDURES_H_ #define X2AP_ENB_MANAGEMENT_PROCEDURES_H @@ -38,9 +45,10 @@ x2ap_eNB_data_t* x2ap_is_eNB_id_in_list(uint32_t eNB_id); x2ap_eNB_data_t* x2ap_is_eNB_assoc_id_in_list(uint32_t sctp_assoc_id); +x2ap_eNB_data_t* x2ap_is_eNB_pci_in_list (const uint32_t pci); + struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p, int32_t assoc_id, uint16_t cnx_id); #endif /* X2AP_ENB_MANAGEMENT_PROCEDURES_H_ */ - diff --git a/openair2/X2AP/x2ap_ids.c b/openair2/X2AP/x2ap_ids.c new file mode 100644 index 0000000000000000000000000000000000000000..02f1bbfc0e11171b3400317e34a2d5843a220885 --- /dev/null +++ b/openair2/X2AP/x2ap_ids.c @@ -0,0 +1,128 @@ +/* + * 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 "x2ap_ids.h" + +#include <string.h> + +void x2ap_id_manager_init(x2ap_id_manager *m) +{ + int i; + memset(m, 0, sizeof(x2ap_id_manager)); + for (i = 0; i < X2AP_MAX_IDS; i++) + m->ids[i].rnti = -1; +} + +int x2ap_allocate_new_id(x2ap_id_manager *m) +{ + int i; + for (i = 0; i < X2AP_MAX_IDS; i++) + if (m->ids[i].rnti == -1) { + m->ids[i].rnti = 0; + m->ids[i].id_source = -1; + m->ids[i].id_target = -1; + return i; + } + return -1; +} + +void x2ap_release_id(x2ap_id_manager *m, int id) +{ + m->ids[id].rnti = -1; +} + +int x2ap_find_id(x2ap_id_manager *m, int id_source, int id_target) +{ + int i; + for (i = 0; i < X2AP_MAX_IDS; i++) + if (m->ids[i].rnti != -1 && + m->ids[i].id_source == id_source && + m->ids[i].id_target == id_target) + return i; + return -1; +} + +int x2ap_find_id_from_id_source(x2ap_id_manager *m, int id_source) +{ + int i; + for (i = 0; i < X2AP_MAX_IDS; i++) + if (m->ids[i].rnti != -1 && + m->ids[i].id_source == id_source) + return i; + return -1; +} + +int x2ap_find_id_from_rnti(x2ap_id_manager *m, int rnti) +{ + int i; + for (i = 0; i < X2AP_MAX_IDS; i++) + if (m->ids[i].rnti == rnti) + return i; + return -1; +} + +void x2ap_set_ids(x2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target) +{ + m->ids[ue_id].rnti = rnti; + m->ids[ue_id].id_source = id_source; + m->ids[ue_id].id_target = id_target; +} + +/* real type of target is x2ap_eNB_data_t * */ +void x2ap_id_set_target(x2ap_id_manager *m, int ue_id, void *target) +{ + m->ids[ue_id].target = target; +} + +void x2ap_id_set_state(x2ap_id_manager *m, int ue_id, x2id_state_t state) +{ + m->ids[ue_id].state = state; +} + +void x2ap_set_reloc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time) +{ + m->ids[ue_id].t_reloc_prep_start = time; +} + +void x2ap_set_reloc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time) +{ + m->ids[ue_id].tx2_reloc_overall_start = time; +} + +int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].id_source; +} + +int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].id_target; +} + +int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].rnti; +} + +void *x2ap_id_get_target(x2ap_id_manager *m, int ue_id) +{ + return m->ids[ue_id].target; +} diff --git a/openair2/X2AP/x2ap_ids.h b/openair2/X2AP/x2ap_ids.h new file mode 100644 index 0000000000000000000000000000000000000000..3d2799e8c46d3248a1fab193f35203510a9af9ff --- /dev/null +++ b/openair2/X2AP/x2ap_ids.h @@ -0,0 +1,80 @@ +/* + * 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 X2AP_IDS_H_ +#define X2AP_IDS_H_ + +#include <stdint.h> + +/* maximum number of simultaneous handovers, do not set too high */ +#define X2AP_MAX_IDS 16 + +/* + * state: + * - when starting handover in source, UE is in state X2ID_STATE_SOURCE_PREPARE + * - after receiving HO_ack in source, UE is in state X2ID_STATE_SOURCE_OVERALL + * - in target, UE is in state X2ID_STATE_TARGET + * The state is used to check timers. + */ +typedef enum { + X2ID_STATE_SOURCE_PREPARE, + X2ID_STATE_SOURCE_OVERALL, + X2ID_STATE_TARGET +} x2id_state_t; + +typedef struct { + int rnti; /* -1 when free */ + int id_source; + int id_target; + + /* the target eNB. Real type is x2ap_eNB_data_t * */ + void *target; + + /* state: needed to check timers */ + x2id_state_t state; + + /* timers */ + uint64_t t_reloc_prep_start; + uint64_t tx2_reloc_overall_start; +} x2ap_id; + +typedef struct { + x2ap_id ids[X2AP_MAX_IDS]; +} x2ap_id_manager; + +void x2ap_id_manager_init(x2ap_id_manager *m); +int x2ap_allocate_new_id(x2ap_id_manager *m); +void x2ap_release_id(x2ap_id_manager *m, int id); +int x2ap_find_id(x2ap_id_manager *, int id_source, int id_target); +int x2ap_find_id_from_id_source(x2ap_id_manager *, int id_source); +int x2ap_find_id_from_rnti(x2ap_id_manager *, int rnti); +void x2ap_set_ids(x2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target); +void x2ap_id_set_state(x2ap_id_manager *m, int ue_id, x2id_state_t state); +/* real type of target is x2ap_eNB_data_t * */ +void x2ap_id_set_target(x2ap_id_manager *m, int ue_id, void *target); +void x2ap_set_reloc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time); +void x2ap_set_reloc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time); +int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id); +int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id); +int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id); +void *x2ap_id_get_target(x2ap_id_manager *m, int ue_id); + +#endif /* X2AP_IDS_H_ */ diff --git a/openair2/X2AP/x2ap_timers.c b/openair2/X2AP/x2ap_timers.c new file mode 100644 index 0000000000000000000000000000000000000000..a0a7b61ad7023259436f3e408dfd8da4591a22b3 --- /dev/null +++ b/openair2/X2AP/x2ap_timers.c @@ -0,0 +1,105 @@ +/* + * 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 "x2ap_timers.h" +#include "assertions.h" +#include "PHY/defs_common.h" /* TODO: try to not include this */ +#include "x2ap_messages_types.h" +#include "x2ap_eNB_defs.h" +#include "x2ap_ids.h" +#include "x2ap_eNB_management_procedures.h" +#include "x2ap_eNB_generate_messages.h" + +void x2ap_timers_init(x2ap_timers_t *t, int t_reloc_prep, int tx2_reloc_overall) +{ + t->tti = 0; + t->t_reloc_prep = t_reloc_prep; + t->tx2_reloc_overall = tx2_reloc_overall; +} + +void x2ap_check_timers(instance_t instance) +{ + x2ap_eNB_instance_t *instance_p; + x2ap_timers_t *t; + x2ap_id_manager *m; + int i; + x2ap_handover_cancel_cause_t cause; + void *target; + MessageDef *msg; + int x2_ongoing; + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + t = &instance_p->timers; + m = &instance_p->id_manager; + + /* increment subframe count */ + t->tti++; + + x2_ongoing = 0; + + for (i = 0; i < X2AP_MAX_IDS; i++) { + if (m->ids[i].rnti == -1) continue; + x2_ongoing++; + + if (m->ids[i].state == X2ID_STATE_SOURCE_PREPARE && + t->tti > m->ids[i].t_reloc_prep_start + t->t_reloc_prep) { + LOG_I(X2AP, "X2 timeout reloc prep\n"); + /* t_reloc_prep timed out */ + cause = X2AP_T_RELOC_PREP_TIMEOUT; + goto timeout; + } + + if (m->ids[i].state == X2ID_STATE_SOURCE_OVERALL && + t->tti > m->ids[i].tx2_reloc_overall_start + t->tx2_reloc_overall) { + LOG_I(X2AP, "X2 timeout reloc overall\n"); + /* tx2_reloc_overall timed out */ + cause = X2AP_TX2_RELOC_OVERALL_TIMEOUT; + goto timeout; + } + + /* no timeout -> check next UE */ + continue; + +timeout: + /* inform target about timeout */ + target = x2ap_id_get_target(m, i); + x2ap_eNB_generate_x2_handover_cancel(instance_p, target, i, cause); + + /* inform RRC of cancellation */ + msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_CANCEL); + X2AP_HANDOVER_CANCEL(msg).rnti = x2ap_id_get_rnti(m, i); + X2AP_HANDOVER_CANCEL(msg).cause = cause; + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + + /* remove UE from X2AP */ + x2ap_release_id(m, i); + } + + if (x2_ongoing && t->tti % 1000 == 0) + LOG_I(X2AP, "X2 has %d process ongoing\n", x2_ongoing); +} + +uint64_t x2ap_timer_get_tti(x2ap_timers_t *t) +{ + return t->tti; +} diff --git a/openair2/X2AP/x2ap_timers.h b/openair2/X2AP/x2ap_timers.h new file mode 100644 index 0000000000000000000000000000000000000000..d4579422d599cd685e44372da8b47bf15ddec296 --- /dev/null +++ b/openair2/X2AP/x2ap_timers.h @@ -0,0 +1,45 @@ +/* + * 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 X2AP_TIMERS_H_ +#define X2AP_TIMERS_H_ + +#include <stdint.h> +#include "platform_types.h" + +typedef struct { + /* incremented every TTI (every millisecond when in realtime). + * Used to check timers. + * 64 bits gives us more than 500 million years of (realtime) processing. + * It should be enough. + */ + uint64_t tti; + + /* timer values (unit: TTI, ie. millisecond when in realtime) */ + int t_reloc_prep; + int tx2_reloc_overall; +} x2ap_timers_t; + +void x2ap_timers_init(x2ap_timers_t *t, int t_reloc_prep, int tx2_reloc_overall); +void x2ap_check_timers(instance_t instance); +uint64_t x2ap_timer_get_tti(x2ap_timers_t *t); + +#endif /* X2AP_TIMERS_H_ */ diff --git a/openair3/COMMON/messages_types.h b/openair3/COMMON/messages_types.h index 47d9d32f2b689a99aea9c0dc8d6de983a4061af1..56a16da554b7a0b34e583df2f1a7c48d210016c1 100644 --- a/openair3/COMMON/messages_types.h +++ b/openair3/COMMON/messages_types.h @@ -31,6 +31,7 @@ #include "ip_forward_messages_types.h" #include "s11_messages_types.h" #include "s1ap_messages_types.h" +#include "f1ap_messages_types.h" #include "nas_messages_types.h" #include "s6a_messages_types.h" #include "sctp_messages_types.h" diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index c8bfd1255c0ebd600d02bc0803186a0c4be6b5eb..d904e90f228238971ab64917480dda48868f9aab 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -61,8 +61,7 @@ extern RAN_CONTEXT_t RC; static int gtpv1u_dump_socket_g; //----------------------------------------------------------------------------- -int gtpv1u_eNB_create_dump_socket(void) -{ +int gtpv1u_eNB_create_dump_socket(void) { struct ifreq ifr; int hdrincl=1; @@ -92,8 +91,7 @@ int gtpv1u_eNB_create_dump_socket(void) } //----------------------------------------------------------------------------- -static void gtpv1u_eNB_write_dump_socket(uint8_t *buffer_pP, uint32_t buffer_lengthP) -{ +static void gtpv1u_eNB_write_dump_socket(uint8_t *buffer_pP, uint32_t buffer_lengthP) { struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; @@ -108,12 +106,10 @@ static void gtpv1u_eNB_write_dump_socket(uint8_t *buffer_pP, uint32_t buffer_len #endif //----------------------------------------------------------------------------- -static int gtpv1u_eNB_send_init_udp(const Gtpv1uS1Req * req) -{ +static int gtpv1u_eNB_send_init_udp(const Gtpv1uS1Req *req) { // Create and alloc new message MessageDef *message_p; - struct in_addr addr={0}; - + struct in_addr addr= {0}; message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_INIT); if (message_p == NULL) { @@ -124,21 +120,20 @@ static int gtpv1u_eNB_send_init_udp(const Gtpv1uS1Req * req) addr.s_addr = req->enb_ip_address_for_S1u_S12_S4_up; UDP_INIT(message_p).address = inet_ntoa(addr); LOG_I(GTPU, "Tx UDP_INIT IP addr %s (%x)\n", UDP_INIT(message_p).address,UDP_INIT(message_p).port); - MSC_LOG_EVENT( - MSC_GTPU_ENB, - "0 UDP bind %s:%u", - UDP_INIT(message_p).address, - UDP_INIT(message_p).port); + MSC_GTPU_ENB, + "0 UDP bind %s:%u", + UDP_INIT(message_p).address, + UDP_INIT(message_p).port); return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p); } static int gtpv1u_s1_req( const instance_t instanceP, - const Gtpv1uS1Req * const req) { + const Gtpv1uS1Req *const req) { memcpy(&RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, - &req->enb_ip_address_for_S1u_S12_S4_up, - sizeof (req->enb_ip_address_for_S1u_S12_S4_up)); + &req->enb_ip_address_for_S1u_S12_S4_up, + sizeof (req->enb_ip_address_for_S1u_S12_S4_up)); gtpv1u_eNB_send_init_udp(req); return 0; } @@ -148,8 +143,7 @@ NwGtpv1uRcT gtpv1u_eNB_log_request(NwGtpv1uLogMgrHandleT hLogMgr, uint32_t logLevel, NwCharT *file, uint32_t line, - NwCharT *logStr) -{ + NwCharT *logStr) { LOG_D(GTPU, "%s\n", logStr); return NW_GTPV1U_OK; } @@ -161,12 +155,10 @@ NwGtpv1uRcT gtpv1u_eNB_send_udp_msg( uint32_t buffer_len, uint32_t buffer_offset, uint32_t peerIpAddr, - uint16_t peerPort) -{ + uint16_t peerPort) { // Create and alloc new message MessageDef *message_p = NULL; udp_data_req_t *udp_data_req_p = NULL; - message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_DATA_REQ); if (message_p) { @@ -190,8 +182,7 @@ NwGtpv1uRcT gtpv1u_eNB_send_udp_msg( /* Callback called when a gtpv1u message arrived on UDP interface */ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( NwGtpv1uUlpHandleT hUlp, - NwGtpv1uUlpApiT *pUlpApi) -{ + NwGtpv1uUlpApiT *pUlpApi) { boolean_t result = FALSE; teid_t teid = 0; hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; @@ -204,94 +195,88 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( * - T-PDU * - END-MARKER */ - case NW_GTPV1U_ULP_API_RECV_TPDU: { - uint8_t buffer[4096]; - uint32_t buffer_len; - /* Nw-gptv1u stack has processed a PDU. we can schedule it to PDCP - * for transmission. - */ - teid = pUlpApi->apiInfo.recvMsgInfo.teid; - - if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg, - buffer, &buffer_len)) { - LOG_E(GTPU, "Error while retrieving T-PDU"); - } + case NW_GTPV1U_ULP_API_RECV_TPDU: { + uint8_t buffer[4096]; + uint32_t buffer_len; + /* Nw-gptv1u stack has processed a PDU. we can schedule it to PDCP + * for transmission. + */ + teid = pUlpApi->apiInfo.recvMsgInfo.teid; + + if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg, + buffer, &buffer_len)) { + LOG_E(GTPU, "Error while retrieving T-PDU"); + } - itti_free(TASK_UDP, ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf); + itti_free(TASK_UDP, ((NwGtpv1uMsgT *)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf); #if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0 - gtpv1u_eNB_write_dump_socket(buffer,buffer_len); + gtpv1u_eNB_write_dump_socket(buffer,buffer_len); #endif + rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack, + pUlpApi->apiInfo.recvMsgInfo.hMsg); - rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack, - pUlpApi->apiInfo.recvMsgInfo.hMsg); - if (rc != NW_GTPV1U_OK) { - LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc); - } + if (rc != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc); + } - //----------------------- - // GTPV1U->PDCP mapping - //----------------------- - hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, teid, (void**)>pv1u_teid_data_p); + //----------------------- + // GTPV1U->PDCP mapping + //----------------------- + hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, teid, (void **)>pv1u_teid_data_p); - if (hash_rc == HASH_TABLE_OK) { + if (hash_rc == HASH_TABLE_OK) { #if defined(LOG_GTPU) && LOG_GTPU > 0 - LOG_D(GTPU, "Received T-PDU from gtpv1u stack teid %u size %d -> enb module id %u ue module id %u rab id %u\n", - teid, - buffer_len, - gtpv1u_teid_data_p->enb_id, - gtpv1u_teid_data_p->ue_id, - gtpv1u_teid_data_p->eps_bearer_id); + LOG_D(GTPU, "Received T-PDU from gtpv1u stack teid %u size %d -> enb module id %u ue module id %u rab id %u\n", + teid, + buffer_len, + gtpv1u_teid_data_p->enb_id, + gtpv1u_teid_data_p->ue_id, + gtpv1u_teid_data_p->eps_bearer_id); #endif - -//#warning "LG eps bearer mapping to DRB id to do (offset -4)" - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gtpv1u_teid_data_p->enb_id, ENB_FLAG_YES, gtpv1u_teid_data_p->ue_id, 0, 0,gtpv1u_teid_data_p->enb_id); - MSC_LOG_TX_MESSAGE( - MSC_GTPU_ENB, - MSC_PDCP_ENB, - NULL,0, - MSC_AS_TIME_FMT" DATA-REQ rb %u size %u", - 0,0, - (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4, - buffer_len); - - result = pdcp_data_req( - &ctxt, - SRB_FLAG_NO, - (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4, - 0, // mui - SDU_CONFIRM_NO, // confirm - buffer_len, - buffer, - PDCP_TRANSMISSION_MODE_DATA + //#warning "LG eps bearer mapping to DRB id to do (offset -4)" + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gtpv1u_teid_data_p->enb_id, ENB_FLAG_YES, gtpv1u_teid_data_p->ue_id, 0, 0,gtpv1u_teid_data_p->enb_id); + MSC_LOG_TX_MESSAGE( + MSC_GTPU_ENB, + MSC_PDCP_ENB, + NULL,0, + MSC_AS_TIME_FMT" DATA-REQ rb %u size %u", + 0,0, + (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4, + buffer_len); + result = pdcp_data_req( + &ctxt, + SRB_FLAG_NO, + (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4, + 0, // mui + SDU_CONFIRM_NO, // confirm + buffer_len, + buffer, + PDCP_TRANSMISSION_MODE_DATA #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,NULL, NULL + ,NULL, NULL #endif - ); - - - if ( result == FALSE ) { - - if (ctxt.configured == FALSE ) - LOG_W(GTPU, "PDCP data request failed, cause: RB is not configured!\n") ; - else - LOG_W(GTPU, "PDCP data request failed\n"); - - return NW_GTPV1U_FAILURE; + ); + + if ( result == FALSE ) { + if (ctxt.configured == FALSE ) + LOG_W(GTPU, "PDCP data request failed, cause: RB is not configured!\n") ; + else + LOG_W(GTPU, "PDCP data request failed\n"); + + return NW_GTPV1U_FAILURE; + } + } else { + LOG_W(GTPU, "Received T-PDU from gtpv1u stack teid %u unknown size %u", teid, buffer_len); } - - } else { - LOG_W(GTPU, "Received T-PDU from gtpv1u stack teid %u unknown size %u", teid, buffer_len); } - } break; - - default: { - LOG_E(GTPU, "Received undefined UlpApi (%02x) from gtpv1u stack!\n", - pUlpApi->apiType); - } - - } // end of switch - + + default: { + LOG_E(GTPU, "Received undefined UlpApi (%02x) from gtpv1u stack!\n", + pUlpApi->apiType); + } + } // end of switch + return NW_GTPV1U_OK; } @@ -301,8 +286,7 @@ int data_recv_callback(uint16_t portP, uint32_t address, uint8_t *buffer, uint32_t length, - void *arg_p) -{ + void *arg_p) { gtpv1u_data_t *gtpv1u_data_p; if (arg_p == NULL) { @@ -310,7 +294,6 @@ int data_recv_callback(uint16_t portP, } gtpv1u_data_p = (gtpv1u_data_t *)arg_p; - return nwGtpv1uProcessUdpReq(gtpv1u_data_p->gtpv1u_stack, buffer, length, @@ -421,9 +404,7 @@ static NwGtpv1uRcT gtpv1u_start_timer_wrapper( uint32_t timeoutUsec, uint32_t tmrType, void *timeoutArg, - NwGtpv1uTimerHandleT *hTmr) -{ - + NwGtpv1uTimerHandleT *hTmr) { NwGtpv1uRcT rc = NW_GTPV1U_OK; long timer_id; @@ -453,11 +434,8 @@ static NwGtpv1uRcT gtpv1u_start_timer_wrapper( static NwGtpv1uRcT gtpv1u_stop_timer_wrapper( NwGtpv1uTimerMgrHandleT tmrMgrHandle, - NwGtpv1uTimerHandleT hTmr) -{ - + NwGtpv1uTimerHandleT hTmr) { NwGtpv1uRcT rc = NW_GTPV1U_OK; - return rc; } @@ -468,18 +446,14 @@ gtpv1u_initial_req( gtpv1u_data_t *gtpv1u_data_pP, teid_t teidP, tcp_udp_port_t portP, - uint32_t address) -{ + uint32_t address) { NwGtpv1uUlpApiT ulp_req; NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; - memset(&ulp_req, 0, sizeof(NwGtpv1uUlpApiT)); - ulp_req.apiType = NW_GTPV1U_ULP_API_INITIAL_REQ; ulp_req.apiInfo.initialReqInfo.teid = teidP; ulp_req.apiInfo.initialReqInfo.peerPort = portP; ulp_req.apiInfo.initialReqInfo.peerIp = address; - rc = nwGtpv1uProcessUlpReq(gtpv1u_data_pP->gtpv1u_stack, &ulp_req); if (rc == NW_GTPV1U_OK) { @@ -500,9 +474,7 @@ gtpv1u_new_data_req( uint8_t *buffer_pP, uint32_t buf_lenP, uint32_t buf_offsetP -) -{ - +) { NwGtpv1uUlpApiT stack_req; NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; struct gtpv1u_ue_data_s ue; @@ -510,17 +482,14 @@ gtpv1u_new_data_req( struct gtpv1u_bearer_s *bearer_p = NULL; hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;; gtpv1u_data_t *gtpv1u_data_p = NULL; - memset(&ue, 0, sizeof(struct gtpv1u_ue_data_s)); ue.ue_id = ue_rntiP; - AssertFatal(enb_module_idP >=0, "Bad parameter enb module id %u\n", enb_module_idP); AssertFatal((rab_idP - GTPV1U_BEARER_OFFSET)< GTPV1U_MAX_BEARERS_ID, "Bad parameter rab id %u\n", rab_idP); AssertFatal((rab_idP - GTPV1U_BEARER_OFFSET) >= 0 , "Bad parameter rab id %u\n", rab_idP); - gtpv1u_data_p = RC.gtpv1u_data_g; /* Check that UE context is present in ue map. */ - hash_rc = hashtable_get(gtpv1u_data_p->ue_mapping, (uint64_t)ue_rntiP, (void**)&ue_inst_p); + hash_rc = hashtable_get(gtpv1u_data_p->ue_mapping, (uint64_t)ue_rntiP, (void **)&ue_inst_p); if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS ) { LOG_E(GTPU, "[UE %d] Trying to send data on non-existing UE context\n", ue_rntiP); @@ -536,18 +505,16 @@ gtpv1u_new_data_req( if (bearer_p->state != BEARER_UP) { LOG_W(GTPU, "Trying to send data over bearer with state(%u) != BEARER_UP\n", bearer_p->state); -//#warning LG: HACK WHILE WAITING FOR NAS, normally return -1 + //#warning LG: HACK WHILE WAITING FOR NAS, normally return -1 if (bearer_p->state != BEARER_IN_CONFIG) return -1; } memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); - stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU; stack_req.apiInfo.sendtoInfo.teid = bearer_p->teid_sgw; stack_req.apiInfo.sendtoInfo.ipAddr = bearer_p->sgw_ip_addr; - LOG_D(GTPU, "TX TO TEID %u addr 0x%x\n",bearer_p->teid_sgw, bearer_p->sgw_ip_addr); rc = nwGtpv1uGpduMsgNew(gtpv1u_data_p->gtpv1u_stack, bearer_p->teid_sgw, @@ -587,10 +554,9 @@ gtpv1u_new_data_req( int gtpv1u_create_s1u_tunnel( const instance_t instanceP, - const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP, - gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP - ) -{ + const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP, + gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP +) { /* Create a new nw-gtpv1-u stack req using API */ NwGtpv1uUlpApiT stack_req; NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; @@ -606,17 +572,14 @@ gtpv1u_create_s1u_tunnel( int ip_offset = 0; in_addr_t in_addr; int addrs_length_in_bytes= 0; - - MSC_LOG_RX_MESSAGE( - MSC_GTPU_ENB, - MSC_RRC_ENB, - NULL,0, - MSC_AS_TIME_FMT" CREATE_TUNNEL_REQ RNTI %"PRIx16" inst %u ntuns %u ebid %u sgw-s1u teid %u", - 0,0,create_tunnel_req_pP->rnti, instanceP, - create_tunnel_req_pP->num_tunnels, create_tunnel_req_pP->eps_bearer_id[0], - create_tunnel_req_pP->sgw_S1u_teid[0]); - + MSC_GTPU_ENB, + MSC_RRC_ENB, + NULL,0, + MSC_AS_TIME_FMT" CREATE_TUNNEL_REQ RNTI %"PRIx16" inst %u ntuns %u ebid %u sgw-s1u teid %u", + 0,0,create_tunnel_req_pP->rnti, instanceP, + create_tunnel_req_pP->num_tunnels, create_tunnel_req_pP->eps_bearer_id[0], + create_tunnel_req_pP->sgw_S1u_teid[0]); create_tunnel_resp_pP->rnti = create_tunnel_req_pP->rnti; create_tunnel_resp_pP->status = 0; create_tunnel_resp_pP->num_tunnels = 0; @@ -627,7 +590,6 @@ gtpv1u_create_s1u_tunnel( LOG_D(GTPU, "Rx GTPV1U_ENB_CREATE_TUNNEL_REQ ue rnti %x eps bearer id %u\n", create_tunnel_req_pP->rnti, eps_bearer_id); memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); - stack_req.apiType = NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT; do { @@ -636,7 +598,6 @@ gtpv1u_create_s1u_tunnel( stack_req.apiInfo.createTunnelEndPointInfo.teid = s1u_teid; stack_req.apiInfo.createTunnelEndPointInfo.hUlpSession = 0; stack_req.apiInfo.createTunnelEndPointInfo.hStackSession = 0; - rc = nwGtpv1uProcessUlpReq(RC.gtpv1u_data_g->gtpv1u_stack, &stack_req); LOG_D(GTPU, ".\n"); } while (rc != NW_GTPV1U_OK); @@ -647,7 +608,6 @@ gtpv1u_create_s1u_tunnel( hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, (void **)>pv1u_ue_data_p); if ((hash_rc == HASH_TABLE_KEY_NOT_EXISTS) || (hash_rc == HASH_TABLE_OK)) { - if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { gtpv1u_ue_data_p = calloc (1, sizeof(gtpv1u_ue_data_t)); hash_rc = hashtable_insert(RC.gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_p); @@ -660,7 +620,6 @@ gtpv1u_create_s1u_tunnel( &RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, sizeof (in_addr_t)); create_tunnel_resp_pP->enb_addr.length = sizeof (in_addr_t); - addrs_length_in_bytes = create_tunnel_req_pP->sgw_addr[i].length / 8; AssertFatal((addrs_length_in_bytes == 4) || (addrs_length_in_bytes == 16) || @@ -670,7 +629,7 @@ gtpv1u_create_s1u_tunnel( if ((addrs_length_in_bytes == 4) || (addrs_length_in_bytes == 20)) { - in_addr = *((in_addr_t*)create_tunnel_req_pP->sgw_addr[i].buffer); + in_addr = *((in_addr_t *)create_tunnel_req_pP->sgw_addr[i].buffer); ip_offset = 4; gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].sgw_ip_addr = in_addr; } @@ -688,7 +647,6 @@ gtpv1u_create_s1u_tunnel( gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_sgw = create_tunnel_req_pP->sgw_S1u_teid[i]; gtpv1u_ue_data_p->num_bearers++; create_tunnel_resp_pP->enb_S1u_teid[i] = s1u_teid; - } else { create_tunnel_resp_pP->enb_S1u_teid[i] = 0; create_tunnel_resp_pP->status = 0xFF; @@ -696,11 +654,10 @@ gtpv1u_create_s1u_tunnel( create_tunnel_resp_pP->eps_bearer_id[i] = eps_bearer_id; create_tunnel_resp_pP->num_tunnels += 1; - //----------------------- // GTPV1U->PDCP mapping //----------------------- - hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, s1u_teid, (void**)>pv1u_teid_data_p); + hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, s1u_teid, (void **)>pv1u_teid_data_p); if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { gtpv1u_teid_data_p = calloc (1, sizeof(gtpv1u_teid_data_t)); @@ -714,14 +671,14 @@ gtpv1u_create_s1u_tunnel( create_tunnel_resp_pP->status = 0xFF; } } - MSC_LOG_TX_MESSAGE( - MSC_GTPU_ENB, - MSC_RRC_ENB, - NULL,0, - "0 GTPV1U_ENB_CREATE_TUNNEL_RESP rnti %x teid %x", - create_tunnel_resp_pP->rnti, - s1u_teid); + MSC_LOG_TX_MESSAGE( + MSC_GTPU_ENB, + MSC_RRC_ENB, + NULL,0, + "0 GTPV1U_ENB_CREATE_TUNNEL_RESP rnti %x teid %x", + create_tunnel_resp_pP->rnti, + s1u_teid); LOG_D(GTPU, "Tx GTPV1U_ENB_CREATE_TUNNEL_RESP ue rnti %x status %d\n", create_tunnel_req_pP->rnti, create_tunnel_resp_pP->status); @@ -729,12 +686,10 @@ gtpv1u_create_s1u_tunnel( } int gtpv1u_update_s1u_tunnel( - const instance_t instanceP, - const gtpv1u_enb_create_tunnel_req_t * const create_tunnel_req_pP, - const rnti_t prior_rnti - ) -{ - + const instance_t instanceP, + const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP, + const rnti_t prior_rnti +) { /* Local tunnel end-point identifier */ teid_t s1u_teid = 0; gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL; @@ -744,12 +699,12 @@ int gtpv1u_update_s1u_tunnel( hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; int i,j; uint8_t bearers_num = 0,bearers_total = 0; - //----------------------- // PDCP->GTPV1U mapping //----------------------- hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, prior_rnti, (void **)>pv1u_ue_data_p); - if(hash_rc != HASH_TABLE_OK){ + + if(hash_rc != HASH_TABLE_OK) { LOG_E(GTPU,"Error get ue_mapping(rnti=%x) from GTPV1U hashtable error\n", prior_rnti); return -1; } @@ -757,65 +712,66 @@ int gtpv1u_update_s1u_tunnel( gtpv1u_ue_data_new_p = calloc (1, sizeof(gtpv1u_ue_data_t)); memcpy(gtpv1u_ue_data_new_p,gtpv1u_ue_data_p,sizeof(gtpv1u_ue_data_t)); gtpv1u_ue_data_new_p->ue_id = create_tunnel_req_pP->rnti; - hash_rc = hashtable_insert(RC.gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_new_p); AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable"); LOG_I(GTPU, "inserting ue_mapping(rnti=%x) in GTPV1U hashtable\n", - create_tunnel_req_pP->rnti); - + create_tunnel_req_pP->rnti); hash_rc = hashtable_remove(RC.gtpv1u_data_g->ue_mapping, prior_rnti); LOG_I(GTPU, "hashtable_remove ue_mapping(rnti=%x) in GTPV1U hashtable\n", - prior_rnti); + prior_rnti); //----------------------- // GTPV1U->PDCP mapping //----------------------- bearers_total =gtpv1u_ue_data_new_p->num_bearers; - for(j = 0;j<GTPV1U_MAX_BEARERS_ID;j++){ + for(j = 0; j<GTPV1U_MAX_BEARERS_ID; j++) { if(gtpv1u_ue_data_new_p->bearers[j].state != BEARER_IN_CONFIG) continue; bearers_num++; + for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) { if(j == (create_tunnel_req_pP->eps_bearer_id[i]-GTPV1U_BEARER_OFFSET)) break; } - if(i < create_tunnel_req_pP->num_tunnels){ + + if(i < create_tunnel_req_pP->num_tunnels) { s1u_teid = gtpv1u_ue_data_new_p->bearers[j].teid_eNB; - hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, s1u_teid, (void**)>pv1u_teid_data_p); + hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, s1u_teid, (void **)>pv1u_teid_data_p); + if (hash_rc == HASH_TABLE_OK) { gtpv1u_teid_data_p->ue_id = create_tunnel_req_pP->rnti; gtpv1u_teid_data_p->eps_bearer_id = create_tunnel_req_pP->eps_bearer_id[i]; - LOG_I(GTPU, "updata teid_mapping te_id %u (prior_rnti %x rnti %x) in GTPV1U hashtable\n", s1u_teid,prior_rnti,create_tunnel_req_pP->rnti); - }else{ + } else { LOG_W(GTPU, "Error get teid mapping(s1u_teid=%u) from GTPV1U hashtable", s1u_teid); } - }else{ + } else { s1u_teid = gtpv1u_ue_data_new_p->bearers[j].teid_eNB; hash_rc = hashtable_remove(RC.gtpv1u_data_g->teid_mapping, s1u_teid); if (hash_rc != HASH_TABLE_OK) { LOG_D(GTPU, "Removed user rnti %x , enb S1U teid %u not found\n", prior_rnti, s1u_teid); } + gtpv1u_ue_data_new_p->bearers[j].state = BEARER_DOWN; gtpv1u_ue_data_new_p->num_bearers--; LOG_I(GTPU, "delete teid_mapping te_id %u (rnti%x) bearer_id %d in GTPV1U hashtable\n", s1u_teid,prior_rnti,j+GTPV1U_BEARER_OFFSET);; } + if(bearers_num > bearers_total) break; } - return 0; + return 0; } //----------------------------------------------------------------------------- -static int gtpv1u_delete_s1u_tunnel( +int gtpv1u_delete_s1u_tunnel( const instance_t instanceP, - const gtpv1u_enb_delete_tunnel_req_t * const req_pP) -{ + const gtpv1u_enb_delete_tunnel_req_t *const req_pP) { NwGtpv1uUlpApiT stack_req; NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; MessageDef *message_p = NULL; @@ -823,22 +779,16 @@ static int gtpv1u_delete_s1u_tunnel( hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; teid_t teid_eNB = 0; int erab_index = 0; - message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_DELETE_TUNNEL_RESP); - GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).rnti = req_pP->rnti; GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).status = 0; - - - hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, req_pP->rnti, (void**)>pv1u_ue_data_p); + hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, req_pP->rnti, (void **)>pv1u_ue_data_p); if (hash_rc == HASH_TABLE_OK) { - for (erab_index = 0; erab_index < req_pP->num_erab; erab_index++) { teid_eNB = gtpv1u_ue_data_p->bearers[req_pP->eps_bearer_id[erab_index] - GTPV1U_BEARER_OFFSET].teid_eNB; LOG_D(GTPU, "Rx GTPV1U_ENB_DELETE_TUNNEL user rnti %x eNB S1U teid %u eps bearer id %u\n", req_pP->rnti, teid_eNB, req_pP->eps_bearer_id[erab_index]); - { memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); stack_req.apiType = NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT; @@ -846,7 +796,6 @@ static int gtpv1u_delete_s1u_tunnel( req_pP->eps_bearer_id[erab_index], teid_eNB); stack_req.apiInfo.destroyTunnelEndPointInfo.hStackSessionHandle = gtpv1u_ue_data_p->bearers[req_pP->eps_bearer_id[erab_index] - GTPV1U_BEARER_OFFSET].teid_eNB_stack_session; - rc = nwGtpv1uProcessUlpReq(RC.gtpv1u_data_g->gtpv1u_stack, &stack_req); LOG_D(GTPU, ".\n"); } @@ -881,36 +830,30 @@ static int gtpv1u_delete_s1u_tunnel( } }// else silently do nothing - LOG_D(GTPU, "Tx GTPV1U_ENB_DELETE_TUNNEL_RESP user rnti %x eNB S1U teid %u status %u\n", GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).rnti, GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).enb_S1u_teid, GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).status); - MSC_LOG_TX_MESSAGE( - MSC_GTPU_ENB, - MSC_RRC_ENB, - NULL,0, - "0 GTPV1U_ENB_DELETE_TUNNEL_RESP rnti %x teid %x", - GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).rnti, - teid_eNB); - + MSC_GTPU_ENB, + MSC_RRC_ENB, + NULL,0, + "0 GTPV1U_ENB_DELETE_TUNNEL_RESP rnti %x teid %x", + GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).rnti, + teid_eNB); return itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p); } //----------------------------------------------------------------------------- -int gtpv1u_eNB_init(void) -{ +int gtpv1u_eNB_init(void) { NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; NwGtpv1uUlpEntityT ulp; NwGtpv1uUdpEntityT udp; NwGtpv1uLogMgrEntityT log; NwGtpv1uTimerMgrEntityT tmr; - // enb_properties_p = enb_config_get()->properties[0]; - RC.gtpv1u_data_g = (gtpv1u_data_t*)calloc(sizeof(gtpv1u_data_t),1); - + RC.gtpv1u_data_g = (gtpv1u_data_t *)calloc(sizeof(gtpv1u_data_t),1); LOG_I(GTPU, "Initializing GTPU stack %p\n",&RC.gtpv1u_data_g); //gtpv1u_data_g.gtpv1u_stack; /* Initialize UE hashtable */ @@ -918,8 +861,7 @@ int gtpv1u_eNB_init(void) AssertFatal(RC.gtpv1u_data_g->ue_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create returned %p\n", RC.gtpv1u_data_g->ue_mapping); RC.gtpv1u_data_g->teid_mapping = hashtable_create (256, NULL, NULL); AssertFatal(RC.gtpv1u_data_g->teid_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create\n"); -// RC.gtpv1u_data_g.enb_ip_address_for_S1u_S12_S4_up = enb_properties_p->enb_ipv4_address_for_S1U; - + // RC.gtpv1u_data_g.enb_ip_address_for_S1u_S12_S4_up = enb_properties_p->enb_ipv4_address_for_S1U; //gtpv1u_data_g.udp_data; RC.gtpv1u_data_g->seq_num = 0; RC.gtpv1u_data_g->restart_counter = 0; @@ -936,7 +878,6 @@ int gtpv1u_eNB_init(void) return -1; } - /* Set the ULP API callback. Called once message have been processed by the * nw-gtpv1u stack. */ @@ -983,30 +924,26 @@ int gtpv1u_eNB_init(void) } #endif - LOG_D(GTPU, "Initializing GTPV1U interface for eNB: DONE\n"); return 0; } //----------------------------------------------------------------------------- void *gtpv1u_eNB_process_itti_msg(void *notUsed) { - /* Trying to fetch a message from the message queue. - * If the queue is empty, this function will block till a - * message is sent to the task. - */ - instance_t instance; - MessageDef *received_message_p = NULL; - int rc = 0; - - itti_receive_msg(TASK_GTPV1_U, &received_message_p); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_IN); - DevAssert(received_message_p != NULL); - - instance = ITTI_MSG_INSTANCE(received_message_p); - //msg_name_p = ITTI_MSG_NAME(received_message_p); - - switch (ITTI_MSG_ID(received_message_p)) { - + /* Trying to fetch a message from the message queue. + * If the queue is empty, this function will block till a + * message is sent to the task. + */ + instance_t instance; + MessageDef *received_message_p = NULL; + int rc = 0; + itti_receive_msg(TASK_GTPV1_U, &received_message_p); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_IN); + DevAssert(received_message_p != NULL); + instance = ITTI_MSG_INSTANCE(received_message_p); + //msg_name_p = ITTI_MSG_NAME(received_message_p); + + switch (ITTI_MSG_ID(received_message_p)) { case GTPV1U_ENB_S1_REQ: gtpv1u_s1_req(instance, &received_message_p->ittiMsg.gtpv1uS1Req); @@ -1037,17 +974,14 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL; teid_t enb_s1u_teid = 0; teid_t sgw_s1u_teid = 0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_IN); data_req_p = >PV1U_ENB_TUNNEL_DATA_REQ(received_message_p); //ipv4_send_data(ipv4_data_p->sd, data_ind_p->buffer, data_ind_p->length); - #if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0 gtpv1u_eNB_write_dump_socket(&data_req_p->buffer[data_req_p->offset],data_req_p->length); #endif memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); - - hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, (uint64_t)data_req_p->rnti, (void**)>pv1u_ue_data_p); + hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, (uint64_t)data_req_p->rnti, (void **)>pv1u_ue_data_p); if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: while getting ue rnti %x in hashtable ue_mapping\n", data_req_p->rnti); @@ -1058,7 +992,6 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU; stack_req.apiInfo.sendtoInfo.teid = sgw_s1u_teid; stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].sgw_ip_addr; - rc = nwGtpv1uGpduMsgNew( RC.gtpv1u_data_g->gtpv1u_stack, sgw_s1u_teid, @@ -1072,7 +1005,7 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { if (rc != NW_GTPV1U_OK) { LOG_E(GTPU, "nwGtpv1uGpduMsgNew failed: 0x%x\n", rc); MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u", - enb_s1u_teid,sgw_s1u_teid,data_req_p->length); + enb_s1u_teid,sgw_s1u_teid,data_req_p->length); (void)enb_s1u_teid; /* avoid gcc warning "set but not used" */ } else { rc = nwGtpv1uProcessUlpReq(RC.gtpv1u_data_g->gtpv1u_stack, &stack_req); @@ -1080,19 +1013,18 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { if (rc != NW_GTPV1U_OK) { LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: 0x%x\n", rc); MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u", - enb_s1u_teid,sgw_s1u_teid,data_req_p->length); + enb_s1u_teid,sgw_s1u_teid,data_req_p->length); } else { - MSC_LOG_TX_MESSAGE( - MSC_GTPU_ENB, - MSC_GTPU_SGW, - NULL, - 0, - MSC_AS_TIME_FMT" G-PDU ltid %u rtid %u size %u", - 0,0, - enb_s1u_teid, - sgw_s1u_teid, - data_req_p->length); - + MSC_LOG_TX_MESSAGE( + MSC_GTPU_ENB, + MSC_GTPU_SGW, + NULL, + 0, + MSC_AS_TIME_FMT" G-PDU ltid %u rtid %u size %u", + 0,0, + enb_s1u_teid, + sgw_s1u_teid, + data_req_p->length); } rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack, @@ -1113,11 +1045,11 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { case TERMINATE_MESSAGE: { if (RC.gtpv1u_data_g->ue_mapping != NULL) { - hashtable_destroy (RC.gtpv1u_data_g->ue_mapping); + hashtable_destroy (&(RC.gtpv1u_data_g->ue_mapping)); } if (RC.gtpv1u_data_g->teid_mapping != NULL) { - hashtable_destroy (RC.gtpv1u_data_g->teid_mapping); + hashtable_destroy (&(RC.gtpv1u_data_g->teid_mapping)); } LOG_W(GTPU, " *** Exiting GTPU thread\n"); @@ -1135,21 +1067,18 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { ITTI_MSG_NAME(received_message_p)); } break; - } - - rc = itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p); - AssertFatal(rc == EXIT_SUCCESS, "Failed to free memory (%d)!\n", rc); - received_message_p = NULL; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_OUT); + } - return NULL; + rc = itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p); + AssertFatal(rc == EXIT_SUCCESS, "Failed to free memory (%d)!\n", rc); + received_message_p = NULL; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_OUT); + return NULL; } //----------------------------------------------------------------------------- -void *gtpv1u_eNB_task(void *args) -{ +void *gtpv1u_eNB_task(void *args) { int rc = 0; - rc = gtpv1u_eNB_init(); AssertFatal(rc == 0, "gtpv1u_eNB_init Failed"); itti_mark_task_ready(TASK_GTPV1_U); diff --git a/openair3/GTPV1-U/gtpv1u_task.c b/openair3/GTPV1-U/gtpv1u_task.c index e821885ab5198055484b183f12eef1411b243b9a..1339839cf971edd203f2e9100a769a7b4df9ac26 100644 --- a/openair3/GTPV1-U/gtpv1u_task.c +++ b/openair3/GTPV1-U/gtpv1u_task.c @@ -95,7 +95,7 @@ void gtpu_print_hex_octets(unsigned char* dataP, unsigned long sizeP) h = tv.tv_sec/3600/24; m = (tv.tv_sec / 60) % 60; s = tv.tv_sec % 60; - snprintf(timeofday, 64, "%02d:%02d:%02d.%06d", h,m,s,tv.tv_usec); + snprintf(timeofday, 64, "%02u:%02u:%02u.%06d", h,m,s,tv.tv_usec); GTPU_DEBUG("%s------+-------------------------------------------------|\n",timeofday); GTPU_DEBUG("%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday); @@ -116,7 +116,7 @@ void gtpu_print_hex_octets(unsigned char* dataP, unsigned long sizeP) buffer_marker = 0; } - buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " %04ld |", octet_index); + buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " %04lu |", octet_index); } /* diff --git a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c index eb27189a6133b6785b43c5539e11d09573d57ed8..3e8da5d015faa56051c35f48185908137d81afeb 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c +++ b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c @@ -689,9 +689,9 @@ nwGtpv1uInitialize( NW_INOUT NwGtpv1uStackHandleT *hGtpuStackHandle, uint32_t st NwGtpv1uStackT *thiz; thiz = (NwGtpv1uStackT *) malloc( sizeof(NwGtpv1uStackT)); - memset(thiz, 0, sizeof(NwGtpv1uStackT)); if(thiz) { + memset(thiz, 0, sizeof(NwGtpv1uStackT)); thiz->id = (NwPtrT)thiz; thiz->stackType = stackType; thiz->seq = (uint16_t) ((uintptr_t)thiz) ; // FIXME interesting casts... don't know what this is good for... @@ -892,6 +892,11 @@ nwGtpv1uProcessUdpReq( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, ret = nwGtpv1uProcessGpdu(thiz, udpData, udpDataLen, peerIp); break; + case NW_GTP_END_MARKER: + GTPU_DEBUG("NW_GTP_END_MARKER\n"); + ret = NW_GTPV1U_OK; + break; + default: ret = NW_GTPV1U_FAILURE; NW_ASSERT(0); diff --git a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c index 535ab8f1faf62f9b3e13f43391fab1a464f78ae5..365d6d23a5ff124b2ade204f940534c82aa7eb34 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c +++ b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1uMsg.c @@ -144,7 +144,7 @@ nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle, AssertFatal((msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE) <= tpduOffset, "Mismatch GTPU len, msgExtraLen %u tpduOffset %u", msgExtraLen, - tpduOffset); + (uint32_t) tpduOffset); pMsg->msgBuf = tpdu; pMsg->msgBufLen = tpduLength + msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE; pMsg->msgBufOffset = tpduOffset - (msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE); diff --git a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h index ffa9c0c85e7814932729a92baf2727472d804896..8f2908e52aa182f11d8067d4c005addf4f01f778 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h +++ b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h @@ -32,7 +32,7 @@ extern uint32_t g_log_level; { \ char _logStr[1024]; \ snprintf(_logStr, 1024, __VA_ARGS__); \ - printf("NWGTPv2U-APP %s - %s <%s,%u>\n", gLogLevelStr[_logLevel], _logStr, basename(__FILE__), __LINE__);\ + printf("NWGTPv2U-APP %s - %s <%s,%d>\n", gLogLevelStr[_logLevel], _logStr, basename(__FILE__), __LINE__);\ } \ } while(0) diff --git a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.c b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.c index f6102d52508057c7e9f24de0c3bc63bb2beba1d8..63ad59b23f82b5cd731305a8c1258b48efe5cd37 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.c +++ b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.c @@ -64,8 +64,8 @@ NwGtpv1uRcT nwTimerStart( NwGtpv1uTimerMgrHandleT tmrMgrHandle, struct timeval tv; NW_LOG(NW_LOG_LEVEL_INFO, - "Received start timer request from stack with timer type %u, arg %x, for %u sec and %u usec", - tmrType, timeoutArg, timeoutSec, timeoutUsec); + "Received start timer request from stack with timer type %d , arg %x, for %d sec and %d usec", + tmrType, (unsigned int)timeoutArg, timeoutSec, timeoutUsec); pTmr = (NwMiniTmrMgrEntityT *) malloc (sizeof(NwMiniTmrMgrEntityT)); @@ -90,7 +90,7 @@ NwGtpv1uRcT nwTimerStop( NwGtpv1uTimerMgrHandleT tmrMgrHandle, NwGtpv1uTimerHandleT hTmr) { NW_LOG(NW_LOG_LEVEL_INFO, - "Received stop timer request from stack for timer handle %u", hTmr); + "Received stop timer request from stack for timer handle %d", hTmr); evtimer_del(&(((NwMiniTmrMgrEntityT *)hTmr)->ev)); free((void *)hTmr); return NW_GTPV1U_OK; diff --git a/openair3/NAS/COMMON/EMM/MSG/emm_msg.c b/openair3/NAS/COMMON/EMM/MSG/emm_msg.c index b9c9b93a9caf3625076d3351b7d0e35ba2261980..cd55a3fffb9e1de70685bd89c33d2c5f26e438b5 100644 --- a/openair3/NAS/COMMON/EMM/MSG/emm_msg.c +++ b/openair3/NAS/COMMON/EMM/MSG/emm_msg.c @@ -44,9 +44,8 @@ Description Defines EPS Mobility Management messages #include "TLVDecoder.h" #include "TLVEncoder.h" -#if ((defined(NAS_BUILT_IN_EPC) && defined(NAS_MME)) || (defined(ENABLE_NAS_UE_LOGGING) && defined(NAS_BUILT_IN_UE) && defined(NAS_UE))) -# include "nas_itti_messaging.h" -#endif + +#include "nas_itti_messaging.h" /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -83,25 +82,18 @@ static int _emm_msg_encode_header(const emm_msg_header_t *header, ** Others: None ** ** ** ***************************************************************************/ -int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len) -{ +int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len) { LOG_FUNC_IN; - int header_result; int decode_result; - -#if ((defined(NAS_BUILT_IN_EPC) && defined(NAS_MME)) || (defined(ENABLE_NAS_UE_LOGGING) && defined(NAS_BUILT_IN_UE) && defined(NAS_UE))) uint8_t *buffer_log = buffer; uint32_t len_log = len; int down_link; - # if ((defined(NAS_BUILT_IN_EPC) && defined(NAS_MME))) down_link = 0; # else down_link = 1; # endif -#endif - /* First decode the EMM message header */ header_result = _emm_msg_decode_header(&msg->header, buffer, len); @@ -113,144 +105,143 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len) buffer += header_result; len -= header_result; - LOG_TRACE(INFO, "EMM-MSG - Message Type 0x%02x", msg->header.message_type); switch(msg->header.message_type) { - case EMM_INFORMATION: - decode_result = decode_emm_information(&msg->emm_information, buffer, len); - break; - - case UPLINK_NAS_TRANSPORT: - decode_result = decode_uplink_nas_transport(&msg->uplink_nas_transport, buffer, - len); - break; - - case AUTHENTICATION_REJECT: - decode_result = decode_authentication_reject(&msg->authentication_reject, - buffer, len); - break; - - case AUTHENTICATION_FAILURE: - decode_result = decode_authentication_failure(&msg->authentication_failure, - buffer, len); - break; - - case DETACH_ACCEPT: - decode_result = decode_detach_accept(&msg->detach_accept, buffer, len); - break; - - case SERVICE_REJECT: - decode_result = decode_service_reject(&msg->service_reject, buffer, len); - break; - - case AUTHENTICATION_REQUEST: - decode_result = decode_authentication_request(&msg->authentication_request, - buffer, len); - break; - - case TRACKING_AREA_UPDATE_REQUEST: - decode_result = decode_tracking_area_update_request( - &msg->tracking_area_update_request, buffer, len); - break; - - case ATTACH_REQUEST: - decode_result = decode_attach_request(&msg->attach_request, buffer, len); - break; - - case EMM_STATUS: - decode_result = decode_emm_status(&msg->emm_status, buffer, len); - break; - - case IDENTITY_RESPONSE: - decode_result = decode_identity_response(&msg->identity_response, buffer, len); - break; - - case IDENTITY_REQUEST: - decode_result = decode_identity_request(&msg->identity_request, buffer, len); - break; - - case GUTI_REALLOCATION_COMMAND: - decode_result = decode_guti_reallocation_command(&msg->guti_reallocation_command, - buffer, len); - break; - - case TRACKING_AREA_UPDATE_REJECT: - decode_result = decode_tracking_area_update_reject( - &msg->tracking_area_update_reject, buffer, len); - break; - - case ATTACH_ACCEPT: - decode_result = decode_attach_accept(&msg->attach_accept, buffer, len); - break; - - case SECURITY_MODE_COMPLETE: - decode_result = decode_security_mode_complete(&msg->security_mode_complete, - buffer, len); - break; - - case TRACKING_AREA_UPDATE_ACCEPT: - decode_result = decode_tracking_area_update_accept( - &msg->tracking_area_update_accept, buffer, len); - break; - - case ATTACH_REJECT: - decode_result = decode_attach_reject(&msg->attach_reject, buffer, len); - break; - - case ATTACH_COMPLETE: - decode_result = decode_attach_complete(&msg->attach_complete, buffer, len); - break; - - case TRACKING_AREA_UPDATE_COMPLETE: - decode_result = decode_tracking_area_update_complete( - &msg->tracking_area_update_complete, buffer, len); - break; - - case CS_SERVICE_NOTIFICATION: - decode_result = decode_cs_service_notification(&msg->cs_service_notification, - buffer, len); - break; - - case SECURITY_MODE_REJECT: - decode_result = decode_security_mode_reject(&msg->security_mode_reject, buffer, - len); - break; - - case DETACH_REQUEST: - decode_result = decode_detach_request(&msg->detach_request, buffer, len); - break; - - case GUTI_REALLOCATION_COMPLETE: - decode_result = decode_guti_reallocation_complete( - &msg->guti_reallocation_complete, buffer, len); - break; - - case SECURITY_MODE_COMMAND: - decode_result = decode_security_mode_command(&msg->security_mode_command, - buffer, len); - break; - - case DOWNLINK_NAS_TRANSPORT: - decode_result = decode_downlink_nas_transport(&msg->downlink_nas_transport, - buffer, len); - break; - - case EXTENDED_SERVICE_REQUEST: - decode_result = decode_extended_service_request(&msg->extended_service_request, - buffer, len); - break; - - case AUTHENTICATION_RESPONSE: - decode_result = decode_authentication_response(&msg->authentication_response, - buffer, len); - break; - - default: - LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", - msg->header.message_type); - decode_result = TLV_DECODE_WRONG_MESSAGE_TYPE; - /* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */ + case EMM_INFORMATION: + decode_result = decode_emm_information(&msg->emm_information, buffer, len); + break; + + case UPLINK_NAS_TRANSPORT: + decode_result = decode_uplink_nas_transport(&msg->uplink_nas_transport, buffer, + len); + break; + + case AUTHENTICATION_REJECT: + decode_result = decode_authentication_reject(&msg->authentication_reject, + buffer, len); + break; + + case AUTHENTICATION_FAILURE: + decode_result = decode_authentication_failure(&msg->authentication_failure, + buffer, len); + break; + + case DETACH_ACCEPT: + decode_result = decode_detach_accept(&msg->detach_accept, buffer, len); + break; + + case SERVICE_REJECT: + decode_result = decode_service_reject(&msg->service_reject, buffer, len); + break; + + case AUTHENTICATION_REQUEST: + decode_result = decode_authentication_request(&msg->authentication_request, + buffer, len); + break; + + case TRACKING_AREA_UPDATE_REQUEST: + decode_result = decode_tracking_area_update_request( + &msg->tracking_area_update_request, buffer, len); + break; + + case ATTACH_REQUEST: + decode_result = decode_attach_request(&msg->attach_request, buffer, len); + break; + + case EMM_STATUS: + decode_result = decode_emm_status(&msg->emm_status, buffer, len); + break; + + case IDENTITY_RESPONSE: + decode_result = decode_identity_response(&msg->identity_response, buffer, len); + break; + + case IDENTITY_REQUEST: + decode_result = decode_identity_request(&msg->identity_request, buffer, len); + break; + + case GUTI_REALLOCATION_COMMAND: + decode_result = decode_guti_reallocation_command(&msg->guti_reallocation_command, + buffer, len); + break; + + case TRACKING_AREA_UPDATE_REJECT: + decode_result = decode_tracking_area_update_reject( + &msg->tracking_area_update_reject, buffer, len); + break; + + case ATTACH_ACCEPT: + decode_result = decode_attach_accept(&msg->attach_accept, buffer, len); + break; + + case SECURITY_MODE_COMPLETE: + decode_result = decode_security_mode_complete(&msg->security_mode_complete, + buffer, len); + break; + + case TRACKING_AREA_UPDATE_ACCEPT: + decode_result = decode_tracking_area_update_accept( + &msg->tracking_area_update_accept, buffer, len); + break; + + case ATTACH_REJECT: + decode_result = decode_attach_reject(&msg->attach_reject, buffer, len); + break; + + case ATTACH_COMPLETE: + decode_result = decode_attach_complete(&msg->attach_complete, buffer, len); + break; + + case TRACKING_AREA_UPDATE_COMPLETE: + decode_result = decode_tracking_area_update_complete( + &msg->tracking_area_update_complete, buffer, len); + break; + + case CS_SERVICE_NOTIFICATION: + decode_result = decode_cs_service_notification(&msg->cs_service_notification, + buffer, len); + break; + + case SECURITY_MODE_REJECT: + decode_result = decode_security_mode_reject(&msg->security_mode_reject, buffer, + len); + break; + + case DETACH_REQUEST: + decode_result = decode_detach_request(&msg->detach_request, buffer, len); + break; + + case GUTI_REALLOCATION_COMPLETE: + decode_result = decode_guti_reallocation_complete( + &msg->guti_reallocation_complete, buffer, len); + break; + + case SECURITY_MODE_COMMAND: + decode_result = decode_security_mode_command(&msg->security_mode_command, + buffer, len); + break; + + case DOWNLINK_NAS_TRANSPORT: + decode_result = decode_downlink_nas_transport(&msg->downlink_nas_transport, + buffer, len); + break; + + case EXTENDED_SERVICE_REQUEST: + decode_result = decode_extended_service_request(&msg->extended_service_request, + buffer, len); + break; + + case AUTHENTICATION_RESPONSE: + decode_result = decode_authentication_response(&msg->authentication_response, + buffer, len); + break; + + default: + LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", + msg->header.message_type); + decode_result = TLV_DECODE_WRONG_MESSAGE_TYPE; + /* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */ } if (decode_result < 0) { @@ -284,24 +275,17 @@ int emm_msg_decode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ** Others: None ** ** ** ***************************************************************************/ -int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) -{ +int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) { LOG_FUNC_IN; - int header_result; int encode_result; - -#if ((defined(NAS_BUILT_IN_EPC) && defined(NAS_MME)) || (defined(ENABLE_NAS_UE_LOGGING) && defined(NAS_BUILT_IN_UE) && defined(NAS_UE))) uint8_t *buffer_log = buffer; int down_link; - # if ((defined(NAS_BUILT_IN_EPC) && defined(NAS_MME))) down_link = 1; # else down_link = 0; # endif -#endif - /* First encode the EMM message header */ header_result = _emm_msg_encode_header(&msg->header, buffer, len); @@ -315,144 +299,144 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) len -= header_result; switch(msg->header.message_type) { - case EMM_INFORMATION: - encode_result = encode_emm_information(&msg->emm_information, buffer, len); - break; - - case UPLINK_NAS_TRANSPORT: - encode_result = encode_uplink_nas_transport(&msg->uplink_nas_transport, buffer, - len); - break; - - case AUTHENTICATION_REJECT: - encode_result = encode_authentication_reject(&msg->authentication_reject, - buffer, len); - break; - - case AUTHENTICATION_FAILURE: - encode_result = encode_authentication_failure(&msg->authentication_failure, - buffer, len); - break; - - case DETACH_ACCEPT: - encode_result = encode_detach_accept(&msg->detach_accept, buffer, len); - break; - - case SERVICE_REJECT: - encode_result = encode_service_reject(&msg->service_reject, buffer, len); - break; - - case AUTHENTICATION_REQUEST: - encode_result = encode_authentication_request(&msg->authentication_request, - buffer, len); - break; - - case TRACKING_AREA_UPDATE_REQUEST: - encode_result = encode_tracking_area_update_request( - &msg->tracking_area_update_request, buffer, len); - break; - - case ATTACH_REQUEST: - encode_result = encode_attach_request(&msg->attach_request, buffer, len); - break; - - case EMM_STATUS: - encode_result = encode_emm_status(&msg->emm_status, buffer, len); - break; - - case IDENTITY_RESPONSE: - encode_result = encode_identity_response(&msg->identity_response, buffer, len); - break; - - case IDENTITY_REQUEST: - encode_result = encode_identity_request(&msg->identity_request, buffer, len); - break; - - case GUTI_REALLOCATION_COMMAND: - encode_result = encode_guti_reallocation_command(&msg->guti_reallocation_command, - buffer, len); - break; - - case TRACKING_AREA_UPDATE_REJECT: - encode_result = encode_tracking_area_update_reject( - &msg->tracking_area_update_reject, buffer, len); - break; - - case ATTACH_ACCEPT: - encode_result = encode_attach_accept(&msg->attach_accept, buffer, len); - break; - - case SECURITY_MODE_COMPLETE: - encode_result = encode_security_mode_complete(&msg->security_mode_complete, - buffer, len); - break; - - case TRACKING_AREA_UPDATE_ACCEPT: - encode_result = encode_tracking_area_update_accept( - &msg->tracking_area_update_accept, buffer, len); - break; - - case ATTACH_REJECT: - encode_result = encode_attach_reject(&msg->attach_reject, buffer, len); - break; - - case ATTACH_COMPLETE: - encode_result = encode_attach_complete(&msg->attach_complete, buffer, len); - break; - - case TRACKING_AREA_UPDATE_COMPLETE: - encode_result = encode_tracking_area_update_complete( - &msg->tracking_area_update_complete, buffer, len); - break; - - case CS_SERVICE_NOTIFICATION: - encode_result = encode_cs_service_notification(&msg->cs_service_notification, - buffer, len); - break; - - case SECURITY_MODE_REJECT: - encode_result = encode_security_mode_reject(&msg->security_mode_reject, buffer, - len); - break; - - case DETACH_REQUEST: - encode_result = encode_detach_request(&msg->detach_request, buffer, len); - break; - - case GUTI_REALLOCATION_COMPLETE: - encode_result = encode_guti_reallocation_complete( - &msg->guti_reallocation_complete, buffer, len); - break; - - case SECURITY_MODE_COMMAND: - encode_result = encode_security_mode_command(&msg->security_mode_command, - buffer, len); - break; - - case DOWNLINK_NAS_TRANSPORT: - encode_result = encode_downlink_nas_transport(&msg->downlink_nas_transport, - buffer, len); - break; - - case EXTENDED_SERVICE_REQUEST: - encode_result = encode_extended_service_request(&msg->extended_service_request, - buffer, len); - break; - - case AUTHENTICATION_RESPONSE: - encode_result = encode_authentication_response(&msg->authentication_response, - buffer, len); - break; - - case SERVICE_REQUEST: - encode_result = encode_service_request(&msg->service_request, buffer, len); - break; - - default: - LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", - msg->header.message_type); - encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE; - /* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */ + case EMM_INFORMATION: + encode_result = encode_emm_information(&msg->emm_information, buffer, len); + break; + + case UPLINK_NAS_TRANSPORT: + encode_result = encode_uplink_nas_transport(&msg->uplink_nas_transport, buffer, + len); + break; + + case AUTHENTICATION_REJECT: + encode_result = encode_authentication_reject(&msg->authentication_reject, + buffer, len); + break; + + case AUTHENTICATION_FAILURE: + encode_result = encode_authentication_failure(&msg->authentication_failure, + buffer, len); + break; + + case DETACH_ACCEPT: + encode_result = encode_detach_accept(&msg->detach_accept, buffer, len); + break; + + case SERVICE_REJECT: + encode_result = encode_service_reject(&msg->service_reject, buffer, len); + break; + + case AUTHENTICATION_REQUEST: + encode_result = encode_authentication_request(&msg->authentication_request, + buffer, len); + break; + + case TRACKING_AREA_UPDATE_REQUEST: + encode_result = encode_tracking_area_update_request( + &msg->tracking_area_update_request, buffer, len); + break; + + case ATTACH_REQUEST: + encode_result = encode_attach_request(&msg->attach_request, buffer, len); + break; + + case EMM_STATUS: + encode_result = encode_emm_status(&msg->emm_status, buffer, len); + break; + + case IDENTITY_RESPONSE: + encode_result = encode_identity_response(&msg->identity_response, buffer, len); + break; + + case IDENTITY_REQUEST: + encode_result = encode_identity_request(&msg->identity_request, buffer, len); + break; + + case GUTI_REALLOCATION_COMMAND: + encode_result = encode_guti_reallocation_command(&msg->guti_reallocation_command, + buffer, len); + break; + + case TRACKING_AREA_UPDATE_REJECT: + encode_result = encode_tracking_area_update_reject( + &msg->tracking_area_update_reject, buffer, len); + break; + + case ATTACH_ACCEPT: + encode_result = encode_attach_accept(&msg->attach_accept, buffer, len); + break; + + case SECURITY_MODE_COMPLETE: + encode_result = encode_security_mode_complete(&msg->security_mode_complete, + buffer, len); + break; + + case TRACKING_AREA_UPDATE_ACCEPT: + encode_result = encode_tracking_area_update_accept( + &msg->tracking_area_update_accept, buffer, len); + break; + + case ATTACH_REJECT: + encode_result = encode_attach_reject(&msg->attach_reject, buffer, len); + break; + + case ATTACH_COMPLETE: + encode_result = encode_attach_complete(&msg->attach_complete, buffer, len); + break; + + case TRACKING_AREA_UPDATE_COMPLETE: + encode_result = encode_tracking_area_update_complete( + &msg->tracking_area_update_complete, buffer, len); + break; + + case CS_SERVICE_NOTIFICATION: + encode_result = encode_cs_service_notification(&msg->cs_service_notification, + buffer, len); + break; + + case SECURITY_MODE_REJECT: + encode_result = encode_security_mode_reject(&msg->security_mode_reject, buffer, + len); + break; + + case DETACH_REQUEST: + encode_result = encode_detach_request(&msg->detach_request, buffer, len); + break; + + case GUTI_REALLOCATION_COMPLETE: + encode_result = encode_guti_reallocation_complete( + &msg->guti_reallocation_complete, buffer, len); + break; + + case SECURITY_MODE_COMMAND: + encode_result = encode_security_mode_command(&msg->security_mode_command, + buffer, len); + break; + + case DOWNLINK_NAS_TRANSPORT: + encode_result = encode_downlink_nas_transport(&msg->downlink_nas_transport, + buffer, len); + break; + + case EXTENDED_SERVICE_REQUEST: + encode_result = encode_extended_service_request(&msg->extended_service_request, + buffer, len); + break; + + case AUTHENTICATION_RESPONSE: + encode_result = encode_authentication_response(&msg->authentication_response, + buffer, len); + break; + + case SERVICE_REQUEST: + encode_result = encode_service_request(&msg->service_request, buffer, len); + break; + + default: + LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", + msg->header.message_type); + encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE; + /* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */ } if (encode_result < 0) { @@ -495,8 +479,7 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len) ** ** ***************************************************************************/ static int _emm_msg_decode_header(emm_msg_header_t *header, - const uint8_t *buffer, uint32_t len) -{ + const uint8_t *buffer, uint32_t len) { int size = 0; /* Check the buffer length */ @@ -538,8 +521,7 @@ static int _emm_msg_decode_header(emm_msg_header_t *header, ** ** ***************************************************************************/ static int _emm_msg_encode_header(const emm_msg_header_t *header, - uint8_t *buffer, uint32_t len) -{ + uint8_t *buffer, uint32_t len) { int size = 0; /* Check the buffer length */ @@ -558,7 +540,6 @@ static int _emm_msg_encode_header(const emm_msg_header_t *header, ENCODE_U8(buffer + size, *(uint8_t *)(header), size); /* Encode the message type */ ENCODE_U8(buffer + size, header->message_type, size); - return (size); } diff --git a/openair3/NAS/COMMON/UTIL/tst/timer.c b/openair3/NAS/COMMON/UTIL/tst/timer.c index 701c878f4de3f5cd728109d20c9d928de44e31c7..2215bcee2d1ff2241f50be34712072be4afecdee 100644 --- a/openair3/NAS/COMMON/UTIL/tst/timer.c +++ b/openair3/NAS/COMMON/UTIL/tst/timer.c @@ -96,7 +96,7 @@ int main (int argc, const char* argv[]) /* Start NB_TIMERS_MAX timers to expire at time interval of 1s */ for (int i=0; i < NB_TIMERS_MAX; i++) { if (_start(&timer[i], i) != RETURNok) { - printf("ERROR: timer_start(i=%u) failed\n", i); + printf("ERROR: timer_start(i=%d) failed\n", i); } } diff --git a/openair3/NAS/TEST/NETWORK/network_simulator.c b/openair3/NAS/TEST/NETWORK/network_simulator.c index 294241a3845fbf6d663daad85365a16d707d6c34..461f701f95181d08a1c8cd2cb4a6a6de7dc33f8e 100644 --- a/openair3/NAS/TEST/NETWORK/network_simulator.c +++ b/openair3/NAS/TEST/NETWORK/network_simulator.c @@ -319,7 +319,7 @@ int main (int argc, const char* argv[]) _network_simulator_msg_sent += 1; } - printf("\nINFO\t: %d messages received, %d messages sent\n", + printf("\nINFO\t: %u messages received, %u messages sent\n", _network_simulator_msg_recv, _network_simulator_msg_sent); } diff --git a/openair3/NAS/TEST/USER/user_simulator.c b/openair3/NAS/TEST/USER/user_simulator.c index fa015df30af33599815c5341059ba2a831716964..1c429c3b8508c1b766d0c27a0d1289d3d2edb8a7 100644 --- a/openair3/NAS/TEST/USER/user_simulator.c +++ b/openair3/NAS/TEST/USER/user_simulator.c @@ -143,7 +143,7 @@ int main (int argc, const char* argv[]) } printf("INFO\t: The User Simulator is now connected to %s (%d)\n", - devpath, USER_GETFD()); + devpath, (int)USER_GETFD()); } else { /* Initialize network socket handlers */ _user_simulator_id.open = socket_udp_open; @@ -163,7 +163,7 @@ int main (int argc, const char* argv[]) } printf("INFO\t: The User Simulator is now connected to %s/%s (%d)\n", - host, port, USER_GETFD()); + host, port, (int)USER_GETFD()); } @@ -231,7 +231,7 @@ int main (int argc, const char* argv[]) /* * Termination cleanup */ - printf("INFO\t: Closing user endpoint descriptor %d\n", USER_GETFD()); + printf("INFO\t: Closing user endpoint descriptor %d\n", (int)USER_GETFD()); USER_CLOSE(); printf("INFO\t: User simulator exited\n"); @@ -282,7 +282,7 @@ static int _set_signal_handler(int signal, void (handler)(int)) static void _signal_handler(int signal_number) { printf("\nWARNING\t: Signal %d received\n", signal_number); - printf("INFO\t: Closing user socket %d\n", USER_GETFD()); + printf("INFO\t: Closing user socket %d\n", (int)USER_GETFD()); USER_CLOSE(); printf("INFO\t: User simulator exited\n"); exit(EXIT_SUCCESS); diff --git a/openair3/NAS/UE/API/USER/at_response.c b/openair3/NAS/UE/API/USER/at_response.c index a488aa78d9f7c949564c3553150e040b36981fa8..859db90d7e0d5393045771260e30b35f968e7484 100644 --- a/openair3/NAS/UE/API/USER/at_response.c +++ b/openair3/NAS/UE/API/USER/at_response.c @@ -88,41 +88,41 @@ static int _at_response_encode_cgev (char* buffer, const at_response_t* data); typedef int (*_at_response_encode_function_t) (char* buffer, const at_response_t*); static _at_response_encode_function_t _at_response_encode_function[AT_RESPONSE_ID_MAX] = { - NULL, - _at_response_encode_cgsn, /* CGSN */ - _at_response_encode_cgmi, /* CGMI */ - _at_response_encode_cgmm, /* CGMM */ - _at_response_encode_cgmr, /* CGMR */ - _at_response_encode_cimi, /* CIMI */ - _at_response_encode_cfun, /* CFUN */ - _at_response_encode_cpin, /* CPIN */ - _at_response_encode_csq, /* CSQ */ - _at_response_encode_cesq, /* CESQ */ - _at_response_encode_clac, /* CLAC */ - _at_response_encode_cmee, /* CMEE */ - _at_response_encode_cnum, /* CNUM */ - _at_response_encode_clck, /* CLCK */ - _at_response_encode_cops, /* COPS */ - _at_response_encode_creg, /* CREG */ - _at_response_encode_cgatt, /* CGATT */ - _at_response_encode_cgreg, /* CGREG */ - _at_response_encode_cereg, /* CEREG */ - _at_response_encode_cgdcont, /* CGDCONT */ - _at_response_encode_cgact, /* CGACT */ - _at_response_encode_cgpaddr, /* CGPADDR */ - _at_response_encode_cgev, /* CGEV: unsolicited result */ + NULL, + _at_response_encode_cgsn, /* CGSN */ + _at_response_encode_cgmi, /* CGMI */ + _at_response_encode_cgmm, /* CGMM */ + _at_response_encode_cgmr, /* CGMR */ + _at_response_encode_cimi, /* CIMI */ + _at_response_encode_cfun, /* CFUN */ + _at_response_encode_cpin, /* CPIN */ + _at_response_encode_csq, /* CSQ */ + _at_response_encode_cesq, /* CESQ */ + _at_response_encode_clac, /* CLAC */ + _at_response_encode_cmee, /* CMEE */ + _at_response_encode_cnum, /* CNUM */ + _at_response_encode_clck, /* CLCK */ + _at_response_encode_cops, /* COPS */ + _at_response_encode_creg, /* CREG */ + _at_response_encode_cgatt, /* CGATT */ + _at_response_encode_cgreg, /* CGREG */ + _at_response_encode_cereg, /* CEREG */ + _at_response_encode_cgdcont, /* CGDCONT */ + _at_response_encode_cgact, /* CGACT */ + _at_response_encode_cgpaddr, /* CGPADDR */ + _at_response_encode_cgev, /* CGEV: unsolicited result */ }; /* String representation of Packet Domain events (cf. network_pdn_state_t) */ static const char* _at_response_event_str[] = { - "UNKNOWN EVENT", - "ME PDN ACT", - "NW PDN DEACT", - "ME PDN DEACT", - "NW ACT", - "ME ACT", - "NW DEACT", - "ME DEACT", + "UNKNOWN EVENT", + "ME PDN ACT", + "NW PDN DEACT", + "ME PDN DEACT", + "NW ACT", + "ME ACT", + "NW DEACT", + "ME DEACT", }; /****************************************************************************/ @@ -147,24 +147,24 @@ static const char* _at_response_event_str[] = { ***************************************************************************/ int at_response_encode(char* buffer, const at_response_t* at_response) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int bytes = RETURNerror; - _at_response_encode_function_t encode; + int bytes = RETURNerror; + _at_response_encode_function_t encode; - if (at_response->id < AT_RESPONSE_ID_MAX) { - /* Call encoding function applicable to the AT command response */ - encode = _at_response_encode_function[at_response->id]; + if (at_response->id < AT_RESPONSE_ID_MAX) { + /* Call encoding function applicable to the AT command response */ + encode = _at_response_encode_function[at_response->id]; - if (encode != NULL) { - bytes = (*encode)(buffer, at_response); - } else { - /* Generic encoding: OK, ERROR */ - bytes = 0; + if (encode != NULL) { + bytes = (*encode)(buffer, at_response); + } else { + /* Generic encoding: OK, ERROR */ + bytes = 0; + } } - } - LOG_FUNC_RETURN (bytes); + LOG_FUNC_RETURN (bytes); } /****************************************************************************/ @@ -188,21 +188,21 @@ int at_response_encode(char* buffer, const at_response_t* at_response) ***************************************************************************/ static int _at_response_encode_cgsn(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_ACT) { - const at_cgsn_resp_t * cgsn = &(data->response.cgsn); + if (data->type == AT_COMMAND_ACT) { + const at_cgsn_resp_t * cgsn = &(data->response.cgsn); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CGSN: %s\r\n", cgsn->sn); - } + offset += sprintf(buffer+offset, "+CGSN: %s\r\n", cgsn->sn); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -222,21 +222,21 @@ static int _at_response_encode_cgsn(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cgmi(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_ACT) { - const at_cgmi_resp_t * cgmi = &(data->response.cgmi); + if (data->type == AT_COMMAND_ACT) { + const at_cgmi_resp_t * cgmi = &(data->response.cgmi); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CGMI: %s\r\n", cgmi->manufacturer); - } + offset += sprintf(buffer+offset, "+CGMI: %s\r\n", cgmi->manufacturer); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -256,21 +256,21 @@ static int _at_response_encode_cgmi(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cgmm(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_ACT) { - const at_cgmm_resp_t * cgmm = &(data->response.cgmm); + if (data->type == AT_COMMAND_ACT) { + const at_cgmm_resp_t * cgmm = &(data->response.cgmm); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CGMM: %s\r\n", cgmm->model); - } + offset += sprintf(buffer+offset, "+CGMM: %s\r\n", cgmm->model); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -290,21 +290,21 @@ static int _at_response_encode_cgmm(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cgmr(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_ACT) { - const at_cgmr_resp_t * cgmr = &(data->response.cgmr); + if (data->type == AT_COMMAND_ACT) { + const at_cgmr_resp_t * cgmr = &(data->response.cgmr); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CGMR: %s\r\n", cgmr->revision); - } + offset += sprintf(buffer+offset, "+CGMR: %s\r\n", cgmr->revision); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -324,21 +324,21 @@ static int _at_response_encode_cgmr(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cimi(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_ACT) { - const at_cimi_resp_t * cimi = &(data->response.cimi); + if (data->type == AT_COMMAND_ACT) { + const at_cimi_resp_t * cimi = &(data->response.cimi); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CIMI: %s\r\n", cimi->IMSI); - } + offset += sprintf(buffer+offset, "+CIMI: %s\r\n", cimi->IMSI); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -358,27 +358,27 @@ static int _at_response_encode_cimi(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cfun(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - const at_cfun_resp_t * cfun = &(data->response.cfun); - int offset = 0; + const at_cfun_resp_t * cfun = &(data->response.cfun); + int offset = 0; - if (data->type == AT_COMMAND_GET) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (data->type == AT_COMMAND_GET) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CFUN: %d\r\n", cfun->fun); - } else if (data->type == AT_COMMAND_TST) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + offset += sprintf(buffer+offset, "+CFUN: %d\r\n", cfun->fun); + } else if (data->type == AT_COMMAND_TST) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CFUN: (%d-%d),(%d,%d)\r\n", - AT_CFUN_MIN, AT_CFUN_MAX, AT_CFUN_NORST, AT_CFUN_RST); - } + offset += sprintf(buffer+offset, "+CFUN: (%d-%d),(%d,%d)\r\n", + AT_CFUN_MIN, AT_CFUN_MAX, AT_CFUN_NORST, AT_CFUN_RST); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -398,21 +398,21 @@ static int _at_response_encode_cfun(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cpin(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_GET) { - const at_cpin_resp_t * cpin = &(data->response.cpin); + if (data->type == AT_COMMAND_GET) { + const at_cpin_resp_t * cpin = &(data->response.cpin); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CPIN: %s\r\n", cpin->code); - } + offset += sprintf(buffer+offset, "+CPIN: %s\r\n", cpin->code); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -432,29 +432,29 @@ static int _at_response_encode_cpin(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_csq(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; - - const at_csq_resp_t * csq = &(data->response.csq); - int offset = 0; - - if (data->type == AT_COMMAND_ACT) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); + LOG_FUNC_IN; + + const at_csq_resp_t * csq = &(data->response.csq); + int offset = 0; + + if (data->type == AT_COMMAND_ACT) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + offset += sprintf(buffer+offset, "+CSQ: %d,%d\r\n", + csq->rssi, csq->ber); + } else if (data->type == AT_COMMAND_TST) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + offset += sprintf(buffer+offset, "+CSQ: (%d-%d),(%d-%d)\r\n", + AT_CSQ_RSSI_0, AT_CSQ_RSSI_31, + AT_CSQ_BER_0, AT_CSQ_BER_7); } - offset += sprintf(buffer+offset, "+CSQ: %d,%d\r\n", - csq->rssi, csq->ber); - } else if (data->type == AT_COMMAND_TST) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } - - offset += sprintf(buffer+offset, "+CSQ: (%d-%d),(%d-%d)\r\n", - AT_CSQ_RSSI_0, AT_CSQ_RSSI_31, - AT_CSQ_BER_0, AT_CSQ_BER_7); - } - - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -474,35 +474,35 @@ static int _at_response_encode_csq(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cesq(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; - - const at_cesq_resp_t * cesq = &(data->response.cesq); - int offset = 0; - - if (data->type == AT_COMMAND_ACT) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); + LOG_FUNC_IN; + + const at_cesq_resp_t * cesq = &(data->response.cesq); + int offset = 0; + + if (data->type == AT_COMMAND_ACT) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + offset += sprintf(buffer+offset, "+CESQ: %d,%d,%d,%d,%d,%d\r\n", + cesq->rssi, cesq->ber, cesq->rscp, + cesq->ecno, cesq->rsrq, cesq->rsrp); + } else if (data->type == AT_COMMAND_TST) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + offset += sprintf(buffer+offset, "+CESQ: (%d-%d),(%d-%d),(%d-%d)," + "(%d-%d),(%d-%d),(%d-%d)\r\n", + AT_CESQ_RSSI_0, AT_CESQ_RSSI_31, + AT_CESQ_BER_0, AT_CESQ_BER_7, + AT_CESQ_RSCP_0, AT_CESQ_RSCP_96, + AT_CESQ_ECNO_0, AT_CESQ_ECNO_49, + AT_CESQ_RSRQ_0, AT_CESQ_RSRQ_34, + AT_CESQ_RSRP_0, AT_CESQ_RSRP_97); } - offset += sprintf(buffer+offset, "+CESQ: %d,%d,%d,%d,%d,%d\r\n", - cesq->rssi, cesq->ber, cesq->rscp, - cesq->ecno, cesq->rsrq, cesq->rsrp); - } else if (data->type == AT_COMMAND_TST) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } - - offset += sprintf(buffer+offset, "+CESQ: (%d-%d),(%d-%d),(%d-%d)," - "(%d-%d),(%d-%d),(%d-%d)\r\n", - AT_CESQ_RSSI_0, AT_CESQ_RSSI_31, - AT_CESQ_BER_0, AT_CESQ_BER_7, - AT_CESQ_RSCP_0, AT_CESQ_RSCP_96, - AT_CESQ_ECNO_0, AT_CESQ_ECNO_49, - AT_CESQ_RSRQ_0, AT_CESQ_RSRQ_34, - AT_CESQ_RSRP_0, AT_CESQ_RSRP_97); - } - - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -522,27 +522,27 @@ static int _at_response_encode_cesq(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_clac(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - const at_clac_resp_t * clac = &(data->response.clac); - int offset = 0; - int i; + const at_clac_resp_t * clac = &(data->response.clac); + int offset = 0; + int i; - if (data->type == AT_COMMAND_ACT) { - if (clac->n_acs > 0) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (data->type == AT_COMMAND_ACT) { + if (clac->n_acs > 0) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "%s", clac->ac[0]); + offset += sprintf(buffer+offset, "%s", clac->ac[0]); - for (i = 1; i < clac->n_acs; i++) { - offset += sprintf(buffer+offset, "\r\n%s", clac->ac[i]); - } + for (i = 1; i < clac->n_acs; i++) { + offset += sprintf(buffer+offset, "\r\n%s", clac->ac[i]); + } + } } - } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -562,22 +562,22 @@ static int _at_response_encode_clac(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cnum(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_ACT) { - const at_cnum_resp_t * cnum = &(data->response.cnum); + if (data->type == AT_COMMAND_ACT) { + const at_cnum_resp_t * cnum = &(data->response.cnum); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CNUM: ,%s,%u\r\n", - cnum->number, cnum->type); - } + offset += sprintf(buffer+offset, "+CNUM: ,%s,%u\r\n", + cnum->number, (unsigned int)cnum->type); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -597,26 +597,26 @@ static int _at_response_encode_cnum(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_clck(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - const at_clck_resp_t * clck = &(data->response.clck); - int offset = 0; + const at_clck_resp_t * clck = &(data->response.clck); + int offset = 0; - if (data->type == AT_COMMAND_SET) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (data->type == AT_COMMAND_SET) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CLCK: %d\r\n", clck->status); - } else if (data->type == AT_COMMAND_TST) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + offset += sprintf(buffer+offset, "+CLCK: %d\r\n", clck->status); + } else if (data->type == AT_COMMAND_TST) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CLCK: %s\r\n", AT_CLCK_SC); - } + offset += sprintf(buffer+offset, "+CLCK: %s\r\n", AT_CLCK_SC); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -636,63 +636,63 @@ static int _at_response_encode_clck(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cops(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; - - int offset = 0; - - if (data->type == AT_COMMAND_GET) { - const at_cops_get_t * cops = &(data->response.cops.get); - - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } - - offset += sprintf(buffer+offset, "+COPS: %d", cops->mode); - - if (data->mask & AT_COPS_RESP_OPER_MASK) { - /* If <oper> is present <format> must be given */ - assert(data->mask & AT_COPS_RESP_FORMAT_MASK); - offset += sprintf(buffer+offset, ",%d", cops->format); - - if (cops->format == AT_COPS_LONG) { - offset += sprintf(buffer+offset, ",%s", - (char*)cops->plmn.id.alpha_long); - } else if (cops->format == AT_COPS_SHORT) { - offset += sprintf(buffer+offset, ",%s", - (char*)cops->plmn.id.alpha_short); - } else if (cops->format == AT_COPS_NUM) { - offset += sprintf(buffer+offset, ",%s", - (char*)cops->plmn.id.num); - } + LOG_FUNC_IN; + + int offset = 0; + + if (data->type == AT_COMMAND_GET) { + const at_cops_get_t * cops = &(data->response.cops.get); + + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + offset += sprintf(buffer+offset, "+COPS: %d", cops->mode); + + if (data->mask & AT_COPS_RESP_OPER_MASK) { + /* If <oper> is present <format> must be given */ + assert(data->mask & AT_COPS_RESP_FORMAT_MASK); + offset += sprintf(buffer+offset, ",%d", cops->format); + + if (cops->format == AT_COPS_LONG) { + offset += sprintf(buffer+offset, ",%s", + (char*)cops->plmn.id.alpha_long); + } else if (cops->format == AT_COPS_SHORT) { + offset += sprintf(buffer+offset, ",%s", + (char*)cops->plmn.id.alpha_short); + } else if (cops->format == AT_COPS_NUM) { + offset += sprintf(buffer+offset, ",%s", + (char*)cops->plmn.id.num); + } + } + + if (data->mask & AT_COPS_RESP_ACT_MASK) { + offset += sprintf(buffer+offset, ",%d", cops->AcT); + } + + offset += sprintf(buffer+offset, "\r\n"); + } else if (data->type == AT_COMMAND_TST) { + const at_cops_tst_t * cops = &(data->response.cops.tst); + + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + offset += sprintf(buffer+offset, "+COPS: "); + + /* Display the list of operators present in the network */ + strncpy(buffer+offset, cops->data, cops->size); + offset += cops->size; + + /* Display the list of supported network registration modes and + * supported representation formats of network operators */ + //offset += sprintf(buffer+offset, ",,(%d-%d),(%d,%d,%d)", + // AT_COPS_AUTO, AT_COPS_MANAUTO, + // AT_COPS_LONG, AT_COPS_SHORT, AT_COPS_NUM); + offset += sprintf(buffer+offset, "\r\n"); } - if (data->mask & AT_COPS_RESP_ACT_MASK) { - offset += sprintf(buffer+offset, ",%d", cops->AcT); - } - - offset += sprintf(buffer+offset, "\r\n"); - } else if (data->type == AT_COMMAND_TST) { - const at_cops_tst_t * cops = &(data->response.cops.tst); - - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } - - offset += sprintf(buffer+offset, "+COPS: "); - - /* Display the list of operators present in the network */ - strncpy(buffer+offset, cops->data, cops->size); - offset += cops->size; - - /* Display the list of supported network registration modes and - * supported representation formats of network operators */ - //offset += sprintf(buffer+offset, ",,(%d-%d),(%d,%d,%d)", - // AT_COPS_AUTO, AT_COPS_MANAUTO, - // AT_COPS_LONG, AT_COPS_SHORT, AT_COPS_NUM); - offset += sprintf(buffer+offset, "\r\n"); - } - - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -712,28 +712,28 @@ static int _at_response_encode_cops(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cgatt(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_GET) { - const at_cgatt_resp_t * cgatt = &(data->response.cgatt); + if (data->type == AT_COMMAND_GET) { + const at_cgatt_resp_t * cgatt = &(data->response.cgatt); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CGATT: %d\r\n", cgatt->state); - } else if (data->type == AT_COMMAND_TST) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + offset += sprintf(buffer+offset, "+CGATT: %d\r\n", cgatt->state); + } else if (data->type == AT_COMMAND_TST) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CGATT: (%d,%d)\r\n", - AT_CGATT_STATE_MIN, AT_CGATT_STATE_MAX); - } + offset += sprintf(buffer+offset, "+CGATT: (%d,%d)\r\n", + AT_CGATT_STATE_MIN, AT_CGATT_STATE_MAX); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -753,43 +753,43 @@ static int _at_response_encode_cgatt(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_creg(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_GET) { - const at_creg_resp_t * creg = &(data->response.creg); + if (data->type == AT_COMMAND_GET) { + const at_creg_resp_t * creg = &(data->response.creg); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CREG: %d,%d", - creg->n, creg->stat); + offset += sprintf(buffer+offset, "+CREG: %d,%d", + creg->n, creg->stat); - if (data->mask & AT_CREG_RESP_LAC_MASK) { - offset += sprintf(buffer+offset, ",%s", creg->lac); - } + if (data->mask & AT_CREG_RESP_LAC_MASK) { + offset += sprintf(buffer+offset, ",%s", creg->lac); + } - if (data->mask & AT_CREG_RESP_CI_MASK) { - offset += sprintf(buffer+offset, ",%s", creg->ci); - } + if (data->mask & AT_CREG_RESP_CI_MASK) { + offset += sprintf(buffer+offset, ",%s", creg->ci); + } - if (data->mask & AT_CREG_RESP_ACT_MASK) { - offset += sprintf(buffer+offset, ",%d", creg->AcT); - } + if (data->mask & AT_CREG_RESP_ACT_MASK) { + offset += sprintf(buffer+offset, ",%d", creg->AcT); + } - offset += sprintf(buffer+offset, "\r\n"); - } else if (data->type == AT_COMMAND_TST) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + offset += sprintf(buffer+offset, "\r\n"); + } else if (data->type == AT_COMMAND_TST) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CREG: (%d-%d)\r\n", - AT_CREG_N_MIN, AT_CREG_N_MAX); - } + offset += sprintf(buffer+offset, "+CREG: (%d-%d)\r\n", + AT_CREG_N_MIN, AT_CREG_N_MAX); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -809,47 +809,47 @@ static int _at_response_encode_creg(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cgreg(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_GET) { - const at_cgreg_resp_t * cgreg = &(data->response.cgreg); + if (data->type == AT_COMMAND_GET) { + const at_cgreg_resp_t * cgreg = &(data->response.cgreg); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CGREG: %d,%d", - cgreg->n, cgreg->stat); + offset += sprintf(buffer+offset, "+CGREG: %d,%d", + cgreg->n, cgreg->stat); - if (data->mask & AT_CGREG_RESP_LAC_MASK) { - offset += sprintf(buffer+offset, ",%s", cgreg->lac); - } + if (data->mask & AT_CGREG_RESP_LAC_MASK) { + offset += sprintf(buffer+offset, ",%s", cgreg->lac); + } - if (data->mask & AT_CGREG_RESP_CI_MASK) { - offset += sprintf(buffer+offset, ",%s", cgreg->ci); - } + if (data->mask & AT_CGREG_RESP_CI_MASK) { + offset += sprintf(buffer+offset, ",%s", cgreg->ci); + } - if (data->mask & AT_CGREG_RESP_ACT_MASK) { - offset += sprintf(buffer+offset, ",%d", cgreg->AcT); - } + if (data->mask & AT_CGREG_RESP_ACT_MASK) { + offset += sprintf(buffer+offset, ",%d", cgreg->AcT); + } - if (data->mask & AT_CGREG_RESP_RAC_MASK) { - offset += sprintf(buffer+offset, ",%s", cgreg->rac); - } + if (data->mask & AT_CGREG_RESP_RAC_MASK) { + offset += sprintf(buffer+offset, ",%s", cgreg->rac); + } - offset += sprintf(buffer+offset, "\r\n"); - } else if (data->type == AT_COMMAND_TST) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + offset += sprintf(buffer+offset, "\r\n"); + } else if (data->type == AT_COMMAND_TST) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CGREG: (%d-%d)\r\n", - AT_CGREG_N_MIN, AT_CGREG_N_MAX); - } + offset += sprintf(buffer+offset, "+CGREG: (%d-%d)\r\n", + AT_CGREG_N_MIN, AT_CGREG_N_MAX); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -869,43 +869,43 @@ static int _at_response_encode_cgreg(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cereg(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_GET) { - const at_cereg_resp_t * cereg = &(data->response.cereg); + if (data->type == AT_COMMAND_GET) { + const at_cereg_resp_t * cereg = &(data->response.cereg); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CEREG: %d,%d", - cereg->n, cereg->stat); + offset += sprintf(buffer+offset, "+CEREG: %d,%d", + cereg->n, cereg->stat); - if (data->mask & AT_CEREG_RESP_TAC_MASK) { - offset += sprintf(buffer+offset, ",%s", cereg->tac); - } + if (data->mask & AT_CEREG_RESP_TAC_MASK) { + offset += sprintf(buffer+offset, ",%s", cereg->tac); + } - if (data->mask & AT_CEREG_RESP_CI_MASK) { - offset += sprintf(buffer+offset, ",%s", cereg->ci); - } + if (data->mask & AT_CEREG_RESP_CI_MASK) { + offset += sprintf(buffer+offset, ",%s", cereg->ci); + } - if (data->mask & AT_CEREG_RESP_ACT_MASK) { - offset += sprintf(buffer+offset, ",%d", cereg->AcT); - } + if (data->mask & AT_CEREG_RESP_ACT_MASK) { + offset += sprintf(buffer+offset, ",%d", cereg->AcT); + } - offset += sprintf(buffer+offset, "\r\n"); - } else if (data->type == AT_COMMAND_TST) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + offset += sprintf(buffer+offset, "\r\n"); + } else if (data->type == AT_COMMAND_TST) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CEREG: (%d-%d)\r\n", - AT_CEREG_N_MIN, AT_CEREG_N_MAX); - } + offset += sprintf(buffer+offset, "+CEREG: (%d-%d)\r\n", + AT_CEREG_N_MIN, AT_CEREG_N_MAX); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -925,65 +925,65 @@ static int _at_response_encode_cereg(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cgdcont(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; - - int offset = 0; - int i; - - if (data->type == AT_COMMAND_GET) { - const at_cgdcont_get_t * cgdcont = &(data->response.cgdcont.get); - - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); + LOG_FUNC_IN; + + int offset = 0; + int i; + + if (data->type == AT_COMMAND_GET) { + const at_cgdcont_get_t * cgdcont = &(data->response.cgdcont.get); + + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + /* Display the list of defined PDN contexts */ + for (i = 0; i < cgdcont->n_pdns; i++) { + offset += sprintf(buffer+offset, "+CGDCONT: %u", (unsigned int)cgdcont->cid[i]); + + if (cgdcont->PDP_type[i] == NET_PDN_TYPE_IPV4) { + offset += sprintf(buffer+offset, ",IP"); + } else if (cgdcont->PDP_type[i] == NET_PDN_TYPE_IPV6) { + offset += sprintf(buffer+offset, ",IPV6"); + } else if (cgdcont->PDP_type[i] == NET_PDN_TYPE_IPV4V6) { + offset += sprintf(buffer+offset, ",IPV4V6"); + } + + offset += sprintf(buffer+offset, ",%s", cgdcont->APN[i]); + /* No data/header compression */ + offset += sprintf(buffer+offset, ",%u,%u\r\n", + (unsigned int)(AT_CGDCONT_D_COMP_OFF), (unsigned int)(AT_CGDCONT_H_COMP_OFF)); + } + } else if (data->type == AT_COMMAND_TST) { + const at_cgdcont_tst_t * cgdcont = &(data->response.cgdcont.tst); + + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + /* IPv4 PDN type */ + offset += sprintf(buffer+offset, "+CGDCONT: "); + offset += sprintf(buffer+offset, "(1-%d),IP,,,(%d-%d),(%d-%d)", + cgdcont->n_cid, + AT_CGDCONT_D_COMP_MIN, AT_CGDCONT_D_COMP_MAX, + AT_CGDCONT_H_COMP_MIN, AT_CGDCONT_H_COMP_MAX); + /* IPv6 PDN type */ + offset += sprintf(buffer+offset, "\r\n+CGDCONT: "); + offset += sprintf(buffer+offset, "(1-%d),IPV6,,,(%d-%d),(%d-%d)", + cgdcont->n_cid, + AT_CGDCONT_D_COMP_MIN, AT_CGDCONT_D_COMP_MAX, + AT_CGDCONT_H_COMP_MIN, AT_CGDCONT_H_COMP_MAX); + /* IPv4v6 PDN type */ + offset += sprintf(buffer+offset, "\r\n+CGDCONT: "); + offset += sprintf(buffer+offset, "(1-%d),IPV4V6,,,(%d-%d),(%d-%d)", + cgdcont->n_cid, + AT_CGDCONT_D_COMP_MIN, AT_CGDCONT_D_COMP_MAX, + AT_CGDCONT_H_COMP_MIN, AT_CGDCONT_H_COMP_MAX); + + offset += sprintf(buffer+offset, "\r\n"); } - /* Display the list of defined PDN contexts */ - for (i = 0; i < cgdcont->n_pdns; i++) { - offset += sprintf(buffer+offset, "+CGDCONT: %u", cgdcont->cid[i]); - - if (cgdcont->PDP_type[i] == NET_PDN_TYPE_IPV4) { - offset += sprintf(buffer+offset, ",IP"); - } else if (cgdcont->PDP_type[i] == NET_PDN_TYPE_IPV6) { - offset += sprintf(buffer+offset, ",IPV6"); - } else if (cgdcont->PDP_type[i] == NET_PDN_TYPE_IPV4V6) { - offset += sprintf(buffer+offset, ",IPV4V6"); - } - - offset += sprintf(buffer+offset, ",%s", cgdcont->APN[i]); - /* No data/header compression */ - offset += sprintf(buffer+offset, ",%u,%u\r\n", - AT_CGDCONT_D_COMP_OFF, AT_CGDCONT_H_COMP_OFF); - } - } else if (data->type == AT_COMMAND_TST) { - const at_cgdcont_tst_t * cgdcont = &(data->response.cgdcont.tst); - - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } - - /* IPv4 PDN type */ - offset += sprintf(buffer+offset, "+CGDCONT: "); - offset += sprintf(buffer+offset, "(1-%u),IP,,,(%u-%u),(%u-%u)", - cgdcont->n_cid, - AT_CGDCONT_D_COMP_MIN, AT_CGDCONT_D_COMP_MAX, - AT_CGDCONT_H_COMP_MIN, AT_CGDCONT_H_COMP_MAX); - /* IPv6 PDN type */ - offset += sprintf(buffer+offset, "\r\n+CGDCONT: "); - offset += sprintf(buffer+offset, "(1-%u),IPV6,,,(%u-%u),(%u-%u)", - cgdcont->n_cid, - AT_CGDCONT_D_COMP_MIN, AT_CGDCONT_D_COMP_MAX, - AT_CGDCONT_H_COMP_MIN, AT_CGDCONT_H_COMP_MAX); - /* IPv4v6 PDN type */ - offset += sprintf(buffer+offset, "\r\n+CGDCONT: "); - offset += sprintf(buffer+offset, "(1-%u),IPV4V6,,,(%u-%u),(%u-%u)", - cgdcont->n_cid, - AT_CGDCONT_D_COMP_MIN, AT_CGDCONT_D_COMP_MAX, - AT_CGDCONT_H_COMP_MIN, AT_CGDCONT_H_COMP_MAX); - - offset += sprintf(buffer+offset, "\r\n"); - } - - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -1003,33 +1003,33 @@ static int _at_response_encode_cgdcont(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cgact(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; - - int offset = 0; - int i; - - if (data->type == AT_COMMAND_GET) { - const at_cgact_resp_t * cgact = &(data->response.cgact); - - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); + LOG_FUNC_IN; + + int offset = 0; + int i; + + if (data->type == AT_COMMAND_GET) { + const at_cgact_resp_t * cgact = &(data->response.cgact); + + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + /* Display the list of defined PDN status */ + for (i = 0; i < cgact->n_pdns; i++) { + offset += sprintf(buffer+offset, "+CGACT: %u,%u\r\n", + (unsigned int)cgact->cid[i], (unsigned int)cgact->state[i]); + } + } else if (data->type == AT_COMMAND_TST) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + offset += sprintf(buffer+offset, "+CGACT: (%d,%d)\r\n", + AT_CGACT_STATE_MIN, AT_CGACT_STATE_MAX); } - /* Display the list of defined PDN status */ - for (i = 0; i < cgact->n_pdns; i++) { - offset += sprintf(buffer+offset, "+CGACT: %u,%u\r\n", - cgact->cid[i], cgact->state[i]); - } - } else if (data->type == AT_COMMAND_TST) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } - - offset += sprintf(buffer+offset, "+CGACT: (%d,%d)\r\n", - AT_CGACT_STATE_MIN, AT_CGACT_STATE_MAX); - } - - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -1049,69 +1049,72 @@ static int _at_response_encode_cgact(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cgpaddr(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; - - int offset = 0; - const at_cgpaddr_resp_t * cgpaddr = &(data->response.cgpaddr); - int i; - - if (data->type == AT_COMMAND_SET) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } - - /* Display the list of IP addresses assigned to each defined PDN - * connections */ - for (i = 0; i < cgpaddr->n_pdns; i++) { - offset += sprintf(buffer+offset, "+CGPADDR: %u", cgpaddr->cid[i]); - - if (cgpaddr->PDP_addr_1[i] != NULL) { - /* IPv4 address */ - offset += sprintf(buffer+offset, ",%hhu.%hhu.%hhu.%hhu", - cgpaddr->PDP_addr_1[i][0], - cgpaddr->PDP_addr_1[i][1], - cgpaddr->PDP_addr_1[i][2], - cgpaddr->PDP_addr_1[i][3]); - } - - if (cgpaddr->PDP_addr_2[i] != NULL) { - /* IPv6 Link-local address prefixe */ - offset += sprintf(buffer+offset, - ",%hhu.%hhu.%hhu.%hhu.%hhu.%hhu.%hhu.%hhu", - 0xfe, 0x80, 0, 0, 0, 0, 0, 0); - /* IPv6 Link-local address */ - offset += sprintf(buffer+offset, - ".%hhu.%hhu.%hhu.%hhu.%hhu.%hhu.%hhu.%hhu", - cgpaddr->PDP_addr_2[i][0], - cgpaddr->PDP_addr_2[i][1], - cgpaddr->PDP_addr_2[i][2], - cgpaddr->PDP_addr_2[i][3], - cgpaddr->PDP_addr_2[i][4], - cgpaddr->PDP_addr_2[i][5], - cgpaddr->PDP_addr_2[i][6], - cgpaddr->PDP_addr_2[i][7]); - } - - offset += sprintf(buffer+offset, "\r\n"); + LOG_FUNC_IN; + + int offset = 0; + const at_cgpaddr_resp_t * cgpaddr = &(data->response.cgpaddr); + int i; + + if (data->type == AT_COMMAND_SET) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + /* Display the list of IP addresses assigned to each defined PDN + * connections */ + for (i = 0; i < cgpaddr->n_pdns; i++) { + offset += sprintf(buffer+offset, "+CGPADDR: %u", (unsigned int)cgpaddr->cid[i]); + + if (cgpaddr->PDP_addr_1[i] != NULL) { + /* IPv4 address */ + offset += sprintf(buffer+offset, ",%hhu.%hhu.%hhu.%hhu", + (unsigned int)cgpaddr->PDP_addr_1[i][0], + (unsigned int)cgpaddr->PDP_addr_1[i][1], + (unsigned int)cgpaddr->PDP_addr_1[i][2], + (unsigned int)cgpaddr->PDP_addr_1[i][3]); + } + + if (cgpaddr->PDP_addr_2[i] != NULL) { + /* IPv6 Link-local address prefixe */ + offset += sprintf(buffer+offset, + ",%hhu.%hhu.%hhu.%hhu.%hhu.%hhu.%hhu.%hhu", + (unsigned int)0xfe, (unsigned int)0x80, + (unsigned int)0, (unsigned int)0, + (unsigned int)0, (unsigned int)0, + (unsigned int)0, (unsigned int)0); + /* IPv6 Link-local address */ + offset += sprintf(buffer+offset, + ".%hhu.%hhu.%hhu.%hhu.%hhu.%hhu.%hhu.%hhu", + (unsigned int)cgpaddr->PDP_addr_2[i][0], + (unsigned int)cgpaddr->PDP_addr_2[i][1], + (unsigned int)cgpaddr->PDP_addr_2[i][2], + (unsigned int)cgpaddr->PDP_addr_2[i][3], + (unsigned int)cgpaddr->PDP_addr_2[i][4], + (unsigned int)cgpaddr->PDP_addr_2[i][5], + (unsigned int)cgpaddr->PDP_addr_2[i][6], + (unsigned int)cgpaddr->PDP_addr_2[i][7]); + } + + offset += sprintf(buffer+offset, "\r\n"); + } + } else if (data->type == AT_COMMAND_TST) { + /* Display the list of defined PDN contexts */ + if (cgpaddr->n_pdns > 0) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } + + offset += sprintf(buffer+offset, "+CGPADDR: %u", (unsigned int)cgpaddr->cid[0]); + + for (i = 1; i < cgpaddr->n_pdns; i++) { + offset += sprintf(buffer+offset, ",%u", (unsigned int)cgpaddr->cid[i]); + } + + offset += sprintf(buffer+offset, "\r\n"); + } } - } else if (data->type == AT_COMMAND_TST) { - /* Display the list of defined PDN contexts */ - if (cgpaddr->n_pdns > 0) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } - offset += sprintf(buffer+offset, "+CGPADDR: %u", cgpaddr->cid[0]); - - for (i = 1; i < cgpaddr->n_pdns; i++) { - offset += sprintf(buffer+offset, ",%u", cgpaddr->cid[i]); - } - - offset += sprintf(buffer+offset, "\r\n"); - } - } - - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -1131,28 +1134,28 @@ static int _at_response_encode_cgpaddr(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cmee(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_GET) { - const at_cmee_resp_t * cmee = &(data->response.cmee); + if (data->type == AT_COMMAND_GET) { + const at_cmee_resp_t * cmee = &(data->response.cmee); - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CMEE: %d\r\n", cmee->n); - } else if (data->type == AT_COMMAND_TST) { - if (at_response_format_v1) { - offset += sprintf(buffer, "\r\n"); - } + offset += sprintf(buffer+offset, "+CMEE: %d\r\n", cmee->n); + } else if (data->type == AT_COMMAND_TST) { + if (at_response_format_v1) { + offset += sprintf(buffer, "\r\n"); + } - offset += sprintf(buffer+offset, "+CMEE: (%d,%d)\r\n", - AT_CMEE_N_MIN, AT_CMEE_N_MAX); - } + offset += sprintf(buffer+offset, "+CMEE: (%d,%d)\r\n", + AT_CMEE_N_MIN, AT_CMEE_N_MAX); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } /**************************************************************************** @@ -1172,16 +1175,16 @@ static int _at_response_encode_cmee(char* buffer, const at_response_t* data) ***************************************************************************/ static int _at_response_encode_cgev(char* buffer, const at_response_t* data) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int offset = 0; + int offset = 0; - if (data->type == AT_COMMAND_GET) { - const at_cgev_resp_t * cgev = &(data->response.cgev); - offset += sprintf(buffer+offset, "+CGEV: %s %u\r\n", - _at_response_event_str[cgev->code], cgev->cid); - } + if (data->type == AT_COMMAND_GET) { + const at_cgev_resp_t * cgev = &(data->response.cgev); + offset += sprintf(buffer+offset, "+CGEV: %s %u\r\n", + _at_response_event_str[cgev->code], (unsigned int)cgev->cid); + } - LOG_FUNC_RETURN (offset); + LOG_FUNC_RETURN (offset); } diff --git a/openair3/NAS/UE/API/USER/user_api.h b/openair3/NAS/UE/API/USER/user_api.h index e554b4ef0b7c6d3ab7dd6c3910da6e4a6a7c8dd7..1056a6b7f42d9ad3cf76c9b87183ed4bc65abe2e 100644 --- a/openair3/NAS/UE/API/USER/user_api.h +++ b/openair3/NAS/UE/API/USER/user_api.h @@ -44,7 +44,7 @@ Description Implements the API used by the NAS layer running in the UE #include "networkDef.h" #include "at_command.h" #include "user_api_defs.h" -#include "user_defs.h" +#include "../../user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -58,13 +58,13 @@ Description Implements the API used by the NAS layer running in the UE /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int user_api_initialize(user_api_id_t *user_api_id, const char* host, const char* port, const char* devname, const char* devparams); +int user_api_initialize(user_api_id_t *user_api_id, const char *host, const char *port, const char *devname, const char *devparams); -int user_api_emm_callback(user_api_id_t *user_api_id, Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, const char* data, size_t size); +int user_api_emm_callback(user_api_id_t *user_api_id, Stat_t stat, tac_t tac, ci_t ci, AcT_t AcT, const char *data, size_t size); int user_api_esm_callback(user_api_id_t *user_api_id, int cid, network_pdn_state_t state); int user_api_get_fd(user_api_id_t *user_api_id); -const void* user_api_get_data(user_at_commands_t *commands, int index); +const void *user_api_get_data(user_at_commands_t *commands, int index); int user_api_read_data(user_api_id_t *user_api_id); int user_api_set_data(user_api_id_t *user_api_id, char *message); @@ -72,6 +72,6 @@ int user_api_send_data(user_api_id_t *user_api_id, int length); void user_api_close(user_api_id_t *user_api_id); int user_api_decode_data(user_api_id_t *user_api_id, user_at_commands_t *commands, int length); -int user_api_encode_data(user_api_id_t *user_api_id, const void* data, int add_success_code); +int user_api_encode_data(user_api_id_t *user_api_id, const void *data, int add_success_code); #endif /* __USER_API_H__ */ diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index 055127b15d41fd6d4a10b1c2ac487a35dd9f9357..d30f778e3b7f7d2114e5d23c81da0cb393babcb2 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -41,7 +41,7 @@ Description Defines the EPS Mobility Management procedure call manager, #include "commonDef.h" #include "networkDef.h" -#include "user_defs.h" +#include "../user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -58,7 +58,7 @@ Description Defines the EPS Mobility Management procedure call manager, * EPS Mobility Management sublayer */ typedef int (*emm_indication_callback_t) (user_api_id_t *user_api_id, Stat_t, tac_t, ci_t, AcT_t, - const char*, size_t); + const char *, size_t); /****************************************************************************/ /******************** G L O B A L V A R I A B L E S ********************/ diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index f0f4efa769f5180dc5b73f5c31ea04ada5e71a49..48730f2ca9d2f68e981f8268362d89b8af8bde1b 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -138,119 +138,119 @@ int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int is_to_define, const OctetString *apn, int is_emergency, unsigned int *pti) { - LOG_FUNC_IN; + LOG_FUNC_IN; - int rc = RETURNerror; - int pid = cid - 1; - esm_data_t *esm_data = user-> esm_data; - esm_pt_data_t *esm_pt_data = user-> esm_pt_data; + int rc = RETURNerror; + int pid = cid - 1; + esm_data_t *esm_data = user-> esm_data; + esm_pt_data_t *esm_pt_data = user-> esm_pt_data; - if (!is_to_define) { - LOG_TRACE(INFO, "ESM-PROC - Undefine PDN connection (cid=%d)", cid); - /* Delete the PDN connection entry */ - int pti = _pdn_connectivity_delete(esm_data, pid); + if (!is_to_define) { + LOG_TRACE(INFO, "ESM-PROC - Undefine PDN connection (cid=%d)", cid); + /* Delete the PDN connection entry */ + int pti = _pdn_connectivity_delete(esm_data, pid); - if (pti != ESM_PT_UNASSIGNED) { - /* Release the procedure transaction data */ - rc = esm_pt_release(esm_pt_data, pti); - } + if (pti != ESM_PT_UNASSIGNED) { + /* Release the procedure transaction data */ + rc = esm_pt_release(esm_pt_data, pti); + } - LOG_FUNC_RETURN(rc); - } else if (pti != NULL) { - LOG_TRACE(INFO, "ESM-PROC - Assign new procedure transaction identity " - "(cid=%d)", cid); - /* Assign new procedure transaction identity */ - *pti = esm_pt_assign(esm_pt_data); - - if (*pti == ESM_PT_UNASSIGNED) { - LOG_TRACE(WARNING, "ESM-PROC - Failed to assign new procedure " - "transaction identity"); - LOG_FUNC_RETURN (RETURNerror); - } + LOG_FUNC_RETURN(rc); + } else if (pti != NULL) { + LOG_TRACE(INFO, "ESM-PROC - Assign new procedure transaction identity " + "(cid=%d)", cid); + /* Assign new procedure transaction identity */ + *pti = esm_pt_assign(esm_pt_data); + + if (*pti == ESM_PT_UNASSIGNED) { + LOG_TRACE(WARNING, "ESM-PROC - Failed to assign new procedure " + "transaction identity"); + LOG_FUNC_RETURN (RETURNerror); + } - /* Update the PDN connection data */ - rc = _pdn_connectivity_set_pti(esm_data, pid, *pti); + /* Update the PDN connection data */ + rc = _pdn_connectivity_set_pti(esm_data, pid, *pti); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "ESM-PROC - Failed to update PDN connection"); - } + if (rc != RETURNok) { + LOG_TRACE(WARNING, "ESM-PROC - Failed to update PDN connection"); + } - LOG_FUNC_RETURN (rc); - } - - LOG_TRACE(INFO,"ESM-PROC - Define new %s PDN connection to APN %s (cid=%d)", - (pdn_type == ESM_PDN_TYPE_IPV4)? "IPv4" : - (pdn_type == ESM_PDN_TYPE_IPV6)? "IPv6" : "IPv4v6", - apn->value, cid); - - if (is_emergency && esm_data->emergency) { - /* The UE shall not request additional PDN connection for - * emergency bearer services */ - LOG_TRACE(WARNING, "ESM-PROC - PDN connection for emergency bearer " - "services is already active"); - LOG_FUNC_RETURN (RETURNerror); - } else if (pid < ESM_DATA_PDN_MAX) { - if ((pid == esm_data->pdn[pid].pid) && (esm_data->pdn[pid].is_active)) { - /* PDN connection with the specified identifier is active */ - LOG_TRACE(WARNING, "ESM-PROC - PDN connection is active"); - LOG_FUNC_RETURN (RETURNerror); + LOG_FUNC_RETURN (rc); } - } else { - LOG_TRACE(WARNING, "ESM-PROC - PDN connection identifier is not valid"); - LOG_FUNC_RETURN (RETURNerror); - } - - if (apn && apn->length > 0) { - /* The UE requested subsequent connectivity to additionnal PDNs */ - int pid = _pdn_connectivity_find_apn(esm_data, apn); - - if ( (pid >= 0) && esm_data->pdn[pid].is_active ) { - /* An active PDN connection to this APN already exists */ - if ( (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4V6) && - (esm_data->pdn[pid].data->type != pdn_type) ) { - /* The UE is requesting PDN connection for other IP version - * than the one already activated */ - if (!esm_data->pdn[pid].data->addr_realloc) { - /* The network does not allow PDN connectivity using - * IPv4 and IPv6 address versions to the same APN */ - if (pdn_type != ESM_PDN_TYPE_IPV4V6) { - LOG_TRACE(WARNING, "ESM-PROC - %s PDN connectivity to " - "%s is not allowed by the network", - (pdn_type != ESM_PDN_TYPE_IPV4)? "IPv6" : - "IPv4", apn->value); - } else { - LOG_TRACE(WARNING, "ESM-PROC - %s PDN connection to %s " - "already exists", - (esm_data->pdn[pid].data->type != - ESM_PDN_TYPE_IPV4)? "IPv6" : "IPv4", - apn->value); - } - - LOG_FUNC_RETURN (RETURNerror); + + LOG_TRACE(INFO,"ESM-PROC - Define new %s PDN connection to APN %s (cid=%d)", + (pdn_type == ESM_PDN_TYPE_IPV4)? "IPv4" : + (pdn_type == ESM_PDN_TYPE_IPV6)? "IPv6" : "IPv4v6", + (apn!=NULL)?apn->value:0, cid); + + if (is_emergency && esm_data->emergency) { + /* The UE shall not request additional PDN connection for + * emergency bearer services */ + LOG_TRACE(WARNING, "ESM-PROC - PDN connection for emergency bearer " + "services is already active"); + LOG_FUNC_RETURN (RETURNerror); + } else if (pid < ESM_DATA_PDN_MAX) { + if ((pid == esm_data->pdn[pid].pid) && (esm_data->pdn[pid].is_active)) { + /* PDN connection with the specified identifier is active */ + LOG_TRACE(WARNING, "ESM-PROC - PDN connection is active"); + LOG_FUNC_RETURN (RETURNerror); } - } else { - /* The UE is requesting PDN connection to this APN using the - * same IP version than the one already activated */ - LOG_TRACE(WARNING, "ESM-PROC - %s PDN connection to %s " - "already exists", - (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? - (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV6)? - "IPv4v6" : "IPv6" : "IPv4", apn->value); + } else { + LOG_TRACE(WARNING, "ESM-PROC - PDN connection identifier is not valid"); LOG_FUNC_RETURN (RETURNerror); - } } - } - - /* - * New PDN context has to be defined to allow connectivity to an APN: - * The UE may attempt to attach to the network using the default APN, - * or request PDN connectivity to emergency bearer services. The UE - * may also subsequently request connectivity to additional PDNs if - * not already established, or may have been allowed to request PDN - * connectivity for other IP version than the one already activated - */ - rc = _pdn_connectivity_create(esm_data, pid, apn, pdn_type, is_emergency); - LOG_FUNC_RETURN(rc); + + if (apn && apn->length > 0) { + /* The UE requested subsequent connectivity to additionnal PDNs */ + int pid = _pdn_connectivity_find_apn(esm_data, apn); + + if ( (pid >= 0) && esm_data->pdn[pid].is_active ) { + /* An active PDN connection to this APN already exists */ + if ( (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4V6) && + (esm_data->pdn[pid].data->type != pdn_type) ) { + /* The UE is requesting PDN connection for other IP version + * than the one already activated */ + if (!esm_data->pdn[pid].data->addr_realloc) { + /* The network does not allow PDN connectivity using + * IPv4 and IPv6 address versions to the same APN */ + if (pdn_type != ESM_PDN_TYPE_IPV4V6) { + LOG_TRACE(WARNING, "ESM-PROC - %s PDN connectivity to " + "%s is not allowed by the network", + (pdn_type != ESM_PDN_TYPE_IPV4)? "IPv6" : + "IPv4", apn->value); + } else { + LOG_TRACE(WARNING, "ESM-PROC - %s PDN connection to %s " + "already exists", + (esm_data->pdn[pid].data->type != + ESM_PDN_TYPE_IPV4)? "IPv6" : "IPv4", + apn->value); + } + + LOG_FUNC_RETURN (RETURNerror); + } + } else { + /* The UE is requesting PDN connection to this APN using the + * same IP version than the one already activated */ + LOG_TRACE(WARNING, "ESM-PROC - %s PDN connection to %s " + "already exists", + (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? + (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV6)? + "IPv4v6" : "IPv6" : "IPv4", apn->value); + LOG_FUNC_RETURN (RETURNerror); + } + } + } + + /* + * New PDN context has to be defined to allow connectivity to an APN: + * The UE may attempt to attach to the network using the default APN, + * or request PDN connectivity to emergency bearer services. The UE + * may also subsequently request connectivity to additional PDNs if + * not already established, or may have been allowed to request PDN + * connectivity for other IP version than the one already activated + */ + rc = _pdn_connectivity_create(esm_data, pid, apn, pdn_type, is_emergency); + LOG_FUNC_RETURN(rc); } /**************************************************************************** @@ -283,42 +283,42 @@ int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int is_to_define, int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int pti, OctetString *msg, int sent_by_ue) { - LOG_FUNC_IN; - esm_pt_data_t *esm_pt_data = user->esm_pt_data; - int rc = RETURNok; - - LOG_TRACE(INFO, "ESM-PROC - Initiate PDN connectivity (pti=%d)", pti); - - if (is_standalone) { - emm_sap_t emm_sap; - emm_esm_data_t *emm_esm = &emm_sap.u.emm_esm.u.data; - /* - * Notity EMM that ESM PDU has to be forwarded to lower layers - */ - emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = user->ueid; - emm_esm->msg.length = msg->length; - emm_esm->msg.value = msg->value; - rc = emm_sap_send(user, &emm_sap); - - if (rc != RETURNerror) { - /* Start T3482 retransmission timer */ - rc = esm_pt_start_timer(user, pti, msg, T3482_DEFAULT_VALUE, - _pdn_connectivity_t3482_handler); + LOG_FUNC_IN; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; + int rc = RETURNok; + + LOG_TRACE(INFO, "ESM-PROC - Initiate PDN connectivity (pti=%d)", pti); + + if (is_standalone) { + emm_sap_t emm_sap; + emm_esm_data_t *emm_esm = &emm_sap.u.emm_esm.u.data; + /* + * Notity EMM that ESM PDU has to be forwarded to lower layers + */ + emm_sap.primitive = EMMESM_UNITDATA_REQ; + emm_sap.u.emm_esm.ueid = user->ueid; + emm_esm->msg.length = msg->length; + emm_esm->msg.value = msg->value; + rc = emm_sap_send(user, &emm_sap); + + if (rc != RETURNerror) { + /* Start T3482 retransmission timer */ + rc = esm_pt_start_timer(user, pti, msg, T3482_DEFAULT_VALUE, + _pdn_connectivity_t3482_handler); + } } - } - if (rc != RETURNerror) { - /* Set the procedure transaction state to PENDING */ - rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_PENDING); + if (rc != RETURNerror) { + /* Set the procedure transaction state to PENDING */ + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_PENDING); - if (rc != RETURNok) { - /* The procedure transaction was already in PENDING state */ - LOG_TRACE(WARNING, "ESM-PROC - PTI %d was already PENDING", pti); + if (rc != RETURNok) { + /* The procedure transaction was already in PENDING state */ + LOG_TRACE(WARNING, "ESM-PROC - PTI %d was already PENDING", pti); + } } - } - LOG_FUNC_RETURN(rc); + LOG_FUNC_RETURN(rc); } /**************************************************************************** @@ -351,73 +351,73 @@ int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_typ const OctetString *pdn_addr, const OctetString *apn, int *esm_cause) { - LOG_FUNC_IN; - esm_data_t *esm_data = user->esm_data; - esm_pt_data_t *esm_pt_data = user->esm_pt_data; - int rc; - int pid = RETURNerror; - char apn_first_char[4]; - - LOG_VAR(char, str[128]); - - if (isprint(apn->value[0])) { - apn_first_char[0] = '\0'; - } else { - sprintf (apn_first_char, "%02X", apn->value[0]); - } - - LOG_TRACE(INFO, "ESM-PROC - PDN connectivity accepted by the network " - "(pti=%d) APN = %s\"%s\", IP address = %s", pti, apn_first_char, isprint(apn->value[0]) ? &apn->value[0] : &apn->value[1], - (pdn_type == ESM_PDN_TYPE_IPV4)? esm_data_get_ipv4_addr(pdn_addr, str) : - (pdn_type == ESM_PDN_TYPE_IPV6)? esm_data_get_ipv6_addr(pdn_addr, str) : - esm_data_get_ipv4v6_addr(pdn_addr, str)); - - /* Stop T3482 timer if running */ - esm_pt_stop_timer(esm_pt_data, pti); - /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); - - if (rc != RETURNok) { - /* The procedure transaction was already in INACTIVE state - * as the request may have already been accepted; consider - * this request message with same PTI as a network re- - * transmission */ - LOG_TRACE(WARNING, "ESM-PROC - PTI %d network retransmission", pti); - *esm_cause = ESM_CAUSE_PTI_ALREADY_IN_USE; - } else { - /* XXX - 3GPP TS 24.301, section 6.5.1.3 and 7.3.1 - * The UE should ensure that the procedure transaction identity - * (PTI) assigned to this procedure is not released immediately. - * While the PTI value is not released, the UE regards any received - * ACTIVATE DEFAULT EPS BEARER CONTEXT REQUEST message with the same - * PTI value as a network retransmission. - * The way to achieve this is implementation dependent. - */ + LOG_FUNC_IN; + esm_data_t *esm_data = user->esm_data; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; + int rc; + int pid = RETURNerror; + char apn_first_char[4]; - /* Check whether a PDN connection exists to this APN */ - pid = _pdn_connectivity_find_pdn(esm_data, apn, pdn_type); + LOG_VAR(char, str[128]); - if (pid < 0) { - /* No any PDN connection has been defined to establish connectivity - * to this APN */ - LOG_TRACE(WARNING, "ESM-PROC - PDN connection entry for " - "APN \"%s\" (type=%d) not found", apn->value, pdn_type); - *esm_cause = ESM_CAUSE_UNKNOWN_ACCESS_POINT_NAME; - LOG_FUNC_RETURN(RETURNerror); + if (isprint(apn->value[0])) { + apn_first_char[0] = '\0'; + } else { + sprintf (apn_first_char, "%02X", apn->value[0]); } - /* Update the PDN connection */ - rc = _pdn_connectivity_update(esm_data, pid, apn, pdn_type, pdn_addr, *esm_cause); + LOG_TRACE(INFO, "ESM-PROC - PDN connectivity accepted by the network " + "(pti=%d) APN = %s\"%s\", IP address = %s", pti, apn_first_char, isprint(apn->value[0]) ? &apn->value[0] : &apn->value[1], + (pdn_type == ESM_PDN_TYPE_IPV4)? esm_data_get_ipv4_addr(pdn_addr, str) : + (pdn_type == ESM_PDN_TYPE_IPV6)? esm_data_get_ipv6_addr(pdn_addr, str) : + esm_data_get_ipv4v6_addr(pdn_addr, str)); + + /* Stop T3482 timer if running */ + esm_pt_stop_timer(esm_pt_data, pti); + /* Set the procedure transaction state to INACTIVE */ + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); if (rc != RETURNok) { - LOG_TRACE(WARNING, "ESM-PROC - Failed to update PDN connection " - "(pid=%d)", pid); - *esm_cause = ESM_CAUSE_REQUEST_REJECTED_UNSPECIFIED; - LOG_FUNC_RETURN(RETURNerror); + /* The procedure transaction was already in INACTIVE state + * as the request may have already been accepted; consider + * this request message with same PTI as a network re- + * transmission */ + LOG_TRACE(WARNING, "ESM-PROC - PTI %d network retransmission", pti); + *esm_cause = ESM_CAUSE_PTI_ALREADY_IN_USE; + } else { + /* XXX - 3GPP TS 24.301, section 6.5.1.3 and 7.3.1 + * The UE should ensure that the procedure transaction identity + * (PTI) assigned to this procedure is not released immediately. + * While the PTI value is not released, the UE regards any received + * ACTIVATE DEFAULT EPS BEARER CONTEXT REQUEST message with the same + * PTI value as a network retransmission. + * The way to achieve this is implementation dependent. + */ + + /* Check whether a PDN connection exists to this APN */ + pid = _pdn_connectivity_find_pdn(esm_data, apn, pdn_type); + + if (pid < 0) { + /* No any PDN connection has been defined to establish connectivity + * to this APN */ + LOG_TRACE(WARNING, "ESM-PROC - PDN connection entry for " + "APN \"%s\" (type=%d) not found", apn->value, pdn_type); + *esm_cause = ESM_CAUSE_UNKNOWN_ACCESS_POINT_NAME; + LOG_FUNC_RETURN(RETURNerror); + } + + /* Update the PDN connection */ + rc = _pdn_connectivity_update(esm_data, pid, apn, pdn_type, pdn_addr, *esm_cause); + + if (rc != RETURNok) { + LOG_TRACE(WARNING, "ESM-PROC - Failed to update PDN connection " + "(pid=%d)", pid); + *esm_cause = ESM_CAUSE_REQUEST_REJECTED_UNSPECIFIED; + LOG_FUNC_RETURN(RETURNerror); + } } - } - LOG_FUNC_RETURN (pid); + LOG_FUNC_RETURN (pid); } /**************************************************************************** @@ -444,33 +444,33 @@ int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_typ ***************************************************************************/ int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause) { - LOG_FUNC_IN; - esm_pt_data_t *esm_pt_data = user->esm_pt_data; - int rc; - - LOG_TRACE(WARNING, "ESM-PROC - PDN connectivity rejected by " - "the network (pti=%d), ESM cause = %d", pti, *esm_cause); - - /* Stop T3482 timer if running */ - (void) esm_pt_stop_timer(esm_pt_data, pti); - /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); - - if (rc != RETURNok) { - /* The procedure transaction was already in INACTIVE state */ - LOG_TRACE(WARNING, "ESM-PROC - PTI %d was already INACTIVE", pti); - *esm_cause = ESM_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE; - } else { - /* Release the procedure transaction identity */ - rc = esm_pt_release(user->esm_pt_data, pti); + LOG_FUNC_IN; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; + int rc; + + LOG_TRACE(WARNING, "ESM-PROC - PDN connectivity rejected by " + "the network (pti=%d), ESM cause = %d", pti, *esm_cause); + + /* Stop T3482 timer if running */ + (void) esm_pt_stop_timer(esm_pt_data, pti); + /* Set the procedure transaction state to INACTIVE */ + rc = esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); if (rc != RETURNok) { - LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); - *esm_cause = ESM_CAUSE_REQUEST_REJECTED_UNSPECIFIED; + /* The procedure transaction was already in INACTIVE state */ + LOG_TRACE(WARNING, "ESM-PROC - PTI %d was already INACTIVE", pti); + *esm_cause = ESM_CAUSE_MESSAGE_TYPE_NOT_COMPATIBLE; + } else { + /* Release the procedure transaction identity */ + rc = esm_pt_release(user->esm_pt_data, pti); + + if (rc != RETURNok) { + LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); + *esm_cause = ESM_CAUSE_REQUEST_REJECTED_UNSPECIFIED; + } } - } - LOG_FUNC_RETURN(rc); + LOG_FUNC_RETURN(rc); } /**************************************************************************** @@ -495,22 +495,22 @@ int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause) ***************************************************************************/ int esm_proc_pdn_connectivity_complete(nas_user_t *user) { - LOG_FUNC_IN; - esm_pt_data_t *esm_pt_data = user->esm_pt_data; - int rc = RETURNerror; + LOG_FUNC_IN; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; + int rc = RETURNerror; - LOG_TRACE(INFO, "ESM-PROC - PDN connectivity complete"); + LOG_TRACE(INFO, "ESM-PROC - PDN connectivity complete"); - /* Get the procedure transaction identity assigned to the PDN connection - * entry which is still pending in the inactive state */ - int pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_INACTIVE); + /* Get the procedure transaction identity assigned to the PDN connection + * entry which is still pending in the inactive state */ + int pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_INACTIVE); - if (pti != ESM_PT_UNASSIGNED) { - /* Release the procedure transaction identity */ - rc = esm_pt_release(esm_pt_data, pti); - } + if (pti != ESM_PT_UNASSIGNED) { + /* Release the procedure transaction identity */ + rc = esm_pt_release(esm_pt_data, pti); + } - LOG_FUNC_RETURN(rc); + LOG_FUNC_RETURN(rc); } /**************************************************************************** @@ -536,40 +536,40 @@ int esm_proc_pdn_connectivity_complete(nas_user_t *user) ***************************************************************************/ int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending) { - LOG_FUNC_IN; - esm_pt_data_t *esm_pt_data = user->esm_pt_data; - int rc; - int pti; - - LOG_TRACE(WARNING, "ESM-PROC - PDN connectivity failure in state %s", - (is_pending)? "PENDING" : "INACTIVE"); - - if (is_pending) { - /* Get the procedure transaction identity assigned to the pending PDN - * connection entry */ - pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_PENDING); - - if (pti == ESM_PT_UNASSIGNED) { - LOG_TRACE(ERROR, "ESM-PROC - No procedure transaction is PENDING"); - return (RETURNerror); - } + LOG_FUNC_IN; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; + int rc; + int pti; + + LOG_TRACE(WARNING, "ESM-PROC - PDN connectivity failure in state %s", + (is_pending)? "PENDING" : "INACTIVE"); + + if (is_pending) { + /* Get the procedure transaction identity assigned to the pending PDN + * connection entry */ + pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_PENDING); + + if (pti == ESM_PT_UNASSIGNED) { + LOG_TRACE(ERROR, "ESM-PROC - No procedure transaction is PENDING"); + return (RETURNerror); + } - /* Set the procedure transaction state to INACTIVE */ - (void) esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); - } else { - /* Get the procedure transaction identity assigned to the PDN - * connection entry which is still pending in the inactive state */ - pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_INACTIVE); - } + /* Set the procedure transaction state to INACTIVE */ + (void) esm_pt_set_status(esm_pt_data, pti, ESM_PT_INACTIVE); + } else { + /* Get the procedure transaction identity assigned to the PDN + * connection entry which is still pending in the inactive state */ + pti = esm_pt_get_pending_pti(esm_pt_data, ESM_PT_INACTIVE); + } - /* Release the procedure transaction identity */ - rc = esm_pt_release(esm_pt_data, pti); + /* Release the procedure transaction identity */ + rc = esm_pt_release(esm_pt_data, pti); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); - } + if (rc != RETURNok) { + LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", pti); + } - LOG_FUNC_RETURN(rc); + LOG_FUNC_RETURN(rc); } @@ -607,62 +607,62 @@ int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending) ** Others: None ** ** ** ***************************************************************************/ -// FIXME +// FIXME static void *_pdn_connectivity_t3482_handler(void *args) { - LOG_FUNC_IN; - - int rc; - - /* Get retransmission timer parameters data */ - esm_pt_timer_data_t *data = args; - nas_user_t *user = data->user; - esm_pt_data_t *esm_pt_data = user->esm_pt_data; - - /* Increment the retransmission counter */ - data->count += 1; - - LOG_TRACE(WARNING, "ESM-PROC - T3482 timer expired (pti=%d), " - "retransmission counter = %d", data->pti, data->count); - - if (data->count < ESM_PDN_CONNECTIVITY_COUNTER_MAX) { - emm_sap_t emm_sap; - emm_esm_data_t *emm_esm = &emm_sap.u.emm_esm.u.data; - /* - * Notify EMM that the PDN connectivity request message - * has to be sent again - */ - emm_sap.primitive = EMMESM_UNITDATA_REQ; - emm_sap.u.emm_esm.ueid = user->ueid; - emm_esm->msg.length = data->msg.length; - emm_esm->msg.value = data->msg.value; - rc = emm_sap_send(user, &emm_sap); - - if (rc != RETURNerror) { - /* Restart the timer T3482 */ - rc = esm_pt_start_timer(user, data->pti, &data->msg, T3482_DEFAULT_VALUE, - _pdn_connectivity_t3482_handler); - } - } else { - /* Set the procedure transaction state to INACTIVE */ - rc = esm_pt_set_status(esm_pt_data, data->pti, ESM_PT_INACTIVE); - - if (rc != RETURNok) { - /* The procedure transaction was already in INACTIVE state */ - LOG_TRACE(WARNING, "ESM-PROC - PTI %d was already INACTIVE", - data->pti); + LOG_FUNC_IN; + + int rc; + + /* Get retransmission timer parameters data */ + esm_pt_timer_data_t *data = args; + nas_user_t *user = data->user; + esm_pt_data_t *esm_pt_data = user->esm_pt_data; + + /* Increment the retransmission counter */ + data->count += 1; + + LOG_TRACE(WARNING, "ESM-PROC - T3482 timer expired (pti=%d), " + "retransmission counter = %d", data->pti, data->count); + + if (data->count < ESM_PDN_CONNECTIVITY_COUNTER_MAX) { + emm_sap_t emm_sap; + emm_esm_data_t *emm_esm = &emm_sap.u.emm_esm.u.data; + /* + * Notify EMM that the PDN connectivity request message + * has to be sent again + */ + emm_sap.primitive = EMMESM_UNITDATA_REQ; + emm_sap.u.emm_esm.ueid = user->ueid; + emm_esm->msg.length = data->msg.length; + emm_esm->msg.value = data->msg.value; + rc = emm_sap_send(user, &emm_sap); + + if (rc != RETURNerror) { + /* Restart the timer T3482 */ + rc = esm_pt_start_timer(user, data->pti, &data->msg, T3482_DEFAULT_VALUE, + _pdn_connectivity_t3482_handler); + } } else { - /* Release the transaction identity assigned to this procedure */ - rc = esm_pt_release(esm_pt_data, data->pti); - - if (rc != RETURNok) { - LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", - data->pti); - } + /* Set the procedure transaction state to INACTIVE */ + rc = esm_pt_set_status(esm_pt_data, data->pti, ESM_PT_INACTIVE); + + if (rc != RETURNok) { + /* The procedure transaction was already in INACTIVE state */ + LOG_TRACE(WARNING, "ESM-PROC - PTI %d was already INACTIVE", + data->pti); + } else { + /* Release the transaction identity assigned to this procedure */ + rc = esm_pt_release(esm_pt_data, data->pti); + + if (rc != RETURNok) { + LOG_TRACE(WARNING, "ESM-PROC - Failed to release PTI %d", + data->pti); + } + } } - } - LOG_FUNC_RETURN(NULL); + LOG_FUNC_RETURN(NULL); } /* @@ -692,63 +692,63 @@ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetSt esm_proc_pdn_type_t pdn_type, int is_emergency) { - esm_pdn_t *pdn = NULL; + esm_pdn_t *pdn = NULL; - LOG_TRACE(INFO, "ESM-PROC - Create new PDN connection (pid=%d)", pid); + LOG_TRACE(INFO, "ESM-PROC - Create new PDN connection (pid=%d)", pid); - if (pid >= ESM_DATA_PDN_MAX) { - return (RETURNerror); - } else if (esm_data->pdn[pid].is_active) { - LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); - return (RETURNerror); - } - - if (esm_data->pdn[pid].data != NULL) { - /* Update existing non-active PDN connection */ - pdn = esm_data->pdn[pid].data; - } else { - /* Create new PDN connection */ - pdn = (esm_pdn_t *)malloc(sizeof(esm_pdn_t)); - - if (pdn == NULL) { - LOG_TRACE(WARNING, "ESM-PROC - " - "Failed to create new PDN connection"); - return (RETURNerror); + if (pid >= ESM_DATA_PDN_MAX) { + return (RETURNerror); + } else if (esm_data->pdn[pid].is_active) { + LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); + return (RETURNerror); } - memset(pdn, 0, sizeof(esm_pdn_t)); - /* Increment the number of PDN connections */ - esm_data->n_pdns += 1; - /* Set the PDN connection identifier */ - esm_data->pdn[pid].pid = pid; - /* Reset the PDN connection active indicator */ - esm_data->pdn[pid].is_active = FALSE; - /* Setup the PDN connection data */ - esm_data->pdn[pid].data = pdn; - } - - /* Update the PDN connection data */ - pdn->is_emergency = is_emergency; - - if ( apn && (apn->length > 0) ) { - if (pdn->apn.length > 0) { - free(pdn->apn.value); - pdn->apn.length = 0; + if (esm_data->pdn[pid].data != NULL) { + /* Update existing non-active PDN connection */ + pdn = esm_data->pdn[pid].data; + } else { + /* Create new PDN connection */ + pdn = (esm_pdn_t *)malloc(sizeof(esm_pdn_t)); + + if (pdn == NULL) { + LOG_TRACE(WARNING, "ESM-PROC - " + "Failed to create new PDN connection"); + return (RETURNerror); + } + + memset(pdn, 0, sizeof(esm_pdn_t)); + /* Increment the number of PDN connections */ + esm_data->n_pdns += 1; + /* Set the PDN connection identifier */ + esm_data->pdn[pid].pid = pid; + /* Reset the PDN connection active indicator */ + esm_data->pdn[pid].is_active = FALSE; + /* Setup the PDN connection data */ + esm_data->pdn[pid].data = pdn; } - pdn->apn.value = (uint8_t *)malloc(apn->length + 1); + /* Update the PDN connection data */ + pdn->is_emergency = is_emergency; + + if ( apn && (apn->length > 0) ) { + if (pdn->apn.length > 0) { + free(pdn->apn.value); + pdn->apn.length = 0; + } + + pdn->apn.value = (uint8_t *)malloc(apn->length + 1); - if (pdn->apn.value) { - pdn->apn.length = apn->length; - memcpy(pdn->apn.value, apn->value, apn->length); - pdn->apn.value[pdn->apn.length] = '\0'; + if (pdn->apn.value) { + pdn->apn.length = apn->length; + memcpy(pdn->apn.value, apn->value, apn->length); + pdn->apn.value[pdn->apn.length] = '\0'; + } } - } - pdn->type = pdn_type; - pdn->addr_realloc = FALSE; + pdn->type = pdn_type; + pdn->addr_realloc = FALSE; - return (RETURNok); + return (RETURNok); } /**************************************************************************** @@ -772,75 +772,75 @@ static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetSt const OctetString *pdn_addr, int esm_cause) { - LOG_TRACE(INFO, "ESM-PROC - Update PDN connection (pid=%d)", pid); + LOG_TRACE(INFO, "ESM-PROC - Update PDN connection (pid=%d)", pid); - if (pid >= ESM_DATA_PDN_MAX) { - return (RETURNerror); - } else if (pid != esm_data->pdn[pid].pid) { - LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier is not valid"); - return (RETURNerror); - } else if (esm_data->pdn[pid].data == NULL) { - LOG_TRACE(ERROR, "ESM-PROC - PDN connection has not been allocated"); - return (RETURNerror); - } else if (esm_data->pdn[pid].is_active) { - LOG_TRACE(WARNING, "ESM-PROC - Active %s PDN connection to %s already " - "exists", (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? - "IPv6" : "IPv4", esm_data->pdn[pid].data->apn.value); - return (RETURNerror); - } + if (pid >= ESM_DATA_PDN_MAX) { + return (RETURNerror); + } else if (pid != esm_data->pdn[pid].pid) { + LOG_TRACE(ERROR, "ESM-PROC - PDN connection identifier is not valid"); + return (RETURNerror); + } else if (esm_data->pdn[pid].data == NULL) { + LOG_TRACE(ERROR, "ESM-PROC - PDN connection has not been allocated"); + return (RETURNerror); + } else if (esm_data->pdn[pid].is_active) { + LOG_TRACE(WARNING, "ESM-PROC - Active %s PDN connection to %s already " + "exists", (esm_data->pdn[pid].data->type != ESM_PDN_TYPE_IPV4)? + "IPv6" : "IPv4", esm_data->pdn[pid].data->apn.value); + return (RETURNerror); + } - /* Get the PDN connection */ - esm_pdn_t *pdn = esm_data->pdn[pid].data; + /* Get the PDN connection */ + esm_pdn_t *pdn = esm_data->pdn[pid].data; - /* Setup the Access Point Name value */ - if ( apn && (apn->length > 0) ) { - if (pdn->apn.length > 0) { - free(pdn->apn.value); - pdn->apn.length = 0; - } + /* Setup the Access Point Name value */ + if ( apn && (apn->length > 0) ) { + if (pdn->apn.length > 0) { + free(pdn->apn.value); + pdn->apn.length = 0; + } - pdn->apn.value = (uint8_t *)malloc(apn->length + 1); + pdn->apn.value = (uint8_t *)malloc(apn->length + 1); - if (pdn->apn.value) { - pdn->apn.length = apn->length; - memcpy(pdn->apn.value, apn->value, apn->length); - pdn->apn.value[pdn->apn.length] = '\0'; + if (pdn->apn.value) { + pdn->apn.length = apn->length; + memcpy(pdn->apn.value, apn->value, apn->length); + pdn->apn.value[pdn->apn.length] = '\0'; + } } - } - /* Setup the IP address allocated by the network */ - if ( pdn_addr && (pdn_addr->length > 0) ) { - int length = ((pdn_addr->length < ESM_DATA_IP_ADDRESS_SIZE) ? - pdn_addr->length : ESM_DATA_IP_ADDRESS_SIZE); - memcpy(pdn->ip_addr, pdn_addr->value, length); - pdn->type = pdn_type; - } - - /* - * 3GPP TS 24.301, section 6.2.2 - * Update the address re-allocation indicator - */ - if (esm_cause == ESM_CAUSE_SINGLE_ADDRESS_BEARERS_ONLY_ALLOWED) { - /* The UE requested IPv4 or IPv6 address and the network allows - * single addressing per bearer: - * The UE should subsequently request another PDN connection for - * the other IP version using the UE requested PDN connectivity - * procedure to the same APN with a single address PDN type - * (IPv4 or IPv6) other than the one already activated */ - pdn->addr_realloc = TRUE; - } else if ( (esm_cause == ESM_CAUSE_PDN_TYPE_IPV4_ONLY_ALLOWED) || - (esm_cause == ESM_CAUSE_PDN_TYPE_IPV6_ONLY_ALLOWED) ) { - /* The UE requested IPv4 or IPv6 address and the network allows - * IPv4 or IPv6 PDN address only: - * The UE shall not subsequently initiate another UE requested - * PDN connectivity procedure to the same APN to obtain a PDN - * type different from the one allowed by the network */ - pdn->addr_realloc = FALSE; - } else if (pdn_type != ESM_PDN_TYPE_IPV4V6) { - pdn->addr_realloc = TRUE; - } + /* Setup the IP address allocated by the network */ + if ( pdn_addr && (pdn_addr->length > 0) ) { + int length = ((pdn_addr->length < ESM_DATA_IP_ADDRESS_SIZE) ? + pdn_addr->length : ESM_DATA_IP_ADDRESS_SIZE); + memcpy(pdn->ip_addr, pdn_addr->value, length); + pdn->type = pdn_type; + } + + /* + * 3GPP TS 24.301, section 6.2.2 + * Update the address re-allocation indicator + */ + if (esm_cause == ESM_CAUSE_SINGLE_ADDRESS_BEARERS_ONLY_ALLOWED) { + /* The UE requested IPv4 or IPv6 address and the network allows + * single addressing per bearer: + * The UE should subsequently request another PDN connection for + * the other IP version using the UE requested PDN connectivity + * procedure to the same APN with a single address PDN type + * (IPv4 or IPv6) other than the one already activated */ + pdn->addr_realloc = TRUE; + } else if ( (esm_cause == ESM_CAUSE_PDN_TYPE_IPV4_ONLY_ALLOWED) || + (esm_cause == ESM_CAUSE_PDN_TYPE_IPV6_ONLY_ALLOWED) ) { + /* The UE requested IPv4 or IPv6 address and the network allows + * IPv4 or IPv6 PDN address only: + * The UE shall not subsequently initiate another UE requested + * PDN connectivity procedure to the same APN to obtain a PDN + * type different from the one allowed by the network */ + pdn->addr_realloc = FALSE; + } else if (pdn_type != ESM_PDN_TYPE_IPV4V6) { + pdn->addr_realloc = TRUE; + } - return (RETURNok); + return (RETURNok); } /**************************************************************************** @@ -861,42 +861,42 @@ static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetSt ***************************************************************************/ static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid) { - int pti = ESM_PT_UNASSIGNED; - - if (pid < ESM_DATA_PDN_MAX) { - if (pid != esm_data->pdn[pid].pid) { - LOG_TRACE(ERROR, - "ESM-PROC - PDN connection identifier is not valid"); - } else if (esm_data->pdn[pid].data == NULL) { - LOG_TRACE(ERROR, - "ESM-PROC - PDN connection has not been allocated"); - } else if (esm_data->pdn[pid].is_active) { - LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); - } else { - /* Get the identity of the procedure transaction that created - * the PDN connection */ - pti = esm_data->pdn[pid].data->pti; + int pti = ESM_PT_UNASSIGNED; + + if (pid < ESM_DATA_PDN_MAX) { + if (pid != esm_data->pdn[pid].pid) { + LOG_TRACE(ERROR, + "ESM-PROC - PDN connection identifier is not valid"); + } else if (esm_data->pdn[pid].data == NULL) { + LOG_TRACE(ERROR, + "ESM-PROC - PDN connection has not been allocated"); + } else if (esm_data->pdn[pid].is_active) { + LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); + } else { + /* Get the identity of the procedure transaction that created + * the PDN connection */ + pti = esm_data->pdn[pid].data->pti; + } } - } - if (pti != ESM_PT_UNASSIGNED) { - /* Decrement the number of PDN connections */ - esm_data->n_pdns -= 1; - /* Set the PDN connection as available */ - esm_data->pdn[pid].pid = -1; + if (pti != ESM_PT_UNASSIGNED) { + /* Decrement the number of PDN connections */ + esm_data->n_pdns -= 1; + /* Set the PDN connection as available */ + esm_data->pdn[pid].pid = -1; + + /* Release allocated PDN connection data */ + if (esm_data->pdn[pid].data->apn.length > 0) { + free(esm_data->pdn[pid].data->apn.value); + } - /* Release allocated PDN connection data */ - if (esm_data->pdn[pid].data->apn.length > 0) { - free(esm_data->pdn[pid].data->apn.value); + free(esm_data->pdn[pid].data); + esm_data->pdn[pid].data = NULL; + LOG_TRACE(WARNING, "ESM-PROC - PDN connection %d released", pid); } - free(esm_data->pdn[pid].data); - esm_data->pdn[pid].data = NULL; - LOG_TRACE(WARNING, "ESM-PROC - PDN connection %d released", pid); - } - - /* Return the procedure transaction identity */ - return (pti); + /* Return the procedure transaction identity */ + return (pti); } /**************************************************************************** @@ -916,24 +916,24 @@ static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid) ***************************************************************************/ static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti) { - if (pid < ESM_DATA_PDN_MAX) { - if (pid != esm_data->pdn[pid].pid) { - LOG_TRACE(ERROR, - "ESM-PROC - PDN connection identifier is not valid"); - } else if (esm_data->pdn[pid].data == NULL) { - LOG_TRACE(ERROR, - "ESM-PROC - PDN connection has not been allocated"); - } else if (esm_data->pdn[pid].is_active) { - LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); - } else { - /* Update the identity of the procedure transaction assigned to - * the PDN connection */ - esm_data->pdn[pid].data->pti = pti; - return (RETURNok); + if (pid < ESM_DATA_PDN_MAX) { + if (pid != esm_data->pdn[pid].pid) { + LOG_TRACE(ERROR, + "ESM-PROC - PDN connection identifier is not valid"); + } else if (esm_data->pdn[pid].data == NULL) { + LOG_TRACE(ERROR, + "ESM-PROC - PDN connection has not been allocated"); + } else if (esm_data->pdn[pid].is_active) { + LOG_TRACE(ERROR, "ESM-PROC - PDN connection is active"); + } else { + /* Update the identity of the procedure transaction assigned to + * the PDN connection */ + esm_data->pdn[pid].data->pti = pti; + return (RETURNok); + } } - } - return (RETURNerror); + return (RETURNerror); } /**************************************************************************** @@ -953,26 +953,26 @@ static int _pdn_connectivity_set_pti(esm_data_t *esm_data, int pid, int pti) ***************************************************************************/ static int _pdn_connectivity_find_apn(esm_data_t *esm_data, const OctetString *apn) { - int i; + int i; - for (i = 0; i < ESM_DATA_PDN_MAX; i++) { - if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) { - if (esm_data->pdn[i].data->apn.length != apn->length) { - continue; - } + for (i = 0; i < ESM_DATA_PDN_MAX; i++) { + if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) { + if (esm_data->pdn[i].data->apn.length != apn->length) { + continue; + } - if (memcmp(esm_data->pdn[i].data->apn.value, - apn->value, apn->length) != 0) { - continue; - } + if (memcmp(esm_data->pdn[i].data->apn.value, + apn->value, apn->length) != 0) { + continue; + } - /* PDN entry found */ - break; + /* PDN entry found */ + break; + } } - } - /* Return the identifier of the PDN connection */ - return (esm_data->pdn[i].pid); + /* Return the identifier of the PDN connection */ + return (esm_data->pdn[i].pid); } /**************************************************************************** @@ -994,35 +994,35 @@ static int _pdn_connectivity_find_apn(esm_data_t *esm_data, const OctetString *a static int _pdn_connectivity_find_pdn(esm_data_t *esm_data, const OctetString *apn, const esm_proc_pdn_type_t pdn_type) { - int i; - - for (i = 0; i < ESM_DATA_PDN_MAX; i++) { - if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) { - /* PDN connection established during initial network attachment */ - if (esm_data->pdn[i].data->apn.length == 0) { - break; - } - - /* Subsequent PDN connection established for the specified APN */ - if (esm_data->pdn[i].data->apn.length != apn->length) { - continue; - } - - if (memcmp(esm_data->pdn[i].data->apn.value, - apn->value, apn->length) != 0) { - continue; - } - - if (esm_data->pdn[i].data->type == ESM_PDN_TYPE_IPV4V6) { - break; - } - - if (esm_data->pdn[i].data->type == pdn_type) { - break; - } + int i; + + for (i = 0; i < ESM_DATA_PDN_MAX; i++) { + if ( (esm_data->pdn[i].pid != -1) && esm_data->pdn[i].data ) { + /* PDN connection established during initial network attachment */ + if (esm_data->pdn[i].data->apn.length == 0) { + break; + } + + /* Subsequent PDN connection established for the specified APN */ + if (esm_data->pdn[i].data->apn.length != apn->length) { + continue; + } + + if (memcmp(esm_data->pdn[i].data->apn.value, + apn->value, apn->length) != 0) { + continue; + } + + if (esm_data->pdn[i].data->type == ESM_PDN_TYPE_IPV4V6) { + break; + } + + if (esm_data->pdn[i].data->type == pdn_type) { + break; + } + } } - } - /* Return the identifier of the PDN connection */ - return (esm_data->pdn[i].pid); + /* Return the identifier of the PDN connection */ + return (esm_data->pdn[i].pid); } diff --git a/openair3/NAS/UE/ESM/esm_ebr.h b/openair3/NAS/UE/ESM/esm_ebr.h index dece5c3645bfe0d4218a65e0eb99ee3fc709bf0e..6de4a048a49ef7b32bc073a00a90b3df373a72fe 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.h +++ b/openair3/NAS/UE/ESM/esm_ebr.h @@ -45,7 +45,7 @@ Description Defines functions used to handle state of EPS bearer contexts #include "esmData.h" #include "nas_timer.h" -#include "user_defs.h" +#include "../user_defs.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index 7404cd8b8a83a751e21fad46eca07033e41afcac..cd493dd09e54466cf784b0ec675eac917dc5e68e 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -48,22 +48,17 @@ Description Defines functions used to handle EPS bearer contexts. #include "emm_sap.h" #include "system.h" - -#if defined(ENABLE_ITTI) -# include "assertions.h" -#endif - +#include "assertions.h" +#include "pdcp.h" +#include "nfapi/oai_integration/vendor_ext.h" #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> -#ifdef PDCP_USE_NETLINK #ifdef UESIM_EXPANSION #include "openairinterface5g_limits.h" extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; #endif -#endif -extern uint8_t nfapi_mode; /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -107,18 +102,13 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *, int esm_ebr_context_create( esm_data_t *esm_data, int ueid, int pid, int ebi, int is_default, - const network_qos_t *qos, const network_tft_t *tft) -{ + const network_qos_t *qos, const network_tft_t *tft) { int bid = 0; esm_data_context_t *esm_ctx = NULL; esm_pdn_t *pdn = NULL; - LOG_FUNC_IN; - esm_ctx = esm_data; - bid = ESM_DATA_EPS_BEARER_MAX; - LOG_TRACE(INFO, "ESM-PROC - Create new %s EPS bearer context (ebi=%d) " "for PDN connection (pid=%d)", (is_default)? "default" : "dedicated", ebi, pid); @@ -166,7 +156,7 @@ int esm_ebr_context_create( esm_bearer_t *ebr = (esm_bearer_t *)malloc(sizeof(esm_bearer_t)); if (ebr != NULL) { - memset(ebr, 0 , sizeof(esm_bearer_t)); + memset(ebr, 0, sizeof(esm_bearer_t)); /* Increment the total number of active EPS bearers */ esm_ctx->n_ebrs += 1; /* Increment the number of EPS bearer for this PDN connection */ @@ -207,147 +197,153 @@ int esm_ebr_context_create( // LG ADD TEMP { - char *tmp = NULL; - char ipv4_addr[INET_ADDRSTRLEN]; - //char ipv6_addr[INET6_ADDRSTRLEN]; - char *netmask = NULL; - char broadcast[INET_ADDRSTRLEN]; - struct in_addr in_addr; - char command_line[500]; - int res = -1; - - switch (pdn->type) { - case NET_PDN_TYPE_IPV4V6: - //ipv6_addr[0] = pdn->ip_addr[4]; - /* TODO? */ - - // etc - case NET_PDN_TYPE_IPV4: - // in_addr is in network byte order - in_addr.s_addr = pdn->ip_addr[0] << 24 | - ((pdn->ip_addr[1] << 16) & 0x00FF0000) | - ((pdn->ip_addr[2] << 8) & 0x0000FF00) | - ( pdn->ip_addr[3] & 0x000000FF); - - in_addr.s_addr = htonl(in_addr.s_addr); - - tmp = inet_ntoa(in_addr); - //AssertFatal(tmp , - // "error in PDN IPv4 address %x", - // in_addr.s_addr); - strcpy(ipv4_addr, tmp); - - if (IN_CLASSA(ntohl(in_addr.s_addr))) { - netmask = "255.0.0.0"; - in_addr.s_addr = pdn->ip_addr[0] << 24 | - ((255 << 16) & 0x00FF0000) | - ((255 << 8) & 0x0000FF00) | - ( 255 & 0x000000FF); - in_addr.s_addr = htonl(in_addr.s_addr); - tmp = inet_ntoa(in_addr); - // AssertFatal(tmp , - // "error in PDN IPv4 address %x", - // in_addr.s_addr); - strcpy(broadcast, tmp); - } else if (IN_CLASSB(ntohl(in_addr.s_addr))) { - netmask = "255.255.0.0"; - in_addr.s_addr = pdn->ip_addr[0] << 24 | - ((pdn->ip_addr[1] << 16) & 0x00FF0000) | - ((255 << 8) & 0x0000FF00) | - ( 255 & 0x000000FF); - in_addr.s_addr = htonl(in_addr.s_addr); - tmp = inet_ntoa(in_addr); - // AssertFatal(tmp , - // "error in PDN IPv4 address %x", - // in_addr.s_addr); - strcpy(broadcast, tmp); - } else if (IN_CLASSC(ntohl(in_addr.s_addr))) { - netmask = "255.255.255.0"; - in_addr.s_addr = pdn->ip_addr[0] << 24 | + char *tmp = NULL; + char ipv4_addr[INET_ADDRSTRLEN]; + //char ipv6_addr[INET6_ADDRSTRLEN]; + char *netmask = NULL; + char broadcast[INET_ADDRSTRLEN]; + struct in_addr in_addr; + char command_line[500]; + int res = -1; + + switch (pdn->type) { + case NET_PDN_TYPE_IPV4V6: + + //ipv6_addr[0] = pdn->ip_addr[4]; + /* TODO? */ + + // etc + case NET_PDN_TYPE_IPV4: + // in_addr is in network byte order + in_addr.s_addr = pdn->ip_addr[0] << 24 | ((pdn->ip_addr[1] << 16) & 0x00FF0000) | ((pdn->ip_addr[2] << 8) & 0x0000FF00) | - ( 255 & 0x000000FF); - in_addr.s_addr = htonl(in_addr.s_addr); - tmp = inet_ntoa(in_addr); - // AssertFatal(tmp , - // "error in PDN IPv4 address %x", - // in_addr.s_addr); - strcpy(broadcast, tmp); - } else { - netmask = "255.255.255.255"; - strcpy(broadcast, ipv4_addr); - } - - if(nfapi_mode ==3){ + ( pdn->ip_addr[3] & 0x000000FF); + in_addr.s_addr = htonl(in_addr.s_addr); + tmp = inet_ntoa(in_addr); + //AssertFatal(tmp , + // "error in PDN IPv4 address %x", + // in_addr.s_addr); + strcpy(ipv4_addr, tmp); + + if (IN_CLASSA(ntohl(in_addr.s_addr))) { + netmask = "255.0.0.0"; + in_addr.s_addr = pdn->ip_addr[0] << 24 | + ((255 << 16) & 0x00FF0000) | + ((255 << 8) & 0x0000FF00) | + ( 255 & 0x000000FF); + in_addr.s_addr = htonl(in_addr.s_addr); + tmp = inet_ntoa(in_addr); + // AssertFatal(tmp , + // "error in PDN IPv4 address %x", + // in_addr.s_addr); + strcpy(broadcast, tmp); + } else if (IN_CLASSB(ntohl(in_addr.s_addr))) { + netmask = "255.255.0.0"; + in_addr.s_addr = pdn->ip_addr[0] << 24 | + ((pdn->ip_addr[1] << 16) & 0x00FF0000) | + ((255 << 8) & 0x0000FF00) | + ( 255 & 0x000000FF); + in_addr.s_addr = htonl(in_addr.s_addr); + tmp = inet_ntoa(in_addr); + // AssertFatal(tmp , + // "error in PDN IPv4 address %x", + // in_addr.s_addr); + strcpy(broadcast, tmp); + } else if (IN_CLASSC(ntohl(in_addr.s_addr))) { + netmask = "255.255.255.0"; + in_addr.s_addr = pdn->ip_addr[0] << 24 | + ((pdn->ip_addr[1] << 16) & 0x00FF0000) | + ((pdn->ip_addr[2] << 8) & 0x0000FF00) | + ( 255 & 0x000000FF); + in_addr.s_addr = htonl(in_addr.s_addr); + tmp = inet_ntoa(in_addr); + // AssertFatal(tmp , + // "error in PDN IPv4 address %x", + // in_addr.s_addr); + strcpy(broadcast, tmp); + } else { + netmask = "255.255.255.255"; + strcpy(broadcast, ipv4_addr); + } + + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // this is for L2 FAPI simulator. // change for multiple UE's like 256UEs. // if it's made too many tables , OS may crush so we use one table. -#ifdef PDCP_USE_NETLINK + if(PDCP_USE_NETLINK) { #ifdef UESIM_EXPANSION - uint16_t inst_nic = (pdn->ip_addr[3] & 0x000000FF) - 2; - res = sprintf(command_line, - "ifconfig oip%d %s netmask %s broadcast %s up && " - "ip rule add from %s/24 table %d && " - "ip rule add to %s/24 table %d && " - "ip route add default dev oip%d table %d", - inst_nic + 1, ipv4_addr, netmask, broadcast, - ipv4_addr, 201, - ipv4_addr, 201, - inst_nic + 1, 201); - - inst_pdcp_list[inst_nic] = ueid; + uint16_t inst_nic = (pdn->ip_addr[3] & 0x000000FF) - 2; + res = sprintf(command_line, + "ifconfig %s%d %s netmask %s broadcast %s up && " + "ip rule add from %s/24 table %d && " + "ip rule add to %s/24 table %d && " + "ip route add default dev %s%d table %d", + UE_NAS_USE_TUN?"oaitun_ue":"oip", + inst_nic + 1, ipv4_addr, netmask, broadcast, + ipv4_addr, 201, + ipv4_addr, 201, + UE_NAS_USE_TUN?"oaitun_ue":"oip", + inst_nic + 1, 201); + inst_pdcp_list[inst_nic] = ueid; #else - res = sprintf(command_line, - "ifconfig oip%d %s netmask %s broadcast %s up && " - "ip rule add from %s/32 table %d && " - "ip rule add to %s/32 table %d && " - "ip route add default dev oip%d table %d", - ueid + 1, ipv4_addr, netmask, broadcast, - ipv4_addr, ueid + 201, - ipv4_addr, ueid + 201, - ueid + 1, ueid + 201); -#endif + res = sprintf(command_line, + "ifconfig %s%d %s netmask %s broadcast %s up && " + "ip rule add from %s/32 table %d && " + "ip rule add to %s/32 table %d && " + "ip route add default dev %s%d table %d", + UE_NAS_USE_TUN?"oaitun_ue":"oip", + ueid + 1, ipv4_addr, netmask, broadcast, + ipv4_addr, ueid + 201, + ipv4_addr, ueid + 201, + UE_NAS_USE_TUN?"oaitun_ue":"oip", + ueid + 1, ueid + 201); #endif - } else { - res = sprintf(command_line, - "ifconfig oip%d %s netmask %s broadcast %s up && " - "ip rule add from %s/32 table %d && " - "ip rule add to %s/32 table %d && " - "ip route add default dev oip%d table %d", - ueid + 1, ipv4_addr, netmask, broadcast, - ipv4_addr, ueid + 201, - ipv4_addr, ueid + 201, - ueid + 1, ueid + 201); - } - if ( res<0 ) { + } // PDCP_USE_NETLINK + } else { + res = sprintf(command_line, + "ifconfig %s%d %s netmask %s broadcast %s up && " + "ip rule add from %s/32 table %d && " + "ip rule add to %s/32 table %d && " + "ip route add default dev %s%d table %d", + UE_NAS_USE_TUN?"oaitun_ue":"oip", + ueid + 1, ipv4_addr, netmask, broadcast, + ipv4_addr, ueid + 201, + ipv4_addr, ueid + 201, + UE_NAS_USE_TUN?"oaitun_ue":"oip", + ueid + 1, ueid + 201); + } + + if ( res<0 ) { LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string"); - } - LOG_TRACE(INFO, "ESM-PROC - executing %s ", - command_line); - - /* Calling system() here disrupts UE's realtime processing in some cases. - * This may be because of the call to fork(), which, for some - * unidentified reason, interacts badly with other (realtime) threads. - * background_system() is a replacement mechanism relying on a - * background process that does the system() and reports result to - * the parent process (lte-softmodem, oaisim, ...). The background - * process is created very early in the life of the parent process. - * The processes interact through standard pipes. See - * common/utils/system.c for details. - */ - if (background_system(command_line) != 0) - LOG_TRACE(ERROR, "ESM-PROC - failed command '%s'", command_line); - - break; - - case NET_PDN_TYPE_IPV6: - break; - - default: - break; - } - } - // AssertFatal(0, "Forced stop in NAS UE"); + } + + LOG_TRACE(INFO, "ESM-PROC - executing %s ", + command_line); + + /* Calling system() here disrupts UE's realtime processing in some cases. + * This may be because of the call to fork(), which, for some + * unidentified reason, interacts badly with other (realtime) threads. + * background_system() is a replacement mechanism relying on a + * background process that does the system() and reports result to + * the parent process (lte-softmodem, oaisim, ...). The background + * process is created very early in the life of the parent process. + * The processes interact through standard pipes. See + * common/utils/system.c for details. + */ + if (background_system(command_line) != 0) + LOG_TRACE(ERROR, "ESM-PROC - failed command '%s'", command_line); + + break; + + case NET_PDN_TYPE_IPV6: + break; + + default: + break; + } + } + // AssertFatal(0, "Forced stop in NAS UE"); } /* Return the EPS bearer identity of the default EPS bearer @@ -382,16 +378,13 @@ int esm_ebr_context_create( ** ** ***************************************************************************/ int esm_ebr_context_release(nas_user_t *user, - int ebi, int *pid, int *bid) -{ + int ebi, int *pid, int *bid) { int found = FALSE; esm_pdn_t *pdn = NULL; esm_data_context_t *esm_ctx; esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; user_api_id_t *user_api_id = user->user_api_id; - LOG_FUNC_IN; - esm_ctx = user->esm_data; if (ebi != ESM_EBI_UNASSIGNED) { @@ -496,7 +489,6 @@ int esm_ebr_context_release(nas_user_t *user, */ for (i = 1; pdn->n_bearers > 0; i++) { if (pdn->bearer[i]) { - LOG_TRACE(WARNING, "ESM-PROC - Release EPS bearer context " "(ebi=%d)", pdn->bearer[i]->ebi); @@ -507,11 +499,9 @@ int esm_ebr_context_release(nas_user_t *user, /* Set the EPS bearer context state to INACTIVE */ esm_ebr_set_status(user_api_id, esm_ebr_data, pdn->bearer[i]->ebi, - ESM_EBR_INACTIVE, TRUE); - + ESM_EBR_INACTIVE, TRUE); /* Release EPS bearer data */ esm_ebr_release(esm_ebr_data, pdn->bearer[i]->ebi); - // esm_ebr_release() /* Release dedicated EPS bearer data */ free(pdn->bearer[i]); @@ -533,7 +523,6 @@ int esm_ebr_context_release(nas_user_t *user, } } - /* 3GPP TS 24.301, section 6.4.4.6 * If the UE locally deactivated all EPS bearer contexts, the UE * shall perform a local detach and enter state EMM-DEREGISTERED. @@ -582,10 +571,8 @@ int esm_ebr_context_release(nas_user_t *user, ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi) -{ +int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi) { LOG_FUNC_IN; - int pid; for (pid = 0; pid < ESM_DATA_PDN_MAX; pid++) { @@ -633,10 +620,8 @@ int esm_ebr_context_get_pid(esm_data_t *esm_data, int ebi) ***************************************************************************/ int esm_ebr_context_check_tft(esm_data_t *esm_data, int pid, int ebi, const network_tft_t *tft, - esm_ebr_context_tft_t operation) -{ + esm_ebr_context_tft_t operation) { LOG_FUNC_IN; - int rc = RETURNerror; int i; @@ -702,8 +687,7 @@ int esm_ebr_context_check_tft(esm_data_t *esm_data, int pid, int ebi, ** ** ***************************************************************************/ static int _esm_ebr_context_check_identifiers(const network_tft_t *tft1, - const network_tft_t *tft2) -{ + const network_tft_t *tft2) { int i; int j; @@ -744,8 +728,7 @@ static int _esm_ebr_context_check_identifiers(const network_tft_t *tft1, ** ** ***************************************************************************/ static int _esm_ebr_context_check_precedence(const network_tft_t *tft1, - const network_tft_t *tft2) -{ + const network_tft_t *tft2) { int i; int j; diff --git a/openair3/NAS/UE/nas_itti_messaging.c b/openair3/NAS/UE/nas_itti_messaging.c index 0c5a2fec1fa67f828a1b13292d0d1473f1352e33..55566700d7bb513eca99e64c295caa6c46d40672 100644 --- a/openair3/NAS/UE/nas_itti_messaging.c +++ b/openair3/NAS/UE/nas_itti_messaging.c @@ -27,8 +27,9 @@ # define TASK_ORIGIN TASK_NAS_UE + #if (defined(ENABLE_NAS_UE_LOGGING) && defined(NAS_BUILT_IN_UE) ) -static const uint8_t emm_message_ids[] = { +__attribute__ ((unused)) static const uint8_t emm_message_ids[] = { ATTACH_REQUEST, ATTACH_ACCEPT, ATTACH_COMPLETE, @@ -60,7 +61,7 @@ static const uint8_t emm_message_ids[] = { CS_SERVICE_NOTIFICATION, }; -static const uint8_t esm_message_ids[] = { +__attribute__ ((unused)) static const uint8_t esm_message_ids[] = { ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST, ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT, ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT, diff --git a/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py b/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py index 4603e869a658e1f9e83ecfdd768aea47c81c4d41..b5a141349ba0fe694aa97d3bbcc74595c2b1ce29 100644 --- a/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py +++ b/openair3/S1AP/MESSAGES/ASN1/asn1tostruct.py @@ -253,15 +253,6 @@ for key in iesDefs: f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) f.write(" ANY_t *any_p);\n\n") - f.write("/* %s in iesDefs not in ieofielist.values() */\n" % (key)) - f.write("/** \\brief Compare function for %s ies.\n" % (key)) - f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) - f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower)) - f.write(" **/\n") - f.write("asn_comp_rval_t * %s_compare_%s(\n" % (fileprefix, keylowerunderscore)) - f.write(" %s_t *%s1,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) - f.write(" %s_t *%s2);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) - if len(iesDefs[key]["ies"]) == 0: continue @@ -298,13 +289,6 @@ for key in iesDefs: f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower())) f.write(" %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower)) f.write(" %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct))) - f.write("/** \\brief Compare function for %s ies.\n" % (key)) - f.write(" * \\param %s Pointer to the IES structure.\n" % (firstlower)) - f.write(" * \\param %s Pointer to the IES structure.\n" % (firstlower)) - f.write(" **/\n") - f.write("asn_comp_rval_t * %s_compare_%s(\n" % (fileprefix, firstlower.lower())) - f.write(" %sIEs_t *%s1,\n" % (asn1cStruct, firstlower)) - f.write(" %sIEs_t *%s2);\n\n" % (asn1cStruct, firstlower)) @@ -634,19 +618,19 @@ xer_encode_local(asn_TYPE_descriptor_t *td, void *sptr, mname = td->xml_tag; mlen = strlen(mname); - _i_ASN_TEXT_INDENT(0, indent); - _ASN_CALLBACK3("<", 1, mname, mlen, ">", 1); + ASN__TEXT_INDENT(0, indent); + ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); - tmper = td->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key); + tmper = td->op->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key); if(tmper.encoded == -1) return tmper; - _ASN_CALLBACK3("</", 2, mname, mlen, ">\\n", xcan); + ASN__CALLBACK3("</", 2, mname, mlen, ">\\n", xcan); er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded; - _ASN_ENCODED_OK(er); + ASN__ENCODED_OK(er); cb_failed: - _ASN_ENCODE_FAILED; + ASN__ENCODE_FAILED; } """) @@ -714,7 +698,7 @@ for (key, value) in iesDefs.items(): f.write(" cb(\" </%s>\\n\", %d, app_key);\n" % (key, len(" </%s>\n" % (key)))) f.write(" cb(\"</%s-PDU>\\n\", %d, app_key);\n" % (key, len("</%s-PDU>\n" % (key)))) - f.write(" _ASN_ENCODED_OK(er);\n") + f.write(" ASN__ENCODED_OK(er);\n") #if key not in ieofielist.values(): #f.write("cb_failed:\n") #f.write(" return er;\n") @@ -731,119 +715,6 @@ f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n" % (fileprefix, f.write("#include \"%s-ProtocolIE-ID.h\"\n\n" % (fileprefix_first_upper)) -for key in iesDefs: - if key in ieofielist.values(): - continue - structName = re.sub('ies', '', key) - asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key)) - asn1cStruct = re.sub('Item', 'List', asn1cStruct) - if asn1cStruct.rfind('_') == len(asn1cStruct) - 1: - asn1cStruct = asn1cStruct[:-1] - asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:] - firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct))) - - iesaccess = "" - if key not in ieofielist.values(): - iesaccess = "%s_ies." % (firstwordlower) - - keyName = re.sub('-', '_', key) - keyupperunderscore = keyName.upper() - # No IE to encode... - if len(iesDefs[key]["ies"]) == 0: - continue - - f.write("asn_comp_rval_t * %s_compare_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower()))) - f.write(" %s_t *%s1,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) - f.write(" %s_t *%s2) {\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key)))) - - f.write(" asn_comp_rval_t *rv = NULL;\n\n") - f.write(" asn_comp_rval_t *rv2 = NULL;\n\n") - - f.write(" assert(%s1 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))); - f.write(" assert(%s2 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', key)))); - - loop = 0 - for ie in iesDefs[key]["ies"]: - iename = re.sub('-', '_', re.sub('id-', '', ie[0])) - ienameunderscore = re.sub('-', '_', iename) - ienamefirstwordlower = lowerFirstCamelWord(iename) - ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper() - ietypeunderscore = re.sub('-', '_', ie[2]) - - if ie[3] != "mandatory": - - loop = loop + 1 - if loop == 1: - #f.write(" %s_IE_t *ie1 = NULL;\n" % (fileprefix_first_upper)) - #f.write(" %s_IE_t *ie2 = NULL;\n" % (fileprefix_first_upper)) - f.write(" if (%s1->presenceMask != %s2->presenceMask) {rv=calloc(1,sizeof(asn_comp_rval_t));rv->name = asn_DEF_%s.name;rv->structure1 = %s1;rv->structure2 = %s2;rv->err_code = COMPARE_ERR_CODE_VALUE_NULL; return rv;}\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), lowerFirstCamelWord(re.sub('-', '_', key)), ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), lowerFirstCamelWord(re.sub('-', '_', key)))) - - if ie[3] == "optional": - f.write(" /* Optional field */\n") - elif ie[3] == "conditional": - f.write(" /* Conditional field */\n") - f.write(" if (%s1->presenceMask & %s_%s_PRESENT) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore)) - - - if ie[2] in ieofielist.keys(): - f.write(" /* collection field */\n") - f.write(" rv2 = %s_compare_%s(&%s1->%s, &%s2->%s);\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) - f.write(" if(rv2) {") - f.write(" if (NULL == rv) {") - f.write(" rv = rv2;") - f.write(" } else {") - f.write(" rv2->next = rv;") - f.write(" rv = rv2;") - f.write(" }") - f.write(" rv2 = NULL;") - f.write(" }") - else: - f.write(" /* simple field */\n") - f.write(" rv2 = asn_DEF_%s.compare(&asn_DEF_%s, &%s1->%s, &asn_DEF_%s, &%s2->%s); \n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) - f.write(" if (rv2) {") - f.write(" if (NULL == rv) {") - f.write(" rv = rv2;") - f.write(" } else {") - f.write(" rv2->next = rv;") - f.write(" rv = rv2;") - f.write(" }") - f.write(" rv2 = NULL;") - f.write(" if (!rv->name) rv->name = asn_DEF_%s.name;" % (ietypeunderscore)) - f.write(" }") - - f.write(" assert(0);\n"); - f.write(" }\n\n") - - else: - if ie[2] in ieofielist.keys(): - f.write(" /* Mandatory collection field */\n") - f.write(" rv2 = %s_compare_%s(&%s1->%s, &%s2->%s);\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) - f.write(" if (rv2) {\n") - f.write(" if (NULL == rv) {\n") - f.write(" rv = rv2;\n") - f.write(" } else {\n") - f.write(" rv2->next = rv;\n") - f.write(" rv = rv2;\n") - f.write(" }\n") - f.write(" rv2 = NULL;\n") - f.write(" }\n") - - else: - f.write(" /* Mandatory simple field */\n") - f.write(" rv2 = asn_DEF_%s.compare(&asn_DEF_%s, &%s1->%s, &asn_DEF_%s, &%s2->%s);\n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower )) - f.write(" if(rv2) {\n") - f.write(" if (NULL == rv) {\n") - f.write(" rv = rv2;\n") - f.write(" } else {\n") - f.write(" rv2->next = rv;\n") - f.write(" rv = rv2;\n") - f.write(" }\n") - f.write(" rv2 = NULL;\n") - f.write(" if (!rv->name) rv->name = asn_DEF_%s.name;\n" % (ietypeunderscore)) - f.write(" }\n") - f.write(" return rv;\n") - f.write("}\n\n") - for (key, value) in iesDefs.items(): if key not in ieofielist.values(): continue @@ -859,30 +730,3 @@ for (key, value) in iesDefs.items(): break f.write("extern asn_TYPE_descriptor_t asn_DEF_%s;\n" % (ietypeunderscore)) - - f.write("asn_comp_rval_t * %s_compare_%s(\n" % (fileprefix, re.sub('-', '_', i).lower())) - f.write(" %sIEs_t *%sIEs1,\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i)))) - f.write(" %sIEs_t *%sIEs2) {\n\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i)))) - f.write(" int i;\n") - f.write(" asn_comp_rval_t *rv = NULL;\n\n") - f.write(" asn_comp_rval_t *rv2 = NULL;\n\n") - - - f.write(" assert(%sIEs1 != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', i)))); - f.write(" assert(%sIEs2 != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', i)))); - - f.write(" for (i = 0; i < %sIEs1->%s.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) - f.write(" rv2 = asn_DEF_%s.compare(&asn_DEF_%s, %sIEs1->%s.array[i], &asn_DEF_%s, %sIEs2->%s.array[i]);\n" % (ietypeunderscore, ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), ietypeunderscore, lowerFirstCamelWord(re.sub('-', '_', i)), re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))))) - f.write(" if(rv2) {") - f.write(" if (NULL == rv) {") - f.write(" rv = rv2;") - f.write(" } else {") - f.write(" rv2->next = rv;") - f.write(" rv = rv2;") - f.write(" }") - f.write(" rv2 = NULL;") - f.write(" }") - f.write(" }\n") - f.write(" return rv;\n") - f.write("}\n\n") - diff --git a/openair3/S1AP/s1ap_common.h b/openair3/S1AP/s1ap_common.h index 94b3e43bc65b8789e330f25179381e0d2de4ba47..77d03f4ae4b099471155dc774a208e432303d888 100644 --- a/openair3/S1AP/s1ap_common.h +++ b/openair3/S1AP/s1ap_common.h @@ -90,6 +90,7 @@ extern int asn1_xer_print; # define S1AP_DEBUG(x, args...) do { fprintf(stdout, "[S1AP][D]"x, ##args); } while(0) #endif + #define S1AP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \ do {\ IE_TYPE **ptr; \ @@ -102,15 +103,17 @@ extern int asn1_xer_print; break; \ } \ } \ - if (mandatory) DevAssert(ie != NULL); \ + if (ie == NULL ) { \ + S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\ + } \ + if (mandatory) DevAssert(ie != NULL); \ } while(0) - /** \brief Function callback prototype. **/ typedef int (*s1ap_message_decoded_callback)( - uint32_t assoc_id, - uint32_t stream, - S1AP_S1AP_PDU_t *pdu + uint32_t assoc_id, + uint32_t stream, + S1AP_S1AP_PDU_t *pdu ); /** \brief Handle criticality diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 9eab896d8314ae6e6b9ccb804d64d887cb548265..282e7b5f60354cff5c80bfb2e6de7970be5e65dc 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -349,6 +349,12 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { } break; + case S1AP_PATH_SWITCH_REQ: { + s1ap_eNB_path_switch_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &S1AP_PATH_SWITCH_REQ(received_msg)); + } + break; + case S1AP_UE_CONTEXT_RELEASE_COMPLETE: { s1ap_ue_context_release_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg), &S1AP_UE_CONTEXT_RELEASE_COMPLETE(received_msg)); diff --git a/openair3/S1AP/s1ap_eNB_decoder.c b/openair3/S1AP/s1ap_eNB_decoder.c index dd1dfadc23fecb583509b5275f4db15f36d06617..3eb182b159db73c3d981cd9078deebdf528f92e0 100644 --- a/openair3/S1AP/s1ap_eNB_decoder.c +++ b/openair3/S1AP/s1ap_eNB_decoder.c @@ -107,6 +107,11 @@ static int s1ap_eNB_decode_successful_outcome(S1AP_S1AP_PDU_t *pdu) { free(res.buffer); break; + case S1AP_ProcedureCode_id_PathSwitchRequest: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu); + free(res.buffer); + break; + default: S1AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n", (int)pdu->choice.successfulOutcome.procedureCode); @@ -125,6 +130,10 @@ static int s1ap_eNB_decode_unsuccessful_outcome(S1AP_S1AP_PDU_t *pdu) { res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu); free(res.buffer); break; + case S1AP_ProcedureCode_id_PathSwitchRequest: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu); + free(res.buffer); + break; default: S1AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n", diff --git a/openair3/S1AP/s1ap_eNB_encoder.c b/openair3/S1AP/s1ap_eNB_encoder.c index e282d1dd78227f3104b92fd95a89d0d5128060c3..0cd46214fc050997b06144af12deb77e4a2d3c39 100644 --- a/openair3/S1AP/s1ap_eNB_encoder.c +++ b/openair3/S1AP/s1ap_eNB_encoder.c @@ -113,6 +113,11 @@ int s1ap_eNB_encode_initiating(S1AP_S1AP_PDU_t *pdu, free(res.buffer); break; + case S1AP_ProcedureCode_id_PathSwitchRequest: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu); + free(res.buffer); + break; + default: S1AP_DEBUG("Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage.procedureCode); diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 0f7afb68f76d03d2ae832a2ce49f848db6c64504..0c3b1ee25b152c06cd76d464169e8afe95cb2494 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -94,12 +94,22 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, uint32_t stream, S1AP_S1AP_PDU_t *pdu); +static +int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, + uint32_t stream, + S1AP_S1AP_PDU_t *pdu); + +static +int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_id, + uint32_t stream, + S1AP_S1AP_PDU_t *pdu); + /* Handlers matrix. Only eNB related procedure present here */ s1ap_message_decoded_callback messages_callback[][3] = { { 0, 0, 0 }, /* HandoverPreparation */ { 0, 0, 0 }, /* HandoverResourceAllocation */ { 0, 0, 0 }, /* HandoverNotification */ - { 0, 0, 0 }, /* PathSwitchRequest */ + { 0, s1ap_eNB_handle_s1_path_switch_request_ack, s1ap_eNB_handle_s1_path_switch_request_failure }, /* PathSwitchRequest */ { 0, 0, 0 }, /* HandoverCancel */ { s1ap_eNB_handle_e_rab_setup_request, 0, 0 }, /* E_RABSetup */ { s1ap_eNB_handle_e_rab_modify_request, 0, 0 }, /* E_RABModify */ @@ -260,7 +270,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, } S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_Cause, true); + S1AP_ProtocolIE_ID_id_Cause,true); if ((ie->value.choice.Cause.present == S1AP_Cause_PR_misc) && (ie->value.choice.Cause.choice.misc == S1AP_CauseMisc_unspecified)) { @@ -300,6 +310,7 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_ServedGUMMEIs, true); + /* The list of served gummei can contain at most 8 elements. * LTE related gummei is the first element in the list, i.e with an id of 0. */ @@ -330,7 +341,7 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, } for (j = 0; j < gummei_item_p->servedGroupIDs.list.count; j++) { - S1AP_MME_Group_ID_t *mme_group_id_p; + S1AP_MME_Group_ID_t *mme_group_id_p; struct served_group_id_s *new_group_id_p; mme_group_id_p = gummei_item_p->servedGroupIDs.list.array[j]; new_group_id_p = calloc(1, sizeof(struct served_group_id_s)); @@ -355,7 +366,9 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, /* Set the capacity of this MME */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); + mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; + /* Optionaly set the mme name */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MMEname, false); @@ -404,7 +417,7 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, false); /* optional */ - if (!ie) { + if (ie != NULL) { S1AP_WARN("Received S1 Error indication MME UE S1AP ID 0x%lx\n", ie->value.choice.MME_UE_S1AP_ID); } @@ -412,7 +425,7 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, false); /* optional */ - if (!ie) { + if (ie != NULL) { S1AP_WARN("Received S1 Error indication eNB UE S1AP ID 0x%lx\n", ie->value.choice.ENB_UE_S1AP_ID); } @@ -744,17 +757,28 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, /* id-MME-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); - mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; + } else { + return -1; + } + /* id-eNB-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); - enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; - if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, - enb_ue_s1ap_id)) == NULL) { - S1AP_ERROR("[SCTP %d] Received initial context setup request for non " - "existing UE context 0x%06lx\n", assoc_id, - enb_ue_s1ap_id); + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; + + if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, + enb_ue_s1ap_id)) == NULL) { + S1AP_ERROR("[SCTP %d] Received initial context setup request for non " + "existing UE context 0x%06lx\n", assoc_id, + enb_ue_s1ap_id); + return -1; + } + } else { return -1; } @@ -771,67 +795,91 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; ue_desc_p->ue_initial_id = 0; S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).eNB_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id; + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).mme_ue_s1ap_id = ue_desc_p->mme_ue_s1ap_id; /* id-uEaggregateMaximumBitrate */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_uEaggregateMaximumBitrate, true); - asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL), - &(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_ul)); - asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL), - &(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl)); - /* id-E-RABToBeSetupListCtxtSUReq */ + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL), + &(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_ul)); + asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL), + &(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl)); + /* id-E-RABToBeSetupListCtxtSUReq */ + } else { + return -1; + } + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeSetupListCtxtSUReq, true); - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_of_e_rabs = - ie->value.choice.E_RABToBeSetupListCtxtSUReq.list.count; - - for (i = 0; i < ie->value.choice.E_RABToBeSetupListCtxtSUReq.list.count; i++) { - S1AP_E_RABToBeSetupItemCtxtSUReq_t *item_p; - item_p = &(((S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t *)ie->value.choice.E_RABToBeSetupListCtxtSUReq.list.array[i])->value.choice.E_RABToBeSetupItemCtxtSUReq); - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].e_rab_id = item_p->e_RAB_ID; - - if (item_p->nAS_PDU != NULL) { - /* Only copy NAS pdu if present */ - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.length = item_p->nAS_PDU->size; - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer = - malloc(sizeof(uint8_t) * item_p->nAS_PDU->size); - memcpy(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer, - item_p->nAS_PDU->buf, item_p->nAS_PDU->size); - S1AP_DEBUG("Received NAS message with the E_RAB setup procedure\n"); - } else { - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.length = 0; - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer = NULL; - } - /* Set the transport layer address */ - memcpy(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].sgw_addr.buffer, - item_p->transportLayerAddress.buf, item_p->transportLayerAddress.size); - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].sgw_addr.length = - item_p->transportLayerAddress.size * 8 - item_p->transportLayerAddress.bits_unused; - /* GTP tunnel endpoint ID */ - OCTET_STRING_TO_INT32(&item_p->gTP_TEID, S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].gtp_teid); - /* Set the QOS informations */ - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.qci = item_p->e_RABlevelQoSParameters.qCI; - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.priority_level = - item_p->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel; - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = - item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability; - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = - item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability; + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_of_e_rabs = + ie->value.choice.E_RABToBeSetupListCtxtSUReq.list.count; + + for (i = 0; i < ie->value.choice.E_RABToBeSetupListCtxtSUReq.list.count; i++) { + S1AP_E_RABToBeSetupItemCtxtSUReq_t *item_p; + item_p = &(((S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t *)ie->value.choice.E_RABToBeSetupListCtxtSUReq.list.array[i])->value.choice.E_RABToBeSetupItemCtxtSUReq); + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].e_rab_id = item_p->e_RAB_ID; + + if (item_p->nAS_PDU != NULL) { + /* Only copy NAS pdu if present */ + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.length = item_p->nAS_PDU->size; + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer = + malloc(sizeof(uint8_t) * item_p->nAS_PDU->size); + memcpy(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer, + item_p->nAS_PDU->buf, item_p->nAS_PDU->size); + S1AP_DEBUG("Received NAS message with the E_RAB setup procedure\n"); + } else { + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.length = 0; + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer = NULL; + } + + /* Set the transport layer address */ + memcpy(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].sgw_addr.buffer, + item_p->transportLayerAddress.buf, item_p->transportLayerAddress.size); + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].sgw_addr.length = + item_p->transportLayerAddress.size * 8 - item_p->transportLayerAddress.bits_unused; + /* GTP tunnel endpoint ID */ + OCTET_STRING_TO_INT32(&item_p->gTP_TEID, S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].gtp_teid); + /* Set the QOS informations */ + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.qci = item_p->e_RABlevelQoSParameters.qCI; + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.priority_level = + item_p->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel; + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = + item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability; + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability = + item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability; + } /* for i... */ + } else {/* ie != NULL */ + return -1; } /* id-UESecurityCapabilities */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_UESecurityCapabilities, true); - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.encryption_algorithms = - BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms = - BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); - /* id-SecurityKey : Copy the security key */ + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.encryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); + S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); + /* id-SecurityKey : Copy the security key */ + } else {/* ie != NULL */ + return -1; + } + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_SecurityKey, true); - memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, - ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); - itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, + ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); + itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); + } else {/* ie != NULL */ + return -1; + } + return 0; } @@ -859,57 +907,61 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_UE_S1AP_IDs, true); - switch (ie->value.choice.UE_S1AP_IDs.present) { - case S1AP_UE_S1AP_IDs_PR_uE_S1AP_ID_pair: - enb_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.eNB_UE_S1AP_ID; - mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; - MSC_LOG_RX_MESSAGE( - MSC_S1AP_ENB, - MSC_S1AP_MME, - NULL,0, - "0 UEContextRelease/%s eNB_ue_s1ap_id "S1AP_UE_ID_FMT" mme_ue_s1ap_id "S1AP_UE_ID_FMT" len %u", - s1ap_direction2String(pdu->present - 1), - enb_ue_s1ap_id, - mme_ue_s1ap_id); - - if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, - enb_ue_s1ap_id)) == NULL) { - S1AP_ERROR("[SCTP %d] Received UE context release command for non " - "existing UE context 0x%06lx\n", - assoc_id, - enb_ue_s1ap_id); - return -1; - } else { - MSC_LOG_TX_MESSAGE( + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + switch (ie->value.choice.UE_S1AP_IDs.present) { + case S1AP_UE_S1AP_IDs_PR_uE_S1AP_ID_pair: + enb_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.eNB_UE_S1AP_ID; + mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; + MSC_LOG_RX_MESSAGE( MSC_S1AP_ENB, - MSC_RRC_ENB, + MSC_S1AP_MME, NULL,0, - "0 S1AP_UE_CONTEXT_RELEASE_COMMAND/%d eNB_ue_s1ap_id "S1AP_UE_ID_FMT" ", - enb_ue_s1ap_id); - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); - - if (ue_desc_p->mme_ue_s1ap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode - ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id; + "0 UEContextRelease/%s eNB_ue_s1ap_id "S1AP_UE_ID_FMT" mme_ue_s1ap_id "S1AP_UE_ID_FMT" len %u", + s1ap_direction2String(pdu->present - 1), + enb_ue_s1ap_id, + mme_ue_s1ap_id); + + if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, + enb_ue_s1ap_id)) == NULL) { + S1AP_ERROR("[SCTP %d] Received UE context release command for non " + "existing UE context 0x%06lx\n", + assoc_id, + enb_ue_s1ap_id); + return -1; + } else { + MSC_LOG_TX_MESSAGE( + MSC_S1AP_ENB, + MSC_RRC_ENB, + NULL,0, + "0 S1AP_UE_CONTEXT_RELEASE_COMMAND/%d eNB_ue_s1ap_id "S1AP_UE_ID_FMT" ", + enb_ue_s1ap_id); + message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); + + if (ue_desc_p->mme_ue_s1ap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode + ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id; + } + + S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; + itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); + return 0; } - S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; - itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); - return 0; - } - - break; + break; - //#warning "TODO mapping mme_ue_s1ap_id enb_ue_s1ap_id?" + //#warning "TODO mapping mme_ue_s1ap_id enb_ue_s1ap_id?" - case S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID: - mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; - S1AP_ERROR("TO DO mapping mme_ue_s1ap_id enb_ue_s1ap_id"); - (void)mme_ue_s1ap_id; /* TODO: remove - it's to remove gcc warning about unused var */ + case S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID: + mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; + S1AP_ERROR("TO DO mapping mme_ue_s1ap_id enb_ue_s1ap_id"); + (void)mme_ue_s1ap_id; /* TODO: remove - it's to remove gcc warning about unused var */ - case S1AP_UE_S1AP_IDs_PR_NOTHING: - default: - S1AP_ERROR("S1AP_UE_CONTEXT_RELEASE_COMMAND not processed, missing info elements"); - return -1; + case S1AP_UE_S1AP_IDs_PR_NOTHING: + default: + S1AP_ERROR("S1AP_UE_CONTEXT_RELEASE_COMMAND not processed, missing info elements"); + return -1; + } + } else { + return -1; } S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container, @@ -941,11 +993,22 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, /* id-MME-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); - mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; + } else { + return -1; + } + /* id-eNB-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); - enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; + } else { + return -1; + } if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, enb_ue_s1ap_id)) == NULL) { @@ -975,51 +1038,56 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, S1AP_E_RAB_SETUP_REQ(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeSetupListBearerSUReq, true); - S1AP_E_RAB_SETUP_REQ(message_p).nb_e_rabs_tosetup = - ie->value.choice.E_RABToBeSetupListBearerSUReq.list.count; - - for (i = 0; i < ie->value.choice.E_RABToBeSetupListBearerSUReq.list.count; i++) { - S1AP_E_RABToBeSetupItemBearerSUReq_t *item_p; - item_p = &(((S1AP_E_RABToBeSetupItemBearerSUReqIEs_t *)ie->value.choice.E_RABToBeSetupListBearerSUReq.list.array[i])->value.choice.E_RABToBeSetupItemBearerSUReq); - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].e_rab_id = item_p->e_RAB_ID; - - // check for the NAS PDU - if (item_p->nAS_PDU.size > 0 ) { - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length = item_p->nAS_PDU.size; - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size); - memcpy(S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer, - item_p->nAS_PDU.buf, item_p->nAS_PDU.size); - // S1AP_INFO("received a NAS PDU with size %d (%02x.%02x)\n",S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length, item_p->nAS_PDU.buf[0], item_p->nAS_PDU.buf[1]); - } else { - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length = 0; - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = NULL; - S1AP_WARN("NAS PDU is not provided, generate a E_RAB_SETUP Failure (TBD) back to MME \n"); - // return -1; - } - /* Set the transport layer address */ - memcpy(S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.buffer, - item_p->transportLayerAddress.buf, item_p->transportLayerAddress.size); - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.length = - item_p->transportLayerAddress.size * 8 - item_p->transportLayerAddress.bits_unused; - /* S1AP_INFO("sgw addr %s len: %d (size %d, index %d)\n", - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.buffer, - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.length, - item_p->transportLayerAddress.size, i); - */ - /* GTP tunnel endpoint ID */ - OCTET_STRING_TO_INT32(&item_p->gTP_TEID, S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].gtp_teid); - /* Set the QOS informations */ - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.qci = item_p->e_RABlevelQoSParameters.qCI; - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.priority_level = - item_p->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel; - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.pre_emp_capability = - item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability; - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.pre_emp_vulnerability = - item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability; + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + S1AP_E_RAB_SETUP_REQ(message_p).nb_e_rabs_tosetup = + ie->value.choice.E_RABToBeSetupListBearerSUReq.list.count; + + for (i = 0; i < ie->value.choice.E_RABToBeSetupListBearerSUReq.list.count; i++) { + S1AP_E_RABToBeSetupItemBearerSUReq_t *item_p; + item_p = &(((S1AP_E_RABToBeSetupItemBearerSUReqIEs_t *)ie->value.choice.E_RABToBeSetupListBearerSUReq.list.array[i])->value.choice.E_RABToBeSetupItemBearerSUReq); + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].e_rab_id = item_p->e_RAB_ID; + + // check for the NAS PDU + if (item_p->nAS_PDU.size > 0 ) { + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length = item_p->nAS_PDU.size; + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size); + memcpy(S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer, + item_p->nAS_PDU.buf, item_p->nAS_PDU.size); + // S1AP_INFO("received a NAS PDU with size %d (%02x.%02x)\n",S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length, item_p->nAS_PDU.buf[0], item_p->nAS_PDU.buf[1]); + } else { + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length = 0; + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = NULL; + S1AP_WARN("NAS PDU is not provided, generate a E_RAB_SETUP Failure (TBD) back to MME \n"); + } + + /* Set the transport layer address */ + memcpy(S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.buffer, + item_p->transportLayerAddress.buf, item_p->transportLayerAddress.size); + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.length = + item_p->transportLayerAddress.size * 8 - item_p->transportLayerAddress.bits_unused; + /* S1AP_INFO("sgw addr %s len: %d (size %d, index %d)\n", + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.buffer, + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.length, + item_p->transportLayerAddress.size, i); + */ + /* GTP tunnel endpoint ID */ + OCTET_STRING_TO_INT32(&item_p->gTP_TEID, S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].gtp_teid); + /* Set the QOS informations */ + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.qci = item_p->e_RABlevelQoSParameters.qCI; + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.priority_level = + item_p->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel; + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.pre_emp_capability = + item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability; + S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.pre_emp_vulnerability = + item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability; + } /* for i... */ + + itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); + } else { + return -1; } - itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); return 0; } @@ -1063,49 +1131,59 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, /* id-UEIdentityIndexValue : convert UE Identity Index value */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PagingIEs_t, ie, container, S1AP_ProtocolIE_ID_id_UEIdentityIndexValue, true); - S1AP_PAGING_IND(message_p).ue_index_value = BIT_STRING_to_uint32(&ie->value.choice.UEIdentityIndexValue); - S1AP_DEBUG("[SCTP %d] Received Paging ue_index_value (%d)\n", - assoc_id,(uint32_t)S1AP_PAGING_IND(message_p).ue_index_value); - S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code = 0; - S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi = 0; + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + S1AP_PAGING_IND(message_p).ue_index_value = BIT_STRING_to_uint32(&ie->value.choice.UEIdentityIndexValue); + S1AP_DEBUG("[SCTP %d] Received Paging ue_index_value (%d)\n", + assoc_id,(uint32_t)S1AP_PAGING_IND(message_p).ue_index_value); + S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code = 0; + S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi = 0; + } else { + return -1; + } + /* id-UEPagingID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PagingIEs_t, ie, container, S1AP_ProtocolIE_ID_id_UEPagingID, true); - /* convert UE Paging Identity */ - if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_s_TMSI) { - S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_s_tmsi; - OCTET_STRING_TO_INT8(&ie->value.choice.UEPagingID.choice.s_TMSI.mMEC, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code); - OCTET_STRING_TO_INT32(&ie->value.choice.UEPagingID.choice.s_TMSI.m_TMSI, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi); - } else if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_iMSI) { - S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_imsi; - S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length = 0; - - for (int i = 0; i < ie->value.choice.UEPagingID.choice.iMSI.size; i++) { - S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i] = (uint8_t)(ie->value.choice.UEPagingID.choice.iMSI.buf[i] & 0x0F ); - S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length++; - S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1] = (uint8_t)((ie->value.choice.UEPagingID.choice.iMSI.buf[i]>>4) & 0x0F); - LOG_D(S1AP,"paging : i %d %d imsi %d %d \n",2*i,2*i+1,S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1]); - - if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1] == 0x0F) { - if(i != ie->value.choice.UEPagingID.choice.iMSI.size - 1) { - /* invalid paging_p->uePagingID.choise.iMSI.buffer */ - S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI error(i %d 0x0F)\n", assoc_id,i); - return -1; - } - } else { + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + /* convert UE Paging Identity */ + if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_s_TMSI) { + S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_s_tmsi; + OCTET_STRING_TO_INT8(&ie->value.choice.UEPagingID.choice.s_TMSI.mMEC, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code); + OCTET_STRING_TO_INT32(&ie->value.choice.UEPagingID.choice.s_TMSI.m_TMSI, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi); + } else if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_iMSI) { + S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_imsi; + S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length = 0; + + for (int i = 0; i < ie->value.choice.UEPagingID.choice.iMSI.size; i++) { + S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i] = (uint8_t)(ie->value.choice.UEPagingID.choice.iMSI.buf[i] & 0x0F ); S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length++; - } - } + S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1] = (uint8_t)((ie->value.choice.UEPagingID.choice.iMSI.buf[i]>>4) & 0x0F); + LOG_D(S1AP,"paging : i %d %d imsi %d %d \n",2*i,2*i+1,S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1]); + + if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1] == 0x0F) { + if(i != ie->value.choice.UEPagingID.choice.iMSI.size - 1) { + /* invalid paging_p->uePagingID.choise.iMSI.buffer */ + S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI error(i %d 0x0F)\n", assoc_id,i); + return -1; + } + } else { + S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length++; + } + } /* for i... */ - if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length >= S1AP_IMSI_LENGTH) { - /* invalid paging_p->uePagingID.choise.iMSI.size */ - S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI.size(%d) is over IMSI length(%d)\n", assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length, S1AP_IMSI_LENGTH); + if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length >= S1AP_IMSI_LENGTH) { + /* invalid paging_p->uePagingID.choise.iMSI.size */ + S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI.size(%d) is over IMSI length(%d)\n", assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length, S1AP_IMSI_LENGTH); + return -1; + } + } else { /* of if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_iMSI) */ + /* invalid paging_p->uePagingID.present */ + S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.present(%d) is unknown\n", assoc_id, ie->value.choice.UEPagingID.present); return -1; } - } else { - /* invalid paging_p->uePagingID.present */ - S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.present(%d) is unknown\n", assoc_id, ie->value.choice.UEPagingID.present); + } else { /* of ie != NULL */ return -1; } @@ -1125,14 +1203,18 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PagingIEs_t, ie, container, S1AP_ProtocolIE_ID_id_CNDomain, true); - /* id-CNDomain : convert cnDomain */ - if (ie->value.choice.CNDomain == S1AP_CNDomain_ps) { - S1AP_PAGING_IND(message_p).cn_domain = CN_DOMAIN_PS; - } else if (ie->value.choice.CNDomain == S1AP_CNDomain_cs) { - S1AP_PAGING_IND(message_p).cn_domain = CN_DOMAIN_CS; + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + /* id-CNDomain : convert cnDomain */ + if (ie->value.choice.CNDomain == S1AP_CNDomain_ps) { + S1AP_PAGING_IND(message_p).cn_domain = CN_DOMAIN_PS; + } else if (ie->value.choice.CNDomain == S1AP_CNDomain_cs) { + S1AP_PAGING_IND(message_p).cn_domain = CN_DOMAIN_CS; + } else { + /* invalid paging_p->cnDomain */ + S1AP_ERROR("[SCTP %d] Received Paging : cnDomain(%ld) is unknown\n", assoc_id, ie->value.choice.CNDomain); + return -1; + } } else { - /* invalid paging_p->cnDomain */ - S1AP_ERROR("[SCTP %d] Received Paging : cnDomain(%ld) is unknown\n", assoc_id, ie->value.choice.CNDomain); return -1; } @@ -1142,20 +1224,25 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, /* id-TAIList */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PagingIEs_t, ie, container, S1AP_ProtocolIE_ID_id_TAIList, true); - S1AP_INFO("[SCTP %d] Received Paging taiList: count %d\n", assoc_id, ie->value.choice.TAIList.list.count); - - for (int i = 0; i < ie->value.choice.TAIList.list.count; i++) { - S1AP_TAIItem_t *item_p; - item_p = &(((S1AP_TAIItemIEs_t *)ie->value.choice.TAIList.list.array[i])->value.choice.TAIItem); - TBCD_TO_MCC_MNC(&(item_p->tAI.pLMNidentity), S1AP_PAGING_IND(message_p).plmn_identity[i].mcc, - S1AP_PAGING_IND(message_p).plmn_identity[i].mnc, - S1AP_PAGING_IND(message_p).plmn_identity[i].mnc_digit_length); - OCTET_STRING_TO_INT16(&(item_p->tAI.tAC), S1AP_PAGING_IND(message_p).tac[i]); - S1AP_PAGING_IND(message_p).tai_size++; - S1AP_DEBUG("[SCTP %d] Received Paging: MCC %d, MNC %d, TAC %d\n", assoc_id, - S1AP_PAGING_IND(message_p).plmn_identity[i].mcc, - S1AP_PAGING_IND(message_p).plmn_identity[i].mnc, - S1AP_PAGING_IND(message_p).tac[i]); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + S1AP_INFO("[SCTP %d] Received Paging taiList: count %d\n", assoc_id, ie->value.choice.TAIList.list.count); + + for (int i = 0; i < ie->value.choice.TAIList.list.count; i++) { + S1AP_TAIItem_t *item_p; + item_p = &(((S1AP_TAIItemIEs_t *)ie->value.choice.TAIList.list.array[i])->value.choice.TAIItem); + TBCD_TO_MCC_MNC(&(item_p->tAI.pLMNidentity), S1AP_PAGING_IND(message_p).plmn_identity[i].mcc, + S1AP_PAGING_IND(message_p).plmn_identity[i].mnc, + S1AP_PAGING_IND(message_p).plmn_identity[i].mnc_digit_length); + OCTET_STRING_TO_INT16(&(item_p->tAI.tAC), S1AP_PAGING_IND(message_p).tac[i]); + S1AP_PAGING_IND(message_p).tai_size++; + S1AP_DEBUG("[SCTP %d] Received Paging: MCC %d, MNC %d, TAC %d\n", assoc_id, + S1AP_PAGING_IND(message_p).plmn_identity[i].mcc, + S1AP_PAGING_IND(message_p).plmn_identity[i].mnc, + S1AP_PAGING_IND(message_p).tac[i]); + } + } else { + return -1; } //paging parameter values @@ -1197,11 +1284,22 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, /* id-MME-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABModifyRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); - mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; + } else { + return -1; + } + /* id-eNB-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABModifyRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); - enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; + } else { + return -1; + } if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, enb_ue_s1ap_id)) == NULL) { @@ -1228,13 +1326,17 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABModifyRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModReq, true); - for(nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < ie->value.choice.E_RABToBeModifiedListBearerModReq.list.count; nb_of_e_rabs_failed++) { - S1AP_E_RABToBeModifiedItemBearerModReq_t *item_p; - item_p = &(((S1AP_E_RABToBeModifiedItemBearerModReqIEs_t *) - ie->value.choice.E_RABToBeModifiedListBearerModReq.list.array[nb_of_e_rabs_failed])->value.choice.E_RABToBeModifiedItemBearerModReq); - S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id = item_p->e_RAB_ID; - S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].cause = S1AP_Cause_PR_radioNetwork; - S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id; + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + for(nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < ie->value.choice.E_RABToBeModifiedListBearerModReq.list.count; nb_of_e_rabs_failed++) { + S1AP_E_RABToBeModifiedItemBearerModReq_t *item_p; + item_p = &(((S1AP_E_RABToBeModifiedItemBearerModReqIEs_t *) + ie->value.choice.E_RABToBeModifiedListBearerModReq.list.array[nb_of_e_rabs_failed])->value.choice.E_RABToBeModifiedItemBearerModReq); + S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id = item_p->e_RAB_ID; + S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].cause = S1AP_Cause_PR_radioNetwork; + S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id; + } + } else { + return -1; } S1AP_E_RAB_MODIFY_RESP(message_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed; @@ -1251,37 +1353,43 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, /* id-E-RABToBeModifiedListBearerModReq */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABModifyRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModReq, true); - S1AP_E_RAB_MODIFY_REQ(message_p).nb_e_rabs_tomodify = - ie->value.choice.E_RABToBeModifiedListBearerModReq.list.count; - - for (i = 0; i < ie->value.choice.E_RABToBeModifiedListBearerModReq.list.count; i++) { - S1AP_E_RABToBeModifiedItemBearerModReq_t *item_p; - item_p = &(((S1AP_E_RABToBeModifiedItemBearerModReqIEs_t *)ie->value.choice.E_RABToBeModifiedListBearerModReq.list.array[i])->value.choice.E_RABToBeModifiedItemBearerModReq); - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].e_rab_id = item_p->e_RAB_ID; - - // check for the NAS PDU - if (item_p->nAS_PDU.size > 0 ) { - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = item_p->nAS_PDU.size; - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size); - memcpy(S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer, - item_p->nAS_PDU.buf, item_p->nAS_PDU.size); - } else { - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = 0; - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = NULL; - continue; + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + S1AP_E_RAB_MODIFY_REQ(message_p).nb_e_rabs_tomodify = + ie->value.choice.E_RABToBeModifiedListBearerModReq.list.count; + + for (i = 0; i < ie->value.choice.E_RABToBeModifiedListBearerModReq.list.count; i++) { + S1AP_E_RABToBeModifiedItemBearerModReq_t *item_p; + item_p = &(((S1AP_E_RABToBeModifiedItemBearerModReqIEs_t *)ie->value.choice.E_RABToBeModifiedListBearerModReq.list.array[i])->value.choice.E_RABToBeModifiedItemBearerModReq); + S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].e_rab_id = item_p->e_RAB_ID; + + // check for the NAS PDU + if (item_p->nAS_PDU.size > 0 ) { + S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = item_p->nAS_PDU.size; + S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size); + memcpy(S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer, + item_p->nAS_PDU.buf, item_p->nAS_PDU.size); + } else { + S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = 0; + S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = NULL; + continue; + } + + /* Set the QOS informations */ + S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.qci = item_p->e_RABLevelQoSParameters.qCI; + S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.priority_level = + item_p->e_RABLevelQoSParameters.allocationRetentionPriority.priorityLevel; + S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_capability = + item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionCapability; + S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_vulnerability = + item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability; } - /* Set the QOS informations */ - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.qci = item_p->e_RABLevelQoSParameters.qCI; - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.priority_level = - item_p->e_RABLevelQoSParameters.allocationRetentionPriority.priorityLevel; - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_capability = - item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionCapability; - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_vulnerability = - item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability; + itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); + } else { /* of if (ie != NULL)*/ + return -1; } - itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); return 0; } // handle e-rab release command and send it to rrc_end @@ -1308,11 +1416,22 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, /* id-MME-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); - mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; + } else { + return -1; + } + /* id-eNB-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); - enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; + } else { + return -1; + } if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, enb_ue_s1ap_id)) == NULL) { @@ -1359,15 +1478,251 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, /* id-E-RABToBeReleasedList */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeReleasedList, true); - S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = ie->value.choice.E_RABList.list.count; - for (i = 0; i < ie->value.choice.E_RABList.list.count; i++) { - S1AP_E_RABItem_t *item_p; - item_p = &(((S1AP_E_RABItemIEs_t *)ie->value.choice.E_RABList.list.array[i])->value.choice.E_RABItem); - S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID; - S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID); + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = ie->value.choice.E_RABList.list.count; + + for (i = 0; i < ie->value.choice.E_RABList.list.count; i++) { + S1AP_E_RABItem_t *item_p; + item_p = &(((S1AP_E_RABItemIEs_t *)ie->value.choice.E_RABList.list.array[i])->value.choice.E_RABItem); + S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID; + S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID); + } + } else { + return -1; + } + + itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); + return 0; +} + +static +int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, + uint32_t stream, + S1AP_S1AP_PDU_t *pdu) { + s1ap_eNB_mme_data_t *mme_desc_p = NULL; + s1ap_eNB_ue_context_t *ue_desc_p = NULL; + MessageDef *message_p = NULL; + S1AP_PathSwitchRequestAcknowledge_t *pathSwitchRequestAcknowledge; + S1AP_PathSwitchRequestAcknowledgeIEs_t *ie; + S1AP_E_RABToBeSwitchedULItemIEs_t *s1ap_E_RABToBeSwitchedULItemIEs; + S1AP_E_RABToBeSwitchedULItem_t *s1ap_E_RABToBeSwitchedULItem; + S1AP_E_RABItemIEs_t *e_RABItemIEs; + S1AP_E_RABItem_t *e_RABItem; + DevAssert(pdu != NULL); + pathSwitchRequestAcknowledge = &pdu->choice.successfulOutcome.value.choice.PathSwitchRequestAcknowledge; + + /* Path Switch request == UE-related procedure -> stream !=0 */ + if (stream == 0) { + S1AP_ERROR("[SCTP %d] Received s1 path switch request ack on stream (%d)\n", + assoc_id, stream); + return -1; + } + + if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { + S1AP_ERROR("[SCTP %d] Received S1 path switch request ack for non existing " + "MME context\n", assoc_id); + return -1; + } + + // send a message to RRC + message_p = itti_alloc_new_message(TASK_S1AP, S1AP_PATH_SWITCH_REQ_ACK); + /* mandatory */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge, + S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); + if (ie == NULL) { + S1AP_ERROR("[SCTP %d] Received path switch request ack for non " + "ie context is NULL\n", assoc_id); + return -1; + } + + S1AP_PATH_SWITCH_REQ_ACK(message_p).eNB_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; + + if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, + ie->value.choice.ENB_UE_S1AP_ID)) == NULL) { + S1AP_ERROR("[SCTP %d] Received path switch request ack for non " + "existing UE context 0x%06lx\n", assoc_id, + ie->value.choice.ENB_UE_S1AP_ID); + return -1; + } + + S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_initial_id = ue_desc_p->ue_initial_id; + /* mandatory */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge, + S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); + + if (ie == NULL) { + S1AP_ERROR("[SCTP %d] Received path switch request ack for non " + "ie context is NULL\n", assoc_id); + return -1; + } + + S1AP_PATH_SWITCH_REQ_ACK(message_p).mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; + + if ( ue_desc_p->mme_ue_s1ap_id != ie->value.choice.MME_UE_S1AP_ID) { + S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %ld)", + ue_desc_p->mme_ue_s1ap_id, ie->value.choice.MME_UE_S1AP_ID); + } + + /* mandatory */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge, + S1AP_ProtocolIE_ID_id_SecurityContext, true); + + if (ie == NULL) { + S1AP_ERROR("[SCTP %d] Received path switch request ack for non " + "ie context is NULL\n", assoc_id); + return -1; + } + + S1AP_PATH_SWITCH_REQ_ACK(message_p).next_hop_chain_count = + ie->value.choice.SecurityContext.nextHopChainingCount; + memcpy(&S1AP_PATH_SWITCH_REQ_ACK(message_p).next_security_key, + ie->value.choice.SecurityContext.nextHopParameter.buf, + ie->value.choice.SecurityContext.nextHopParameter.size); + /* optional */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge, + S1AP_ProtocolIE_ID_id_uEaggregateMaximumBitrate, false); + + if (ie) { + OCTET_STRING_TO_INT32 ( + &ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL, + S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul + ); + OCTET_STRING_TO_INT32 ( + &ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL, + S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl + ); + } else { + S1AP_WARN("UEAggregateMaximumBitrate not supported\n"); + S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul = 0; + S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl = 0; + } + + /* optional */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge, + S1AP_ProtocolIE_ID_id_E_RABToBeSwitchedULList, false); + + if (ie) { + S1AP_PATH_SWITCH_REQ_ACK(message_p).nb_e_rabs_tobeswitched = ie->value.choice.E_RABToBeSwitchedULList.list.count; + + for (int i = 0; i < ie->value.choice.E_RABToBeSwitchedULList.list.count; i++) { + s1ap_E_RABToBeSwitchedULItemIEs = (S1AP_E_RABToBeSwitchedULItemIEs_t *)ie->value.choice.E_RABToBeSwitchedULList.list.array[i]; + s1ap_E_RABToBeSwitchedULItem = &s1ap_E_RABToBeSwitchedULItemIEs->value.choice.E_RABToBeSwitchedULItem; + S1AP_PATH_SWITCH_REQ_ACK (message_p).e_rabs_tobeswitched[i].e_rab_id = s1ap_E_RABToBeSwitchedULItem->e_RAB_ID; + memcpy(S1AP_PATH_SWITCH_REQ_ACK (message_p).e_rabs_tobeswitched[i].sgw_addr.buffer, + s1ap_E_RABToBeSwitchedULItem->transportLayerAddress.buf, s1ap_E_RABToBeSwitchedULItem->transportLayerAddress.size); + S1AP_PATH_SWITCH_REQ_ACK (message_p).e_rabs_tobeswitched[i].sgw_addr.length = + s1ap_E_RABToBeSwitchedULItem->transportLayerAddress.size * 8 - s1ap_E_RABToBeSwitchedULItem->transportLayerAddress.bits_unused; + OCTET_STRING_TO_INT32(&s1ap_E_RABToBeSwitchedULItem->gTP_TEID, + S1AP_PATH_SWITCH_REQ_ACK (message_p).e_rabs_tobeswitched[i].gtp_teid); + } + } else { + S1AP_WARN("E_RABToBeSwitchedULList not supported\n"); + S1AP_PATH_SWITCH_REQ_ACK(message_p).nb_e_rabs_tobeswitched = 0; + } + + /* optional */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge, + S1AP_ProtocolIE_ID_id_E_RABToBeReleasedList, false); + + if (ie) { + S1AP_PATH_SWITCH_REQ_ACK(message_p).nb_e_rabs_tobereleased = ie->value.choice.E_RABList.list.count; + + for (int i = 0; i < ie->value.choice.E_RABList.list.count; i++) { + e_RABItemIEs = (S1AP_E_RABItemIEs_t *)ie->value.choice.E_RABList.list.array[i]; + e_RABItem = &e_RABItemIEs->value.choice.E_RABItem; + S1AP_PATH_SWITCH_REQ_ACK (message_p).e_rabs_tobereleased[i].e_rab_id = e_RABItem->e_RAB_ID; + } + } else { + S1AP_WARN("E_RABToBeReleasedList not supported\n"); + S1AP_PATH_SWITCH_REQ_ACK(message_p).nb_e_rabs_tobereleased = 0; + } + + /* optional */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge, + S1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false); + + if(!ie) { + S1AP_WARN("Critical Diagnostic not supported\n"); + } + + /* optional */ + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge, + S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID_2, false); + + if(!ie) { + S1AP_WARN("MME_UE_S1AP_ID_2 flag not supported\n"); } + // TODO continue itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); return 0; } + +static +int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_id, + uint32_t stream, + S1AP_S1AP_PDU_t *pdu) { + s1ap_eNB_mme_data_t *mme_desc_p = NULL; + S1AP_PathSwitchRequestFailure_t *pathSwitchRequestFailure; + S1AP_PathSwitchRequestFailureIEs_t *ie; + DevAssert(pdu != NULL); + pathSwitchRequestFailure = &pdu->choice.unsuccessfulOutcome.value.choice.PathSwitchRequestFailure; + + if (stream != 0) { + S1AP_ERROR("[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)\n", + assoc_id, stream); + return -1; + } + + if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { + S1AP_ERROR("[SCTP %d] Received S1 path switch request failure for non existing " + "MME context\n", assoc_id); + return -1; + } + + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestFailureIEs_t, ie, pathSwitchRequestFailure, + S1AP_ProtocolIE_ID_id_Cause, true); + + if (ie == NULL) { + S1AP_ERROR("[SCTP %d] Received S1 path switch request failure for non existing " + "ie context is NULL\n", assoc_id); + return -1; + } + + switch(ie->value.choice.Cause.present) { + case S1AP_Cause_PR_NOTHING: + S1AP_WARN("Received S1 Error indication cause NOTHING\n"); + break; + + case S1AP_Cause_PR_radioNetwork: + S1AP_WARN("Radio Network Layer Cause Failure\n"); + break; + + case S1AP_Cause_PR_transport: + S1AP_WARN("Transport Layer Cause Failure\n"); + break; + + case S1AP_Cause_PR_nas: + S1AP_WARN("NAS Cause Failure\n"); + break; + + case S1AP_Cause_PR_misc: + S1AP_WARN("Miscelaneous Cause Failure\n"); + break; + + default: + S1AP_WARN("Received an unknown S1 Error indication cause\n"); + break; + } + + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestFailureIEs_t, ie, pathSwitchRequestFailure, + S1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false); + + if(!ie) { + S1AP_WARN("Critical Diagnostic not supported\n"); + } + + // TODO continue + return 0; +} diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index 2189140dad0213e506d46b86ab26fcb488fd0714..bd0fd13208158aba2bcb1078f56a7f63eee7b154 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -50,376 +50,376 @@ //------------------------------------------------------------------------------ int s1ap_eNB_handle_nas_first_req( - instance_t instance, s1ap_nas_first_req_t *s1ap_nas_first_req_p) + instance_t instance, s1ap_nas_first_req_t *s1ap_nas_first_req_p) //------------------------------------------------------------------------------ { - s1ap_eNB_instance_t *instance_p = NULL; - struct s1ap_eNB_mme_data_s *mme_desc_p = NULL; - struct s1ap_eNB_ue_context_s *ue_desc_p = NULL; - S1AP_S1AP_PDU_t pdu; - S1AP_InitialUEMessage_t *out; - S1AP_InitialUEMessage_IEs_t *ie; - uint8_t *buffer = NULL; - uint32_t length = 0; - DevAssert(s1ap_nas_first_req_p != NULL); - /* Retrieve the S1AP eNB instance associated with Mod_id */ - instance_p = s1ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); - memset(&pdu, 0, sizeof(pdu)); - pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_initialUEMessage; - pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; - pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_InitialUEMessage; - out = &pdu.choice.initiatingMessage.value.choice.InitialUEMessage; - - /* Select the MME corresponding to the provided GUMMEI. */ - if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_gummei) { - mme_desc_p = s1ap_eNB_nnsf_select_mme_by_gummei( - instance_p, - s1ap_nas_first_req_p->establishment_cause, - s1ap_nas_first_req_p->ue_identity.gummei); - - if (mme_desc_p) { - S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through GUMMEI MCC %d MNC %d MMEGI %d MMEC %d\n", - instance, - mme_desc_p->mme_name, - mme_desc_p->assoc_id, - s1ap_nas_first_req_p->ue_identity.gummei.mcc, - s1ap_nas_first_req_p->ue_identity.gummei.mnc, - s1ap_nas_first_req_p->ue_identity.gummei.mme_group_id, - s1ap_nas_first_req_p->ue_identity.gummei.mme_code); + s1ap_eNB_instance_t *instance_p = NULL; + struct s1ap_eNB_mme_data_s *mme_desc_p = NULL; + struct s1ap_eNB_ue_context_s *ue_desc_p = NULL; + S1AP_S1AP_PDU_t pdu; + S1AP_InitialUEMessage_t *out; + S1AP_InitialUEMessage_IEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length = 0; + DevAssert(s1ap_nas_first_req_p != NULL); + /* Retrieve the S1AP eNB instance associated with Mod_id */ + instance_p = s1ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_initialUEMessage; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_InitialUEMessage; + out = &pdu.choice.initiatingMessage.value.choice.InitialUEMessage; + + /* Select the MME corresponding to the provided GUMMEI. */ + if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_gummei) { + mme_desc_p = s1ap_eNB_nnsf_select_mme_by_gummei( + instance_p, + s1ap_nas_first_req_p->establishment_cause, + s1ap_nas_first_req_p->ue_identity.gummei); + + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through GUMMEI MCC %d MNC %d MMEGI %d MMEC %d\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id, + s1ap_nas_first_req_p->ue_identity.gummei.mcc, + s1ap_nas_first_req_p->ue_identity.gummei.mnc, + s1ap_nas_first_req_p->ue_identity.gummei.mme_group_id, + s1ap_nas_first_req_p->ue_identity.gummei.mme_code); + } } - } - if (mme_desc_p == NULL) { - /* Select the MME corresponding to the provided s-TMSI. */ - if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_s_tmsi) { - mme_desc_p = s1ap_eNB_nnsf_select_mme_by_mme_code( - instance_p, - s1ap_nas_first_req_p->establishment_cause, - s1ap_nas_first_req_p->selected_plmn_identity, - s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code); - - if (mme_desc_p) { - S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through S-TMSI MMEC %d and selected PLMN Identity index %d MCC %d MNC %d\n", - instance, - mme_desc_p->mme_name, - mme_desc_p->assoc_id, - s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code, - s1ap_nas_first_req_p->selected_plmn_identity, - instance_p->mcc[s1ap_nas_first_req_p->selected_plmn_identity], - instance_p->mnc[s1ap_nas_first_req_p->selected_plmn_identity]); - } + if (mme_desc_p == NULL) { + /* Select the MME corresponding to the provided s-TMSI. */ + if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_s_tmsi) { + mme_desc_p = s1ap_eNB_nnsf_select_mme_by_mme_code( + instance_p, + s1ap_nas_first_req_p->establishment_cause, + s1ap_nas_first_req_p->selected_plmn_identity, + s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code); + + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through S-TMSI MMEC %d and selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id, + s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code, + s1ap_nas_first_req_p->selected_plmn_identity, + instance_p->mcc[s1ap_nas_first_req_p->selected_plmn_identity], + instance_p->mnc[s1ap_nas_first_req_p->selected_plmn_identity]); + } + } } - } - if (mme_desc_p == NULL) { - /* Select MME based on the selected PLMN identity, received through RRC - * Connection Setup Complete */ - mme_desc_p = s1ap_eNB_nnsf_select_mme_by_plmn_id( - instance_p, - s1ap_nas_first_req_p->establishment_cause, - s1ap_nas_first_req_p->selected_plmn_identity); - - if (mme_desc_p) { - S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", - instance, - mme_desc_p->mme_name, - mme_desc_p->assoc_id, - s1ap_nas_first_req_p->selected_plmn_identity, - instance_p->mcc[s1ap_nas_first_req_p->selected_plmn_identity], - instance_p->mnc[s1ap_nas_first_req_p->selected_plmn_identity]); + if (mme_desc_p == NULL) { + /* Select MME based on the selected PLMN identity, received through RRC + * Connection Setup Complete */ + mme_desc_p = s1ap_eNB_nnsf_select_mme_by_plmn_id( + instance_p, + s1ap_nas_first_req_p->establishment_cause, + s1ap_nas_first_req_p->selected_plmn_identity); + + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id, + s1ap_nas_first_req_p->selected_plmn_identity, + instance_p->mcc[s1ap_nas_first_req_p->selected_plmn_identity], + instance_p->mnc[s1ap_nas_first_req_p->selected_plmn_identity]); + } } - } - if (mme_desc_p == NULL) { - /* - * If no MME corresponds to the GUMMEI, the s-TMSI, or the selected PLMN - * identity, selects the MME with the highest capacity. - */ - mme_desc_p = s1ap_eNB_nnsf_select_mme( - instance_p, - s1ap_nas_first_req_p->establishment_cause); + if (mme_desc_p == NULL) { + /* + * If no MME corresponds to the GUMMEI, the s-TMSI, or the selected PLMN + * identity, selects the MME with the highest capacity. + */ + mme_desc_p = s1ap_eNB_nnsf_select_mme( + instance_p, + s1ap_nas_first_req_p->establishment_cause); + + if (mme_desc_p) { + S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", + instance, + mme_desc_p->mme_name, + mme_desc_p->assoc_id); + } + } - if (mme_desc_p) { - S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", - instance, - mme_desc_p->mme_name, - mme_desc_p->assoc_id); + if (mme_desc_p == NULL) { + /* + * In case eNB has no MME associated, the eNB should inform RRC and discard + * this request. + */ + S1AP_WARN("No MME is associated to the eNB\n"); + // TODO: Inform RRC + return -1; } - } - if (mme_desc_p == NULL) { - /* - * In case eNB has no MME associated, the eNB should inform RRC and discard - * this request. + /* The eNB should allocate a unique eNB UE S1AP ID for this UE. The value + * will be used for the duration of the connectivity. */ - S1AP_WARN("No MME is associated to the eNB\n"); - // TODO: Inform RRC - return -1; - } - - /* The eNB should allocate a unique eNB UE S1AP ID for this UE. The value - * will be used for the duration of the connectivity. - */ - ue_desc_p = s1ap_eNB_allocate_new_UE_context(); - DevAssert(ue_desc_p != NULL); - /* Keep a reference to the selected MME */ - ue_desc_p->mme_ref = mme_desc_p; - ue_desc_p->ue_initial_id = s1ap_nas_first_req_p->ue_initial_id; - ue_desc_p->eNB_instance = instance_p; - ue_desc_p->selected_plmn_identity = s1ap_nas_first_req_p->selected_plmn_identity; + ue_desc_p = s1ap_eNB_allocate_new_UE_context(); + DevAssert(ue_desc_p != NULL); + /* Keep a reference to the selected MME */ + ue_desc_p->mme_ref = mme_desc_p; + ue_desc_p->ue_initial_id = s1ap_nas_first_req_p->ue_initial_id; + ue_desc_p->eNB_instance = instance_p; + ue_desc_p->selected_plmn_identity = s1ap_nas_first_req_p->selected_plmn_identity; + + do { + struct s1ap_eNB_ue_context_s *collision_p; + /* Peek a random value for the eNB_ue_s1ap_id */ + ue_desc_p->eNB_ue_s1ap_id = (random() + random()) & 0x00ffffff; + + if ((collision_p = RB_INSERT(s1ap_ue_map, &instance_p->s1ap_ue_head, ue_desc_p)) + == NULL) { + S1AP_DEBUG("Found usable eNB_ue_s1ap_id: 0x%06x %u(10)\n", + ue_desc_p->eNB_ue_s1ap_id, + ue_desc_p->eNB_ue_s1ap_id); + /* Break the loop as the id is not already used by another UE */ + break; + } + } while(1); - do { - struct s1ap_eNB_ue_context_s *collision_p; - /* Peek a random value for the eNB_ue_s1ap_id */ - ue_desc_p->eNB_ue_s1ap_id = (random() + random()) & 0x00ffffff; - - if ((collision_p = RB_INSERT(s1ap_ue_map, &instance_p->s1ap_ue_head, ue_desc_p)) - == NULL) { - S1AP_DEBUG("Found usable eNB_ue_s1ap_id: 0x%06x %d(10)\n", - ue_desc_p->eNB_ue_s1ap_id, - ue_desc_p->eNB_ue_s1ap_id); - /* Break the loop as the id is not already used by another UE */ - break; - } - } while(1); - - /* mandatory */ - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_ENB_UE_S1AP_ID; - ie->value.choice.ENB_UE_S1AP_ID = ue_desc_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_NAS_PDU; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_NAS_PDU; + /* mandatory */ + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = ue_desc_p->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_NAS_PDU; #if 1 - ie->value.choice.NAS_PDU.buf = s1ap_nas_first_req_p->nas_pdu.buffer; + ie->value.choice.NAS_PDU.buf = s1ap_nas_first_req_p->nas_pdu.buffer; #else - ie->value.choice.NAS_PDU.buf = malloc(s1ap_nas_first_req_p->nas_pdu.length); - memcpy(ie->value.choice.NAS_PDU.buf, - s1ap_nas_first_req_p->nas_pdu.buffer, - s1ap_nas_first_req_p->nas_pdu.length); + ie->value.choice.NAS_PDU.buf = malloc(s1ap_nas_first_req_p->nas_pdu.length); + memcpy(ie->value.choice.NAS_PDU.buf, + s1ap_nas_first_req_p->nas_pdu.buffer, + s1ap_nas_first_req_p->nas_pdu.length); #endif - ie->value.choice.NAS_PDU.size = s1ap_nas_first_req_p->nas_pdu.length; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_TAI; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TAI; - /* Assuming TAI is the TAI from the cell */ - INT16_TO_OCTET_STRING(instance_p->tac, &ie->value.choice.TAI.tAC); - MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity], - instance_p->mnc[ue_desc_p->selected_plmn_identity], - instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], - &ie->value.choice.TAI.pLMNidentity); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_EUTRAN_CGI; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_EUTRAN_CGI; - /* Set the EUTRAN CGI - * The cell identity is defined on 28 bits but as we use macro enb id, - * we have to pad. - */ - //#warning "TODO get cell id from RRC" - MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id, - 0, // Cell ID - &ie->value.choice.EUTRAN_CGI.cell_ID); - MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], - instance_p->mnc[ue_desc_p->selected_plmn_identity], - instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], - &ie->value.choice.EUTRAN_CGI.pLMNidentity); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* Set the establishment cause according to those provided by RRC */ - DevCheck(s1ap_nas_first_req_p->establishment_cause < RRC_CAUSE_LAST, - s1ap_nas_first_req_p->establishment_cause, RRC_CAUSE_LAST, 0); - /* mandatory */ - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_RRC_Establishment_Cause; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_RRC_Establishment_Cause; - ie->value.choice.RRC_Establishment_Cause = s1ap_nas_first_req_p->establishment_cause; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* optional */ - if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_s_tmsi) { - S1AP_DEBUG("S_TMSI_PRESENT\n"); + ie->value.choice.NAS_PDU.size = s1ap_nas_first_req_p->nas_pdu.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_S_TMSI; + ie->id = S1AP_ProtocolIE_ID_id_TAI; ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_S_TMSI; - MME_CODE_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code, - &ie->value.choice.S_TMSI.mMEC); - M_TMSI_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.s_tmsi.m_tmsi, - &ie->value.choice.S_TMSI.m_TMSI); + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TAI; + /* Assuming TAI is the TAI from the cell */ + INT16_TO_OCTET_STRING(instance_p->tac, &ie->value.choice.TAI.tAC); + MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], + &ie->value.choice.TAI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (0) { + /* mandatory */ ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_CSG_Id; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_CSG_Id; - // ie->value.choice.CSG_Id = ; + ie->id = S1AP_ProtocolIE_ID_id_EUTRAN_CGI; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_EUTRAN_CGI; + /* Set the EUTRAN CGI + * The cell identity is defined on 28 bits but as we use macro enb id, + * we have to pad. + */ + //#warning "TODO get cell id from RRC" + MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id, + 0, // Cell ID + &ie->value.choice.EUTRAN_CGI.cell_ID); + MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], + &ie->value.choice.EUTRAN_CGI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_gummei) { - S1AP_DEBUG("GUMMEI_ID_PRESENT\n"); + /* Set the establishment cause according to those provided by RRC */ + DevCheck(s1ap_nas_first_req_p->establishment_cause < RRC_CAUSE_LAST, + s1ap_nas_first_req_p->establishment_cause, RRC_CAUSE_LAST, 0); + /* mandatory */ ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_GUMMEI_ID; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_GUMMEI; - MCC_MNC_TO_PLMNID( - s1ap_nas_first_req_p->ue_identity.gummei.mcc, - s1ap_nas_first_req_p->ue_identity.gummei.mnc, - s1ap_nas_first_req_p->ue_identity.gummei.mnc_len, - &ie->value.choice.GUMMEI.pLMN_Identity); - MME_GID_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.gummei.mme_group_id, - &ie->value.choice.GUMMEI.mME_Group_ID); - MME_CODE_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.gummei.mme_code, - &ie->value.choice.GUMMEI.mME_Code); + ie->id = S1AP_ProtocolIE_ID_id_RRC_Establishment_Cause; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_RRC_Establishment_Cause; + ie->value.choice.RRC_Establishment_Cause = s1ap_nas_first_req_p->establishment_cause; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - /* optional */ + /* optional */ + if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_s_tmsi) { + S1AP_DEBUG("S_TMSI_PRESENT\n"); + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_S_TMSI; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_S_TMSI; + MME_CODE_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code, + &ie->value.choice.S_TMSI.mMEC); + M_TMSI_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.s_tmsi.m_tmsi, + &ie->value.choice.S_TMSI.m_TMSI); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CSG_Id; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_CSG_Id; + // ie->value.choice.CSG_Id = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + if (s1ap_nas_first_req_p->ue_identity.presenceMask & UE_IDENTITIES_gummei) { + S1AP_DEBUG("GUMMEI_ID_PRESENT\n"); + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_GUMMEI_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_GUMMEI; + MCC_MNC_TO_PLMNID( + s1ap_nas_first_req_p->ue_identity.gummei.mcc, + s1ap_nas_first_req_p->ue_identity.gummei.mnc, + s1ap_nas_first_req_p->ue_identity.gummei.mnc_len, + &ie->value.choice.GUMMEI.pLMN_Identity); + MME_GID_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.gummei.mme_group_id, + &ie->value.choice.GUMMEI.mME_Group_ID); + MME_CODE_TO_OCTET_STRING(s1ap_nas_first_req_p->ue_identity.gummei.mme_code, + &ie->value.choice.GUMMEI.mME_Code); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ #if (S1AP_VERSION >= MAKE_VERSION(9, 0, 0)) - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_CellAccessMode; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_CellAccessMode; - // ie->value.choice.CellAccessMode = ; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CellAccessMode; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_CellAccessMode; + // ie->value.choice.CellAccessMode = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - /* optional */ + /* optional */ #if (S1AP_VERSION >= MAKE_VERSION(10, 0, 0)) - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_GW_TransportLayerAddress; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TransportLayerAddress; - // ie->value.choice.TransportLayerAddress =; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_GW_TransportLayerAddress; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TransportLayerAddress; + // ie->value.choice.TransportLayerAddress =; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - /* optional */ - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_RelayNode_Indicator; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_RelayNode_Indicator; - // ie->value.choice.RelayNode_Indicator =; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_RelayNode_Indicator; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_RelayNode_Indicator; + // ie->value.choice.RelayNode_Indicator =; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } #if (S1AP_VERSION >= MAKE_VERSION(11, 0, 0)) - /* optional */ - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_GUMMEIType; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_GUMMEIType; - // ie->value.choice.GUMMEIType =; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_GUMMEIType; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_GUMMEIType; + // ie->value.choice.GUMMEIType =; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - /* optional */ /* release 11 */ - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_Tunnel_Information_for_BBF; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TunnelInformation; - // ie->value.choice.TunnelInformation =; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ /* release 11 */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_Tunnel_Information_for_BBF; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TunnelInformation; + // ie->value.choice.TunnelInformation =; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - /* optional */ - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_SIPTO_L_GW_TransportLayerAddress; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TransportLayerAddress; - // ie->value.choice.TransportLayerAddress = ; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_SIPTO_L_GW_TransportLayerAddress; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_TransportLayerAddress; + // ie->value.choice.TransportLayerAddress = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - /* optional */ - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_LHN_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_LHN_ID; - // ie->value.choice.LHN_ID = ue_release_req_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_LHN_ID; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_LHN_ID; + // ie->value.choice.LHN_ID = ue_release_req_p->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } #if (S1AP_VERSION >= MAKE_VERSION(13, 0, 0)) - /* optional */ - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_MME_Group_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_MME_Group_ID; - // ie->value.choice.MME_Group_ID =; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_MME_Group_ID; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_MME_Group_ID; + // ie->value.choice.MME_Group_ID =; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - /* optional */ - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_UE_Usage_Type; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_UE_Usage_Type; - // ie->value.choice.UE_Usage_Type =; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_UE_Usage_Type; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_UE_Usage_Type; + // ie->value.choice.UE_Usage_Type =; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - /* optional */ - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_CE_mode_B_SupportIndicator; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_CE_mode_B_SupportIndicator; - // ie->value.choice.CE_mode_B_SupportIndicator = ; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CE_mode_B_SupportIndicator; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_CE_mode_B_SupportIndicator; + // ie->value.choice.CE_mode_B_SupportIndicator = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) - /* optional */ - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_DCN_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_DCN_ID; - // ie->value.choice.DCN_ID = ; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_DCN_ID; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_DCN_ID; + // ie->value.choice.DCN_ID = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - /* optional */ - if (0) { - ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_Coverage_Level; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_Coverage_Level; - // ie->value.choice.Coverage_Level = ue_release_req_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ + if (0) { + ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_Coverage_Level; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_Coverage_Level; + // ie->value.choice.Coverage_Level = ue_release_req_p->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } #endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ #endif /* #if (S1AP_VERSION >= MAKE_VERSION(13, 0, 0)) */ @@ -427,44 +427,44 @@ int s1ap_eNB_handle_nas_first_req( #endif /* #if (S1AP_VERSION >= MAKE_VERSION(10, 0, 0)) */ #endif /* #if (S1AP_VERSION >= MAKE_VERSION(9, 0, 0)) */ - if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { - /* Failed to encode message */ - DevMessage("Failed to encode initial UE message\n"); - } + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { + /* Failed to encode message */ + DevMessage("Failed to encode initial UE message\n"); + } - /* Update the current S1AP UE state */ - ue_desc_p->ue_state = S1AP_UE_WAITING_CSR; - /* Assign a stream for this UE : - * From 3GPP 36.412 7)Transport layers: - * Within the SCTP association established between one MME and eNB pair: - * - a single pair of stream identifiers shall be reserved for the sole use - * of S1AP elementary procedures that utilize non UE-associated signalling. - * - At least one pair of stream identifiers shall be reserved for the sole use - * of S1AP elementary procedures that utilize UE-associated signallings. - * However a few pairs (i.e. more than one) should be reserved. - * - A single UE-associated signalling shall use one SCTP stream and - * the stream should not be changed during the communication of the - * UE-associated signalling. - */ - mme_desc_p->nextstream = (mme_desc_p->nextstream + 1) % mme_desc_p->out_streams; + /* Update the current S1AP UE state */ + ue_desc_p->ue_state = S1AP_UE_WAITING_CSR; + /* Assign a stream for this UE : + * From 3GPP 36.412 7)Transport layers: + * Within the SCTP association established between one MME and eNB pair: + * - a single pair of stream identifiers shall be reserved for the sole use + * of S1AP elementary procedures that utilize non UE-associated signalling. + * - At least one pair of stream identifiers shall be reserved for the sole use + * of S1AP elementary procedures that utilize UE-associated signallings. + * However a few pairs (i.e. more than one) should be reserved. + * - A single UE-associated signalling shall use one SCTP stream and + * the stream should not be changed during the communication of the + * UE-associated signalling. + */ + mme_desc_p->nextstream = (mme_desc_p->nextstream + 1) % mme_desc_p->out_streams; - if ((mme_desc_p->nextstream == 0) && (mme_desc_p->out_streams > 1)) { - mme_desc_p->nextstream += 1; - } + if ((mme_desc_p->nextstream == 0) && (mme_desc_p->out_streams > 1)) { + mme_desc_p->nextstream += 1; + } - ue_desc_p->tx_stream = mme_desc_p->nextstream; - MSC_LOG_TX_MESSAGE( - MSC_S1AP_ENB, - MSC_S1AP_MME, - (const char *)NULL, - 0, - MSC_AS_TIME_FMT" initialUEMessage initiatingMessage eNB_ue_s1ap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - ue_desc_p->eNB_ue_s1ap_id); - /* Send encoded message over sctp */ - s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, mme_desc_p->assoc_id, - buffer, length, ue_desc_p->tx_stream); - return 0; + ue_desc_p->tx_stream = mme_desc_p->nextstream; + MSC_LOG_TX_MESSAGE( + MSC_S1AP_ENB, + MSC_S1AP_MME, + (const char *)NULL, + 0, + MSC_AS_TIME_FMT" initialUEMessage initiatingMessage eNB_ue_s1ap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_desc_p->eNB_ue_s1ap_id); + /* Send encoded message over sctp */ + s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, mme_desc_p->assoc_id, + buffer, length, ue_desc_p->tx_stream); + return 0; } //------------------------------------------------------------------------------ @@ -473,246 +473,248 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, S1AP_S1AP_PDU_t *pdu) //------------------------------------------------------------------------------ { - s1ap_eNB_mme_data_t *mme_desc_p = NULL; - s1ap_eNB_ue_context_t *ue_desc_p = NULL; - s1ap_eNB_instance_t *s1ap_eNB_instance = NULL; - S1AP_DownlinkNASTransport_t *container; - S1AP_DownlinkNASTransport_IEs_t *ie; - S1AP_ENB_UE_S1AP_ID_t enb_ue_s1ap_id; - S1AP_MME_UE_S1AP_ID_t mme_ue_s1ap_id; - DevAssert(pdu != NULL); - - /* UE-related procedure -> stream != 0 */ - if (stream == 0) { - S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream == 0\n", - assoc_id); - return -1; - } + s1ap_eNB_mme_data_t *mme_desc_p = NULL; + s1ap_eNB_ue_context_t *ue_desc_p = NULL; + s1ap_eNB_instance_t *s1ap_eNB_instance = NULL; + S1AP_DownlinkNASTransport_t *container; + S1AP_DownlinkNASTransport_IEs_t *ie; + S1AP_ENB_UE_S1AP_ID_t enb_ue_s1ap_id; + S1AP_MME_UE_S1AP_ID_t mme_ue_s1ap_id; + DevAssert(pdu != NULL); + + /* UE-related procedure -> stream != 0 */ + if (stream == 0) { + S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream == 0\n", + assoc_id); + return -1; + } - if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { - S1AP_ERROR( - "[SCTP %d] Received NAS downlink message for non existing MME context\n", - assoc_id); - return -1; - } + if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { + S1AP_ERROR( + "[SCTP %d] Received NAS downlink message for non existing MME context\n", + assoc_id); + return -1; + } - s1ap_eNB_instance = mme_desc_p->s1ap_eNB_instance; - /* Prepare the S1AP message to encode */ - container = &pdu->choice.initiatingMessage.value.choice.DownlinkNASTransport; - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, - S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); - mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, - S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); - enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; - - if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance, - enb_ue_s1ap_id)) == NULL) { - MSC_LOG_RX_DISCARDED_MESSAGE( - MSC_S1AP_ENB, - MSC_S1AP_MME, - NULL, - 0, - MSC_AS_TIME_FMT" downlinkNASTransport eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", - enb_ue_s1ap_id, - mme_ue_s1ap_id); - S1AP_ERROR("[SCTP %d] Received NAS downlink message for non existing UE context eNB_UE_S1AP_ID: 0x%lx\n", - assoc_id, - enb_ue_s1ap_id); - return -1; - } + s1ap_eNB_instance = mme_desc_p->s1ap_eNB_instance; + /* Prepare the S1AP message to encode */ + container = &pdu->choice.initiatingMessage.value.choice.DownlinkNASTransport; + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, + S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); + mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; + + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, + S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); + enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; + + if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance, + enb_ue_s1ap_id)) == NULL) { + MSC_LOG_RX_DISCARDED_MESSAGE( + MSC_S1AP_ENB, + MSC_S1AP_MME, + NULL, + 0, + MSC_AS_TIME_FMT" downlinkNASTransport eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", + enb_ue_s1ap_id, + mme_ue_s1ap_id); + S1AP_ERROR("[SCTP %d] Received NAS downlink message for non existing UE context eNB_UE_S1AP_ID: 0x%lx\n", + assoc_id, + enb_ue_s1ap_id); + return -1; + } - if (0 == ue_desc_p->rx_stream) { - ue_desc_p->rx_stream = stream; - } else if (stream != ue_desc_p->rx_stream) { - S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream %u, expecting %u\n", - assoc_id, stream, ue_desc_p->rx_stream); - return -1; - } + if (0 == ue_desc_p->rx_stream) { + ue_desc_p->rx_stream = stream; + } else if (stream != ue_desc_p->rx_stream) { + S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream %u, expecting %u\n", + assoc_id, stream, ue_desc_p->rx_stream); + return -1; + } - /* Is it the first outcome of the MME for this UE ? If so store the mme - * UE s1ap id. - */ - if (ue_desc_p->mme_ue_s1ap_id == 0) { - ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id; - } else { - /* We already have a mme ue s1ap id check the received is the same */ - if (ue_desc_p->mme_ue_s1ap_id != mme_ue_s1ap_id) { - S1AP_ERROR("[SCTP %d] Mismatch in MME UE S1AP ID (0x%lx != 0x%"PRIx32"\n", - assoc_id, - mme_ue_s1ap_id, - ue_desc_p->mme_ue_s1ap_id - ); - return -1; + /* Is it the first outcome of the MME for this UE ? If so store the mme + * UE s1ap id. + */ + if (ue_desc_p->mme_ue_s1ap_id == 0) { + ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id; + } else { + /* We already have a mme ue s1ap id check the received is the same */ + if (ue_desc_p->mme_ue_s1ap_id != mme_ue_s1ap_id) { + S1AP_ERROR("[SCTP %d] Mismatch in MME UE S1AP ID (0x%lx != 0x%"PRIx32"\n", + assoc_id, + mme_ue_s1ap_id, + ue_desc_p->mme_ue_s1ap_id + ); + return -1; + } } - } - MSC_LOG_RX_MESSAGE( - MSC_S1AP_ENB, - MSC_S1AP_MME, - NULL, - 0, - MSC_AS_TIME_FMT" downlinkNASTransport eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", - assoc_id, - mme_ue_s1ap_id); - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, - S1AP_ProtocolIE_ID_id_NAS_PDU, true); - /* Forward the NAS PDU to RRC */ - s1ap_eNB_itti_send_nas_downlink_ind(s1ap_eNB_instance->instance, - ue_desc_p->ue_initial_id, - ue_desc_p->eNB_ue_s1ap_id, - ie->value.choice.NAS_PDU.buf, - ie->value.choice.NAS_PDU.size); - return 0; + MSC_LOG_RX_MESSAGE( + MSC_S1AP_ENB, + MSC_S1AP_MME, + NULL, + 0, + MSC_AS_TIME_FMT" downlinkNASTransport eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", + assoc_id, + mme_ue_s1ap_id); + + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, + S1AP_ProtocolIE_ID_id_NAS_PDU, true); + /* Forward the NAS PDU to RRC */ + s1ap_eNB_itti_send_nas_downlink_ind(s1ap_eNB_instance->instance, + ue_desc_p->ue_initial_id, + ue_desc_p->eNB_ue_s1ap_id, + ie->value.choice.NAS_PDU.buf, + ie->value.choice.NAS_PDU.size); + return 0; } //------------------------------------------------------------------------------ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_p) //------------------------------------------------------------------------------ { - struct s1ap_eNB_ue_context_s *ue_context_p; - s1ap_eNB_instance_t *s1ap_eNB_instance_p; - S1AP_S1AP_PDU_t pdu; - S1AP_UplinkNASTransport_t *out; - S1AP_UplinkNASTransport_IEs_t *ie; - uint8_t *buffer; - uint32_t length; - DevAssert(s1ap_uplink_nas_p != NULL); - /* Retrieve the S1AP eNB instance associated with Mod_id */ - s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(s1ap_eNB_instance_p != NULL); - - if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, s1ap_uplink_nas_p->eNB_ue_s1ap_id)) == NULL) { - /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ - S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %06x\n", - s1ap_uplink_nas_p->eNB_ue_s1ap_id); - return -1; - } - - /* Uplink NAS transport can occur either during an s1ap connected state - * or during initial attach (for example: NAS authentication). - */ - if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || - ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { - S1AP_WARN("You are attempting to send NAS data over non-connected " - "eNB ue s1ap id: %u, current state: %d\n", - s1ap_uplink_nas_p->eNB_ue_s1ap_id, ue_context_p->ue_state); - return -1; - } + struct s1ap_eNB_ue_context_s *ue_context_p; + s1ap_eNB_instance_t *s1ap_eNB_instance_p; + S1AP_S1AP_PDU_t pdu; + S1AP_UplinkNASTransport_t *out; + S1AP_UplinkNASTransport_IEs_t *ie; + uint8_t *buffer; + uint32_t length; + DevAssert(s1ap_uplink_nas_p != NULL); + /* Retrieve the S1AP eNB instance associated with Mod_id */ + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + DevAssert(s1ap_eNB_instance_p != NULL); + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, s1ap_uplink_nas_p->eNB_ue_s1ap_id)) == NULL) { + /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ + S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %06x\n", + s1ap_uplink_nas_p->eNB_ue_s1ap_id); + return -1; + } - /* Prepare the S1AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_uplinkNASTransport; - pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; - pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_UplinkNASTransport; - out = &pdu.choice.initiatingMessage.value.choice.UplinkNASTransport; - /* mandatory */ - ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_MME_UE_S1AP_ID; - ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_ENB_UE_S1AP_ID; - ie->value.choice.ENB_UE_S1AP_ID = ue_context_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_NAS_PDU; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_NAS_PDU; - ie->value.choice.NAS_PDU.buf = s1ap_uplink_nas_p->nas_pdu.buffer; - ie->value.choice.NAS_PDU.size = s1ap_uplink_nas_p->nas_pdu.length; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_EUTRAN_CGI; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI; - MCC_MNC_TO_PLMNID( - s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity], - s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity], - s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], - &ie->value.choice.EUTRAN_CGI.pLMNidentity); - //#warning "TODO get cell id from RRC" - MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id, - 0, - &ie->value.choice.EUTRAN_CGI.cell_ID); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_TAI; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_TAI; - MCC_MNC_TO_PLMNID( - s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity], - s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity], - s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], - &ie->value.choice.TAI.pLMNidentity); - TAC_TO_ASN1(s1ap_eNB_instance_p->tac, &ie->value.choice.TAI.tAC); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* optional */ -#if (S1AP_VERSION >= MAKE_VERSION(10, 0, 0)) + /* Uplink NAS transport can occur either during an s1ap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || + ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { + S1AP_WARN("You are attempting to send NAS data over non-connected " + "eNB ue s1ap id: %u, current state: %d\n", + s1ap_uplink_nas_p->eNB_ue_s1ap_id, ue_context_p->ue_state); + return -1; + } - if (0) { + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_uplinkNASTransport; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_UplinkNASTransport; + out = &pdu.choice.initiatingMessage.value.choice.UplinkNASTransport; + /* mandatory */ ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_GW_TransportLayerAddress; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_TransportLayerAddress; - // ie->value.choice.TransportLayerAddress = ; + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ -#if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) - - if (0) { + /* mandatory */ + ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = ue_context_p->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_NAS_PDU; + ie->value.choice.NAS_PDU.buf = s1ap_uplink_nas_p->nas_pdu.buffer; + ie->value.choice.NAS_PDU.size = s1ap_uplink_nas_p->nas_pdu.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_SIPTO_L_GW_TransportLayerAddress; + ie->id = S1AP_ProtocolIE_ID_id_EUTRAN_CGI; ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_TransportLayerAddress; - // ie->value.choice.TransportLayerAddress = ; + ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI; + MCC_MNC_TO_PLMNID( + s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], + &ie->value.choice.EUTRAN_CGI.pLMNidentity); + //#warning "TODO get cell id from RRC" + MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id, + 0, + &ie->value.choice.EUTRAN_CGI.cell_ID); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (0) { + /* mandatory */ ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_LHN_ID; + ie->id = S1AP_ProtocolIE_ID_id_TAI; ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_LHN_ID; - // ie->value.choice.LHN_ID =; + ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_TAI; + MCC_MNC_TO_PLMNID( + s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity], + s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], + &ie->value.choice.TAI.pLMNidentity); + TAC_TO_ASN1(s1ap_eNB_instance_p->tac, &ie->value.choice.TAI.tAC); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* optional */ +#if (S1AP_VERSION >= MAKE_VERSION(10, 0, 0)) + + if (0) { + ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_GW_TransportLayerAddress; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_TransportLayerAddress; + // ie->value.choice.TransportLayerAddress = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ +#if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) + + if (0) { + ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_SIPTO_L_GW_TransportLayerAddress; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_TransportLayerAddress; + // ie->value.choice.TransportLayerAddress = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + if (0) { + ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_LHN_ID; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_LHN_ID; + // ie->value.choice.LHN_ID =; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } #endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ #endif /* #if (S1AP_VERSION >= MAKE_VERSION(10, 0, 0)) */ - if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { - S1AP_ERROR("Failed to encode uplink NAS transport\n"); - /* Encode procedure has failed... */ - return -1; - } + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { + S1AP_ERROR("Failed to encode uplink NAS transport\n"); + /* Encode procedure has failed... */ + return -1; + } - MSC_LOG_TX_MESSAGE( - MSC_S1AP_ENB, - MSC_S1AP_MME, - (const char *)NULL, - 0, - MSC_AS_TIME_FMT" uplinkNASTransport initiatingMessage eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->eNB_ue_s1ap_id, - ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ - s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, - ue_context_p->mme_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); - return 0; + MSC_LOG_TX_MESSAGE( + MSC_S1AP_ENB, + MSC_S1AP_MME, + (const char *)NULL, + 0, + MSC_AS_TIME_FMT" uplinkNASTransport initiatingMessage eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->eNB_ue_s1ap_id, + ue_context_p->mme_ue_s1ap_id); + /* UE associated signalling -> use the allocated stream */ + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + return 0; } @@ -721,549 +723,549 @@ int s1ap_eNB_nas_non_delivery_ind(instance_t instance, s1ap_nas_non_delivery_ind_t *s1ap_nas_non_delivery_ind) //------------------------------------------------------------------------------ { - struct s1ap_eNB_ue_context_s *ue_context_p; - s1ap_eNB_instance_t *s1ap_eNB_instance_p; - S1AP_S1AP_PDU_t pdu; - S1AP_NASNonDeliveryIndication_t *out; - S1AP_NASNonDeliveryIndication_IEs_t *ie; - uint8_t *buffer; - uint32_t length; - DevAssert(s1ap_nas_non_delivery_ind != NULL); - /* Retrieve the S1AP eNB instance associated with Mod_id */ - s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(s1ap_eNB_instance_p != NULL); - - if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, s1ap_nas_non_delivery_ind->eNB_ue_s1ap_id)) == NULL) { - /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ - S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %06x\n", - s1ap_nas_non_delivery_ind->eNB_ue_s1ap_id); - MSC_LOG_EVENT( - MSC_S1AP_ENB, - MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to MME failed, no context for eNB_ue_s1ap_id %06x", - s1ap_nas_non_delivery_ind->eNB_ue_s1ap_id); - return -1; - } + struct s1ap_eNB_ue_context_s *ue_context_p; + s1ap_eNB_instance_t *s1ap_eNB_instance_p; + S1AP_S1AP_PDU_t pdu; + S1AP_NASNonDeliveryIndication_t *out; + S1AP_NASNonDeliveryIndication_IEs_t *ie; + uint8_t *buffer; + uint32_t length; + DevAssert(s1ap_nas_non_delivery_ind != NULL); + /* Retrieve the S1AP eNB instance associated with Mod_id */ + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + DevAssert(s1ap_eNB_instance_p != NULL); + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, s1ap_nas_non_delivery_ind->eNB_ue_s1ap_id)) == NULL) { + /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ + S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %06x\n", + s1ap_nas_non_delivery_ind->eNB_ue_s1ap_id); + MSC_LOG_EVENT( + MSC_S1AP_ENB, + MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to MME failed, no context for eNB_ue_s1ap_id %06x", + s1ap_nas_non_delivery_ind->eNB_ue_s1ap_id); + return -1; + } - /* Prepare the S1AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_NASNonDeliveryIndication; - pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; - pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_NASNonDeliveryIndication; - out = &pdu.choice.initiatingMessage.value.choice.NASNonDeliveryIndication; - /* mandatory */ - ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_MME_UE_S1AP_ID; - ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_ENB_UE_S1AP_ID; - ie->value.choice.ENB_UE_S1AP_ID = ue_context_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_NAS_PDU; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_NAS_PDU; - ie->value.choice.NAS_PDU.buf = s1ap_nas_non_delivery_ind->nas_pdu.buffer; - ie->value.choice.NAS_PDU.size = s1ap_nas_non_delivery_ind->nas_pdu.length; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_Cause; - ie->criticality = S1AP_Criticality_ignore; - /* Send a dummy cause */ - ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_Cause; - ie->value.choice.Cause.present = S1AP_Cause_PR_radioNetwork; - ie->value.choice.Cause.choice.radioNetwork = S1AP_CauseRadioNetwork_radio_connection_with_ue_lost; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_NASNonDeliveryIndication; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_NASNonDeliveryIndication; + out = &pdu.choice.initiatingMessage.value.choice.NASNonDeliveryIndication; + /* mandatory */ + ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = ue_context_p->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_NAS_PDU; + ie->value.choice.NAS_PDU.buf = s1ap_nas_non_delivery_ind->nas_pdu.buffer; + ie->value.choice.NAS_PDU.size = s1ap_nas_non_delivery_ind->nas_pdu.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_Cause; + ie->criticality = S1AP_Criticality_ignore; + /* Send a dummy cause */ + ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_Cause; + ie->value.choice.Cause.present = S1AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = S1AP_CauseRadioNetwork_radio_connection_with_ue_lost; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { - S1AP_ERROR("Failed to encode NAS NON delivery indication\n"); - /* Encode procedure has failed... */ - MSC_LOG_EVENT( - MSC_S1AP_ENB, - MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to MME failed (encoding)"); - return -1; - } + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { + S1AP_ERROR("Failed to encode NAS NON delivery indication\n"); + /* Encode procedure has failed... */ + MSC_LOG_EVENT( + MSC_S1AP_ENB, + MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to MME failed (encoding)"); + return -1; + } - MSC_LOG_TX_MESSAGE( - MSC_S1AP_ENB, - MSC_S1AP_MME, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" NASNonDeliveryIndication initiatingMessage eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->eNB_ue_s1ap_id, - ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ - s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, - ue_context_p->mme_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); - return 0; + MSC_LOG_TX_MESSAGE( + MSC_S1AP_ENB, + MSC_S1AP_MME, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" NASNonDeliveryIndication initiatingMessage eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->eNB_ue_s1ap_id, + ue_context_p->mme_ue_s1ap_id); + /* UE associated signalling -> use the allocated stream */ + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + return 0; } //------------------------------------------------------------------------------ int s1ap_eNB_initial_ctxt_resp( - instance_t instance, s1ap_initial_context_setup_resp_t *initial_ctxt_resp_p) + instance_t instance, s1ap_initial_context_setup_resp_t *initial_ctxt_resp_p) //------------------------------------------------------------------------------ { - s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; - struct s1ap_eNB_ue_context_s *ue_context_p = NULL; - S1AP_S1AP_PDU_t pdu; - S1AP_InitialContextSetupResponse_t *out; - S1AP_InitialContextSetupResponseIEs_t *ie; - uint8_t *buffer = NULL; - uint32_t length; - int i; - /* Retrieve the S1AP eNB instance associated with Mod_id */ - s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(initial_ctxt_resp_p != NULL); - DevAssert(s1ap_eNB_instance_p != NULL); - - if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, - initial_ctxt_resp_p->eNB_ue_s1ap_id)) == NULL) { - /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ - S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", - initial_ctxt_resp_p->eNB_ue_s1ap_id); - return -1; - } - - /* Uplink NAS transport can occur either during an s1ap connected state - * or during initial attach (for example: NAS authentication). - */ - if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || - ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { - S1AP_WARN("You are attempting to send NAS data over non-connected " - "eNB ue s1ap id: %06x, current state: %d\n", - initial_ctxt_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state); - return -1; - } + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + S1AP_S1AP_PDU_t pdu; + S1AP_InitialContextSetupResponse_t *out; + S1AP_InitialContextSetupResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + /* Retrieve the S1AP eNB instance associated with Mod_id */ + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + DevAssert(initial_ctxt_resp_p != NULL); + DevAssert(s1ap_eNB_instance_p != NULL); + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + initial_ctxt_resp_p->eNB_ue_s1ap_id)) == NULL) { + /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ + S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", + initial_ctxt_resp_p->eNB_ue_s1ap_id); + return -1; + } - /* Prepare the S1AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_InitialContextSetup; - pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; - pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_InitialContextSetupResponse; - out = &pdu.choice.successfulOutcome.value.choice.InitialContextSetupResponse; - /* mandatory */ - ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_MME_UE_S1AP_ID; - ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_ENB_UE_S1AP_ID; - ie->value.choice.ENB_UE_S1AP_ID = initial_ctxt_resp_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_E_RABSetupListCtxtSURes; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_E_RABSetupListCtxtSURes; + /* Uplink NAS transport can occur either during an s1ap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || + ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { + S1AP_WARN("You are attempting to send NAS data over non-connected " + "eNB ue s1ap id: %06x, current state: %d\n", + initial_ctxt_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state); + return -1; + } - for (i = 0; i < initial_ctxt_resp_p->nb_of_e_rabs; i++) { - S1AP_E_RABSetupItemCtxtSUResIEs_t *item; + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_InitialContextSetup; + pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_InitialContextSetupResponse; + out = &pdu.choice.successfulOutcome.value.choice.InitialContextSetupResponse; /* mandatory */ - item = (S1AP_E_RABSetupItemCtxtSUResIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupItemCtxtSUResIEs_t)); - item->id = S1AP_ProtocolIE_ID_id_E_RABSetupItemCtxtSURes; - item->criticality = S1AP_Criticality_ignore; - item->value.present = S1AP_E_RABSetupItemCtxtSUResIEs__value_PR_E_RABSetupItemCtxtSURes; - item->value.choice.E_RABSetupItemCtxtSURes.e_RAB_ID = initial_ctxt_resp_p->e_rabs[i].e_rab_id; - GTP_TEID_TO_ASN1(initial_ctxt_resp_p->e_rabs[i].gtp_teid, &item->value.choice.E_RABSetupItemCtxtSURes.gTP_TEID); - item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf = malloc(initial_ctxt_resp_p->e_rabs[i].eNB_addr.length); - memcpy(item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf, - initial_ctxt_resp_p->e_rabs[i].eNB_addr.buffer, - initial_ctxt_resp_p->e_rabs[i].eNB_addr.length); - item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.size = initial_ctxt_resp_p->e_rabs[i].eNB_addr.length; - item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.bits_unused = 0; - S1AP_DEBUG("initial_ctxt_resp_p: e_rab ID %ld, enb_addr %d.%d.%d.%d, SIZE %ld \n", - item->value.choice.E_RABSetupItemCtxtSURes.e_RAB_ID, - item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf[0], - item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf[1], - item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf[2], - item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf[3], - item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.size); - ASN_SEQUENCE_ADD(&ie->value.choice.E_RABSetupListCtxtSURes.list, item); - } - - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* optional */ - if (initial_ctxt_resp_p->nb_of_e_rabs_failed) { ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_E_RABFailedToSetupListCtxtSURes; + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_E_RABList; - - for (i = 0; i < initial_ctxt_resp_p->nb_of_e_rabs_failed; i++) { - S1AP_E_RABItemIEs_t *item; - /* mandatory */ - item = (S1AP_E_RABItemIEs_t *)calloc(1, sizeof(S1AP_E_RABItemIEs_t)); - item->id = S1AP_ProtocolIE_ID_id_E_RABItem; - item->criticality = S1AP_Criticality_ignore; - item->value.present = S1AP_E_RABItemIEs__value_PR_E_RABItem; - item->value.choice.E_RABItem.e_RAB_ID = initial_ctxt_resp_p->e_rabs_failed[i].e_rab_id; - item->value.choice.E_RABItem.cause.present = initial_ctxt_resp_p->e_rabs_failed[i].cause; - - switch(item->value.choice.E_RABItem.cause.present) { - case S1AP_Cause_PR_radioNetwork: - item->value.choice.E_RABItem.cause.choice.radioNetwork = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; - break; - - case S1AP_Cause_PR_transport: - item->value.choice.E_RABItem.cause.choice.transport = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; - break; - - case S1AP_Cause_PR_nas: - item->value.choice.E_RABItem.cause.choice.nas = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; - break; - - case S1AP_Cause_PR_protocol: - item->value.choice.E_RABItem.cause.choice.protocol = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; - break; - - case S1AP_Cause_PR_misc: - item->value.choice.E_RABItem.cause.choice.misc = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; - break; - - case S1AP_Cause_PR_NOTHING: - default: - break; - } - - S1AP_DEBUG("initial context setup response: failed e_rab ID %ld\n", item->value.choice.E_RABItem.e_RAB_ID); - ASN_SEQUENCE_ADD(&ie->value.choice.E_RABList.list, item); - } - + ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (0) { + /* mandatory */ ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_CriticalityDiagnostics; - // ie->value.choice.CriticalityDiagnostics =; + ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = initial_ctxt_resp_p->eNB_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { - S1AP_ERROR("Failed to encode uplink NAS transport\n"); - /* Encode procedure has failed... */ - return -1; - } - - MSC_LOG_TX_MESSAGE( - MSC_S1AP_ENB, - MSC_S1AP_MME, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - initial_ctxt_resp_p->eNB_ue_s1ap_id, - ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ - s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, - ue_context_p->mme_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); - return 0; -} - -//------------------------------------------------------------------------------ -int s1ap_eNB_ue_capabilities(instance_t instance, - s1ap_ue_cap_info_ind_t *ue_cap_info_ind_p) -//------------------------------------------------------------------------------ -{ - s1ap_eNB_instance_t *s1ap_eNB_instance_p; - struct s1ap_eNB_ue_context_s *ue_context_p; - S1AP_S1AP_PDU_t pdu; - S1AP_UECapabilityInfoIndication_t *out; - S1AP_UECapabilityInfoIndicationIEs_t *ie; - uint8_t *buffer; - uint32_t length; - /* Retrieve the S1AP eNB instance associated with Mod_id */ - s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(ue_cap_info_ind_p != NULL); - DevAssert(s1ap_eNB_instance_p != NULL); - - if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, - ue_cap_info_ind_p->eNB_ue_s1ap_id)) == NULL) { - /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ - S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n", - ue_cap_info_ind_p->eNB_ue_s1ap_id); - return -1; - } - - /* UE capabilities message can occur either during an s1ap connected state - * or during initial attach (for example: NAS authentication). - */ - if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || - ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { - S1AP_WARN("You are attempting to send NAS data over non-connected " - "eNB ue s1ap id: %u, current state: %d\n", - ue_cap_info_ind_p->eNB_ue_s1ap_id, ue_context_p->ue_state); - return -1; - } - - /* Prepare the S1AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_UECapabilityInfoIndication; - pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; - pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_UECapabilityInfoIndication; - out = &pdu.choice.initiatingMessage.value.choice.UECapabilityInfoIndication; - /* mandatory */ - ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_UECapabilityInfoIndicationIEs__value_PR_MME_UE_S1AP_ID; - ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_UECapabilityInfoIndicationIEs__value_PR_ENB_UE_S1AP_ID; - ie->value.choice.ENB_UE_S1AP_ID = ue_cap_info_ind_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_UERadioCapability; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_UECapabilityInfoIndicationIEs__value_PR_UERadioCapability; - ie->value.choice.UERadioCapability.buf = ue_cap_info_ind_p->ue_radio_cap.buffer; - ie->value.choice.UERadioCapability.size = ue_cap_info_ind_p->ue_radio_cap.length; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* optional */ -#if (S1AP_VERSION >= MAKE_VERSION(12, 0, 0)) - - if (0) { - ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_UERadioCapabilityForPaging; + /* mandatory */ + ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABSetupListCtxtSURes; ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_UECapabilityInfoIndicationIEs__value_PR_UERadioCapabilityForPaging; - // ie->value.choice.UERadioCapabilityForPaging = ; + ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_E_RABSetupListCtxtSURes; + + for (i = 0; i < initial_ctxt_resp_p->nb_of_e_rabs; i++) { + S1AP_E_RABSetupItemCtxtSUResIEs_t *item; + /* mandatory */ + item = (S1AP_E_RABSetupItemCtxtSUResIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupItemCtxtSUResIEs_t)); + item->id = S1AP_ProtocolIE_ID_id_E_RABSetupItemCtxtSURes; + item->criticality = S1AP_Criticality_ignore; + item->value.present = S1AP_E_RABSetupItemCtxtSUResIEs__value_PR_E_RABSetupItemCtxtSURes; + item->value.choice.E_RABSetupItemCtxtSURes.e_RAB_ID = initial_ctxt_resp_p->e_rabs[i].e_rab_id; + GTP_TEID_TO_ASN1(initial_ctxt_resp_p->e_rabs[i].gtp_teid, &item->value.choice.E_RABSetupItemCtxtSURes.gTP_TEID); + item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf = malloc(initial_ctxt_resp_p->e_rabs[i].eNB_addr.length); + memcpy(item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf, + initial_ctxt_resp_p->e_rabs[i].eNB_addr.buffer, + initial_ctxt_resp_p->e_rabs[i].eNB_addr.length); + item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.size = initial_ctxt_resp_p->e_rabs[i].eNB_addr.length; + item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.bits_unused = 0; + S1AP_DEBUG("initial_ctxt_resp_p: e_rab ID %ld, enb_addr %d.%d.%d.%d, SIZE %ld \n", + item->value.choice.E_RABSetupItemCtxtSURes.e_RAB_ID, + item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf[0], + item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf[1], + item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf[2], + item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf[3], + item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.size); + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABSetupListCtxtSURes.list, item); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } -#endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ + /* optional */ + if (initial_ctxt_resp_p->nb_of_e_rabs_failed) { + ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABFailedToSetupListCtxtSURes; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_E_RABList; + + for (i = 0; i < initial_ctxt_resp_p->nb_of_e_rabs_failed; i++) { + S1AP_E_RABItemIEs_t *item; + /* mandatory */ + item = (S1AP_E_RABItemIEs_t *)calloc(1, sizeof(S1AP_E_RABItemIEs_t)); + item->id = S1AP_ProtocolIE_ID_id_E_RABItem; + item->criticality = S1AP_Criticality_ignore; + item->value.present = S1AP_E_RABItemIEs__value_PR_E_RABItem; + item->value.choice.E_RABItem.e_RAB_ID = initial_ctxt_resp_p->e_rabs_failed[i].e_rab_id; + item->value.choice.E_RABItem.cause.present = initial_ctxt_resp_p->e_rabs_failed[i].cause; + + switch(item->value.choice.E_RABItem.cause.present) { + case S1AP_Cause_PR_radioNetwork: + item->value.choice.E_RABItem.cause.choice.radioNetwork = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_transport: + item->value.choice.E_RABItem.cause.choice.transport = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_nas: + item->value.choice.E_RABItem.cause.choice.nas = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_protocol: + item->value.choice.E_RABItem.cause.choice.protocol = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_misc: + item->value.choice.E_RABItem.cause.choice.misc = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_NOTHING: + default: + break; + } + + S1AP_DEBUG("initial context setup response: failed e_rab ID %ld\n", item->value.choice.E_RABItem.e_RAB_ID); + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABList.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { - /* Encode procedure has failed... */ - S1AP_ERROR("Failed to encode UE capabilities indication\n"); - return -1; - } + /* optional */ + if (0) { + ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics =; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - MSC_LOG_TX_MESSAGE( - MSC_S1AP_ENB, - MSC_S1AP_MME, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" UECapabilityInfoIndication initiatingMessage eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - ue_cap_info_ind_p->eNB_ue_s1ap_id, - ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ - s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, - ue_context_p->mme_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); - return 0; + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { + S1AP_ERROR("Failed to encode uplink NAS transport\n"); + /* Encode procedure has failed... */ + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_S1AP_ENB, + MSC_S1AP_MME, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + initial_ctxt_resp_p->eNB_ue_s1ap_id, + ue_context_p->mme_ue_s1ap_id); + /* UE associated signalling -> use the allocated stream */ + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + return 0; } //------------------------------------------------------------------------------ -int s1ap_eNB_e_rab_setup_resp(instance_t instance, - s1ap_e_rab_setup_resp_t *e_rab_setup_resp_p) +int s1ap_eNB_ue_capabilities(instance_t instance, + s1ap_ue_cap_info_ind_t *ue_cap_info_ind_p) //------------------------------------------------------------------------------ { - s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; - struct s1ap_eNB_ue_context_s *ue_context_p = NULL; - S1AP_S1AP_PDU_t pdu; - S1AP_E_RABSetupResponse_t *out; - S1AP_E_RABSetupResponseIEs_t *ie; - uint8_t *buffer = NULL; - uint32_t length; - int i; - /* Retrieve the S1AP eNB instance associated with Mod_id */ - s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(e_rab_setup_resp_p != NULL); - DevAssert(s1ap_eNB_instance_p != NULL); - - if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, - e_rab_setup_resp_p->eNB_ue_s1ap_id)) == NULL) { - /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ - S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", - e_rab_setup_resp_p->eNB_ue_s1ap_id); - return -1; - } - - /* Uplink NAS transport can occur either during an s1ap connected state - * or during initial attach (for example: NAS authentication). - */ - if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || - ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { - S1AP_WARN("You are attempting to send NAS data over non-connected " - "eNB ue s1ap id: %06x, current state: %d\n", - e_rab_setup_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state); - return -1; - } - - /* Prepare the S1AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_E_RABModify; - pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; - pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABSetupResponse; - out = &pdu.choice.successfulOutcome.value.choice.E_RABSetupResponse; - /* mandatory */ - ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_MME_UE_S1AP_ID; - ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_ENB_UE_S1AP_ID; - ie->value.choice.ENB_UE_S1AP_ID = e_rab_setup_resp_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* optional */ - if (e_rab_setup_resp_p->nb_of_e_rabs > 0) { - ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_E_RABSetupListBearerSURes; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_E_RABSetupListBearerSURes; - - for (i = 0; i < e_rab_setup_resp_p->nb_of_e_rabs; i++) { - S1AP_E_RABSetupItemBearerSUResIEs_t *item; - /* mandatory */ - item = (S1AP_E_RABSetupItemBearerSUResIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupItemBearerSUResIEs_t)); - item->id = S1AP_ProtocolIE_ID_id_E_RABSetupItemBearerSURes; - item->criticality = S1AP_Criticality_ignore; - item->value.present = S1AP_E_RABSetupItemBearerSUResIEs__value_PR_E_RABSetupItemBearerSURes; - item->value.choice.E_RABSetupItemBearerSURes.e_RAB_ID = e_rab_setup_resp_p->e_rabs[i].e_rab_id; - GTP_TEID_TO_ASN1(e_rab_setup_resp_p->e_rabs[i].gtp_teid, &item->value.choice.E_RABSetupItemBearerSURes.gTP_TEID); - item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf = malloc(e_rab_setup_resp_p->e_rabs[i].eNB_addr.length); - memcpy(item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf, - e_rab_setup_resp_p->e_rabs[i].eNB_addr.buffer, - e_rab_setup_resp_p->e_rabs[i].eNB_addr.length); - item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.size = e_rab_setup_resp_p->e_rabs[i].eNB_addr.length; - item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.bits_unused = 0; - S1AP_DEBUG("e_rab_setup_resp: e_rab ID %ld, teid %u, enb_addr %d.%d.%d.%d, SIZE %ld\n", - item->value.choice.E_RABSetupItemBearerSURes.e_RAB_ID, - e_rab_setup_resp_p->e_rabs[i].gtp_teid, - item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf[0], - item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf[1], - item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf[2], - item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf[3], - item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.size); - ASN_SEQUENCE_ADD(&ie->value.choice.E_RABSetupListBearerSURes.list, item); + s1ap_eNB_instance_t *s1ap_eNB_instance_p; + struct s1ap_eNB_ue_context_s *ue_context_p; + S1AP_S1AP_PDU_t pdu; + S1AP_UECapabilityInfoIndication_t *out; + S1AP_UECapabilityInfoIndicationIEs_t *ie; + uint8_t *buffer; + uint32_t length; + /* Retrieve the S1AP eNB instance associated with Mod_id */ + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + DevAssert(ue_cap_info_ind_p != NULL); + DevAssert(s1ap_eNB_instance_p != NULL); + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + ue_cap_info_ind_p->eNB_ue_s1ap_id)) == NULL) { + /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ + S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n", + ue_cap_info_ind_p->eNB_ue_s1ap_id); + return -1; } - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (e_rab_setup_resp_p->nb_of_e_rabs_failed > 0) { - ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_E_RABFailedToSetupListBearerSURes; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_E_RABList; - - for (i = 0; i < e_rab_setup_resp_p->nb_of_e_rabs_failed; i++) { - S1AP_E_RABItemIEs_t *item; - item = (S1AP_E_RABItemIEs_t *)calloc(1, sizeof(S1AP_E_RABItemIEs_t)); - item->id = S1AP_ProtocolIE_ID_id_E_RABItem; - item->criticality = S1AP_Criticality_ignore; - item->value.present = S1AP_E_RABItemIEs__value_PR_E_RABItem; - item->value.choice.E_RABItem.e_RAB_ID = e_rab_setup_resp_p->e_rabs_failed[i].e_rab_id; - item->value.choice.E_RABItem.cause.present = e_rab_setup_resp_p->e_rabs_failed[i].cause; + /* UE capabilities message can occur either during an s1ap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || + ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { + S1AP_WARN("You are attempting to send NAS data over non-connected " + "eNB ue s1ap id: %u, current state: %d\n", + ue_cap_info_ind_p->eNB_ue_s1ap_id, ue_context_p->ue_state); + return -1; + } - switch(item->value.choice.E_RABItem.cause.present) { - case S1AP_Cause_PR_radioNetwork: - item->value.choice.E_RABItem.cause.choice.radioNetwork = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; - break; + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_UECapabilityInfoIndication; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_UECapabilityInfoIndication; + out = &pdu.choice.initiatingMessage.value.choice.UECapabilityInfoIndication; + /* mandatory */ + ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_UECapabilityInfoIndicationIEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_UECapabilityInfoIndicationIEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = ue_cap_info_ind_p->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_UERadioCapability; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_UECapabilityInfoIndicationIEs__value_PR_UERadioCapability; + ie->value.choice.UERadioCapability.buf = ue_cap_info_ind_p->ue_radio_cap.buffer; + ie->value.choice.UERadioCapability.size = ue_cap_info_ind_p->ue_radio_cap.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* optional */ +#if (S1AP_VERSION >= MAKE_VERSION(12, 0, 0)) - case S1AP_Cause_PR_transport: - item->value.choice.E_RABItem.cause.choice.transport = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; - break; + if (0) { + ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_UERadioCapabilityForPaging; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_UECapabilityInfoIndicationIEs__value_PR_UERadioCapabilityForPaging; + // ie->value.choice.UERadioCapabilityForPaging = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - case S1AP_Cause_PR_nas: - item->value.choice.E_RABItem.cause.choice.nas = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; - break; +#endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ - case S1AP_Cause_PR_protocol: - item->value.choice.E_RABItem.cause.choice.protocol = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; - break; + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { + /* Encode procedure has failed... */ + S1AP_ERROR("Failed to encode UE capabilities indication\n"); + return -1; + } - case S1AP_Cause_PR_misc: - item->value.choice.E_RABItem.cause.choice.misc = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; - break; + MSC_LOG_TX_MESSAGE( + MSC_S1AP_ENB, + MSC_S1AP_MME, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" UECapabilityInfoIndication initiatingMessage eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_cap_info_ind_p->eNB_ue_s1ap_id, + ue_context_p->mme_ue_s1ap_id); + /* UE associated signalling -> use the allocated stream */ + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + return 0; +} - case S1AP_Cause_PR_NOTHING: - default: - break; - } +//------------------------------------------------------------------------------ +int s1ap_eNB_e_rab_setup_resp(instance_t instance, + s1ap_e_rab_setup_resp_t *e_rab_setup_resp_p) +//------------------------------------------------------------------------------ +{ + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + S1AP_S1AP_PDU_t pdu; + S1AP_E_RABSetupResponse_t *out; + S1AP_E_RABSetupResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + /* Retrieve the S1AP eNB instance associated with Mod_id */ + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + DevAssert(e_rab_setup_resp_p != NULL); + DevAssert(s1ap_eNB_instance_p != NULL); + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + e_rab_setup_resp_p->eNB_ue_s1ap_id)) == NULL) { + /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ + S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", + e_rab_setup_resp_p->eNB_ue_s1ap_id); + return -1; + } - S1AP_DEBUG("e_rab_modify_resp: failed e_rab ID %ld\n", item->value.choice.E_RABItem.e_RAB_ID); - ASN_SEQUENCE_ADD(&ie->value.choice.E_RABList.list, item); + /* Uplink NAS transport can occur either during an s1ap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || + ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { + S1AP_WARN("You are attempting to send NAS data over non-connected " + "eNB ue s1ap id: %06x, current state: %d\n", + e_rab_setup_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state); + return -1; } + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_E_RABModify; + pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABSetupResponse; + out = &pdu.choice.successfulOutcome.value.choice.E_RABSetupResponse; + /* mandatory */ + ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (0) { + /* mandatory */ ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_CriticalityDiagnostics; - // ie->value.choice.CriticalityDiagnostics = ; + ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = e_rab_setup_resp_p->eNB_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - /* S1AP_E_RABSetupListBearerSURes_t e_RABSetupListBearerSURes; - memset(&e_RABSetupListBearerSURes, 0, sizeof(S1AP_E_RABSetupListBearerSURes_t)); - if (s1ap_encode_s1ap_e_rabsetuplistbearersures(&e_RABSetupListBearerSURes, &initial_ies_p->e_RABSetupListBearerSURes.s1ap_E_RABSetupItemBearerSURes) < 0 ) - return -1; - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_S1AP_E_RABSetupListBearerSURes, &e_RABSetupListBearerSURes); - */ - fprintf(stderr, "start encode\n"); + /* optional */ + if (e_rab_setup_resp_p->nb_of_e_rabs > 0) { + ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABSetupListBearerSURes; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_E_RABSetupListBearerSURes; + + for (i = 0; i < e_rab_setup_resp_p->nb_of_e_rabs; i++) { + S1AP_E_RABSetupItemBearerSUResIEs_t *item; + /* mandatory */ + item = (S1AP_E_RABSetupItemBearerSUResIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupItemBearerSUResIEs_t)); + item->id = S1AP_ProtocolIE_ID_id_E_RABSetupItemBearerSURes; + item->criticality = S1AP_Criticality_ignore; + item->value.present = S1AP_E_RABSetupItemBearerSUResIEs__value_PR_E_RABSetupItemBearerSURes; + item->value.choice.E_RABSetupItemBearerSURes.e_RAB_ID = e_rab_setup_resp_p->e_rabs[i].e_rab_id; + GTP_TEID_TO_ASN1(e_rab_setup_resp_p->e_rabs[i].gtp_teid, &item->value.choice.E_RABSetupItemBearerSURes.gTP_TEID); + item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf = malloc(e_rab_setup_resp_p->e_rabs[i].eNB_addr.length); + memcpy(item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf, + e_rab_setup_resp_p->e_rabs[i].eNB_addr.buffer, + e_rab_setup_resp_p->e_rabs[i].eNB_addr.length); + item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.size = e_rab_setup_resp_p->e_rabs[i].eNB_addr.length; + item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.bits_unused = 0; + S1AP_DEBUG("e_rab_setup_resp: e_rab ID %ld, teid %u, enb_addr %d.%d.%d.%d, SIZE %ld\n", + item->value.choice.E_RABSetupItemBearerSURes.e_RAB_ID, + e_rab_setup_resp_p->e_rabs[i].gtp_teid, + item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf[0], + item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf[1], + item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf[2], + item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.buf[3], + item->value.choice.E_RABSetupItemBearerSURes.transportLayerAddress.size); + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABSetupListBearerSURes.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { - S1AP_ERROR("Failed to encode uplink transport\n"); - /* Encode procedure has failed... */ - return -1; - } + /* optional */ + if (e_rab_setup_resp_p->nb_of_e_rabs_failed > 0) { + ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABFailedToSetupListBearerSURes; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_E_RABList; + + for (i = 0; i < e_rab_setup_resp_p->nb_of_e_rabs_failed; i++) { + S1AP_E_RABItemIEs_t *item; + item = (S1AP_E_RABItemIEs_t *)calloc(1, sizeof(S1AP_E_RABItemIEs_t)); + item->id = S1AP_ProtocolIE_ID_id_E_RABItem; + item->criticality = S1AP_Criticality_ignore; + item->value.present = S1AP_E_RABItemIEs__value_PR_E_RABItem; + item->value.choice.E_RABItem.e_RAB_ID = e_rab_setup_resp_p->e_rabs_failed[i].e_rab_id; + item->value.choice.E_RABItem.cause.present = e_rab_setup_resp_p->e_rabs_failed[i].cause; + + switch(item->value.choice.E_RABItem.cause.present) { + case S1AP_Cause_PR_radioNetwork: + item->value.choice.E_RABItem.cause.choice.radioNetwork = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_transport: + item->value.choice.E_RABItem.cause.choice.transport = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_nas: + item->value.choice.E_RABItem.cause.choice.nas = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_protocol: + item->value.choice.E_RABItem.cause.choice.protocol = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_misc: + item->value.choice.E_RABItem.cause.choice.misc = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_NOTHING: + default: + break; + } + + S1AP_DEBUG("e_rab_modify_resp: failed e_rab ID %ld\n", item->value.choice.E_RABItem.e_RAB_ID); + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABList.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - MSC_LOG_TX_MESSAGE( - MSC_S1AP_ENB, - MSC_S1AP_MME, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" E_RAN Setup successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - e_rab_setup_resp_p->eNB_ue_s1ap_id, - ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ - s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, - ue_context_p->mme_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); - return 0; + /* optional */ + if (0) { + ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* S1AP_E_RABSetupListBearerSURes_t e_RABSetupListBearerSURes; + memset(&e_RABSetupListBearerSURes, 0, sizeof(S1AP_E_RABSetupListBearerSURes_t)); + if (s1ap_encode_s1ap_e_rabsetuplistbearersures(&e_RABSetupListBearerSURes, &initial_ies_p->e_RABSetupListBearerSURes.s1ap_E_RABSetupItemBearerSURes) < 0 ) + return -1; + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_S1AP_E_RABSetupListBearerSURes, &e_RABSetupListBearerSURes); + */ + fprintf(stderr, "start encode\n"); + + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { + S1AP_ERROR("Failed to encode uplink transport\n"); + /* Encode procedure has failed... */ + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_S1AP_ENB, + MSC_S1AP_MME, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" E_RAN Setup successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + e_rab_setup_resp_p->eNB_ue_s1ap_id, + ue_context_p->mme_ue_s1ap_id); + /* UE associated signalling -> use the allocated stream */ + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + return 0; } //------------------------------------------------------------------------------ @@ -1271,325 +1273,562 @@ int s1ap_eNB_e_rab_modify_resp(instance_t instance, s1ap_e_rab_modify_resp_t *e_rab_modify_resp_p) //------------------------------------------------------------------------------ { - s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; - struct s1ap_eNB_ue_context_s *ue_context_p = NULL; - S1AP_S1AP_PDU_t pdu; - S1AP_E_RABModifyResponse_t *out; - S1AP_E_RABModifyResponseIEs_t *ie; - uint8_t *buffer = NULL; - uint32_t length; - int i; - /* Retrieve the S1AP eNB instance associated with Mod_id */ - s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(e_rab_modify_resp_p != NULL); - DevAssert(s1ap_eNB_instance_p != NULL); - - if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, - e_rab_modify_resp_p->eNB_ue_s1ap_id)) == NULL) { - /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ - S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", - e_rab_modify_resp_p->eNB_ue_s1ap_id); - return -1; - } - - /* Uplink NAS transport can occur either during an s1ap connected state - * or during initial attach (for example: NAS authentication). - */ - if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || - ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { - S1AP_WARN("You are attempting to send NAS data over non-connected " - "eNB ue s1ap id: %06x, current state: %d\n", - e_rab_modify_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state); - return -1; - } + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + S1AP_S1AP_PDU_t pdu; + S1AP_E_RABModifyResponse_t *out; + S1AP_E_RABModifyResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + /* Retrieve the S1AP eNB instance associated with Mod_id */ + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + DevAssert(e_rab_modify_resp_p != NULL); + DevAssert(s1ap_eNB_instance_p != NULL); + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + e_rab_modify_resp_p->eNB_ue_s1ap_id)) == NULL) { + /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ + S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", + e_rab_modify_resp_p->eNB_ue_s1ap_id); + return -1; + } - /* Prepare the S1AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_E_RABModify; - pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; - pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABModifyResponse; - out = &pdu.choice.successfulOutcome.value.choice.E_RABModifyResponse; - /* mandatory */ - ie = (S1AP_E_RABModifyResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_MME_UE_S1AP_ID; - ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_E_RABModifyResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_ENB_UE_S1AP_ID; - ie->value.choice.ENB_UE_S1AP_ID = e_rab_modify_resp_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* Uplink NAS transport can occur either during an s1ap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || + ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { + S1AP_WARN("You are attempting to send NAS data over non-connected " + "eNB ue s1ap id: %06x, current state: %d\n", + e_rab_modify_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state); + return -1; + } - /* optional */ - if (e_rab_modify_resp_p->nb_of_e_rabs > 0) { + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_E_RABModify; + pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABModifyResponse; + out = &pdu.choice.successfulOutcome.value.choice.E_RABModifyResponse; + /* mandatory */ ie = (S1AP_E_RABModifyResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_E_RABModifyListBearerModRes; + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_E_RABModifyListBearerModRes; - - for (i = 0; i < e_rab_modify_resp_p->nb_of_e_rabs; i++) { - S1AP_E_RABModifyItemBearerModResIEs_t *item; - item = (S1AP_E_RABModifyItemBearerModResIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyItemBearerModResIEs_t)); - item->id = S1AP_ProtocolIE_ID_id_E_RABModifyItemBearerModRes; - item->criticality = S1AP_Criticality_ignore; - item->value.present = S1AP_E_RABModifyItemBearerModResIEs__value_PR_E_RABModifyItemBearerModRes; - item->value.choice.E_RABModifyItemBearerModRes.e_RAB_ID = e_rab_modify_resp_p->e_rabs[i].e_rab_id; - S1AP_DEBUG("e_rab_modify_resp: modified e_rab ID %ld\n", item->value.choice.E_RABModifyItemBearerModRes.e_RAB_ID); - ASN_SEQUENCE_ADD(&ie->value.choice.E_RABModifyListBearerModRes.list, item); - } - + ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (e_rab_modify_resp_p->nb_of_e_rabs_failed > 0) { + /* mandatory */ ie = (S1AP_E_RABModifyResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_E_RABFailedToModifyList; + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_E_RABList; - - for (i = 0; i < e_rab_modify_resp_p->nb_of_e_rabs_failed; i++) { - S1AP_E_RABItemIEs_t *item; - item = (S1AP_E_RABItemIEs_t *)calloc(1, sizeof(S1AP_E_RABItemIEs_t)); - item->id = S1AP_ProtocolIE_ID_id_E_RABItem; - item->criticality = S1AP_Criticality_ignore; - item->value.present = S1AP_E_RABItemIEs__value_PR_E_RABItem; - item->value.choice.E_RABItem.e_RAB_ID = e_rab_modify_resp_p->e_rabs_failed[i].e_rab_id; - item->value.choice.E_RABItem.cause.present = e_rab_modify_resp_p->e_rabs_failed[i].cause; - - switch(item->value.choice.E_RABItem.cause.present) { - case S1AP_Cause_PR_radioNetwork: - item->value.choice.E_RABItem.cause.choice.radioNetwork = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; - break; + ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = e_rab_modify_resp_p->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - case S1AP_Cause_PR_transport: - item->value.choice.E_RABItem.cause.choice.transport = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; - break; + /* optional */ + if (e_rab_modify_resp_p->nb_of_e_rabs > 0) { + ie = (S1AP_E_RABModifyResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABModifyListBearerModRes; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_E_RABModifyListBearerModRes; + + for (i = 0; i < e_rab_modify_resp_p->nb_of_e_rabs; i++) { + S1AP_E_RABModifyItemBearerModResIEs_t *item; + item = (S1AP_E_RABModifyItemBearerModResIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyItemBearerModResIEs_t)); + item->id = S1AP_ProtocolIE_ID_id_E_RABModifyItemBearerModRes; + item->criticality = S1AP_Criticality_ignore; + item->value.present = S1AP_E_RABModifyItemBearerModResIEs__value_PR_E_RABModifyItemBearerModRes; + item->value.choice.E_RABModifyItemBearerModRes.e_RAB_ID = e_rab_modify_resp_p->e_rabs[i].e_rab_id; + S1AP_DEBUG("e_rab_modify_resp: modified e_rab ID %ld\n", item->value.choice.E_RABModifyItemBearerModRes.e_RAB_ID); + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABModifyListBearerModRes.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - case S1AP_Cause_PR_nas: - item->value.choice.E_RABItem.cause.choice.nas = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; - break; + /* optional */ + if (e_rab_modify_resp_p->nb_of_e_rabs_failed > 0) { + ie = (S1AP_E_RABModifyResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABFailedToModifyList; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_E_RABList; + + for (i = 0; i < e_rab_modify_resp_p->nb_of_e_rabs_failed; i++) { + S1AP_E_RABItemIEs_t *item; + item = (S1AP_E_RABItemIEs_t *)calloc(1, sizeof(S1AP_E_RABItemIEs_t)); + item->id = S1AP_ProtocolIE_ID_id_E_RABItem; + item->criticality = S1AP_Criticality_ignore; + item->value.present = S1AP_E_RABItemIEs__value_PR_E_RABItem; + item->value.choice.E_RABItem.e_RAB_ID = e_rab_modify_resp_p->e_rabs_failed[i].e_rab_id; + item->value.choice.E_RABItem.cause.present = e_rab_modify_resp_p->e_rabs_failed[i].cause; + + switch(item->value.choice.E_RABItem.cause.present) { + case S1AP_Cause_PR_radioNetwork: + item->value.choice.E_RABItem.cause.choice.radioNetwork = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_transport: + item->value.choice.E_RABItem.cause.choice.transport = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_nas: + item->value.choice.E_RABItem.cause.choice.nas = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_protocol: + item->value.choice.E_RABItem.cause.choice.protocol = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_misc: + item->value.choice.E_RABItem.cause.choice.misc = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_NOTHING: + default: + break; + } + + S1AP_DEBUG("e_rab_modify_resp: failed e_rab ID %ld\n", item->value.choice.E_RABItem.e_RAB_ID); + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABList.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - case S1AP_Cause_PR_protocol: - item->value.choice.E_RABItem.cause.choice.protocol = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; - break; + /* optional */ + if (0) { + ie = (S1AP_E_RABModifyResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - case S1AP_Cause_PR_misc: - item->value.choice.E_RABItem.cause.choice.misc = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; - break; + fprintf(stderr, "start encode\n"); - case S1AP_Cause_PR_NOTHING: - default: - break; - } + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { + S1AP_ERROR("Failed to encode uplink transport\n"); + /* Encode procedure has failed... */ + return -1; + } - S1AP_DEBUG("e_rab_modify_resp: failed e_rab ID %ld\n", item->value.choice.E_RABItem.e_RAB_ID); - ASN_SEQUENCE_ADD(&ie->value.choice.E_RABList.list, item); + MSC_LOG_TX_MESSAGE( + MSC_S1AP_ENB, + MSC_S1AP_MME, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" E_RAN Modify successful Outcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + e_rab_modify_resp_p->eNB_ue_s1ap_id, + ue_context_p->mme_ue_s1ap_id); + /* UE associated signalling -> use the allocated stream */ + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + return 0; +} +//------------------------------------------------------------------------------ +int s1ap_eNB_e_rab_release_resp(instance_t instance, + s1ap_e_rab_release_resp_t *e_rab_release_resp_p) +//------------------------------------------------------------------------------ +{ + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + S1AP_S1AP_PDU_t pdu; + S1AP_E_RABReleaseResponse_t *out; + S1AP_E_RABReleaseResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + /* Retrieve the S1AP eNB instance associated with Mod_id */ + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + DevAssert(e_rab_release_resp_p != NULL); + DevAssert(s1ap_eNB_instance_p != NULL); + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + e_rab_release_resp_p->eNB_ue_s1ap_id)) == NULL) { + /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ + S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n", + e_rab_release_resp_p->eNB_ue_s1ap_id); + return -1; } + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_E_RABRelease; + pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABReleaseResponse; + out = &pdu.choice.successfulOutcome.value.choice.E_RABReleaseResponse; + /* mandatory */ + ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - - /* optional */ - if (0) { - ie = (S1AP_E_RABModifyResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + /* mandatory */ + ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_CriticalityDiagnostics; - // ie->value.choice.CriticalityDiagnostics = ; + ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = e_rab_release_resp_p->eNB_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } - fprintf(stderr, "start encode\n"); + /* optional */ + if (e_rab_release_resp_p->nb_of_e_rabs_released > 0) { + ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABReleaseListBearerRelComp; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_E_RABReleaseListBearerRelComp; + + for (i = 0; i < e_rab_release_resp_p->nb_of_e_rabs_released; i++) { + S1AP_E_RABReleaseItemBearerRelCompIEs_t *item; + item = (S1AP_E_RABReleaseItemBearerRelCompIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseItemBearerRelCompIEs_t)); + item->id = S1AP_ProtocolIE_ID_id_E_RABReleaseItemBearerRelComp; + item->criticality = S1AP_Criticality_ignore; + item->value.present = S1AP_E_RABReleaseItemBearerRelCompIEs__value_PR_E_RABReleaseItemBearerRelComp; + item->value.choice.E_RABReleaseItemBearerRelComp.e_RAB_ID = e_rab_release_resp_p->e_rab_release[i].e_rab_id; + S1AP_DEBUG("e_rab_release_resp: e_rab ID %ld\n", item->value.choice.E_RABReleaseItemBearerRelComp.e_RAB_ID); + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABReleaseListBearerRelComp.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { - S1AP_ERROR("Failed to encode uplink transport\n"); - /* Encode procedure has failed... */ - return -1; - } + /* optional */ + if (e_rab_release_resp_p->nb_of_e_rabs_failed > 0) { + ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABFailedToReleaseList; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_E_RABList; + + for (i = 0; i < e_rab_release_resp_p->nb_of_e_rabs_failed; i++) { + S1AP_E_RABItemIEs_t *item; + item = (S1AP_E_RABItemIEs_t *)calloc(1, sizeof(S1AP_E_RABItemIEs_t)); + item->id = S1AP_ProtocolIE_ID_id_E_RABItem; + item->criticality = S1AP_Criticality_ignore; + item->value.present = S1AP_E_RABItemIEs__value_PR_E_RABItem; + item->value.choice.E_RABItem.e_RAB_ID = e_rab_release_resp_p->e_rabs_failed[i].e_rab_id; + item->value.choice.E_RABItem.cause.present = e_rab_release_resp_p->e_rabs_failed[i].cause; + + switch(item->value.choice.E_RABItem.cause.present) { + case S1AP_Cause_PR_radioNetwork: + item->value.choice.E_RABItem.cause.choice.radioNetwork = e_rab_release_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_transport: + item->value.choice.E_RABItem.cause.choice.transport = e_rab_release_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_nas: + item->value.choice.E_RABItem.cause.choice.nas = e_rab_release_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_protocol: + item->value.choice.E_RABItem.cause.choice.protocol = e_rab_release_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_misc: + item->value.choice.E_RABItem.cause.choice.misc = e_rab_release_resp_p->e_rabs_failed[i].cause_value; + break; + + case S1AP_Cause_PR_NOTHING: + default: + break; + } + + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABList.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } - MSC_LOG_TX_MESSAGE( - MSC_S1AP_ENB, - MSC_S1AP_MME, - (const char *)buffer, - length, - MSC_AS_TIME_FMT" E_RAN Modify successful Outcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", - 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - e_rab_modify_resp_p->eNB_ue_s1ap_id, - ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ - s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, - ue_context_p->mme_ref->assoc_id, buffer, - length, ue_context_p->tx_stream); - return 0; + /* optional */ + if (0) { + ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ +#if (S1AP_VERSION >= MAKE_VERSION(12, 0, 0)) + + if(0) { + ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_UserLocationInformation; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_UserLocationInformation; + // ie->value.choice.UserLocationInformation = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + +#endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ + fprintf(stderr, "start encode\n"); + + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { + S1AP_ERROR("Failed to encode release response\n"); + /* Encode procedure has failed... */ + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_S1AP_ENB, + MSC_S1AP_MME, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" E_RAN Release successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + e_rab_release_resp_p->eNB_ue_s1ap_id, + ue_context_p->mme_ue_s1ap_id); + /* UE associated signalling -> use the allocated stream */ + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + S1AP_INFO("e_rab_release_response sended eNB_UE_S1AP_ID %d mme_ue_s1ap_id %d nb_of_e_rabs_released %d nb_of_e_rabs_failed %d\n", + e_rab_release_resp_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id,e_rab_release_resp_p->nb_of_e_rabs_released,e_rab_release_resp_p->nb_of_e_rabs_failed); + return 0; } -//------------------------------------------------------------------------------ -int s1ap_eNB_e_rab_release_resp(instance_t instance, - s1ap_e_rab_release_resp_t *e_rab_release_resp_p) + +int s1ap_eNB_path_switch_req(instance_t instance, + s1ap_path_switch_req_t *path_switch_req_p) //------------------------------------------------------------------------------ { - s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; - struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + struct s1ap_eNB_mme_data_s *mme_desc_p = NULL; + S1AP_S1AP_PDU_t pdu; - S1AP_E_RABReleaseResponse_t *out; - S1AP_E_RABReleaseResponseIEs_t *ie; - uint8_t *buffer = NULL; + S1AP_PathSwitchRequest_t *out; + S1AP_PathSwitchRequestIEs_t *ie; + + S1AP_E_RABToBeSwitchedDLItemIEs_t *e_RABToBeSwitchedDLItemIEs; + S1AP_E_RABToBeSwitchedDLItem_t *e_RABToBeSwitchedDLItem; + + uint8_t *buffer = NULL; uint32_t length; - int i; + int ret = 0;//-1; + /* Retrieve the S1AP eNB instance associated with Mod_id */ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(e_rab_release_resp_p != NULL); + + DevAssert(path_switch_req_p != NULL); DevAssert(s1ap_eNB_instance_p != NULL); - if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, - e_rab_release_resp_p->eNB_ue_s1ap_id)) == NULL) { + //if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + // path_switch_req_p->eNB_ue_s1ap_id)) == NULL) { /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ - S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n", - e_rab_release_resp_p->eNB_ue_s1ap_id); + //S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", + // path_switch_req_p->eNB_ue_s1ap_id); + //return -1; + //} + + /* Uplink NAS transport can occur either during an s1ap connected state + * or during initial attach (for example: NAS authentication). + */ + //if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED || + // ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) { + //S1AP_WARN("You are attempting to send NAS data over non-connected " + // "eNB ue s1ap id: %06x, current state: %d\n", + // path_switch_req_p->eNB_ue_s1ap_id, ue_context_p->ue_state); + //return -1; + //} + + /* Select the MME corresponding to the provided GUMMEI. */ + mme_desc_p = s1ap_eNB_nnsf_select_mme_by_gummei_no_cause(s1ap_eNB_instance_p, path_switch_req_p->ue_gummei); + + if (mme_desc_p == NULL) { + /* + * In case eNB has no MME associated, the eNB should inform RRC and discard + * this request. + */ + + S1AP_WARN("No MME is associated to the eNB\n"); + // TODO: Inform RRC return -1; } - /* Prepare the S1AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_E_RABRelease; - pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; - pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABReleaseResponse; - out = &pdu.choice.successfulOutcome.value.choice.E_RABReleaseResponse; - /* mandatory */ - ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_MME_UE_S1AP_ID; - ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ - ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_ENB_UE_S1AP_ID; - ie->value.choice.ENB_UE_S1AP_ID = e_rab_release_resp_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* The eNB should allocate a unique eNB UE S1AP ID for this UE. The value + * will be used for the duration of the connectivity. + */ + ue_context_p = s1ap_eNB_allocate_new_UE_context(); + DevAssert(ue_context_p != NULL); - /* optional */ - if (e_rab_release_resp_p->nb_of_e_rabs_released > 0) { - ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_E_RABReleaseListBearerRelComp; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_E_RABReleaseListBearerRelComp; + /* Keep a reference to the selected MME */ + ue_context_p->mme_ref = mme_desc_p; + ue_context_p->ue_initial_id = path_switch_req_p->ue_initial_id; + ue_context_p->eNB_instance = s1ap_eNB_instance_p; + + do { + struct s1ap_eNB_ue_context_s *collision_p; - for (i = 0; i < e_rab_release_resp_p->nb_of_e_rabs_released; i++) { - S1AP_E_RABReleaseItemBearerRelCompIEs_t *item; - item = (S1AP_E_RABReleaseItemBearerRelCompIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseItemBearerRelCompIEs_t)); - item->id = S1AP_ProtocolIE_ID_id_E_RABReleaseItemBearerRelComp; - item->criticality = S1AP_Criticality_ignore; - item->value.present = S1AP_E_RABReleaseItemBearerRelCompIEs__value_PR_E_RABReleaseItemBearerRelComp; - item->value.choice.E_RABReleaseItemBearerRelComp.e_RAB_ID = e_rab_release_resp_p->e_rab_release[i].e_rab_id; - S1AP_DEBUG("e_rab_release_resp: e_rab ID %ld\n", item->value.choice.E_RABReleaseItemBearerRelComp.e_RAB_ID); - ASN_SEQUENCE_ADD(&ie->value.choice.E_RABReleaseListBearerRelComp.list, item); + /* Peek a random value for the eNB_ue_s1ap_id */ + ue_context_p->eNB_ue_s1ap_id = (random() + random()) & 0x00ffffff; + + if ((collision_p = RB_INSERT(s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head, ue_context_p)) + == NULL) { + S1AP_DEBUG("Found usable eNB_ue_s1ap_id: 0x%06x %u(10)\n", + ue_context_p->eNB_ue_s1ap_id, + ue_context_p->eNB_ue_s1ap_id); + /* Break the loop as the id is not already used by another UE */ + break; } + } while(1); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + ue_context_p->mme_ue_s1ap_id = path_switch_req_p->mme_ue_s1ap_id; - /* optional */ - if (e_rab_release_resp_p->nb_of_e_rabs_failed > 0) { - ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_E_RABFailedToReleaseList; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_E_RABList; + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_PathSwitchRequest; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_PathSwitchRequest; + out = &pdu.choice.initiatingMessage.value.choice.PathSwitchRequest; + + /* mandatory */ + ie = (S1AP_PathSwitchRequestIEs_t *)calloc(1, sizeof(S1AP_PathSwitchRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_PathSwitchRequestIEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = ue_context_p->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - for (i = 0; i < e_rab_release_resp_p->nb_of_e_rabs_failed; i++) { - S1AP_E_RABItemIEs_t *item; - item = (S1AP_E_RABItemIEs_t *)calloc(1, sizeof(S1AP_E_RABItemIEs_t)); - item->id = S1AP_ProtocolIE_ID_id_E_RABItem; - item->criticality = S1AP_Criticality_ignore; - item->value.present = S1AP_E_RABItemIEs__value_PR_E_RABItem; - item->value.choice.E_RABItem.e_RAB_ID = e_rab_release_resp_p->e_rabs_failed[i].e_rab_id; - item->value.choice.E_RABItem.cause.present = e_rab_release_resp_p->e_rabs_failed[i].cause; + /* mandatory */ + if (path_switch_req_p->nb_of_e_rabs > 0) { + ie = (S1AP_PathSwitchRequestIEs_t *)calloc(1, sizeof(S1AP_PathSwitchRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABToBeSwitchedDLList; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_PathSwitchRequestIEs__value_PR_E_RABToBeSwitchedDLList; - switch(item->value.choice.E_RABItem.cause.present) { - case S1AP_Cause_PR_radioNetwork: - item->value.choice.E_RABItem.cause.choice.radioNetwork = e_rab_release_resp_p->e_rabs_failed[i].cause_value; - break; + for (int i = 0; i < path_switch_req_p->nb_of_e_rabs; i++) { + e_RABToBeSwitchedDLItemIEs = (S1AP_E_RABToBeSwitchedDLItemIEs_t *)calloc(1, sizeof(S1AP_E_RABToBeSwitchedDLItemIEs_t)); + e_RABToBeSwitchedDLItemIEs->id = S1AP_ProtocolIE_ID_id_E_RABToBeSwitchedDLItem; + e_RABToBeSwitchedDLItemIEs->criticality = S1AP_Criticality_reject; + e_RABToBeSwitchedDLItemIEs->value.present = S1AP_E_RABToBeSwitchedDLItemIEs__value_PR_E_RABToBeSwitchedDLItem; - case S1AP_Cause_PR_transport: - item->value.choice.E_RABItem.cause.choice.transport = e_rab_release_resp_p->e_rabs_failed[i].cause_value; - break; + e_RABToBeSwitchedDLItem = &e_RABToBeSwitchedDLItemIEs->value.choice.E_RABToBeSwitchedDLItem; + e_RABToBeSwitchedDLItem->e_RAB_ID = path_switch_req_p->e_rabs_tobeswitched[i].e_rab_id; + INT32_TO_OCTET_STRING(path_switch_req_p->e_rabs_tobeswitched[i].gtp_teid, &e_RABToBeSwitchedDLItem->gTP_TEID); - case S1AP_Cause_PR_nas: - item->value.choice.E_RABItem.cause.choice.nas = e_rab_release_resp_p->e_rabs_failed[i].cause_value; - break; + e_RABToBeSwitchedDLItem->transportLayerAddress.size = path_switch_req_p->e_rabs_tobeswitched[i].eNB_addr.length; + e_RABToBeSwitchedDLItem->transportLayerAddress.bits_unused = 0; - case S1AP_Cause_PR_protocol: - item->value.choice.E_RABItem.cause.choice.protocol = e_rab_release_resp_p->e_rabs_failed[i].cause_value; - break; + e_RABToBeSwitchedDLItem->transportLayerAddress.buf = calloc(1,e_RABToBeSwitchedDLItem->transportLayerAddress.size); - case S1AP_Cause_PR_misc: - item->value.choice.E_RABItem.cause.choice.misc = e_rab_release_resp_p->e_rabs_failed[i].cause_value; - break; + memcpy (e_RABToBeSwitchedDLItem->transportLayerAddress.buf, + path_switch_req_p->e_rabs_tobeswitched[i].eNB_addr.buffer, + path_switch_req_p->e_rabs_tobeswitched[i].eNB_addr.length); - case S1AP_Cause_PR_NOTHING: - default: - break; - } + S1AP_DEBUG("path_switch_req: e_rab ID %ld, teid %u, enb_addr %d.%d.%d.%d, SIZE %zu\n", + e_RABToBeSwitchedDLItem->e_RAB_ID, + path_switch_req_p->e_rabs_tobeswitched[i].gtp_teid, + e_RABToBeSwitchedDLItem->transportLayerAddress.buf[0], + e_RABToBeSwitchedDLItem->transportLayerAddress.buf[1], + e_RABToBeSwitchedDLItem->transportLayerAddress.buf[2], + e_RABToBeSwitchedDLItem->transportLayerAddress.buf[3], + e_RABToBeSwitchedDLItem->transportLayerAddress.size); - ASN_SEQUENCE_ADD(&ie->value.choice.E_RABList.list, item); + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABToBeSwitchedDLList.list, e_RABToBeSwitchedDLItemIEs); } ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); } - /* optional */ - if (0) { - ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_CriticalityDiagnostics; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_CriticalityDiagnostics; - // ie->value.choice.CriticalityDiagnostics = ; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* mandatory */ + ie = (S1AP_PathSwitchRequestIEs_t *)calloc(1, sizeof(S1AP_PathSwitchRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_SourceMME_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_PathSwitchRequestIEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = path_switch_req_p->mme_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* optional */ -#if (S1AP_VERSION >= MAKE_VERSION(12, 0, 0)) + /* mandatory */ + ie = (S1AP_PathSwitchRequestIEs_t *)calloc(1, sizeof(S1AP_PathSwitchRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_EUTRAN_CGI; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_PathSwitchRequestIEs__value_PR_EUTRAN_CGI; + MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id, + 0, + &ie->value.choice.EUTRAN_CGI.cell_ID); + MCC_MNC_TO_TBCD(s1ap_eNB_instance_p->mcc[0], + s1ap_eNB_instance_p->mnc[0], + s1ap_eNB_instance_p->mnc_digit_length[0], + &ie->value.choice.EUTRAN_CGI.pLMNidentity); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - if(0) { - ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_UserLocationInformation; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_UserLocationInformation; - // ie->value.choice.UserLocationInformation = ; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - } + /* mandatory */ + ie = (S1AP_PathSwitchRequestIEs_t *)calloc(1, sizeof(S1AP_PathSwitchRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_TAI; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_PathSwitchRequestIEs__value_PR_TAI; + /* Assuming TAI is the TAI from the cell */ + INT16_TO_OCTET_STRING(s1ap_eNB_instance_p->tac, &ie->value.choice.TAI.tAC); + MCC_MNC_TO_PLMNID(s1ap_eNB_instance_p->mcc[0], + s1ap_eNB_instance_p->mnc[0], + s1ap_eNB_instance_p->mnc_digit_length[0], + &ie->value.choice.TAI.pLMNidentity); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); -#endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ - fprintf(stderr, "start encode\n"); + /* mandatory */ + ie = (S1AP_PathSwitchRequestIEs_t *)calloc(1, sizeof(S1AP_PathSwitchRequestIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_UESecurityCapabilities; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_PathSwitchRequestIEs__value_PR_UESecurityCapabilities; + ENCRALG_TO_BIT_STRING(path_switch_req_p->security_capabilities.encryption_algorithms, + &ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); + INTPROTALG_TO_BIT_STRING(path_switch_req_p->security_capabilities.integrity_algorithms, + &ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { - S1AP_ERROR("Failed to encode release response\n"); + S1AP_ERROR("Failed to encode Path Switch Req \n"); /* Encode procedure has failed... */ return -1; } + /* Update the current S1AP UE state */ + ue_context_p->ue_state = S1AP_UE_WAITING_CSR; + + /* Assign a stream for this UE : + * From 3GPP 36.412 7)Transport layers: + * Within the SCTP association established between one MME and eNB pair: + * - a single pair of stream identifiers shall be reserved for the sole use + * of S1AP elementary procedures that utilize non UE-associated signalling. + * - At least one pair of stream identifiers shall be reserved for the sole use + * of S1AP elementary procedures that utilize UE-associated signallings. + * However a few pairs (i.e. more than one) should be reserved. + * - A single UE-associated signalling shall use one SCTP stream and + * the stream should not be changed during the communication of the + * UE-associated signalling. + */ + mme_desc_p->nextstream = (mme_desc_p->nextstream + 1) % mme_desc_p->out_streams; + + if ((mme_desc_p->nextstream == 0) && (mme_desc_p->out_streams > 1)) { + mme_desc_p->nextstream += 1; + } + + ue_context_p->tx_stream = mme_desc_p->nextstream; + MSC_LOG_TX_MESSAGE( MSC_S1AP_ENB, MSC_S1AP_MME, (const char *)buffer, length, - MSC_AS_TIME_FMT" E_RAN Release successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", + MSC_AS_TIME_FMT" E_RAN Setup successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), - e_rab_release_resp_p->eNB_ue_s1ap_id, - ue_context_p->mme_ue_s1ap_id); + ue_context_p->eNB_ue_s1ap_id, + path_switch_req_p->mme_ue_s1ap_id); + /* UE associated signalling -> use the allocated stream */ s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, - ue_context_p->mme_ref->assoc_id, buffer, + mme_desc_p->assoc_id, buffer, length, ue_context_p->tx_stream); - S1AP_INFO("e_rab_release_response sended eNB_UE_S1AP_ID %d mme_ue_s1ap_id %d nb_of_e_rabs_released %d nb_of_e_rabs_failed %d\n", - e_rab_release_resp_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id,e_rab_release_resp_p->nb_of_e_rabs_released,e_rab_release_resp_p->nb_of_e_rabs_failed); - return 0; + + return ret; } diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.h b/openair3/S1AP/s1ap_eNB_nas_procedures.h index a7f144c0ca3653ab0a2665f8d1be619a1fe9d1a5..c4257198727a042cfacd7eeafac65e1dfc36a232 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.h +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.h @@ -49,4 +49,7 @@ int s1ap_eNB_e_rab_modify_resp(instance_t instance, int s1ap_eNB_e_rab_release_resp(instance_t instance, s1ap_e_rab_release_resp_t *e_rab_release_resp_p); + +int s1ap_eNB_path_switch_req(instance_t instance, + s1ap_path_switch_req_t *path_switch_req_p); #endif /* S1AP_ENB_NAS_PROCEDURES_H_ */ diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c index 63dc92b5e260e33c82a3dd076788b4761b1d763c..6319f6e054d878fb19087e0c3f3fa8e946a6d602 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.c +++ b/openair3/S1AP/s1ap_eNB_nnsf.c @@ -321,3 +321,79 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t *instance_p, * connectivity. */ return NULL; } + + +struct s1ap_eNB_mme_data_s * +s1ap_eNB_nnsf_select_mme_by_gummei_no_cause(s1ap_eNB_instance_t *instance_p, + s1ap_gummei_t gummei) +{ + struct s1ap_eNB_mme_data_s *mme_data_p = NULL; + struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; + uint8_t current_capacity = 0; + + RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + struct served_gummei_s *gummei_p = NULL; + + if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) { + /* The association between MME and eNB is not ready for the moment, + * go to the next known MME. + */ + if (mme_data_p->state == S1AP_ENB_OVERLOAD) { + /* MME is overloaded. We have to check the RRC establishment + * cause and take decision to the select this MME depending on + * the overload state. + */ + } else { + /* The MME is not overloaded, association is simply not ready. */ + continue; + } + } + + if (current_capacity < mme_data_p->relative_mme_capacity) { + /* We find a better MME, keep a reference to it */ + current_capacity = mme_data_p->relative_mme_capacity; + mme_highest_capacity_p = mme_data_p; + } + + /* Looking for MME gummei matching the one provided by NAS */ + STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) { + struct served_group_id_s *group_id_p = NULL; + struct mme_code_s *mme_code_p = NULL; + struct plmn_identity_s *served_plmn_p = NULL; + + STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) { + if ((served_plmn_p->mcc == gummei.mcc) && + (served_plmn_p->mnc == gummei.mnc)) { + break; + } + } + STAILQ_FOREACH(mme_code_p, &gummei_p->mme_codes, next) { + if (mme_code_p->mme_code == gummei.mme_code) { + break; + } + } + STAILQ_FOREACH(group_id_p, &gummei_p->served_group_ids, next) { + if (group_id_p->mme_group_id == gummei.mme_group_id) { + break; + } + } + + /* The MME matches the parameters provided by the NAS layer -> + * the MME is knwown and the association is ready. + * Return the reference to the MME to use it for this UE. + */ + if ((group_id_p != NULL) && + (mme_code_p != NULL) && + (served_plmn_p != NULL)) { + return mme_data_p; + } + } + } + + /* At this point no MME matches the provided GUMMEI. Select the one with the + * highest relative capacity. + * In case the list of known MME is empty, simply return NULL, that way the RRC + * layer should know about it and reject RRC connectivity. + */ + return mme_highest_capacity_p; +} diff --git a/openair3/S1AP/s1ap_eNB_nnsf.h b/openair3/S1AP/s1ap_eNB_nnsf.h index 706f3ada6ff8380bf7e94d6a541817eb83064e07..d5f080649b0e6563ea138420fb35b7481cba2727 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.h +++ b/openair3/S1AP/s1ap_eNB_nnsf.h @@ -42,4 +42,8 @@ s1ap_eNB_nnsf_select_mme_by_gummei(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause, s1ap_gummei_t gummei); +struct s1ap_eNB_mme_data_s* +s1ap_eNB_nnsf_select_mme_by_gummei_no_cause(s1ap_eNB_instance_t *instance_p, + s1ap_gummei_t gummei); + #endif /* S1AP_ENB_NNSF_H_ */ diff --git a/openair3/S1AP/s1ap_eNB_overload.c b/openair3/S1AP/s1ap_eNB_overload.c index cf208fc16e3e47dfaa2d63d64842bed52caa9397..9358ae62bdb6286873240f3194af9e609921172f 100644 --- a/openair3/S1AP/s1ap_eNB_overload.c +++ b/openair3/S1AP/s1ap_eNB_overload.c @@ -47,60 +47,60 @@ int s1ap_eNB_handle_overload_start(uint32_t assoc_id, uint32_t stream, S1AP_S1AP_PDU_t *pdu) { - s1ap_eNB_mme_data_t *mme_desc_p; - S1AP_OverloadStart_t *container; - S1AP_OverloadStartIEs_t *ie; - - DevAssert(pdu != NULL); - - container = &pdu->choice.initiatingMessage.value.choice.OverloadStart; - - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_OverloadStartIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_OverloadResponse, true); - - DevCheck(ie->value.choice.OverloadResponse.present == - S1AP_OverloadResponse_PR_overloadAction, - S1AP_OverloadResponse_PR_overloadAction, 0, 0); - - /* Non UE-associated signalling -> stream 0 */ - DevCheck(stream == 0, stream, 0, 0); - - if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { - /* No MME context associated */ - return -1; - } - - /* Mark the MME as overloaded and set the overload state according to - * the value received. - */ - mme_desc_p->state = S1AP_ENB_OVERLOAD; - mme_desc_p->overload_state = - ie->value.choice.OverloadResponse.choice.overloadAction; - - return 0; + s1ap_eNB_mme_data_t *mme_desc_p; + S1AP_OverloadStart_t *container; + S1AP_OverloadStartIEs_t *ie; + + DevAssert(pdu != NULL); + + container = &pdu->choice.initiatingMessage.value.choice.OverloadStart; + + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_OverloadStartIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_OverloadResponse, true); + if (ie != NULL) { + DevCheck(ie->value.choice.OverloadResponse.present == + S1AP_OverloadResponse_PR_overloadAction, + S1AP_OverloadResponse_PR_overloadAction, 0, 0); + } + /* Non UE-associated signalling -> stream 0 */ + DevCheck(stream == 0, stream, 0, 0); + + if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { + /* No MME context associated */ + return -1; + } + + /* Mark the MME as overloaded and set the overload state according to + * the value received. + */ + mme_desc_p->state = S1AP_ENB_OVERLOAD; + mme_desc_p->overload_state = + ie->value.choice.OverloadResponse.choice.overloadAction; + + return 0; } int s1ap_eNB_handle_overload_stop(uint32_t assoc_id, uint32_t stream, S1AP_S1AP_PDU_t *pdu) { - /* We received Overload stop message, meaning that the MME is no more - * overloaded. This is an empty message, with only message header and no - * Information Element. - */ - DevAssert(pdu != NULL); + /* We received Overload stop message, meaning that the MME is no more + * overloaded. This is an empty message, with only message header and no + * Information Element. + */ + DevAssert(pdu != NULL); - s1ap_eNB_mme_data_t *mme_desc_p; + s1ap_eNB_mme_data_t *mme_desc_p; - /* Non UE-associated signalling -> stream 0 */ - DevCheck(stream == 0, stream, 0, 0); + /* Non UE-associated signalling -> stream 0 */ + DevCheck(stream == 0, stream, 0, 0); - if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { - /* No MME context associated */ - return -1; - } + if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { + /* No MME context associated */ + return -1; + } - mme_desc_p->state = S1AP_ENB_STATE_CONNECTED; - mme_desc_p->overload_state = S1AP_NO_OVERLOAD; - return 0; + mme_desc_p->state = S1AP_ENB_STATE_CONNECTED; + mme_desc_p->overload_state = S1AP_NO_OVERLOAD; + return 0; } diff --git a/openair3/S1AP/s1ap_eNB_trace.c b/openair3/S1AP/s1ap_eNB_trace.c index 653aa98ccdd1390c965e11c018cc9d9b7db18616..19f50592386843fb774cf8bc3adbbd35b728cfb1 100644 --- a/openair3/S1AP/s1ap_eNB_trace.c +++ b/openair3/S1AP/s1ap_eNB_trace.c @@ -42,107 +42,109 @@ void s1ap_eNB_generate_trace_failure(struct s1ap_eNB_ue_context_s *ue_desc_p, S1AP_E_UTRAN_Trace_ID_t *trace_id, S1AP_Cause_t *cause_p) { - S1AP_S1AP_PDU_t pdu; - S1AP_TraceFailureIndication_t *out; - S1AP_TraceFailureIndicationIEs_t *ie; - uint8_t *buffer = NULL; - uint32_t length; - - DevAssert(ue_desc_p != NULL); - DevAssert(trace_id != NULL); - DevAssert(cause_p != NULL); - - /* Prepare the S1AP message to encode */ - memset(&pdu, 0, sizeof(pdu)); - pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; - pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_TraceFailureIndication; - pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; - pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_TraceFailureIndication; - out = &pdu.choice.initiatingMessage.value.choice.TraceFailureIndication; - - /* mandatory */ - ie = (S1AP_TraceFailureIndicationIEs_t *)calloc(1, sizeof(S1AP_TraceFailureIndicationIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_TraceFailureIndicationIEs__value_PR_MME_UE_S1AP_ID; - ie->value.choice.MME_UE_S1AP_ID = ue_desc_p->mme_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* mandatory */ - ie = (S1AP_TraceFailureIndicationIEs_t *)calloc(1, sizeof(S1AP_TraceFailureIndicationIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; - ie->criticality = S1AP_Criticality_reject; - ie->value.present = S1AP_TraceFailureIndicationIEs__value_PR_ENB_UE_S1AP_ID; - ie->value.choice.ENB_UE_S1AP_ID = ue_desc_p->eNB_ue_s1ap_id; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* mandatory */ - ie = (S1AP_TraceFailureIndicationIEs_t *)calloc(1, sizeof(S1AP_TraceFailureIndicationIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_E_UTRAN_Trace_ID; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_TraceFailureIndicationIEs__value_PR_E_UTRAN_Trace_ID; - memcpy(&ie->value.choice.E_UTRAN_Trace_ID, trace_id, sizeof(S1AP_E_UTRAN_Trace_ID_t)); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - /* mandatory */ - ie = (S1AP_TraceFailureIndicationIEs_t *)calloc(1, sizeof(S1AP_TraceFailureIndicationIEs_t)); - ie->id = S1AP_ProtocolIE_ID_id_Cause; - ie->criticality = S1AP_Criticality_ignore; - ie->value.present = S1AP_TraceFailureIndicationIEs__value_PR_Cause; - memcpy(&ie->value.choice.Cause, cause_p, sizeof(S1AP_Cause_t)); - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - - if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { - return; - } - - s1ap_eNB_itti_send_sctp_data_req(ue_desc_p->mme_ref->s1ap_eNB_instance->instance, - ue_desc_p->mme_ref->assoc_id, buffer, - length, ue_desc_p->tx_stream); + S1AP_S1AP_PDU_t pdu; + S1AP_TraceFailureIndication_t *out; + S1AP_TraceFailureIndicationIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + + DevAssert(ue_desc_p != NULL); + DevAssert(trace_id != NULL); + DevAssert(cause_p != NULL); + + /* Prepare the S1AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_TraceFailureIndication; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_TraceFailureIndication; + out = &pdu.choice.initiatingMessage.value.choice.TraceFailureIndication; + + /* mandatory */ + ie = (S1AP_TraceFailureIndicationIEs_t *)calloc(1, sizeof(S1AP_TraceFailureIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_TraceFailureIndicationIEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = ue_desc_p->mme_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (S1AP_TraceFailureIndicationIEs_t *)calloc(1, sizeof(S1AP_TraceFailureIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_TraceFailureIndicationIEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = ue_desc_p->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (S1AP_TraceFailureIndicationIEs_t *)calloc(1, sizeof(S1AP_TraceFailureIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_UTRAN_Trace_ID; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_TraceFailureIndicationIEs__value_PR_E_UTRAN_Trace_ID; + memcpy(&ie->value.choice.E_UTRAN_Trace_ID, trace_id, sizeof(S1AP_E_UTRAN_Trace_ID_t)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (S1AP_TraceFailureIndicationIEs_t *)calloc(1, sizeof(S1AP_TraceFailureIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_Cause; + ie->criticality = S1AP_Criticality_ignore; + ie->value.present = S1AP_TraceFailureIndicationIEs__value_PR_Cause; + memcpy(&ie->value.choice.Cause, cause_p, sizeof(S1AP_Cause_t)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { + return; + } + + s1ap_eNB_itti_send_sctp_data_req(ue_desc_p->mme_ref->s1ap_eNB_instance->instance, + ue_desc_p->mme_ref->assoc_id, buffer, + length, ue_desc_p->tx_stream); } int s1ap_eNB_handle_trace_start(uint32_t assoc_id, uint32_t stream, S1AP_S1AP_PDU_t *pdu) { - S1AP_TraceStart_t *container; - S1AP_TraceStartIEs_t *ie; - struct s1ap_eNB_ue_context_s *ue_desc_p; - struct s1ap_eNB_mme_data_s *mme_ref_p; - - DevAssert(pdu != NULL); - - container = &pdu->choice.initiatingMessage.value.choice.TraceStart; - - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_TraceStartIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, TRUE); - mme_ref_p = s1ap_eNB_get_MME(NULL, assoc_id, 0); - DevAssert(mme_ref_p != NULL); - - if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_ref_p->s1ap_eNB_instance, - ie->value.choice.ENB_UE_S1AP_ID)) == NULL) { - /* Could not find context associated with this eNB_ue_s1ap_id -> generate - * trace failure indication. - */ - S1AP_E_UTRAN_Trace_ID_t trace_id; - S1AP_Cause_t cause; - memset(&trace_id, 0, sizeof(S1AP_E_UTRAN_Trace_ID_t)); - memset(&cause, 0, sizeof(S1AP_Cause_t)); - cause.present = S1AP_Cause_PR_radioNetwork; - cause.choice.radioNetwork = S1AP_CauseRadioNetwork_unknown_pair_ue_s1ap_id; - s1ap_eNB_generate_trace_failure(ue_desc_p, &trace_id, &cause); + S1AP_TraceStart_t *container; + S1AP_TraceStartIEs_t *ie; + struct s1ap_eNB_ue_context_s *ue_desc_p = NULL; + struct s1ap_eNB_mme_data_s *mme_ref_p; + + DevAssert(pdu != NULL); + + container = &pdu->choice.initiatingMessage.value.choice.TraceStart; + + S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_TraceStartIEs_t, ie, container, + S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, TRUE); + mme_ref_p = s1ap_eNB_get_MME(NULL, assoc_id, 0); + DevAssert(mme_ref_p != NULL); + if (ie != NULL) { + ue_desc_p = s1ap_eNB_get_ue_context(mme_ref_p->s1ap_eNB_instance, + ie->value.choice.ENB_UE_S1AP_ID); } - - return 0; + if (ue_desc_p == NULL) { + /* Could not find context associated with this eNB_ue_s1ap_id -> generate + * trace failure indication. + */ + S1AP_E_UTRAN_Trace_ID_t trace_id; + S1AP_Cause_t cause; + memset(&trace_id, 0, sizeof(S1AP_E_UTRAN_Trace_ID_t)); + memset(&cause, 0, sizeof(S1AP_Cause_t)); + cause.present = S1AP_Cause_PR_radioNetwork; + cause.choice.radioNetwork = S1AP_CauseRadioNetwork_unknown_pair_ue_s1ap_id; + s1ap_eNB_generate_trace_failure(NULL, &trace_id, &cause); + } + + return 0; } int s1ap_eNB_handle_deactivate_trace(uint32_t assoc_id, uint32_t stream, S1AP_S1AP_PDU_t *message_p) { - // S1AP_DeactivateTraceIEs_t *deactivate_trace_p; - // - // deactivate_trace_p = &message_p->msg.deactivateTraceIEs; + // S1AP_DeactivateTraceIEs_t *deactivate_trace_p; + // + // deactivate_trace_p = &message_p->msg.deactivateTraceIEs; - return 0; + return 0; } diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.c b/openair3/SCTP/sctp_eNB_itti_messaging.c index d2064c74c08671b215bbca98525ca9b58be91d47..789af3f8edf564b34e4630d0ba5f5d02d06591e4 100644 --- a/openair3/SCTP/sctp_eNB_itti_messaging.c +++ b/openair3/SCTP/sctp_eNB_itti_messaging.c @@ -38,7 +38,8 @@ int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, in return itti_send_msg_to_task(task_id, instance, message_p); } -int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t *buffer, +int sctp_itti_send_new_message_ind(task_id_t task_id, instance_t instance, + uint32_t assoc_id, uint8_t *buffer, uint32_t buffer_length, uint16_t stream) { MessageDef *message_p; @@ -57,7 +58,7 @@ int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t sctp_data_ind_p->buffer_length = buffer_length; sctp_data_ind_p->assoc_id = assoc_id; - return itti_send_msg_to_task(task_id, INSTANCE_DEFAULT, message_p); + return itti_send_msg_to_task(task_id, instance, message_p); } int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance, diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.h b/openair3/SCTP/sctp_eNB_itti_messaging.h index 49d2056a3cc254975c18fe469554d50d07bd8379..a35dc2219a35431cf6976b6d3f3a693270c5c6f9 100644 --- a/openair3/SCTP/sctp_eNB_itti_messaging.h +++ b/openair3/SCTP/sctp_eNB_itti_messaging.h @@ -24,7 +24,8 @@ int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, int multi_sd); -int sctp_itti_send_new_message_ind(task_id_t task_id, uint32_t assoc_id, uint8_t *buffer, +int sctp_itti_send_new_message_ind(task_id_t task_id, instance_t instance, + uint32_t assoc_id, uint8_t *buffer, uint32_t buffer_length, uint16_t stream); int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance, diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index e7265d66d6485c25e74f5cf128e0a89e932001f8..4b0945f5eaaccedacf4b45810900e1a8cc35987a 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -59,33 +59,33 @@ enum sctp_connection_type_e { - SCTP_TYPE_CLIENT, - SCTP_TYPE_SERVER, - SCTP_TYPE_MULTI_SERVER, - SCTP_TYPE_MAX + SCTP_TYPE_CLIENT, + SCTP_TYPE_SERVER, + SCTP_TYPE_MULTI_SERVER, + SCTP_TYPE_MAX }; typedef struct sctp_cnx_list_elm_s { - STAILQ_ENTRY(sctp_cnx_list_elm_s) entries; - - /* Type of this association - */ - enum sctp_connection_type_e connection_type; - - int sd; ///< Socket descriptor of connection */ - uint16_t local_port; - uint16_t in_streams; ///< Number of input streams negociated for this connection - uint16_t out_streams; ///< Number of output streams negotiated for this connection - uint16_t ppid; ///< Payload protocol Identifier - int32_t assoc_id; ///< SCTP association id for the connection (note4debug host byte order) - uint32_t messages_recv; ///< Number of messages received on this connection - uint32_t messages_sent; ///< Number of messages sent on this connection - task_id_t task_id; ///< Task id of the task who asked for this connection - instance_t instance; ///< Instance - uint16_t cnx_id; ///< Upper layer identifier - - struct sockaddr *peer_addresses;///< A list of peer addresses for server socket - int nb_peer_addresses; ///< For server socket + STAILQ_ENTRY(sctp_cnx_list_elm_s) entries; + + /* Type of this association + */ + enum sctp_connection_type_e connection_type; + + int sd; ///< Socket descriptor of connection */ + uint16_t local_port; + uint16_t in_streams; ///< Number of input streams negociated for this connection + uint16_t out_streams; ///< Number of output streams negotiated for this connection + uint16_t ppid; ///< Payload protocol Identifier + int32_t assoc_id; ///< SCTP association id for the connection (note4debug host byte order) + uint32_t messages_recv; ///< Number of messages received on this connection + uint32_t messages_sent; ///< Number of messages sent on this connection + task_id_t task_id; ///< Task id of the task who asked for this connection + instance_t instance; ///< Instance + uint16_t cnx_id; ///< Upper layer identifier + + struct sockaddr *peer_addresses;///< A list of peer addresses for server socket + int nb_peer_addresses; ///< For server socket } sctp_cnx_list_elm_t; @@ -95,962 +95,973 @@ static uint16_t sctp_nb_cnx = 0; //------------------------------------------------------------------------------ struct sctp_cnx_list_elm_s *sctp_get_cnx(int32_t assoc_id, int sd) { - struct sctp_cnx_list_elm_s *elm; + struct sctp_cnx_list_elm_s *elm; - STAILQ_FOREACH(elm, &sctp_cnx_list, entries) { - if (assoc_id != -1) { - if (elm->assoc_id == assoc_id) { - return elm; - } - } else { - if (elm->sd == sd) { - return elm; - } + STAILQ_FOREACH(elm, &sctp_cnx_list, entries) { + if (assoc_id != -1) { + if (elm->assoc_id == assoc_id) { + return elm; + } + } else { + if (elm->sd == sd) { + return elm; + } + } } - } - return NULL; + return NULL; } //------------------------------------------------------------------------------ static inline void sctp_eNB_accept_associations_multi( - struct sctp_cnx_list_elm_s *sctp_cnx) + struct sctp_cnx_list_elm_s *sctp_cnx) { - int ns; - int n; - int flags = 0; - socklen_t from_len; - struct sctp_sndrcvinfo sinfo; + int ns; + int n; + int flags = 0; + socklen_t from_len; + struct sctp_sndrcvinfo sinfo; - struct sockaddr_in addr; - uint8_t buffer[SCTP_RECV_BUFFER_SIZE]; + struct sockaddr_in addr; + uint8_t buffer[SCTP_RECV_BUFFER_SIZE]; - DevAssert(sctp_cnx != NULL); + DevAssert(sctp_cnx != NULL); - memset((void *)&addr, 0, sizeof(struct sockaddr_in)); - from_len = (socklen_t)sizeof(struct sockaddr_in); - memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); + memset((void *)&addr, 0, sizeof(struct sockaddr_in)); + from_len = (socklen_t)sizeof(struct sockaddr_in); + memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); - n = sctp_recvmsg(sctp_cnx->sd, (void *)buffer, SCTP_RECV_BUFFER_SIZE, - (struct sockaddr *)&addr, &from_len, - &sinfo, &flags); + n = sctp_recvmsg(sctp_cnx->sd, (void *)buffer, SCTP_RECV_BUFFER_SIZE, + (struct sockaddr *)&addr, &from_len, + &sinfo, &flags); - if (n < 0) { - if (errno == ENOTCONN) { - SCTP_DEBUG("Received not connected for sd %d\n", sctp_cnx->sd); - close(sctp_cnx->sd); - } else { - SCTP_DEBUG("An error occured during read\n"); - SCTP_ERROR("sctp_recvmsg (fd %d, len %d ): %s:%d\n", sctp_cnx->sd, n, strerror(errno), errno); + if (n < 0) { + if (errno == ENOTCONN) { + SCTP_DEBUG("Received not connected for sd %d\n", sctp_cnx->sd); + close(sctp_cnx->sd); + } else { + SCTP_DEBUG("An error occured during read\n"); + SCTP_ERROR("sctp_recvmsg (fd %d, len %d ): %s:%d\n", sctp_cnx->sd, n, strerror(errno), errno); + } + return; } - return; - } - if (flags & MSG_NOTIFICATION) { - union sctp_notification *snp; - snp = (union sctp_notification *)buffer; + if (flags & MSG_NOTIFICATION) { + union sctp_notification *snp; + snp = (union sctp_notification *)buffer; - SCTP_DEBUG("Received notification for sd %d, type %u\n", - sctp_cnx->sd, snp->sn_header.sn_type); + SCTP_DEBUG("Received notification for sd %d, type %u\n", + sctp_cnx->sd, snp->sn_header.sn_type); - /* Association has changed. */ - if (SCTP_ASSOC_CHANGE == snp->sn_header.sn_type) { - struct sctp_assoc_change *sctp_assoc_changed; - sctp_assoc_changed = &snp->sn_assoc_change; + /* Association has changed. */ + if (SCTP_ASSOC_CHANGE == snp->sn_header.sn_type) { + struct sctp_assoc_change *sctp_assoc_changed; + sctp_assoc_changed = &snp->sn_assoc_change; - SCTP_DEBUG("Client association changed: %d\n", sctp_assoc_changed->sac_state); + SCTP_DEBUG("Client association changed: %d\n", sctp_assoc_changed->sac_state); - /* New physical association requested by a peer */ - switch (sctp_assoc_changed->sac_state) { - case SCTP_COMM_UP: { - SCTP_DEBUG("Comm up notified for sd %d, assigned assoc_id %d\n", - sctp_cnx->sd, sctp_assoc_changed->sac_assoc_id); - struct sctp_cnx_list_elm_s *new_cnx; + /* New physical association requested by a peer */ + switch (sctp_assoc_changed->sac_state) { + case SCTP_COMM_UP: { + SCTP_DEBUG("Comm up notified for sd %d, assigned assoc_id %d\n", + sctp_cnx->sd, sctp_assoc_changed->sac_assoc_id); + struct sctp_cnx_list_elm_s *new_cnx; - new_cnx = calloc(1, sizeof(*sctp_cnx)); + new_cnx = calloc(1, sizeof(*sctp_cnx)); - DevAssert(new_cnx != NULL); + DevAssert(new_cnx != NULL); - new_cnx->connection_type = SCTP_TYPE_CLIENT; + new_cnx->connection_type = SCTP_TYPE_CLIENT; - ns = sctp_peeloff(sctp_cnx->sd, sctp_assoc_changed->sac_assoc_id); + ns = sctp_peeloff(sctp_cnx->sd, sctp_assoc_changed->sac_assoc_id); - new_cnx->sd = ns; - new_cnx->task_id = sctp_cnx->task_id; - new_cnx->cnx_id = 0; - new_cnx->ppid = sctp_cnx->ppid; - new_cnx->instance = sctp_cnx->instance; - new_cnx->local_port = sctp_cnx->local_port; - new_cnx->assoc_id = sctp_assoc_changed->sac_assoc_id; + new_cnx->sd = ns; + new_cnx->task_id = sctp_cnx->task_id; + new_cnx->cnx_id = 0; + new_cnx->ppid = sctp_cnx->ppid; + new_cnx->instance = sctp_cnx->instance; + new_cnx->local_port = sctp_cnx->local_port; + new_cnx->assoc_id = sctp_assoc_changed->sac_assoc_id; - if (sctp_get_sockinfo(ns, &new_cnx->in_streams, &new_cnx->out_streams, - &new_cnx->assoc_id) != 0) { - SCTP_ERROR("sctp_get_sockinfo failed\n"); - close(ns); - free(new_cnx); - return; - } + if (sctp_get_sockinfo(ns, &new_cnx->in_streams, &new_cnx->out_streams, + &new_cnx->assoc_id) != 0) { + SCTP_ERROR("sctp_get_sockinfo failed\n"); + close(ns); + free(new_cnx); + return; + } - /* Insert new element at end of list */ - STAILQ_INSERT_TAIL(&sctp_cnx_list, new_cnx, entries); - sctp_nb_cnx++; + /* Insert new element at end of list */ + STAILQ_INSERT_TAIL(&sctp_cnx_list, new_cnx, entries); + sctp_nb_cnx++; - /* Add the socket to list of fd monitored by ITTI */ - itti_subscribe_event_fd(TASK_SCTP, ns); + /* Add the socket to list of fd monitored by ITTI */ + itti_subscribe_event_fd(TASK_SCTP, ns); - sctp_itti_send_association_ind(new_cnx->task_id, new_cnx->instance, - new_cnx->assoc_id, new_cnx->local_port, - new_cnx->out_streams, new_cnx->in_streams); - } - break; + sctp_itti_send_association_ind(new_cnx->task_id, new_cnx->instance, + new_cnx->assoc_id, new_cnx->local_port, + new_cnx->out_streams, new_cnx->in_streams); + } + break; - default: - break; - } + default: + break; + } + } + } else { + SCTP_DEBUG("No notification from SCTP\n"); } - } else { - SCTP_DEBUG("No notification from SCTP\n"); - } } //------------------------------------------------------------------------------ void sctp_handle_new_association_req_multi( - const instance_t instance, - const task_id_t requestor, - const sctp_new_association_req_multi_t * const sctp_new_association_req_p) + const instance_t instance, + const task_id_t requestor, + const sctp_new_association_req_multi_t * const sctp_new_association_req_p) { - int ns; - int sd; + int ns; + int sd; - int32_t assoc_id = 0; + int32_t assoc_id = 0; - struct sctp_cnx_list_elm_s *sctp_cnx = NULL; - enum sctp_connection_type_e connection_type = SCTP_TYPE_CLIENT; + struct sctp_cnx_list_elm_s *sctp_cnx = NULL; + enum sctp_connection_type_e connection_type = SCTP_TYPE_CLIENT; - /* Prepare a new SCTP association as requested by upper layer and try to connect - * to remote host. - */ - DevAssert(sctp_new_association_req_p != NULL); + /* Prepare a new SCTP association as requested by upper layer and try to connect + * to remote host. + */ + DevAssert(sctp_new_association_req_p != NULL); - sd = sctp_new_association_req_p->multi_sd; + sd = sctp_new_association_req_p->multi_sd; - /* Create new socket with IPv6 affinity */ + /* Create new socket with IPv6 affinity */ //#warning "SCTP may Force IPv4 only, here" - /* Mark the socket as non-blocking */ - //if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) { + /* Mark the socket as non-blocking */ + //if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) { //SCTP_ERROR("fcntl F_SETFL O_NONBLOCK failed: %s\n", - // strerror(errno)); + // strerror(errno)); //close(sd); //return; - //} - - /* SOCK_STREAM socket type requires an explicit connect to the remote host - * address and port. - * Only use IPv4 for the first connection attempt - */ - if ((sctp_new_association_req_p->remote_address.ipv6 != 0) || - (sctp_new_association_req_p->remote_address.ipv4 != 0)) { - uint8_t address_index = 0; - uint8_t used_address = sctp_new_association_req_p->remote_address.ipv6 + - sctp_new_association_req_p->remote_address.ipv4; - struct sockaddr_in addr[used_address]; - - memset(addr, 0, used_address * sizeof(struct sockaddr_in)); - - if (sctp_new_association_req_p->remote_address.ipv6 == 1) { - if (inet_pton(AF_INET6, sctp_new_association_req_p->remote_address.ipv6_address, - &addr[address_index].sin_addr.s_addr) != 1) { - SCTP_ERROR("Failed to convert ipv6 address %*s to network type\n", - (int)strlen(sctp_new_association_req_p->remote_address.ipv6_address), - sctp_new_association_req_p->remote_address.ipv6_address); - //close(sd); - //return; - exit(1); - } - - SCTP_DEBUG("Converted ipv6 address %*s to network type\n", - (int)strlen(sctp_new_association_req_p->remote_address.ipv6_address), - sctp_new_association_req_p->remote_address.ipv6_address); - - addr[address_index].sin_family = AF_INET6; - addr[address_index].sin_port = htons(sctp_new_association_req_p->port); - address_index++; - } + //} - if (sctp_new_association_req_p->remote_address.ipv4 == 1) { - if (inet_pton(AF_INET, sctp_new_association_req_p->remote_address.ipv4_address, - &addr[address_index].sin_addr.s_addr) != 1) { - SCTP_ERROR("Failed to convert ipv4 address %*s to network type\n", - (int)strlen(sctp_new_association_req_p->remote_address.ipv4_address), - sctp_new_association_req_p->remote_address.ipv4_address); - //close(sd); - //return; - exit(1); - } - - SCTP_DEBUG("Converted ipv4 address %*s to network type\n", - (int)strlen(sctp_new_association_req_p->remote_address.ipv4_address), - sctp_new_association_req_p->remote_address.ipv4_address); - - addr[address_index].sin_family = AF_INET; - addr[address_index].sin_port = htons(sctp_new_association_req_p->port); - address_index++; - } + /* SOCK_STREAM socket type requires an explicit connect to the remote host + * address and port. + * Only use IPv4 for the first connection attempt + */ + if ((sctp_new_association_req_p->remote_address.ipv6 != 0) || + (sctp_new_association_req_p->remote_address.ipv4 != 0)) { + uint8_t address_index = 0; + uint8_t used_address = sctp_new_association_req_p->remote_address.ipv6 + + sctp_new_association_req_p->remote_address.ipv4; + struct sockaddr_in addr[used_address]; + + memset(addr, 0, used_address * sizeof(struct sockaddr_in)); + + if (sctp_new_association_req_p->remote_address.ipv6 == 1) { + if (inet_pton(AF_INET6, sctp_new_association_req_p->remote_address.ipv6_address, + &addr[address_index].sin_addr.s_addr) != 1) { + SCTP_ERROR("Failed to convert ipv6 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv6_address), + sctp_new_association_req_p->remote_address.ipv6_address); + //close(sd); + //return; + exit(1); + } + + SCTP_DEBUG("Converted ipv6 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv6_address), + sctp_new_association_req_p->remote_address.ipv6_address); + + addr[address_index].sin_family = AF_INET6; + addr[address_index].sin_port = htons(sctp_new_association_req_p->port); + address_index++; + } - /* Connect to remote host and port */ - if (sctp_connectx(sd, (struct sockaddr *)addr, 1, &assoc_id) < 0) { - /* sctp_connectx on non-blocking socket return EINPROGRESS */ - if (errno != EINPROGRESS) { - SCTP_ERROR("Connect failed: %s\n", strerror(errno)); - sctp_itti_send_association_resp( - requestor, instance, -1, sctp_new_association_req_p->ulp_cnx_id, - SCTP_STATE_UNREACHABLE, 0, 0); - /* Add the socket to list of fd monitored by ITTI */ - //itti_unsubscribe_event_fd(TASK_SCTP, sd); - //close(sd); - return; - } else { - SCTP_DEBUG("connectx assoc_id %d in progress..., used %d addresses\n", - assoc_id, used_address); - } - } else { - SCTP_DEBUG("sctp_connectx SUCCESS, used %d addresses assoc_id %d\n", - used_address, - assoc_id); + if (sctp_new_association_req_p->remote_address.ipv4 == 1) { + if (inet_pton(AF_INET, sctp_new_association_req_p->remote_address.ipv4_address, + &addr[address_index].sin_addr.s_addr) != 1) { + SCTP_ERROR("Failed to convert ipv4 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv4_address), + sctp_new_association_req_p->remote_address.ipv4_address); + //close(sd); + //return; + exit(1); + } + + SCTP_DEBUG("Converted ipv4 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv4_address), + sctp_new_association_req_p->remote_address.ipv4_address); + + addr[address_index].sin_family = AF_INET; + addr[address_index].sin_port = htons(sctp_new_association_req_p->port); + address_index++; + } + + /* Connect to remote host and port */ + if (sctp_connectx(sd, (struct sockaddr *)addr, 1, &assoc_id) < 0) { + /* sctp_connectx on non-blocking socket return EINPROGRESS */ + if (errno != EINPROGRESS) { + SCTP_ERROR("Connect failed: %s\n", strerror(errno)); + sctp_itti_send_association_resp( + requestor, instance, -1, sctp_new_association_req_p->ulp_cnx_id, + SCTP_STATE_UNREACHABLE, 0, 0); + /* Add the socket to list of fd monitored by ITTI */ + //itti_unsubscribe_event_fd(TASK_SCTP, sd); + //close(sd); + return; + } else { + SCTP_DEBUG("connectx assoc_id %d in progress..., used %d addresses\n", + assoc_id, used_address); + } + } else { + SCTP_DEBUG("sctp_connectx SUCCESS, used %d addresses assoc_id %d\n", + used_address, + assoc_id); + } } - } - ns = sctp_peeloff(sd,assoc_id); + ns = sctp_peeloff(sd, assoc_id); + if (ns == -1) { + perror("sctp_peeloff"); + printf("sctp_peeloff: sd=%d assoc_id=%d\n", sd, assoc_id); + exit(1); + } - sctp_cnx = calloc(1, sizeof(*sctp_cnx)); + sctp_cnx = calloc(1, sizeof(*sctp_cnx)); - sctp_cnx->connection_type = connection_type; + sctp_cnx->connection_type = connection_type; - sctp_cnx->sd = ns; - sctp_cnx->task_id = requestor; - sctp_cnx->cnx_id = sctp_new_association_req_p->ulp_cnx_id; - sctp_cnx->ppid = sctp_new_association_req_p->ppid; - sctp_cnx->instance = instance; - sctp_cnx->assoc_id = assoc_id; + sctp_cnx->sd = ns; + sctp_cnx->task_id = requestor; + sctp_cnx->cnx_id = sctp_new_association_req_p->ulp_cnx_id; + sctp_cnx->ppid = sctp_new_association_req_p->ppid; + sctp_cnx->instance = instance; + sctp_cnx->assoc_id = assoc_id; - /* Add the socket to list of fd monitored by ITTI */ - itti_subscribe_event_fd(TASK_SCTP, ns); + /* Add the socket to list of fd monitored by ITTI */ + itti_subscribe_event_fd(TASK_SCTP, ns); - /* Insert new element at end of list */ - STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries); - sctp_nb_cnx++; + /* Insert new element at end of list */ + STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries); + sctp_nb_cnx++; - SCTP_DEBUG("Inserted new descriptor for sd %d in list, nb elements %u, assoc_id %d\n", - ns, sctp_nb_cnx, assoc_id); + SCTP_DEBUG("Inserted new descriptor for sd %d in list, nb elements %u, assoc_id %d\n", + ns, sctp_nb_cnx, assoc_id); } //------------------------------------------------------------------------------ void sctp_handle_new_association_req( - const instance_t instance, - const task_id_t requestor, - const sctp_new_association_req_t * const sctp_new_association_req_p) + const instance_t instance, + const task_id_t requestor, + const sctp_new_association_req_t * const sctp_new_association_req_p) { - int sd = 0; - int32_t assoc_id = 0; - - struct sctp_event_subscribe events; - - struct sctp_cnx_list_elm_s *sctp_cnx = NULL; - enum sctp_connection_type_e connection_type = SCTP_TYPE_CLIENT; - - struct ifreq ifr; - struct ifaddrs *ifaddr = NULL; - struct ifaddrs *ifa = NULL; - int family = 0; - int s = 0; - struct in_addr in; - struct in6_addr in6; - /* Prepare a new SCTP association as requested by upper layer and try to connect - * to remote host. - */ - DevAssert(sctp_new_association_req_p != NULL); - - /* Create new socket with IPv6 affinity */ + int sd = 0; + int32_t assoc_id = 0; + + struct sctp_event_subscribe events; + + struct sctp_cnx_list_elm_s *sctp_cnx = NULL; + enum sctp_connection_type_e connection_type = SCTP_TYPE_CLIENT; + + struct ifreq ifr; + struct ifaddrs *ifaddr = NULL; + struct ifaddrs *ifa = NULL; + int family = 0; + int s = 0; + struct in_addr in; + struct in6_addr in6; + /* Prepare a new SCTP association as requested by upper layer and try to connect + * to remote host. + */ + DevAssert(sctp_new_association_req_p != NULL); + + /* Create new socket with IPv6 affinity */ //#warning "SCTP may Force IPv4 only, here" #ifdef NO_VIRTUAL_MACHINE - // in init chunk appears a list of host addresses, IPv4 and IPv4 in an arbitrary (unsorted) order - // SCTP hearbeats starts with first ipv4 addresses then stop triyng with other ipv4 addresses - // if it encounters an IPv6 address in list, so we can force the building of IPv4 addresses only - // with AF_INET (the working IPv4 address can be the last in the list...) - if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) { + // in init chunk appears a list of host addresses, IPv4 and IPv4 in an arbitrary (unsorted) order + // SCTP hearbeats starts with first ipv4 addresses then stop triyng with other ipv4 addresses + // if it encounters an IPv6 address in list, so we can force the building of IPv4 addresses only + // with AF_INET (the working IPv4 address can be the last in the list...) + if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) { #else - if ((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0) { + if ((sd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0) { #endif - SCTP_ERROR("Socket creation failed: %s\n", strerror(errno)); - return; - } - - /* Add the socket to list of fd monitored by ITTI */ - itti_subscribe_event_fd(TASK_SCTP, sd); - - if (sctp_set_init_opt(sd, - sctp_new_association_req_p->in_streams, - sctp_new_association_req_p->out_streams, - SCTP_MAX_ATTEMPTS, SCTP_TIMEOUT) != 0) { - SCTP_ERROR("Setsockopt IPPROTO_SCTP_INITMSG failed: %s\n", - strerror(errno)); - itti_unsubscribe_event_fd(TASK_SCTP, sd); - close(sd); - return; - } - - /* Subscribe to all events */ - memset((void *)&events, 1, sizeof(struct sctp_event_subscribe)); - - if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &events, - sizeof(struct sctp_event_subscribe)) < 0) { - SCTP_ERROR("Setsockopt IPPROTO_SCTP_EVENTS failed: %s\n", - strerror(errno)); - close(sd); - return; - } - - // Bind to device ... or we could bind to address also - if (getifaddrs(&ifaddr) == -1) { - SCTP_ERROR("getifaddrs failed: %s\n", strerror(errno)); - close(sd); - } - - /* Walk through linked list, maintaining head pointer so we - can free list later */ - for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == NULL) - continue; - - family = ifa->ifa_addr->sa_family; - - /* For an AF_INET* interface address, display the address */ - if (sctp_new_association_req_p->local_address.ipv4 && family == AF_INET) { - // compare address - s = inet_aton(sctp_new_association_req_p->local_address.ipv4_address, - &in); - - if (s > 0 ) { - if (((struct sockaddr_in*)ifa->ifa_addr)->sin_addr.s_addr == in.s_addr) { - struct sockaddr_in locaddr; - locaddr.sin_family = AF_INET; - locaddr.sin_port = htons(sctp_new_association_req_p->port); - locaddr.sin_addr.s_addr = in.s_addr; - - if (sctp_bindx(sd, (struct sockaddr*)&locaddr, 1, SCTP_BINDX_ADD_ADDR) < 0) { - SCTP_ERROR("sctp_bindx SCTP_BINDX_ADD_ADDR failed: %s\n", - strerror(errno)); - } else { - SCTP_DEBUG("sctp_bindx SCTP_BINDX_ADD_ADDR socket bound to : %s\n", - inet_ntoa(locaddr.sin_addr)); - } - break; - - } - } - } else if (sctp_new_association_req_p->local_address.ipv6 && family == AF_INET6) { - // compare address - s = inet_pton(AF_INET6, - sctp_new_association_req_p->local_address.ipv6_address, - &in6); - - if (s == 1 ) { - if (memcmp(&((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr, - &in6, sizeof(in6)) == 0) { - memset(&ifr, 0, sizeof(ifr)); - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifa->ifa_name); - - if (setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) { - SCTP_ERROR("Setsockopt SOL_SOCKET failed: %s\n", - strerror(errno)); - } else { - SCTP_DEBUG("Setsockopt SOL_SOCKET socket bound to : %s\n", - ifa->ifa_name); - } - - break; - } - } + SCTP_ERROR("Socket creation failed: %s\n", strerror(errno)); + return; } - } - - freeifaddrs(ifaddr); - - /* Mark the socket as non-blocking */ - if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) { - SCTP_ERROR("fcntl F_SETFL O_NONBLOCK failed: %s\n", - strerror(errno)); - close(sd); - return; - } - - /* SOCK_STREAM socket type requires an explicit connect to the remote host - * address and port. - * Only use IPv4 for the first connection attempt - */ - if ((sctp_new_association_req_p->remote_address.ipv6 != 0) || - (sctp_new_association_req_p->remote_address.ipv4 != 0)) { - uint8_t address_index = 0; - uint8_t used_address = sctp_new_association_req_p->remote_address.ipv6 + - sctp_new_association_req_p->remote_address.ipv4; - struct sockaddr_in addr[used_address]; - - memset(addr, 0, used_address * sizeof(struct sockaddr_in)); - - if (sctp_new_association_req_p->remote_address.ipv6 == 1) { - if (inet_pton(AF_INET6, sctp_new_association_req_p->remote_address.ipv6_address, - &addr[address_index].sin_addr.s_addr) != 1) { - SCTP_ERROR("Failed to convert ipv6 address %*s to network type\n", - (int)strlen(sctp_new_association_req_p->remote_address.ipv6_address), - sctp_new_association_req_p->remote_address.ipv6_address); + + /* Add the socket to list of fd monitored by ITTI */ + itti_subscribe_event_fd(TASK_SCTP, sd); + + if (sctp_set_init_opt(sd, + sctp_new_association_req_p->in_streams, + sctp_new_association_req_p->out_streams, + SCTP_MAX_ATTEMPTS, SCTP_TIMEOUT) != 0) { + SCTP_ERROR("Setsockopt IPPROTO_SCTP_INITMSG failed: %s\n", + strerror(errno)); + itti_unsubscribe_event_fd(TASK_SCTP, sd); close(sd); return; - } - - SCTP_DEBUG("Converted ipv6 address %*s to network type\n", - (int)strlen(sctp_new_association_req_p->remote_address.ipv6_address), - sctp_new_association_req_p->remote_address.ipv6_address); - - addr[address_index].sin_family = AF_INET6; - addr[address_index].sin_port = htons(sctp_new_association_req_p->port); - address_index++; } - if (sctp_new_association_req_p->remote_address.ipv4 == 1) { - if (inet_pton(AF_INET, sctp_new_association_req_p->remote_address.ipv4_address, - &addr[address_index].sin_addr.s_addr) != 1) { - SCTP_ERROR("Failed to convert ipv4 address %*s to network type\n", - (int)strlen(sctp_new_association_req_p->remote_address.ipv4_address), - sctp_new_association_req_p->remote_address.ipv4_address); + /* Subscribe to all events */ + memset((void *)&events, 1, sizeof(struct sctp_event_subscribe)); + + if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &events, + sizeof(struct sctp_event_subscribe)) < 0) { + SCTP_ERROR("Setsockopt IPPROTO_SCTP_EVENTS failed: %s\n", + strerror(errno)); close(sd); return; - } + } - SCTP_DEBUG("Converted ipv4 address %*s to network type\n", - (int)strlen(sctp_new_association_req_p->remote_address.ipv4_address), - sctp_new_association_req_p->remote_address.ipv4_address); + // Bind to device ... or we could bind to address also + if (getifaddrs(&ifaddr) == -1) { + SCTP_ERROR("getifaddrs failed: %s\n", strerror(errno)); + close(sd); + } - addr[address_index].sin_family = AF_INET; - addr[address_index].sin_port = htons(sctp_new_association_req_p->port); - address_index++; + /* Walk through linked list, maintaining head pointer so we + can free list later */ + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; + + family = ifa->ifa_addr->sa_family; + + /* For an AF_INET* interface address, display the address */ + if (sctp_new_association_req_p->local_address.ipv4 && family == AF_INET) { + // compare address + s = inet_aton(sctp_new_association_req_p->local_address.ipv4_address, + &in); + + if (s > 0 ) { + if (((struct sockaddr_in*)ifa->ifa_addr)->sin_addr.s_addr == in.s_addr) { + struct sockaddr_in locaddr; + locaddr.sin_family = AF_INET; + locaddr.sin_port = htons(sctp_new_association_req_p->port); + locaddr.sin_addr.s_addr = in.s_addr; + + if (sctp_bindx(sd, (struct sockaddr*)&locaddr, 1, SCTP_BINDX_ADD_ADDR) < 0) { + SCTP_ERROR("sctp_bindx SCTP_BINDX_ADD_ADDR failed: %s\n", + strerror(errno)); + } else { + SCTP_DEBUG("sctp_bindx SCTP_BINDX_ADD_ADDR socket bound to : %s\n", + inet_ntoa(locaddr.sin_addr)); + } + break; + + } + } + } else if (sctp_new_association_req_p->local_address.ipv6 && family == AF_INET6) { + // compare address + s = inet_pton(AF_INET6, + sctp_new_association_req_p->local_address.ipv6_address, + &in6); + + if (s == 1 ) { + if (memcmp(&((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr, + &in6, sizeof(in6)) == 0) { + memset(&ifr, 0, sizeof(ifr)); + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", ifa->ifa_name); + + if (setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) { + SCTP_ERROR("Setsockopt SOL_SOCKET failed: %s\n", + strerror(errno)); + } else { + SCTP_DEBUG("Setsockopt SOL_SOCKET socket bound to : %s\n", + ifa->ifa_name); + } + + break; + } + } + } } - /* Connect to remote host and port */ - if (sctp_connectx(sd, (struct sockaddr *)addr, 1, &assoc_id) < 0) { - /* sctp_connectx on non-blocking socket return EINPROGRESS */ - if (errno != EINPROGRESS) { - SCTP_ERROR("Connect failed: %s\n", strerror(errno)); - sctp_itti_send_association_resp( - requestor, instance, -1, sctp_new_association_req_p->ulp_cnx_id, - SCTP_STATE_UNREACHABLE, 0, 0); - /* Add the socket to list of fd monitored by ITTI */ - itti_unsubscribe_event_fd(TASK_SCTP, sd); + freeifaddrs(ifaddr); + + /* Mark the socket as non-blocking */ + if (fcntl(sd, F_SETFL, O_NONBLOCK) < 0) { + SCTP_ERROR("fcntl F_SETFL O_NONBLOCK failed: %s\n", + strerror(errno)); close(sd); return; - } else { - SCTP_DEBUG("connectx assoc_id %d in progress..., used %d addresses\n", - assoc_id, used_address); - } - } else { - SCTP_DEBUG("sctp_connectx SUCCESS, used %d addresses assoc_id %d\n", - used_address, - assoc_id); } - } else { - /* No remote address provided -> only bind the socket for now. - * Connection will be accepted in the main event loop + + /* SOCK_STREAM socket type requires an explicit connect to the remote host + * address and port. + * Only use IPv4 for the first connection attempt */ - struct sockaddr_in6 addr6; + if ((sctp_new_association_req_p->remote_address.ipv6 != 0) || + (sctp_new_association_req_p->remote_address.ipv4 != 0)) { + uint8_t address_index = 0; + uint8_t used_address = sctp_new_association_req_p->remote_address.ipv6 + + sctp_new_association_req_p->remote_address.ipv4; + struct sockaddr_in addr[used_address]; + + memset(addr, 0, used_address * sizeof(struct sockaddr_in)); + + if (sctp_new_association_req_p->remote_address.ipv6 == 1) { + if (inet_pton(AF_INET6, sctp_new_association_req_p->remote_address.ipv6_address, + &addr[address_index].sin_addr.s_addr) != 1) { + SCTP_ERROR("Failed to convert ipv6 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv6_address), + sctp_new_association_req_p->remote_address.ipv6_address); + close(sd); + return; + } + + SCTP_DEBUG("Converted ipv6 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv6_address), + sctp_new_association_req_p->remote_address.ipv6_address); + + addr[address_index].sin_family = AF_INET6; + addr[address_index].sin_port = htons(sctp_new_association_req_p->port); + address_index++; + } - connection_type = SCTP_TYPE_SERVER; + if (sctp_new_association_req_p->remote_address.ipv4 == 1) { + if (inet_pton(AF_INET, sctp_new_association_req_p->remote_address.ipv4_address, + &addr[address_index].sin_addr.s_addr) != 1) { + SCTP_ERROR("Failed to convert ipv4 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv4_address), + sctp_new_association_req_p->remote_address.ipv4_address); + close(sd); + return; + } + + SCTP_DEBUG("Converted ipv4 address %*s to network type\n", + (int)strlen(sctp_new_association_req_p->remote_address.ipv4_address), + sctp_new_association_req_p->remote_address.ipv4_address); + + addr[address_index].sin_family = AF_INET; + addr[address_index].sin_port = htons(sctp_new_association_req_p->port); + address_index++; + } + + /* Connect to remote host and port */ + if (sctp_connectx(sd, (struct sockaddr *)addr, 1, &assoc_id) < 0) { + /* sctp_connectx on non-blocking socket return EINPROGRESS */ + if (errno != EINPROGRESS) { + SCTP_ERROR("Connect failed: %s\n", strerror(errno)); + sctp_itti_send_association_resp( + requestor, instance, -1, sctp_new_association_req_p->ulp_cnx_id, + SCTP_STATE_UNREACHABLE, 0, 0); + /* Add the socket to list of fd monitored by ITTI */ + itti_unsubscribe_event_fd(TASK_SCTP, sd); + close(sd); + return; + } else { + SCTP_DEBUG("connectx assoc_id %d in progress..., used %d addresses\n", + assoc_id, used_address); + } + } else { + SCTP_DEBUG("sctp_connectx SUCCESS, used %d addresses assoc_id %d\n", + used_address, + assoc_id); + } + } else { + /* No remote address provided -> only bind the socket for now. + * Connection will be accepted in the main event loop + */ + struct sockaddr_in6 addr6; + + connection_type = SCTP_TYPE_SERVER; - /* For now bind to any interface */ - addr6.sin6_family = AF_INET6; - addr6.sin6_addr = in6addr_any; - addr6.sin6_port = htons(sctp_new_association_req_p->port); + /* For now bind to any interface */ + addr6.sin6_family = AF_INET6; + addr6.sin6_addr = in6addr_any; + addr6.sin6_port = htons(sctp_new_association_req_p->port); - if (bind(sd, (struct sockaddr*)&addr6, sizeof(addr6)) < 0) { - SCTP_ERROR("Failed to bind the socket to address any (v4/v6): %s\n", - strerror(errno)); - close(sd); - return; + if (bind(sd, (struct sockaddr*)&addr6, sizeof(addr6)) < 0) { + SCTP_ERROR("Failed to bind the socket to address any (v4/v6): %s\n", + strerror(errno)); + close(sd); + return; + } } - } - sctp_cnx = calloc(1, sizeof(*sctp_cnx)); + sctp_cnx = calloc(1, sizeof(*sctp_cnx)); - sctp_cnx->connection_type = connection_type; + sctp_cnx->connection_type = connection_type; - sctp_cnx->sd = sd; - sctp_cnx->task_id = requestor; - sctp_cnx->cnx_id = sctp_new_association_req_p->ulp_cnx_id; - sctp_cnx->ppid = sctp_new_association_req_p->ppid; - sctp_cnx->instance = instance; - sctp_cnx->assoc_id = assoc_id; + sctp_cnx->sd = sd; + sctp_cnx->task_id = requestor; + sctp_cnx->cnx_id = sctp_new_association_req_p->ulp_cnx_id; + sctp_cnx->ppid = sctp_new_association_req_p->ppid; + sctp_cnx->instance = instance; + sctp_cnx->assoc_id = assoc_id; - /* Insert new element at end of list */ - STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries); - sctp_nb_cnx++; + /* Insert new element at end of list */ + STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries); + sctp_nb_cnx++; - SCTP_DEBUG("Inserted new descriptor for sd %d in list, nb elements %u, assoc_id %d\n", - sd, sctp_nb_cnx, assoc_id); + SCTP_DEBUG("Inserted new descriptor for sd %d in list, nb elements %u, assoc_id %d\n", + sd, sctp_nb_cnx, assoc_id); } - //------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ void sctp_send_data( - instance_t instance, - task_id_t task_id, - sctp_data_req_t *sctp_data_req_p) + instance_t instance, + task_id_t task_id, + sctp_data_req_t *sctp_data_req_p) { - struct sctp_cnx_list_elm_s *sctp_cnx = NULL; - - DevAssert(sctp_data_req_p != NULL); - DevAssert(sctp_data_req_p->buffer != NULL); - DevAssert(sctp_data_req_p->buffer_length > 0); - - sctp_cnx = sctp_get_cnx(sctp_data_req_p->assoc_id, 0); - - if (sctp_cnx == NULL) { - SCTP_ERROR("Failed to find SCTP description for assoc_id %d\n", - sctp_data_req_p->assoc_id); - /* TODO: notify upper layer */ - return; - } - - if (sctp_data_req_p->stream >= sctp_cnx->out_streams) { - SCTP_ERROR("Requested stream (%"PRIu16") >= nb out streams (%"PRIu16")\n", - sctp_data_req_p->stream, sctp_cnx->out_streams); - return; - } - - /* Send message on specified stream of the sd association - * NOTE: PPID should be defined in network order - */ - if (sctp_sendmsg(sctp_cnx->sd, sctp_data_req_p->buffer, - sctp_data_req_p->buffer_length, NULL, 0, - htonl(sctp_cnx->ppid), 0, sctp_data_req_p->stream, 0, 0) < 0) { - SCTP_ERROR("Sctp_sendmsg failed: %s\n", strerror(errno)); - /* TODO: notify upper layer */ - return; - } - - SCTP_DEBUG("Successfully sent %u bytes on stream %d for assoc_id %u\n", - sctp_data_req_p->buffer_length, sctp_data_req_p->stream, - sctp_cnx->assoc_id); + struct sctp_cnx_list_elm_s *sctp_cnx = NULL; + + DevAssert(sctp_data_req_p != NULL); + DevAssert(sctp_data_req_p->buffer != NULL); + DevAssert(sctp_data_req_p->buffer_length > 0); + + sctp_cnx = sctp_get_cnx(sctp_data_req_p->assoc_id, 0); + + if (sctp_cnx == NULL) { + SCTP_ERROR("Failed to find SCTP description for assoc_id %d\n", + sctp_data_req_p->assoc_id); + /* TODO: notify upper layer */ + return; + } + + if (sctp_data_req_p->stream >= sctp_cnx->out_streams) { + SCTP_ERROR("Requested stream (%"PRIu16") >= nb out streams (%"PRIu16")\n", + sctp_data_req_p->stream, sctp_cnx->out_streams); + return; + } + + /* Send message on specified stream of the sd association + * NOTE: PPID should be defined in network order + */ + if (sctp_sendmsg(sctp_cnx->sd, sctp_data_req_p->buffer, + sctp_data_req_p->buffer_length, NULL, 0, + htonl(sctp_cnx->ppid), 0, sctp_data_req_p->stream, 0, 0) < 0) { + SCTP_ERROR("Sctp_sendmsg failed: %s\n", strerror(errno)); + /* TODO: notify upper layer */ + return; + } + + SCTP_DEBUG("Successfully sent %u bytes on stream %d for assoc_id %u\n", + sctp_data_req_p->buffer_length, sctp_data_req_p->stream, + sctp_cnx->assoc_id); } //------------------------------------------------------------------------------ static int sctp_close_association( - const instance_t instance, - const task_id_t requestor, - sctp_close_association_t *close_association_p) + const instance_t instance, + const task_id_t requestor, + sctp_close_association_t *close_association_p) { - struct sctp_cnx_list_elm_s *sctp_cnx = NULL; + struct sctp_cnx_list_elm_s *sctp_cnx = NULL; - DevAssert(close_association_p != NULL); - sctp_cnx = sctp_get_cnx(close_association_p->assoc_id, 0); + DevAssert(close_association_p != NULL); + sctp_cnx = sctp_get_cnx(close_association_p->assoc_id, 0); - if (sctp_cnx == NULL) { - SCTP_ERROR("Failed to find SCTP description for assoc_id %d\n", - close_association_p->assoc_id); - /* TODO: notify upper layer */ - return -1; - } else { - close(sctp_cnx->sd); - STAILQ_REMOVE(&sctp_cnx_list, sctp_cnx, sctp_cnx_list_elm_s, entries); - SCTP_DEBUG("Removed assoc_id %u (closed socket %u)\n", - sctp_cnx->assoc_id, sctp_cnx->sd); - } - - return 0; + if (sctp_cnx == NULL) { + SCTP_ERROR("Failed to find SCTP description for assoc_id %d\n", + close_association_p->assoc_id); + /* TODO: notify upper layer */ + return -1; + } else { + close(sctp_cnx->sd); + STAILQ_REMOVE(&sctp_cnx_list, sctp_cnx, sctp_cnx_list_elm_s, entries); + SCTP_DEBUG("Removed assoc_id %u (closed socket %u)\n", + sctp_cnx->assoc_id, (unsigned int)sctp_cnx->sd); + } + + return 0; } //------------------------------------------------------------------------------ static int sctp_create_new_listener( - const instance_t instance, - const task_id_t requestor, - sctp_init_t *init_p, - int server_type) + const instance_t instance, + const task_id_t requestor, + sctp_init_t *init_p, + int server_type) { - struct sctp_event_subscribe event; - struct sockaddr *addr = NULL; - struct sctp_cnx_list_elm_s *sctp_cnx = NULL; - uint16_t i = 0, j = 0; - int sd = 0; - int used_addresses = 0; - - DevAssert(init_p != NULL); - - if (init_p->ipv4 == 0 && init_p->ipv6 == 0) { - SCTP_ERROR("Illegal IP configuration upper layer should request at" - "least ipv4 and/or ipv6 config\n"); - return -1; - } + struct sctp_event_subscribe event; + struct sockaddr *addr = NULL; + struct sctp_cnx_list_elm_s *sctp_cnx = NULL; + uint16_t i = 0, j = 0; + int sd = 0; + int used_addresses = 0; + + DevAssert(init_p != NULL); + + if (init_p->ipv4 == 0 && init_p->ipv6 == 0) { + SCTP_ERROR("Illegal IP configuration upper layer should request at" + "least ipv4 and/or ipv6 config\n"); + return -1; + } - if ((used_addresses = init_p->nb_ipv4_addr + init_p->nb_ipv6_addr) == 0) { - SCTP_WARN("No address provided...\n"); - return -1; - } + if ((used_addresses = init_p->nb_ipv4_addr + init_p->nb_ipv6_addr) == 0) { + SCTP_WARN("No address provided...\n"); + return -1; + } - addr = calloc(used_addresses, sizeof(struct sockaddr)); + addr = calloc(used_addresses, sizeof(struct sockaddr)); - SCTP_DEBUG("Creating new listen socket on port %u with\n", init_p->port); + SCTP_DEBUG("Creating new listen socket on port %u with\n", init_p->port); - if (init_p->ipv4 == 1) { - struct sockaddr_in *ip4_addr; + if (init_p->ipv4 == 1) { + struct sockaddr_in *ip4_addr; - SCTP_DEBUG("ipv4 addresses:\n"); + SCTP_DEBUG("ipv4 addresses:\n"); - for (i = 0; i < init_p->nb_ipv4_addr; i++) { - SCTP_DEBUG("\t- "IPV4_ADDR"\n", - IPV4_ADDR_FORMAT(init_p->ipv4_address[i])); - ip4_addr = (struct sockaddr_in *)&addr[i]; - ip4_addr->sin_family = AF_INET; - ip4_addr->sin_port = htons(init_p->port); - ip4_addr->sin_addr.s_addr = init_p->ipv4_address[i]; + for (i = 0; i < init_p->nb_ipv4_addr; i++) { + SCTP_DEBUG("\t- "IPV4_ADDR"\n", + IPV4_ADDR_FORMAT(init_p->ipv4_address[i])); + ip4_addr = (struct sockaddr_in *)&addr[i]; + ip4_addr->sin_family = AF_INET; + ip4_addr->sin_port = htons(init_p->port); + ip4_addr->sin_addr.s_addr = init_p->ipv4_address[i]; + } } - } - if (init_p->ipv6 == 1) { - struct sockaddr_in6 *ip6_addr; + if (init_p->ipv6 == 1) { + struct sockaddr_in6 *ip6_addr; - SCTP_DEBUG("ipv6 addresses:\n"); + SCTP_DEBUG("ipv6 addresses:\n"); - for (j = 0; j < init_p->nb_ipv6_addr; j++) { - SCTP_DEBUG("\t- %s\n", init_p->ipv6_address[j]); - ip6_addr = (struct sockaddr_in6 *)&addr[i + j]; - ip6_addr->sin6_family = AF_INET6; - ip6_addr->sin6_port = htons(init_p->port); + for (j = 0; j < init_p->nb_ipv6_addr; j++) { + SCTP_DEBUG("\t- %s\n", init_p->ipv6_address[j]); + ip6_addr = (struct sockaddr_in6 *)&addr[i + j]; + ip6_addr->sin6_family = AF_INET6; + ip6_addr->sin6_port = htons(init_p->port); - if (inet_pton(AF_INET6, init_p->ipv6_address[j], - ip6_addr->sin6_addr.s6_addr) <= 0) { - SCTP_WARN("Provided ipv6 address %s is not valid\n", - init_p->ipv6_address[j]); - } + if (inet_pton(AF_INET6, init_p->ipv6_address[j], + ip6_addr->sin6_addr.s6_addr) <= 0) { + SCTP_WARN("Provided ipv6 address %s is not valid\n", + init_p->ipv6_address[j]); + } + } } - } - if (server_type) { - if ((sd = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) { - SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno); - return -1; + if (server_type) { + if ((sd = socket(PF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) { + SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno); + free(addr); + return -1; + } } - } - else { - if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) { - SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno); - return -1; + else { + if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) { + SCTP_ERROR("socket: %s:%d\n", strerror(errno), errno); + free(addr); + return -1; + } } - } - memset((void *)&event, 1, sizeof(struct sctp_event_subscribe)); + memset((void *)&event, 1, sizeof(struct sctp_event_subscribe)); - if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &event, - sizeof(struct sctp_event_subscribe)) < 0) { - SCTP_ERROR("setsockopt: %s:%d\n", strerror(errno), errno); - return -1; - } - - sctp_cnx = calloc(1, sizeof(*sctp_cnx)); - - if (server_type) { - sctp_cnx->connection_type = SCTP_TYPE_MULTI_SERVER; - } - else { - sctp_cnx->connection_type = SCTP_TYPE_SERVER; - } - - sctp_cnx->sd = sd; - sctp_cnx->local_port = init_p->port; - sctp_cnx->in_streams = 32; - sctp_cnx->out_streams = 32; - sctp_cnx->ppid = init_p->ppid; - sctp_cnx->task_id = requestor; - sctp_cnx->instance = instance; - - /* Some pre-bind socket configuration */ - if (sctp_set_init_opt(sd, - sctp_cnx->in_streams, - sctp_cnx->out_streams, - 0, - 0) < 0) { - goto err; - } - - if (sctp_bindx(sd, addr, used_addresses, SCTP_BINDX_ADD_ADDR) != 0) { - SCTP_ERROR("sctp_bindx: %s:%d\n", strerror(errno), errno); - return -1; - } + if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &event, + sizeof(struct sctp_event_subscribe)) < 0) { + SCTP_ERROR("setsockopt: %s:%d\n", strerror(errno), errno); + free(addr); + return -1; + } - if (listen(sd, 5) < 0) { - SCTP_ERROR("listen: %s:%d\n", strerror(errno), errno); - return -1; - } + sctp_cnx = calloc(1, sizeof(*sctp_cnx)); - /* Insert new element at end of list */ - STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries); - sctp_nb_cnx++; + if (server_type) { + sctp_cnx->connection_type = SCTP_TYPE_MULTI_SERVER; + } + else { + sctp_cnx->connection_type = SCTP_TYPE_SERVER; + } + + sctp_cnx->sd = sd; + sctp_cnx->local_port = init_p->port; + sctp_cnx->in_streams = 32; + sctp_cnx->out_streams = 32; + sctp_cnx->ppid = init_p->ppid; + sctp_cnx->task_id = requestor; + sctp_cnx->instance = instance; + + /* Some pre-bind socket configuration */ + if (sctp_set_init_opt(sd, + sctp_cnx->in_streams, + sctp_cnx->out_streams, + 0, + 0) < 0) { + goto err; + } + + if (sctp_bindx(sd, addr, used_addresses, SCTP_BINDX_ADD_ADDR) != 0) { + SCTP_ERROR("sctp_bindx: %s:%d\n", strerror(errno), errno); + return -1; + } + + if (listen(sd, 5) < 0) { + SCTP_ERROR("listen: %s:%d\n", strerror(errno), errno); + return -1; + } + + /* Insert new element at end of list */ + STAILQ_INSERT_TAIL(&sctp_cnx_list, sctp_cnx, entries); + sctp_nb_cnx++; - /* Add the socket to list of fd monitored by ITTI */ - itti_subscribe_event_fd(TASK_SCTP, sd); + /* Add the socket to list of fd monitored by ITTI */ + itti_subscribe_event_fd(TASK_SCTP, sd); - return sd; + return sd; err: - if (sd != -1) { - close(sd); - sd = -1; - } + if (sd != -1) { + close(sd); + sd = -1; + } - return -1; + return -1; } //------------------------------------------------------------------------------ static inline void sctp_eNB_accept_associations( - struct sctp_cnx_list_elm_s *sctp_cnx) + struct sctp_cnx_list_elm_s *sctp_cnx) { - int client_sd; - struct sockaddr saddr; - socklen_t saddr_size; - - DevAssert(sctp_cnx != NULL); - - saddr_size = sizeof(saddr); - - /* There is a new client connecting. Accept it... - */ - if ((client_sd = accept(sctp_cnx->sd, &saddr, &saddr_size)) < 0) { - SCTP_ERROR("[%d] accept failed: %s:%d\n", sctp_cnx->sd, strerror(errno), errno); - } else { - struct sctp_cnx_list_elm_s *new_cnx; - uint16_t port; - - /* This is an ipv6 socket */ - port = ((struct sockaddr_in6*)&saddr)->sin6_port; - - /* Contrary to BSD, client socket does not inherit O_NONBLOCK option */ - if (fcntl(client_sd, F_SETFL, O_NONBLOCK) < 0) { - SCTP_ERROR("fcntl F_SETFL O_NONBLOCK failed: %s\n", - strerror(errno)); - close(client_sd); - return; - } + int client_sd; + struct sockaddr saddr; + socklen_t saddr_size; - new_cnx = calloc(1, sizeof(*sctp_cnx)); + DevAssert(sctp_cnx != NULL); - DevAssert(new_cnx != NULL); + saddr_size = sizeof(saddr); - new_cnx->connection_type = SCTP_TYPE_CLIENT; + /* There is a new client connecting. Accept it... + */ + if ((client_sd = accept(sctp_cnx->sd, &saddr, &saddr_size)) < 0) { + SCTP_ERROR("[%d] accept failed: %s:%d\n", sctp_cnx->sd, strerror(errno), errno); + } else { + struct sctp_cnx_list_elm_s *new_cnx; + uint16_t port; - new_cnx->sd = client_sd; - new_cnx->task_id = sctp_cnx->task_id; - new_cnx->cnx_id = 0; - new_cnx->ppid = sctp_cnx->ppid; - new_cnx->instance = sctp_cnx->instance; - new_cnx->local_port = sctp_cnx->local_port; + /* This is an ipv6 socket */ + port = ((struct sockaddr_in6*)&saddr)->sin6_port; - if (sctp_get_sockinfo(client_sd, &new_cnx->in_streams, &new_cnx->out_streams, - &new_cnx->assoc_id) != 0) { - SCTP_ERROR("sctp_get_sockinfo failed\n"); - close(client_sd); - free(new_cnx); - return; - } + /* Contrary to BSD, client socket does not inherit O_NONBLOCK option */ + if (fcntl(client_sd, F_SETFL, O_NONBLOCK) < 0) { + SCTP_ERROR("fcntl F_SETFL O_NONBLOCK failed: %s\n", + strerror(errno)); + close(client_sd); + return; + } - /* Insert new element at end of list */ - STAILQ_INSERT_TAIL(&sctp_cnx_list, new_cnx, entries); - sctp_nb_cnx++; + new_cnx = calloc(1, sizeof(*sctp_cnx)); - /* Add the socket to list of fd monitored by ITTI */ - itti_subscribe_event_fd(TASK_SCTP, client_sd); + DevAssert(new_cnx != NULL); + + new_cnx->connection_type = SCTP_TYPE_CLIENT; + + new_cnx->sd = client_sd; + new_cnx->task_id = sctp_cnx->task_id; + new_cnx->cnx_id = 0; + new_cnx->ppid = sctp_cnx->ppid; + new_cnx->instance = sctp_cnx->instance; + new_cnx->local_port = sctp_cnx->local_port; + + if (sctp_get_sockinfo(client_sd, &new_cnx->in_streams, &new_cnx->out_streams, + &new_cnx->assoc_id) != 0) { + SCTP_ERROR("sctp_get_sockinfo failed\n"); + close(client_sd); + free(new_cnx); + return; + } + + /* Insert new element at end of list */ + STAILQ_INSERT_TAIL(&sctp_cnx_list, new_cnx, entries); + sctp_nb_cnx++; + + /* Add the socket to list of fd monitored by ITTI */ + itti_subscribe_event_fd(TASK_SCTP, client_sd); - sctp_itti_send_association_ind(new_cnx->task_id, new_cnx->instance, - new_cnx->assoc_id, port, - new_cnx->out_streams, new_cnx->in_streams); - } + sctp_itti_send_association_ind(new_cnx->task_id, new_cnx->instance, + new_cnx->assoc_id, port, + new_cnx->out_streams, new_cnx->in_streams); + } } //------------------------------------------------------------------------------ static inline void sctp_eNB_read_from_socket( - struct sctp_cnx_list_elm_s *sctp_cnx) + struct sctp_cnx_list_elm_s *sctp_cnx) { - int flags = 0, n; - socklen_t from_len; - struct sctp_sndrcvinfo sinfo; + int flags = 0, n; + socklen_t from_len; + struct sctp_sndrcvinfo sinfo; - struct sockaddr_in addr; - uint8_t buffer[SCTP_RECV_BUFFER_SIZE]; + struct sockaddr_in addr; + uint8_t buffer[SCTP_RECV_BUFFER_SIZE]; - DevAssert(sctp_cnx != NULL); + DevAssert(sctp_cnx != NULL); - memset((void *)&addr, 0, sizeof(struct sockaddr_in)); - from_len = (socklen_t)sizeof(struct sockaddr_in); - memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); + memset((void *)&addr, 0, sizeof(struct sockaddr_in)); + from_len = (socklen_t)sizeof(struct sockaddr_in); + memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); - n = sctp_recvmsg(sctp_cnx->sd, (void *)buffer, SCTP_RECV_BUFFER_SIZE, - (struct sockaddr *)&addr, &from_len, - &sinfo, &flags); + n = sctp_recvmsg(sctp_cnx->sd, (void *)buffer, SCTP_RECV_BUFFER_SIZE, + (struct sockaddr *)&addr, &from_len, + &sinfo, &flags); - if (n < 0) { - if (errno == ENOTCONN) { - itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd); + if (n < 0) { + if (errno == ENOTCONN) { + itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd); - SCTP_DEBUG("Received not connected for sd %d\n", sctp_cnx->sd); + SCTP_DEBUG("Received not connected for sd %d\n", sctp_cnx->sd); - sctp_itti_send_association_resp( - sctp_cnx->task_id, sctp_cnx->instance, -1, - sctp_cnx->cnx_id, SCTP_STATE_UNREACHABLE, 0, 0); + sctp_itti_send_association_resp( + sctp_cnx->task_id, sctp_cnx->instance, -1, + sctp_cnx->cnx_id, SCTP_STATE_UNREACHABLE, 0, 0); - close(sctp_cnx->sd); - STAILQ_REMOVE(&sctp_cnx_list, sctp_cnx, sctp_cnx_list_elm_s, entries); - sctp_nb_cnx--; - free(sctp_cnx); - } else { - SCTP_DEBUG("An error occured during read\n"); - SCTP_ERROR("sctp_recvmsg (fd %d, len %d ): %s:%d\n", sctp_cnx->sd, n, strerror(errno), errno); - } + close(sctp_cnx->sd); + STAILQ_REMOVE(&sctp_cnx_list, sctp_cnx, sctp_cnx_list_elm_s, entries); + sctp_nb_cnx--; + free(sctp_cnx); + } else { + SCTP_DEBUG("An error occured during read\n"); + SCTP_ERROR("sctp_recvmsg (fd %d, len %d ): %s:%d\n", sctp_cnx->sd, n, strerror(errno), errno); + } - return; - } else if (n == 0) { - SCTP_DEBUG("return of sctp_recvmsg is 0...\n"); - return; - } + return; + } else if (n == 0) { + SCTP_DEBUG("return of sctp_recvmsg is 0...\n"); + return; + } - if (flags & MSG_NOTIFICATION) { - union sctp_notification *snp; - snp = (union sctp_notification *)buffer; + if (flags & MSG_NOTIFICATION) { + union sctp_notification *snp; + snp = (union sctp_notification *)buffer; - SCTP_DEBUG("Received notification for sd %d, type %u\n", - sctp_cnx->sd, snp->sn_header.sn_type); + SCTP_DEBUG("Received notification for sd %d, type %u\n", + sctp_cnx->sd, snp->sn_header.sn_type); - /* Client deconnection */ - if (SCTP_SHUTDOWN_EVENT == snp->sn_header.sn_type) { - itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd); + /* Client deconnection */ + if (SCTP_SHUTDOWN_EVENT == snp->sn_header.sn_type) { + itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd); - close(sctp_cnx->sd); + close(sctp_cnx->sd); - sctp_itti_send_association_resp( - sctp_cnx->task_id, sctp_cnx->instance, sctp_cnx->assoc_id, - sctp_cnx->cnx_id, SCTP_STATE_SHUTDOWN, - 0, 0); + sctp_itti_send_association_resp( + sctp_cnx->task_id, sctp_cnx->instance, sctp_cnx->assoc_id, + sctp_cnx->cnx_id, SCTP_STATE_SHUTDOWN, + 0, 0); - STAILQ_REMOVE(&sctp_cnx_list, sctp_cnx, sctp_cnx_list_elm_s, entries); - sctp_nb_cnx--; + STAILQ_REMOVE(&sctp_cnx_list, sctp_cnx, sctp_cnx_list_elm_s, entries); + sctp_nb_cnx--; - free(sctp_cnx); - } - /* Association has changed. */ - else if (SCTP_ASSOC_CHANGE == snp->sn_header.sn_type) { - struct sctp_assoc_change *sctp_assoc_changed; - sctp_assoc_changed = &snp->sn_assoc_change; - - SCTP_DEBUG("Client association changed: %d\n", sctp_assoc_changed->sac_state); - - /* New physical association requested by a peer */ - switch (sctp_assoc_changed->sac_state) { - case SCTP_COMM_UP: { - if (sctp_get_peeraddresses(sctp_cnx->sd, NULL, NULL) != 0) { - /* TODO Failure -> notify upper layer */ - } else { - sctp_get_sockinfo(sctp_cnx->sd, &sctp_cnx->in_streams, - &sctp_cnx->out_streams, &sctp_cnx->assoc_id); + free(sctp_cnx); + } + /* Association has changed. */ + else if (SCTP_ASSOC_CHANGE == snp->sn_header.sn_type) { + struct sctp_assoc_change *sctp_assoc_changed; + sctp_assoc_changed = &snp->sn_assoc_change; + + SCTP_DEBUG("Client association changed: %d\n", sctp_assoc_changed->sac_state); + + /* New physical association requested by a peer */ + switch (sctp_assoc_changed->sac_state) { + case SCTP_COMM_UP: { + if (sctp_get_peeraddresses(sctp_cnx->sd, NULL, NULL) != 0) { + /* TODO Failure -> notify upper layer */ + } else { + sctp_get_sockinfo(sctp_cnx->sd, &sctp_cnx->in_streams, + &sctp_cnx->out_streams, &sctp_cnx->assoc_id); + } + + SCTP_DEBUG("Comm up notified for sd %d, assigned assoc_id %d\n", + sctp_cnx->sd, sctp_cnx->assoc_id); + + sctp_itti_send_association_resp( + sctp_cnx->task_id, sctp_cnx->instance, sctp_cnx->assoc_id, + sctp_cnx->cnx_id, SCTP_STATE_ESTABLISHED, + sctp_cnx->out_streams, sctp_cnx->in_streams); + + } + break; + + default: + SCTP_WARN("unhandled: SCTP_ASSOC_CHANGE to %d\n", sctp_assoc_changed->sac_state); + break; + } + } + } else { + sctp_cnx->messages_recv++; + + if (ntohl(sinfo.sinfo_ppid) != sctp_cnx->ppid) { + /* Mismatch in Payload Protocol Identifier, + * may be we received unsollicited traffic from stack other than S1AP. + */ + SCTP_ERROR("Received data from peer with unsollicited PPID %d, expecting %d\n", + ntohl(sinfo.sinfo_ppid), + sctp_cnx->ppid); } - SCTP_DEBUG("Comm up notified for sd %d, assigned assoc_id %d\n", - sctp_cnx->sd, sctp_cnx->assoc_id); - - sctp_itti_send_association_resp( - sctp_cnx->task_id, sctp_cnx->instance, sctp_cnx->assoc_id, - sctp_cnx->cnx_id, SCTP_STATE_ESTABLISHED, - sctp_cnx->out_streams, sctp_cnx->in_streams); - - } - break; + SCTP_DEBUG("[%d][%d] Msg of length %d received from port %u, on stream %d, PPID %d\n", + sinfo.sinfo_assoc_id, sctp_cnx->sd, n, ntohs(addr.sin_port), + sinfo.sinfo_stream, ntohl(sinfo.sinfo_ppid)); - default: - SCTP_WARN("unhandled: SCTP_ASSOC_CHANGE to %d\n", sctp_assoc_changed->sac_state); - break; - } - } - } else { - sctp_cnx->messages_recv++; - - if (ntohl(sinfo.sinfo_ppid) != sctp_cnx->ppid) { - /* Mismatch in Payload Protocol Identifier, - * may be we received unsollicited traffic from stack other than S1AP. - */ - SCTP_ERROR("Received data from peer with unsollicited PPID %d, expecting %d\n", - ntohl(sinfo.sinfo_ppid), - sctp_cnx->ppid); + sctp_itti_send_new_message_ind(sctp_cnx->task_id, + sctp_cnx->instance, + sinfo.sinfo_assoc_id, + buffer, + n, + sinfo.sinfo_stream); } - - SCTP_DEBUG("[%d][%d] Msg of length %d received from port %u, on stream %d, PPID %d\n", - sinfo.sinfo_assoc_id, sctp_cnx->sd, n, ntohs(addr.sin_port), - sinfo.sinfo_stream, ntohl(sinfo.sinfo_ppid)); - - sctp_itti_send_new_message_ind(sctp_cnx->task_id, - sinfo.sinfo_assoc_id, - buffer, n, sinfo.sinfo_stream); - } } //------------------------------------------------------------------------------ void sctp_eNB_flush_sockets( - struct epoll_event *events, int nb_events) + struct epoll_event *events, int nb_events) { - int i; - struct sctp_cnx_list_elm_s *sctp_cnx = NULL; + int i; + struct sctp_cnx_list_elm_s *sctp_cnx = NULL; - if (events == NULL) { - return; - } + if (events == NULL) { + return; + } - for (i = 0; i < nb_events; i++) { - sctp_cnx = sctp_get_cnx(-1, events[i].data.fd); + for (i = 0; i < nb_events; i++) { + sctp_cnx = sctp_get_cnx(-1, events[i].data.fd); - if (sctp_cnx == NULL) { - continue; - } + if (sctp_cnx == NULL) { + continue; + } - SCTP_DEBUG("Found data for descriptor %d\n", events[i].data.fd); + SCTP_DEBUG("Found data for descriptor %d\n", events[i].data.fd); - if (sctp_cnx->connection_type == SCTP_TYPE_CLIENT) { - sctp_eNB_read_from_socket(sctp_cnx); - } - else if (sctp_cnx->connection_type == SCTP_TYPE_MULTI_SERVER) { - sctp_eNB_accept_associations_multi(sctp_cnx); - } - else { - sctp_eNB_accept_associations(sctp_cnx); + if (sctp_cnx->connection_type == SCTP_TYPE_CLIENT) { + sctp_eNB_read_from_socket(sctp_cnx); + } + else if (sctp_cnx->connection_type == SCTP_TYPE_MULTI_SERVER) { + sctp_eNB_accept_associations_multi(sctp_cnx); + } + else { + sctp_eNB_accept_associations(sctp_cnx); + } } - } } //------------------------------------------------------------------------------ void sctp_eNB_init(void) { - SCTP_DEBUG("Starting SCTP layer\n"); + SCTP_DEBUG("Starting SCTP layer\n"); - STAILQ_INIT(&sctp_cnx_list); + STAILQ_INIT(&sctp_cnx_list); - itti_mark_task_ready(TASK_SCTP); - MSC_START_USE(); + itti_mark_task_ready(TASK_SCTP); + MSC_START_USE(); } - + //------------------------------------------------------------------------------ void *sctp_eNB_process_itti_msg(void *notUsed) { @@ -1058,88 +1069,88 @@ void *sctp_eNB_process_itti_msg(void *notUsed) struct epoll_event *events; MessageDef *received_msg = NULL; int result; - + itti_receive_msg(TASK_SCTP, &received_msg); /* Check if there is a packet to handle */ if (received_msg != NULL) { - switch (ITTI_MSG_ID(received_msg)) { - case SCTP_INIT_MSG: { - SCTP_DEBUG("Received SCTP_INIT_MSG\n"); - - /* We received a new connection request */ - if (sctp_create_new_listener( - ITTI_MESSAGE_GET_INSTANCE(received_msg), - ITTI_MSG_ORIGIN_ID(received_msg), - &received_msg->ittiMsg.sctp_init,0) < 0) { - /* SCTP socket creation or bind failed... */ - SCTP_ERROR("Failed to create new SCTP listener\n"); - } - } - break; - - case SCTP_INIT_MSG_MULTI_REQ: { - int multi_sd; - - SCTP_DEBUG("Received SCTP_INIT_MSG_MULTI_REQ\n"); - - multi_sd = sctp_create_new_listener( - ITTI_MESSAGE_GET_INSTANCE(received_msg), - ITTI_MSG_ORIGIN_ID(received_msg), - &received_msg->ittiMsg.sctp_init_multi,1); - /* We received a new connection request */ - if (multi_sd < 0) { - /* SCTP socket creation or bind failed... */ - SCTP_ERROR("Failed to create new SCTP listener\n"); + switch (ITTI_MSG_ID(received_msg)) { + case SCTP_INIT_MSG: { + SCTP_DEBUG("Received SCTP_INIT_MSG\n"); + + /* We received a new connection request */ + if (sctp_create_new_listener( + ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_ORIGIN_ID(received_msg), + &received_msg->ittiMsg.sctp_init,0) < 0) { + /* SCTP socket creation or bind failed... */ + SCTP_ERROR("Failed to create new SCTP listener\n"); + } } - sctp_itti_send_init_msg_multi_cnf( + break; + + case SCTP_INIT_MSG_MULTI_REQ: { + int multi_sd; + + SCTP_DEBUG("Received SCTP_INIT_MSG_MULTI_REQ\n"); + + multi_sd = sctp_create_new_listener( + ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_ORIGIN_ID(received_msg), + &received_msg->ittiMsg.sctp_init_multi,1); + /* We received a new connection request */ + if (multi_sd < 0) { + /* SCTP socket creation or bind failed... */ + SCTP_ERROR("Failed to create new SCTP listener\n"); + } + sctp_itti_send_init_msg_multi_cnf( ITTI_MSG_ORIGIN_ID(received_msg), ITTI_MESSAGE_GET_INSTANCE(received_msg), multi_sd); - } - break; - - case SCTP_NEW_ASSOCIATION_REQ: { - sctp_handle_new_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), - ITTI_MSG_ORIGIN_ID(received_msg), - &received_msg->ittiMsg.sctp_new_association_req); - } - break; - - case SCTP_NEW_ASSOCIATION_REQ_MULTI: { - sctp_handle_new_association_req_multi(ITTI_MESSAGE_GET_INSTANCE(received_msg), - ITTI_MSG_ORIGIN_ID(received_msg), - &received_msg->ittiMsg.sctp_new_association_req_multi); - } - break; - - case SCTP_CLOSE_ASSOCIATION: - sctp_close_association(ITTI_MESSAGE_GET_INSTANCE(received_msg), - ITTI_MSG_ORIGIN_ID(received_msg), - &received_msg->ittiMsg.sctp_close_association); + } break; - case TERMINATE_MESSAGE: - SCTP_WARN("*** Exiting SCTP thread\n"); - itti_exit_task(); + case SCTP_NEW_ASSOCIATION_REQ: { + sctp_handle_new_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_ORIGIN_ID(received_msg), + &received_msg->ittiMsg.sctp_new_association_req); + } break; - case SCTP_DATA_REQ: { - sctp_send_data(ITTI_MESSAGE_GET_INSTANCE(received_msg), - ITTI_MSG_ORIGIN_ID(received_msg), - &received_msg->ittiMsg.sctp_data_req); - } - break; + case SCTP_NEW_ASSOCIATION_REQ_MULTI: { + sctp_handle_new_association_req_multi(ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_ORIGIN_ID(received_msg), + &received_msg->ittiMsg.sctp_new_association_req_multi); + } + break; - default: - SCTP_ERROR("Received unhandled message %d:%s\n", - ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + case SCTP_CLOSE_ASSOCIATION: + sctp_close_association(ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_ORIGIN_ID(received_msg), + &received_msg->ittiMsg.sctp_close_association); + break; + + case TERMINATE_MESSAGE: + SCTP_WARN("*** Exiting SCTP thread\n"); + itti_exit_task(); + break; + + case SCTP_DATA_REQ: { + sctp_send_data(ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_ORIGIN_ID(received_msg), + &received_msg->ittiMsg.sctp_data_req); + } break; - } - result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - received_msg = NULL; + default: + SCTP_ERROR("Received unhandled message %d:%s\n", + ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } + + result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + received_msg = NULL; } nb_events = itti_get_events(TASK_SCTP, &events); @@ -1148,15 +1159,15 @@ void *sctp_eNB_process_itti_msg(void *notUsed) return NULL; } - + //------------------------------------------------------------------------------ void *sctp_eNB_task(void *arg) { - sctp_eNB_init(); + sctp_eNB_init(); - while (1) { - (void) sctp_eNB_process_itti_msg(NULL); - } + while (1) { + (void) sctp_eNB_process_itti_msg(NULL); + } - return NULL; + return NULL; } diff --git a/openair3/TEST/EPC_TEST/generate_scenario.c b/openair3/TEST/EPC_TEST/generate_scenario.c index b8d9d9c5885d2a0c19eea56c0d1413db046e778e..a8a359094518ae62b32f9dac52f5d40bc3539647 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.c +++ b/openair3/TEST/EPC_TEST/generate_scenario.c @@ -270,7 +270,7 @@ static void enb_config_display(void) printf( " ENB CONFIG FILE CONTENT LOADED:\n"); printf( "----------------------------------------------------------------------\n"); for (i = 0; i < g_enb_properties.number; i++) { - printf( "ENB CONFIG for instance %u:\n\n", i); + printf( "ENB CONFIG for instance %d:\n\n", i); printf( "\teNB name: \t%s\n",g_enb_properties.properties[i]->eNB_name); printf( "\teNB ID: \t%"PRIu32"\n",g_enb_properties.properties[i]->eNB_id); printf( "\tCell type: \t%s\n",g_enb_properties.properties[i]->cell_type == CELL_MACRO_ENB ? "CELL_MACRO_ENB":"CELL_HOME_ENB"); @@ -353,7 +353,7 @@ void enb_config_init(const char const * lib_config_file_name_pP) setting_enb = config_setting_get_elem(setting, i); active_enb[i] = config_setting_get_string (setting_enb); AssertFatal (active_enb[i] != NULL, - "Failed to parse config file %s, %uth attribute %s \n", + "Failed to parse config file %s, %dth attribute %s \n", lib_config_file_name_pP, i, ENB_CONFIG_STRING_ACTIVE_ENBS); active_enb[i] = strdup(active_enb[i]); num_enb_properties += 1; @@ -393,7 +393,7 @@ void enb_config_init(const char const * lib_config_file_name_pP) ) ) { AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, %u th enb\n", + "Failed to parse eNB configuration file %s, %d th enb\n", lib_config_file_name_pP, i); continue; // FIXME this prevents segfaults below, not sure what happens after function exit } @@ -441,7 +441,7 @@ void enb_config_init(const char const * lib_config_file_name_pP) ) ) { AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, %u th enb %u th mme address !\n", + "Failed to parse eNB configuration file %s, %d th enb %d th mme address !\n", lib_config_file_name_pP, i, j); continue; // FIXME will prevent segfaults below, not sure what happens at function exit... } diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 546878e57692061c502ac17d56f08fd7a5f336d1..3af47f21a8551c1381c3a4f78d4898b6d119c92a 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -249,7 +249,7 @@ int et_hex2data(unsigned char * const data, const unsigned char * const hexstrin char *endptr = NULL; size_t count = 0; - fprintf(stdout, "%s(%s,%d)\n", __FUNCTION__, hexstring, len); + fprintf(stdout, "%s(%s,%u)\n", __FUNCTION__, hexstring, len); if ((len > 1) && (strlen((const char*)hexstring) % 2)) { //or hexstring has an odd length @@ -473,7 +473,7 @@ void et_enb_config_init(const char const * lib_config_file_name_pP) setting_enb = config_setting_get_elem(setting, i); active_enb[i] = config_setting_get_string (setting_enb); AssertFatal (active_enb[i] != NULL, - "Failed to parse config file %s, %uth attribute %s \n", + "Failed to parse config file %s, %dth attribute %s \n", lib_config_file_name_pP, i, ENB_CONFIG_STRING_ACTIVE_ENBS); active_enb[i] = strdup(active_enb[i]); num_enb_properties += 1; @@ -513,7 +513,7 @@ void et_enb_config_init(const char const * lib_config_file_name_pP) ) ) { AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, %u th enb\n", + "Failed to parse eNB configuration file %s, %d th enb\n", lib_config_file_name_pP, i); continue; // FIXME this prevents segfaults below, not sure what happens after function exit } @@ -561,7 +561,7 @@ void et_enb_config_init(const char const * lib_config_file_name_pP) ) ) { AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, %u th enb %u th mme address !\n", + "Failed to parse eNB configuration file %s, %d th enb %d th mme address !\n", lib_config_file_name_pP, i, j); continue; // FIXME will prevent segfaults below, not sure what happens at function exit... } @@ -1103,7 +1103,7 @@ et_config_parse_opt_line ( fprintf(stderr, "Please provide a valid -D/--delay-on-exit argument, %s is not a valid value\n", delay_on_exit); exit(1); } - printf("Delay on exit is %d\n", delay_on_exit); + printf("Delay on exit is %d\n", (int) delay_on_exit); } break; diff --git a/openair3/TEST/EPC_TEST/play_scenario.h b/openair3/TEST/EPC_TEST/play_scenario.h index f9601fe9044aca63d522b3e4085220bec52b8d18..db399a23f1010604a647326123859cc8238b687b 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.h +++ b/openair3/TEST/EPC_TEST/play_scenario.h @@ -398,7 +398,7 @@ typedef struct et_event_s { } u; } et_event_t; -inline void et_free_pointer(void *p) {if (NULL != p) {free(p); p=NULL;}}; +inline void et_free_pointer(void *p) {if (NULL != p) {free(p);}}; //------------------------- void et_free_packet(et_packet_t* packet); diff --git a/openair3/TEST/EPC_TEST/play_scenario_display.c b/openair3/TEST/EPC_TEST/play_scenario_display.c index e10cbdf9bf1b285d6965dcb77c3f4db80b284c84..dd5b6edbd3c679d03a71e4222f3f98040f809271 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_display.c +++ b/openair3/TEST/EPC_TEST/play_scenario_display.c @@ -54,7 +54,7 @@ void et_print_hex_octets(const unsigned char * const byte_stream, const unsigned fprintf(stdout, " |\n"); } - fprintf(stdout, " %04ld |", octet_index); + fprintf(stdout, " %04lu |", octet_index); } /* diff --git a/openair3/TEST/EPC_TEST/play_scenario_parse.c b/openair3/TEST/EPC_TEST/play_scenario_parse.c index 040db30398495f51f3faf25b5bf6fb2a18604806..607ec34dfc25daa20d14e13343f67c5a24ecb449 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_parse.c +++ b/openair3/TEST/EPC_TEST/play_scenario_parse.c @@ -94,7 +94,7 @@ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * co xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value"); if (NULL != xml_char) { xml_char2 = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name"); - fprintf(stdout, "s1ap %p field name %s size %d value %s\n",s1ap, xml_char2, size, xml_char); + fprintf(stdout, "s1ap %p field name %s size %u value %s\n",s1ap, xml_char2, size, xml_char); xmlFree(xml_char2); // if success to get value, do not parse children //AssertFatal ((xmlStrlen(xml_char) == size), "ERROR %s() mismatch in size %d and strlen %d\n", __FUNCTION__, size, xmlStrlen(xml_char)); @@ -104,7 +104,7 @@ void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * co rc = et_hex2data( &s1ap->binary_stream[s1ap->binary_stream_pos], xml_char, xmlStrlen(xml_char)); s1ap->binary_stream_pos += xmlStrlen(xml_char)/2; //et_display_node(cur_node, 0); - AssertFatal (rc >= 0, "ERROR in converting hex string %s len %d size %d rc %d\n", xml_char, xmlStrlen(xml_char), size, rc); + AssertFatal (rc >= 0, "ERROR in converting hex string %s len %d size %u rc %d\n", xml_char, xmlStrlen(xml_char), size, rc); go_deeper_in_tree = 0; //} xmlFree(xml_char); diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index d2bf05c0862f8eddd958621744d08f439b836baa..acc9b18f767ddc2dcec8199e1a04b63e053e8e04 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -616,7 +616,7 @@ int et_scenario_set_packet_received(et_packet_t * const packet) if (0 != packet->timer_id) { rc = timer_remove(packet->timer_id); - AssertFatal(rc == 0, "TODO: Debug Timer on Rx packet num %d unknown", packet->packet_number); + AssertFatal(rc == 0, "TODO: Debug Timer on Rx packet num %u unknown", packet->packet_number); g_scenario->timer_count--; return rc; } @@ -919,7 +919,7 @@ void et_s1ap_update_assoc_id_of_packets(const int32_t assoc_id, break; default: - AssertFatal(0, "Unknown chunk_type %d packet num %d", packet->sctp_hdr.chunk_type, packet->packet_number); + AssertFatal(0, "Unknown chunk_type %d packet num %u", packet->sctp_hdr.chunk_type, packet->packet_number); ; } packet = packet->next; diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c index 001834fcab229ac60d4209bfeb215494e524540f..bc7ca6afbd0d1e3cd4a95b28ad8b58c221a4d651 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c @@ -122,7 +122,7 @@ void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, con hex[2] = '\0'; end_ptr = hex; uli = strtoul(hex, &end_ptr, 16); - AssertFatal((uli != ULONG_MAX) && (end_ptr != NULL) && (*end_ptr == '\0'), "Conversion of hexstring %s failed returned %ld errno %d", hex, uli, errno); + AssertFatal((uli != ULONG_MAX) && (end_ptr != NULL) && (*end_ptr == '\0'), "Conversion of hexstring %s failed returned %lu errno %d", hex, uli, errno); s1ap->binary_stream[pos++] = (unsigned char)uli; } while (pos2 < (2*5)); // update ASN1 diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index fdcdeb037af62ebddb912651d620f7954e2149b5..27f754badc28af6d805eda340143c34912de03ef 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -169,7 +169,7 @@ int udp_eNB_create_socket(int port, char *ip_addr, task_id_t task_id) if ((rc = bind(sd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in))) < 0) { close(sd); - AssertFatal(rc >= 0, "UDP: Failed to bind socket: (%s:%d) address %s port %u\n", + AssertFatal(rc >= 0, "UDP: Failed to bind socket: (%s:%d) address %s port %d\n", strerror(errno), errno, ip_addr, port); } diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index 00287341b2a19f06af32ae4a136d329b73d694b2..71d57cc87d9d2bda784c2e421050f0fabf117f1d 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -131,6 +131,54 @@ do { \ #define M_TMSI_TO_OCTET_STRING INT32_TO_OCTET_STRING #define MME_GID_TO_OCTET_STRING INT16_TO_OCTET_STRING +#define ENCRALG_TO_BIT_STRING(encralg, bitstring) \ + do { \ + (bitstring)->size=2; \ + (bitstring)->bits_unused=0; \ + (bitstring)->buf=calloc (1, sizeof (uint8_t)); \ + (bitstring)->buf[0] = (encralg) >> 8; \ + (bitstring)->buf[1] = (encralg); \ + }while(0) + +#define INTPROTALG_TO_BIT_STRING(intprotalg, bitstring) \ +do { \ + (bitstring)->size=2; \ + (bitstring)->bits_unused=0; \ + (bitstring)->buf=calloc (2, sizeof (uint8_t)); \ + (bitstring)->buf[0] = (intprotalg) >> 8; \ + (bitstring)->buf[1] = (intprotalg); \ +}while(0) + +#define KENB_STAR_TO_BIT_STRING(kenbstar, bitstring) \ +do { \ + (bitstring)->size=32; \ + (bitstring)->bits_unused=0; \ + (bitstring)->buf= calloc (32, sizeof (uint8_t));\ + memcpy((bitstring)->buf, kenbstar, 32*sizeof(uint8_t)); \ +}while(0) + +#define UEAGMAXBITRTD_TO_ASN_PRIMITIVES(uegmaxbitrtd, asnprimitives) \ +do { \ + (asnprimitives)->size=5; \ + (asnprimitives)->buf=calloc (5, sizeof (uint8_t)); \ + (asnprimitives)->buf[0] = (uegmaxbitrtd) >> 32; \ + (asnprimitives)->buf[1] = (uegmaxbitrtd) >> 24; \ + (asnprimitives)->buf[2] = (uegmaxbitrtd) >> 16; \ + (asnprimitives)->buf[3] = (uegmaxbitrtd) >> 8; \ + (asnprimitives)->buf[4] = (uegmaxbitrtd); \ + }while(0) + +#define UEAGMAXBITRTU_TO_ASN_PRIMITIVES(uegmaxbitrtu, asnprimitives) \ +do { \ + (asnprimitives)->size=5; \ + (asnprimitives)->buf=calloc (5, sizeof (uint8_t)); \ + (asnprimitives)->buf[0] = (uegmaxbitrtu) >> 32; \ + (asnprimitives)->buf[1] = (uegmaxbitrtu) >> 24; \ + (asnprimitives)->buf[2] = (uegmaxbitrtu) >> 16; \ + (asnprimitives)->buf[3] = (uegmaxbitrtu) >> 8; \ + (asnprimitives)->buf[4] = (uegmaxbitrtu); \ + }while(0) + #define OCTET_STRING_TO_INT8(aSN, x) \ do { \ DevCheck((aSN)->size == 1, (aSN)->size, 0, 0); \ @@ -139,7 +187,7 @@ do { \ #define OCTET_STRING_TO_INT16(aSN, x) \ do { \ - DevCheck((aSN)->size == 2, (aSN)->size, 0, 0); \ + DevCheck((aSN)->size == 2 || (aSN)->size == 3, (aSN)->size, 0, 0); \ BUFFER_TO_INT16((aSN)->buf, x); \ } while(0) @@ -162,6 +210,13 @@ do { \ ((aSN)->buf[2] << 4) | (aSN)->buf[3]; \ } while(0) +#define BIT_STRING_TO_NR_CELL_IDENTITY(aSN, vALUE) \ +do { \ + DevCheck((aSN)->bits_unused == 4, (aSN)->bits_unused, 4, 0); \ + vALUE = ((aSN)->buf[0] << 28) | ((aSN)->buf[1] << 20) | \ + ((aSN)->buf[2] << 12) | ((aSN)->buf[3]<<4) | ((aSN)->buf[4]>>4); \ +} while(0) + #define MCC_HUNDREDS(vALUE) \ ((vALUE) / 100) /* When MNC is only composed of 2 digits, set the hundreds unit to 0xf */ @@ -189,6 +244,17 @@ do { \ (oCTETsTRING)->size = 3; \ } while(0) +#define PLMNID_TO_MCC_MNC(oCTETsTRING, mCC, mNC, mNCdIGITlENGTH) \ +do { \ + mCC = ((oCTETsTRING)->buf[0] & 0x0F) * 100 + \ + ((oCTETsTRING)->buf[0] >> 4 & 0x0F) * 10 + \ + ((oCTETsTRING)->buf[1] & 0x0F); \ + mNCdIGITlENGTH = ((oCTETsTRING)->buf[1] >> 4 & 0x0F) == 0xF ? 2 : 3; \ + mNC = (mNCdIGITlENGTH == 2 ? 0 : ((oCTETsTRING)->buf[1] >> 4 & 0x0F) * 100) + \ + ((oCTETsTRING)->buf[2] & 0x0F) * 10 + \ + ((oCTETsTRING)->buf[2] >> 4 & 0x0F); \ +} while (0) + #define MCC_MNC_TO_TBCD(mCC, mNC, mNCdIGITlENGTH, tBCDsTRING) \ do { \ char _buf[3]; \ @@ -251,6 +317,92 @@ do { \ + pLMN.MNCdigit2 * 10 + pLMN.MNCdigit1; \ } while(0) + +/* TS 38.473 v15.2.1 section 9.3.1.32: + * C RNTI is BIT_STRING(16) + */ +#define C_RNTI_TO_BIT_STRING(mACRO, bITsTRING) \ +do { \ + (bITsTRING)->buf = calloc(2, sizeof(uint8_t)); \ + (bITsTRING)->buf[0] = (mACRO) >> 8; \ + (bITsTRING)->buf[1] = ((mACRO) & 0x0ff); \ + (bITsTRING)->size = 2; \ + (bITsTRING)->bits_unused = 0; \ +} while(0) + + +/* TS 38.473 v15.2.1 section 9.3.2.3: + * TRANSPORT LAYER ADDRESS for IPv4 is 32bit (TS 38.414) + */ +#define TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(mACRO, bITsTRING) \ +do { \ + (bITsTRING)->buf = calloc(4, sizeof(uint8_t)); \ + (bITsTRING)->buf[0] = (mACRO) >> 24 & 0xFF; \ + (bITsTRING)->buf[1] = (mACRO) >> 16 & 0xFF; \ + (bITsTRING)->buf[2] = (mACRO) >> 8 & 0xFF; \ + (bITsTRING)->buf[3] = (mACRO) >> 4 & 0xFF; \ + (bITsTRING)->size = 4; \ + (bITsTRING)->bits_unused = 0; \ +} while(0) + +#define BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(bITsTRING, mACRO) \ +do { \ + DevCheck((bITsTRING)->size == 4, (bITsTRING)->size, 4, 0); \ + DevCheck((bITsTRING)->bits_unused == 0, (bITsTRING)->bits_unused, 0, 0); \ + mACRO = ((bITsTRING)->buf[0] << 24) + \ + ((bITsTRING)->buf[1] << 16) + \ + ((bITsTRING)->buf[2] << 8) + \ + ((bITsTRING)->buf[3]); \ +} while (0) + + +/* TS 38.473 v15.1.1 section 9.3.1.12: + * NR CELL ID + */ +#define NR_CELL_ID_TO_BIT_STRING(mACRO, bITsTRING) \ +do { \ + (bITsTRING)->buf = calloc(5, sizeof(uint8_t)); \ + (bITsTRING)->buf[0] = ((mACRO) >> 28) & 0xff; \ + (bITsTRING)->buf[1] = ((mACRO) >> 20) & 0xff; \ + (bITsTRING)->buf[2] = ((mACRO) >> 12) & 0xff; \ + (bITsTRING)->buf[3] = ((mACRO) >> 4) & 0xff; \ + (bITsTRING)->buf[4] = ((mACRO) & 0x0f) << 4; \ + (bITsTRING)->size = 5; \ + (bITsTRING)->bits_unused = 4; \ +} while(0) + +/* TS 38.473 v15.2.1 section 9.3.1.55: + * MaskedIMEISV is BIT_STRING(64) + */ +#define MaskedIMEISV_TO_BIT_STRING(mACRO, bITsTRING) \ +do { \ + (bITsTRING)->buf = calloc(8, sizeof(uint8_t)); \ + (bITsTRING)->buf[0] = (mACRO) >> 56 & 0xFF; \ + (bITsTRING)->buf[1] = (mACRO) >> 48 & 0xFF; \ + (bITsTRING)->buf[2] = (mACRO) >> 40 & 0xFF; \ + (bITsTRING)->buf[3] = (mACRO) >> 32 & 0xFF; \ + (bITsTRING)->buf[4] = (mACRO) >> 24 & 0xFF; \ + (bITsTRING)->buf[5] = (mACRO) >> 16 & 0xFF; \ + (bITsTRING)->buf[6] = (mACRO) >> 8 & 0xFF; \ + (bITsTRING)->buf[7] = (mACRO) >> 4 & 0xFF; \ + (bITsTRING)->size = 8; \ + (bITsTRING)->bits_unused = 0; \ +} while(0) + +#define BIT_STRING_TO_MaskedIMEISV(bITsTRING, mACRO) \ +do { \ + DevCheck((bITsTRING)->size == 8, (bITsTRING)->size, 8, 0); \ + DevCheck((bITsTRING)->bits_unused == 0, (bITsTRING)->bits_unused, 0, 0); \ + mACRO = ((bITsTRING)->buf[0] << 56) + \ + ((bITsTRING)->buf[1] << 48) + \ + ((bITsTRING)->buf[2] << 40) + \ + ((bITsTRING)->buf[3] << 32) + \ + ((bITsTRING)->buf[4] << 24) + \ + ((bITsTRING)->buf[5] << 16) + \ + ((bITsTRING)->buf[6] << 8) + \ + ((bITsTRING)->buf[7]); \ +} while (0) + /* TS 36.413 v10.9.0 section 9.2.1.37: * Macro eNB ID: * Equal to the 20 leftmost bits of the Cell diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c index e5966af267047b0285583bab64d2e75370b65385..3ced5ca833a972d1e8f021733dbf1c2ab71cdb16 100644 --- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c +++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c @@ -35,18 +35,18 @@ * @{ */ -//! Number of BladeRF devices +//! Number of BladeRF devices #ifdef __SSE4_1__ # include <smmintrin.h> #endif - + #ifdef __AVX2__ # include <immintrin.h> #endif int num_devices=0; -/*These items configure the underlying asynch stream used by the the sync interface. +/*These items configure the underlying asynch stream used by the the sync interface. */ /*! \brief BladeRF Init function (not used at the moment) @@ -54,119 +54,119 @@ int num_devices=0; * \returns 0 on success */ int trx_brf_init(openair0_device *device) { - return 0; + return 0; } /*! \brief get current timestamp - *\param device the hardware to use + *\param device the hardware to use *\param module the bladeRf module *\returns timestamp of BladeRF */ - + openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module module) { - int status; - struct bladerf_metadata meta; - brf_state_t *brf = (brf_state_t*)device->priv; - memset(&meta, 0, sizeof(meta)); - - if ((status=bladerf_get_timestamp(brf->dev, module, &meta.timestamp)) != 0) { - fprintf(stderr,"Failed to get current %s timestamp: %s\n",(module == BLADERF_MODULE_RX ) ? "RX" : "TX", bladerf_strerror(status)); - return -1; - } // else {printf("Current RX timestampe 0x%016"PRIx64"\n", meta.timestamp); } - - return meta.timestamp; + int status; + struct bladerf_metadata meta; + brf_state_t *brf = (brf_state_t*)device->priv; + memset(&meta, 0, sizeof(meta)); + + if ((status=bladerf_get_timestamp(brf->dev, module, &meta.timestamp)) != 0) { + fprintf(stderr,"Failed to get current %s timestamp: %s\n",(module == BLADERF_MODULE_RX ) ? "RX" : "TX", bladerf_strerror(status)); + return -1; + } // else {printf("Current RX timestampe 0x%016"PRIx64"\n", meta.timestamp); } + + return meta.timestamp; } /*! \brief Start BladeRF - * \param device the hardware to use + * \param device the hardware to use * \returns 0 on success */ int trx_brf_start(openair0_device *device) { - brf_state_t *brf = (brf_state_t*)device->priv; - int status; - - brf->meta_tx.flags = 0; - - if ((status = bladerf_sync_config(brf->dev, - BLADERF_MODULE_TX, - BLADERF_FORMAT_SC16_Q11_META, - brf->num_buffers, - brf->buffer_size, - brf->num_transfers, - 100/*brf->tx_timeout_ms*/)) != 0 ) { - fprintf(stderr,"Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); - abort(); - } - if ((status = bladerf_sync_config(brf->dev, - BLADERF_MODULE_RX, - BLADERF_FORMAT_SC16_Q11_META, - brf->num_buffers, - brf->buffer_size, - brf->num_transfers, - 100/*brf->rx_timeout_ms*/)) != 0 ) { - fprintf(stderr,"Failed to configure RX sync interface: %s\n", bladerf_strerror(status)); - abort(); - } - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, true)) != 0) { - fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status)); - abort(); - } - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true)) != 0) { - fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); - abort(); - } - - return 0; + brf_state_t *brf = (brf_state_t*)device->priv; + int status; + + brf->meta_tx.flags = 0; + + if ((status = bladerf_sync_config(brf->dev, + BLADERF_MODULE_TX, + BLADERF_FORMAT_SC16_Q11_META, + brf->num_buffers, + brf->buffer_size, + brf->num_transfers, + 100/*brf->tx_timeout_ms*/)) != 0 ) { + fprintf(stderr,"Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); + abort(); + } + if ((status = bladerf_sync_config(brf->dev, + BLADERF_MODULE_RX, + BLADERF_FORMAT_SC16_Q11_META, + brf->num_buffers, + brf->buffer_size, + brf->num_transfers, + 100/*brf->rx_timeout_ms*/)) != 0 ) { + fprintf(stderr,"Failed to configure RX sync interface: %s\n", bladerf_strerror(status)); + abort(); + } + if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, true)) != 0) { + fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status)); + abort(); + } + if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true)) != 0) { + fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); + abort(); + } + + return 0; } /*! \brief Called to send samples to the BladeRF 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 timestamp The timestamp at whicch the first sample MUST be sent \param buff Buffer which holds the samples \param nsamps number of samples to be sent \param cc index of the component carrier \param flags Ignored for the moment \returns 0 on success -*/ +*/ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, void **buff, int nsamps, int cc, int flags) { - - int status; - brf_state_t *brf = (brf_state_t*)device->priv; - /* BRF has only 1 rx/tx chaine : is it correct? */ - int16_t *samples = (int16_t*)buff[0]; - - //memset(&brf->meta_tx, 0, sizeof(brf->meta_tx)); - // When BLADERF_META_FLAG_TX_NOW is used the timestamp is not used, so one can't schedule a tx - if (brf->meta_tx.flags == 0 ) - brf->meta_tx.flags = (BLADERF_META_FLAG_TX_BURST_START);// | BLADERF_META_FLAG_TX_BURST_END);// | BLADERF_META_FLAG_TX_NOW); - - - brf->meta_tx.timestamp= (uint64_t) (ptimestamp); - status = bladerf_sync_tx(brf->dev, samples, (unsigned int) nsamps, &brf->meta_tx, 2*brf->tx_timeout_ms); - - if (brf->meta_tx.flags == BLADERF_META_FLAG_TX_BURST_START) - brf->meta_tx.flags = BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP; - - - if (status != 0) { - //fprintf(stderr,"Failed to TX sample: %s\n", bladerf_strerror(status)); - brf->num_tx_errors++; - brf_error(status); - } else if (brf->meta_tx.status & BLADERF_META_STATUS_UNDERRUN){ - /* libbladeRF does not report this status. It is here for future use. */ - fprintf(stderr, "TX Underrun detected. %u valid samples were read.\n", brf->meta_tx.actual_count); - brf->num_underflows++; - } - //printf("Provided TX timestampe %u, meta timestame %u\n", ptimestamp,brf->meta_tx.timestamp); - - // printf("tx status %d \n",brf->meta_tx.status); - brf->tx_current_ts=brf->meta_tx.timestamp; - brf->tx_actual_nsamps+=brf->meta_tx.actual_count; - brf->tx_nsamps+=nsamps; - brf->tx_count++; - - - return nsamps; //brf->meta_tx.actual_count; + + int status; + brf_state_t *brf = (brf_state_t*)device->priv; + /* BRF has only 1 rx/tx chaine : is it correct? */ + int16_t *samples = (int16_t*)buff[0]; + + //memset(&brf->meta_tx, 0, sizeof(brf->meta_tx)); + // When BLADERF_META_FLAG_TX_NOW is used the timestamp is not used, so one can't schedule a tx + if (brf->meta_tx.flags == 0 ) + brf->meta_tx.flags = (BLADERF_META_FLAG_TX_BURST_START);// | BLADERF_META_FLAG_TX_BURST_END);// | BLADERF_META_FLAG_TX_NOW); + + + brf->meta_tx.timestamp= (uint64_t) (ptimestamp); + status = bladerf_sync_tx(brf->dev, samples, (unsigned int) nsamps, &brf->meta_tx, 2*brf->tx_timeout_ms); + + if (brf->meta_tx.flags == BLADERF_META_FLAG_TX_BURST_START) + brf->meta_tx.flags = BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP; + + + if (status != 0) { + //fprintf(stderr,"Failed to TX sample: %s\n", bladerf_strerror(status)); + brf->num_tx_errors++; + brf_error(status); + } else if (brf->meta_tx.status & BLADERF_META_STATUS_UNDERRUN) { + /* libbladeRF does not report this status. It is here for future use. */ + fprintf(stderr, "TX Underrun detected. %u valid samples were read.\n", brf->meta_tx.actual_count); + brf->num_underflows++; + } + //printf("Provided TX timestampe %u, meta timestame %u\n", ptimestamp,brf->meta_tx.timestamp); + + // printf("tx status %d \n",brf->meta_tx.status); + brf->tx_current_ts=brf->meta_tx.timestamp; + brf->tx_actual_nsamps+=brf->meta_tx.actual_count; + brf->tx_nsamps+=nsamps; + brf->tx_count++; + + + return nsamps; //brf->meta_tx.actual_count; } /*! \brief Receive samples from hardware. @@ -182,90 +182,90 @@ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, */ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - int status=0; - brf_state_t *brf = (brf_state_t*)device->priv; - - // BRF has only one rx/tx chain - int16_t *samples = (int16_t*)buff[0]; - - brf->meta_rx.actual_count = 0; - brf->meta_rx.flags = BLADERF_META_FLAG_RX_NOW; - status = bladerf_sync_rx(brf->dev, samples, (unsigned int) nsamps, &brf->meta_rx, 2*brf->rx_timeout_ms); - - // printf("Current RX timestampe %u, nsamps %u, actual %u, cc %d\n", brf->meta_rx.timestamp, nsamps, brf->meta_rx.actual_count, cc); - - if (status != 0) { - fprintf(stderr, "RX failed: %s\n", bladerf_strerror(status)); - // printf("RX failed: %s\n", bladerf_strerror(status)); - brf->num_rx_errors++; - } else if ( brf->meta_rx.status & BLADERF_META_STATUS_OVERRUN) { - brf->num_overflows++; - printf("RX overrun (%d) is detected. t=" "%" PRIu64 "Got %u samples. nsymps %d\n", - brf->num_overflows,brf->meta_rx.timestamp, brf->meta_rx.actual_count, nsamps); - } - - if (brf->meta_rx.actual_count != nsamps) { - printf("RX bad samples count, wanted %d, got %d\n", nsamps, brf->meta_rx.actual_count); - } - - //printf("Current RX timestampe %u\n", brf->meta_rx.timestamp); - //printf("[BRF] (buff %p) ts=0x%"PRIu64" %s\n",samples, brf->meta_rx.timestamp,bladerf_strerror(status)); - brf->rx_current_ts=brf->meta_rx.timestamp; - brf->rx_actual_nsamps+=brf->meta_rx.actual_count; - brf->rx_nsamps+=nsamps; - brf->rx_count++; - - - *ptimestamp = brf->meta_rx.timestamp; - - return nsamps; //brf->meta_rx.actual_count; + int status=0; + brf_state_t *brf = (brf_state_t*)device->priv; + + // BRF has only one rx/tx chain + int16_t *samples = (int16_t*)buff[0]; + + brf->meta_rx.actual_count = 0; + brf->meta_rx.flags = BLADERF_META_FLAG_RX_NOW; + status = bladerf_sync_rx(brf->dev, samples, (unsigned int) nsamps, &brf->meta_rx, 2*brf->rx_timeout_ms); + + // printf("Current RX timestampe %u, nsamps %u, actual %u, cc %d\n", brf->meta_rx.timestamp, nsamps, brf->meta_rx.actual_count, cc); + + if (status != 0) { + fprintf(stderr, "RX failed: %s\n", bladerf_strerror(status)); + // printf("RX failed: %s\n", bladerf_strerror(status)); + brf->num_rx_errors++; + } else if ( brf->meta_rx.status & BLADERF_META_STATUS_OVERRUN) { + brf->num_overflows++; + printf("RX overrun (%d) is detected. t=" "%" PRIu64 "Got %u samples. nsymps %d\n", + brf->num_overflows,brf->meta_rx.timestamp, brf->meta_rx.actual_count, nsamps); + } + + if (brf->meta_rx.actual_count != nsamps) { + printf("RX bad samples count, wanted %d, got %d\n", nsamps, brf->meta_rx.actual_count); + } + + //printf("Current RX timestampe %u\n", brf->meta_rx.timestamp); + //printf("[BRF] (buff %p) ts=0x%"PRIu64" %s\n",samples, brf->meta_rx.timestamp,bladerf_strerror(status)); + brf->rx_current_ts=brf->meta_rx.timestamp; + brf->rx_actual_nsamps+=brf->meta_rx.actual_count; + brf->rx_nsamps+=nsamps; + brf->rx_count++; + + + *ptimestamp = brf->meta_rx.timestamp; + + return nsamps; //brf->meta_rx.actual_count; } -/*! \brief Terminate operation of the BladeRF transceiver -- free all associated resources +/*! \brief Terminate operation of the BladeRF transceiver -- free all associated resources * \param device the hardware to use */ void trx_brf_end(openair0_device *device) { - int status; - brf_state_t *brf = (brf_state_t*)device->priv; - // Disable RX module, shutting down our underlying RX stream - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, false)) != 0) { - fprintf(stderr, "Failed to disable RX module: %s\n", bladerf_strerror(status)); - } - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, false)) != 0) { - fprintf(stderr, "Failed to disable TX module: %s\n", bladerf_strerror(status)); - } - bladerf_close(brf->dev); - exit(1); + int status; + brf_state_t *brf = (brf_state_t*)device->priv; + // Disable RX module, shutting down our underlying RX stream + if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, false)) != 0) { + fprintf(stderr, "Failed to disable RX module: %s\n", bladerf_strerror(status)); + } + if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, false)) != 0) { + fprintf(stderr, "Failed to disable TX module: %s\n", bladerf_strerror(status)); + } + bladerf_close(brf->dev); + exit(1); } -/*! \brief print the BladeRF statistics +/*! \brief print the BladeRF statistics * \param device the hardware to use * \returns 0 on success */ int trx_brf_get_stats(openair0_device* device) { - return(0); + return(0); } -/*! \brief Reset the BladeRF statistics +/*! \brief Reset the BladeRF statistics * \param device the hardware to use * \returns 0 on success */ int trx_brf_reset_stats(openair0_device* device) { - return(0); + return(0); } /*! \brief Stop BladeRF * \param card the hardware to use - * \returns 0 in success + * \returns 0 in success */ int trx_brf_stop(openair0_device* device) { - return(0); + return(0); } @@ -273,39 +273,39 @@ int trx_brf_stop(openair0_device* device) { * \param device the hardware to use * \param openair0_cfg1 openair0 Config structure (ignored. It is there to comply with RF common API) * \param exmimo_dump_config (ignored) - * \returns 0 in success + * \returns 0 in success */ int trx_brf_set_freq(openair0_device* device, openair0_config_t *openair0_cfg1,int exmimo_dump_config) { - int status; - brf_state_t *brf = (brf_state_t *)device->priv; - openair0_config_t *openair0_cfg = (openair0_config_t *)device->openair0_cfg; + int status; + brf_state_t *brf = (brf_state_t *)device->priv; + openair0_config_t *openair0_cfg = (openair0_config_t *)device->openair0_cfg; - if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->tx_freq[0])) != 0){ - fprintf(stderr,"Failed to set TX frequency: %s\n",bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] set TX Frequency to %u\n", (unsigned int) openair0_cfg->tx_freq[0]); + if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->tx_freq[0])) != 0) { + fprintf(stderr,"Failed to set TX frequency: %s\n",bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set TX Frequency to %u\n", (unsigned int) openair0_cfg->tx_freq[0]); - if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_freq[0])) != 0){ - fprintf(stderr,"Failed to set RX frequency: %s\n",bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set RX frequency to %u\n",(unsigned int)openair0_cfg->rx_freq[0]); + if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_freq[0])) != 0) { + fprintf(stderr,"Failed to set RX frequency: %s\n",bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set RX frequency to %u\n",(unsigned int)openair0_cfg->rx_freq[0]); - return(0); + return(0); } /*! \brief Set Gains (TX/RX) * \param device the hardware to use * \param openair0_cfg openair0 Config structure - * \returns 0 in success + * \returns 0 in success */ int trx_brf_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) { - return(0); + return(0); } @@ -317,10 +317,11 @@ int16_t cos_3fsover8[8] = {2047, -1448, 0, 1447, -2047, 1447, 0, /*! \brief calibration table for BladeRF */ rx_gain_calib_table_t calib_table_fx4[] = { - {2300000000.0,53.5}, - {1880000000.0,57.0}, - {816000000.0,73.0}, - {-1,0}}; + {2300000000.0,53.5}, + {1880000000.0,57.0}, + {816000000.0,73.0}, + {-1,0} +}; /*! \brief set RX gain offset from calibration table * \param openair0_cfg RF frontend parameters set by application @@ -328,822 +329,822 @@ rx_gain_calib_table_t calib_table_fx4[] = { */ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) { - int i=0; - // loop through calibration table to find best adjustment factor for RX frequency - double min_diff = 6e9,diff; - - while (openair0_cfg->rx_gain_calib_table[i].freq>0) { - diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); - printf("cal %d: freq %f, offset %f, diff %f\n", - i, - openair0_cfg->rx_gain_calib_table[i].freq, - openair0_cfg->rx_gain_calib_table[i].offset,diff); - if (min_diff > diff) { - min_diff = diff; - openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset; + int i=0; + // loop through calibration table to find best adjustment factor for RX frequency + double min_diff = 6e9,diff; + + while (openair0_cfg->rx_gain_calib_table[i].freq>0) { + diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); + printf("cal %d: freq %f, offset %f, diff %f\n", + i, + openair0_cfg->rx_gain_calib_table[i].freq, + openair0_cfg->rx_gain_calib_table[i].offset,diff); + if (min_diff > diff) { + min_diff = diff; + openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset; + } + i++; } - i++; - } - + } -/*! \brief Calibrate LMSSDR RF +/*! \brief Calibrate LMSSDR RF * \param device the hardware to use */ void calibrate_rf(openair0_device *device) { - /* TODO: this function does not seem to work. Disabled until fixed. */ - return; - - brf_state_t *brf = (brf_state_t *)device->priv; - openair0_timestamp ptimestamp; - int16_t *calib_buffp,*calib_tx_buffp; - int16_t calib_buff[2*RXDCLENGTH]; - int16_t calib_tx_buff[2*RXDCLENGTH]; - int i,j,offI,offQ,offIold,offQold,offInew,offQnew,offphase,offphaseold,offphasenew,offgain,offgainold,offgainnew; - int32_t meanI,meanQ,meanIold,meanQold; - int cnt=0,loop; - - // put TX on a far-away frequency to avoid interference in RX band - bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->rx_freq[0] + 200e6); - // Set gains to close to max - bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, 60); - bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, 60); - - // fill TX buffer with fs/8 complex sinusoid - j=0; - for (i=0;i<RXDCLENGTH;i++) { - calib_tx_buff[j++] = cos_fsover8[i&7]; - calib_tx_buff[j++] = cos_fsover8[(i+6)&7]; // sin - } - calib_buffp = &calib_buff[0]; - calib_tx_buffp = &calib_tx_buff[0]; - // Calibrate RX DC offset - - offIold=offQold=2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offIold); - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQold); - for (i=0;i<10;i++) - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - - for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { - meanIold+=calib_buff[j++]; - meanQold+=calib_buff[j++]; - } - meanIold/=RXDCLENGTH; - meanQold/=RXDCLENGTH; - printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); - - offI=offQ=-2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offI); - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQ); - for (i=0;i<10;i++) - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - meanI+=calib_buff[j++]; - meanQ+=calib_buff[j++]; - } - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - // printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offI,offQ,meanI,meanQ); - - while (cnt++ < 12) { - - offInew=(offIold+offI)>>1; - offQnew=(offQold+offQ)>>1; - - if (meanI*meanI < meanIold*meanIold) { - meanIold = meanI; - offIold = offI; - printf("[BRF] *** RX DC: offI %d => %d\n",offIold,meanI); + /* TODO: this function does not seem to work. Disabled until fixed. */ + return; + + brf_state_t *brf = (brf_state_t *)device->priv; + openair0_timestamp ptimestamp; + int16_t *calib_buffp,*calib_tx_buffp; + int16_t calib_buff[2*RXDCLENGTH]; + int16_t calib_tx_buff[2*RXDCLENGTH]; + int i,j,offI,offQ,offIold,offQold,offInew,offQnew,offphase,offphaseold,offphasenew,offgain,offgainold,offgainnew; + int32_t meanI,meanQ,meanIold,meanQold; + int cnt=0,loop; + + // put TX on a far-away frequency to avoid interference in RX band + bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->rx_freq[0] + 200e6); + // Set gains to close to max + bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, 60); + bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, 60); + + // fill TX buffer with fs/8 complex sinusoid + j=0; + for (i=0; i<RXDCLENGTH; i++) { + calib_tx_buff[j++] = cos_fsover8[i&7]; + calib_tx_buff[j++] = cos_fsover8[(i+6)&7]; // sin } - if (meanQ*meanQ < meanQold*meanQold) { - meanQold = meanQ; - offQold = offQ; - printf("[BRF] *** RX DC: offQ %d => %d\n",offQold,meanQ); + calib_buffp = &calib_buff[0]; + calib_tx_buffp = &calib_tx_buff[0]; + // Calibrate RX DC offset + + offIold=offQold=2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offIold); + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQold); + for (i=0; i<10; i++) + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + + for (meanIold=meanQold=i=j=0; i<RXDCLENGTH; i++) { + meanIold+=calib_buff[j++]; + meanQold+=calib_buff[j++]; } - offI = offInew; - offQ = offQnew; + meanIold/=RXDCLENGTH; + meanQold/=RXDCLENGTH; + printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); + + offI=offQ=-2048; bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offI); bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQ); + for (i=0; i<10; i++) + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - for (i=0;i<10;i++) - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - meanI+=calib_buff[j++]; - meanQ+=calib_buff[j++]; + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + meanI+=calib_buff[j++]; + meanQ+=calib_buff[j++]; } meanI/=RXDCLENGTH; meanQ/=RXDCLENGTH; - printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offI,offQ,meanI,meanQ); - } - - printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offIold); - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQold); - - // TX DC offset - // PUT TX as f_RX + fs/4 - // loop back BLADERF_LB_RF_LNA1 - bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->rx_freq[0] + (unsigned int) device->openair0_cfg->sample_rate/4); - bladerf_set_loopback (brf->dev,BLADERF_LB_RF_LNA1); - - offIold=2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offIold); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { - switch (i&3) { - case 0: - meanIold+=calib_buff[j++]; - break; - case 1: - meanQold+=calib_buff[j++]; - break; - case 2: - meanIold-=calib_buff[j++]; - break; - case 3: - meanQold-=calib_buff[j++]; - break; + // printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offI,offQ,meanI,meanQ); + + while (cnt++ < 12) { + + offInew=(offIold+offI)>>1; + offQnew=(offQold+offQ)>>1; + + if (meanI*meanI < meanIold*meanIold) { + meanIold = meanI; + offIold = offI; + printf("[BRF] *** RX DC: offI %d => %d\n",offIold,meanI); + } + if (meanQ*meanQ < meanQold*meanQold) { + meanQold = meanQ; + offQold = offQ; + printf("[BRF] *** RX DC: offQ %d => %d\n",offQold,meanQ); + } + offI = offInew; + offQ = offQnew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offI); + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQ); + + for (i=0; i<10; i++) + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + meanI+=calib_buff[j++]; + meanQ+=calib_buff[j++]; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offI,offQ,meanI,meanQ); } - } - // meanIold/=RXDCLENGTH; - // meanQold/=RXDCLENGTH; - printf("[BRF] TX DC (offI): %d => (%d,%d)\n",offIold,meanIold,meanQold); - - offI=-2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offI); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - switch (i&3) { - case 0: - meanI+=calib_buff[j++]; - break; - case 1: - meanQ+=calib_buff[j++]; - break; - case 2: - meanI-=calib_buff[j++]; - break; - case 3: - meanQ-=calib_buff[j++]; - break; + + printf("[BRF] RX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_I,offIold); + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_LMS_DCOFF_Q,offQold); + + // TX DC offset + // PUT TX as f_RX + fs/4 + // loop back BLADERF_LB_RF_LNA1 + bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->rx_freq[0] + (unsigned int) device->openair0_cfg->sample_rate/4); + bladerf_set_loopback (brf->dev,BLADERF_LB_RF_LNA1); + + offIold=2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offIold); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); } - } - // meanI/=RXDCLENGTH; - // meanQ/=RXDCLENGTH; - printf("[BRF] TX DC (offI): %d => (%d,%d)\n",offI,meanI,meanQ); - cnt = 0; - while (cnt++ < 12) { - - offInew=(offIold+offI)>>1; - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - printf("[BRF] TX DC (offI): ([%d,%d]) => %d : %d\n",offIold,offI,offInew,meanI*meanI+meanQ*meanQ); - meanIold = meanI; - meanQold = meanQ; - offIold = offI; + for (meanIold=meanQold=i=j=0; i<RXDCLENGTH; i++) { + switch (i&3) { + case 0: + meanIold+=calib_buff[j++]; + break; + case 1: + meanQold+=calib_buff[j++]; + break; + case 2: + meanIold-=calib_buff[j++]; + break; + case 3: + meanQold-=calib_buff[j++]; + break; + } } - offI = offInew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offI); + // meanIold/=RXDCLENGTH; + // meanQold/=RXDCLENGTH; + printf("[BRF] TX DC (offI): %d => (%d,%d)\n",offIold,meanIold,meanQold); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - switch (i&3) { - case 0: - meanI+=calib_buff[j++]; - break; - case 1: - meanQ+=calib_buff[j++]; - break; - case 2: - meanI-=calib_buff[j++]; - break; - case 3: - meanQ-=calib_buff[j++]; - break; - } + offI=-2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offI); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); } - // meanI/=RXDCLENGTH; - // meanQ/=RXDCLENGTH; - // printf("[BRF] TX DC (offI): %d => (%d,%d)\n",offI,meanI,meanQ); - } - - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offIold); - - offQold=2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQold); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/4 - for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { - switch (i&3) { - case 0: - meanIold+=calib_buff[j++]; - break; - case 1: - meanQold+=calib_buff[j++]; - break; - case 2: - meanIold-=calib_buff[j++]; - break; - case 3: - meanQold-=calib_buff[j++]; - break; + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + switch (i&3) { + case 0: + meanI+=calib_buff[j++]; + break; + case 1: + meanQ+=calib_buff[j++]; + break; + case 2: + meanI-=calib_buff[j++]; + break; + case 3: + meanQ-=calib_buff[j++]; + break; + } } - } - // meanIold/=RXDCLENGTH; - // meanQold/=RXDCLENGTH; - printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQold,meanIold,meanQold); - - offQ=-2048; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQ); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - switch (i&3) { - case 0: - meanI+=calib_buff[j++]; - break; - case 1: - meanQ+=calib_buff[j++]; - break; - case 2: - meanI-=calib_buff[j++]; - break; - case 3: - meanQ-=calib_buff[j++]; - break; + // meanI/=RXDCLENGTH; + // meanQ/=RXDCLENGTH; + printf("[BRF] TX DC (offI): %d => (%d,%d)\n",offI,meanI,meanQ); + cnt = 0; + while (cnt++ < 12) { + + offInew=(offIold+offI)>>1; + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + printf("[BRF] TX DC (offI): ([%d,%d]) => %d : %d\n",offIold,offI,offInew,meanI*meanI+meanQ*meanQ); + meanIold = meanI; + meanQold = meanQ; + offIold = offI; + } + offI = offInew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offI); + + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + switch (i&3) { + case 0: + meanI+=calib_buff[j++]; + break; + case 1: + meanQ+=calib_buff[j++]; + break; + case 2: + meanI-=calib_buff[j++]; + break; + case 3: + meanQ-=calib_buff[j++]; + break; + } + } + // meanI/=RXDCLENGTH; + // meanQ/=RXDCLENGTH; + // printf("[BRF] TX DC (offI): %d => (%d,%d)\n",offI,meanI,meanQ); } - } - // meanI/=RXDCLENGTH; - // meanQ/=RXDCLENGTH; - printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); - - cnt=0; - while (cnt++ < 12) { - - offQnew=(offQold+offQ)>>1; - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - printf("[BRF] TX DC (offQ): ([%d,%d]) => %d : %d\n",offQold,offQ,offQnew,meanI*meanI+meanQ*meanQ); - meanIold = meanI; - meanQold = meanQ; - offQold = offQ; - } - offQ = offQnew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQ); + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_I,offIold); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - switch (i&3) { - case 0: - meanI+=calib_buff[j++]; - break; - case 1: - meanQ+=calib_buff[j++]; - break; - case 2: - meanI-=calib_buff[j++]; - break; - case 3: - meanQ-=calib_buff[j++]; - break; - } + offQold=2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQold); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); } - // meanI/=RXDCLENGTH; - // meanQ/=RXDCLENGTH; - // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); - } - - printf("[BRF] TX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); - - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQold); - - // TX IQ imbalance - for (loop=0;loop<2;loop++) { - offphaseold=4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphaseold); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + // project on fs/4 + for (meanIold=meanQold=i=j=0; i<RXDCLENGTH; i++) { + switch (i&3) { + case 0: + meanIold+=calib_buff[j++]; + break; + case 1: + meanQold+=calib_buff[j++]; + break; + case 2: + meanIold-=calib_buff[j++]; + break; + case 3: + meanQold-=calib_buff[j++]; + break; + } } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { - meanIold+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; - meanQold+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - - meanIold/=RXDCLENGTH; - meanQold/=RXDCLENGTH; - printf("[BRF] TX IQ (offphase): %d => (%d,%d)\n",offphaseold,meanIold,meanQold); - - offphase=-4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphase); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; - meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - printf("[BRF] TX IQ (offphase): %d => (%d,%d)\n",offphase,meanI,meanQ); - - cnt=0; - while (cnt++ < 13) { - - offphasenew=(offphaseold+offphase)>>1; - printf("[BRF] TX IQ (offphase): ([%d,%d]) => %d : %d\n",offphaseold,offphase,offphasenew,meanI*meanI+meanQ*meanQ); - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - - - meanIold = meanI; - meanQold = meanQ; - offphaseold = offphase; - } - offphase = offphasenew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphase); - - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; - meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - - // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); - } - - printf("[BRF] TX IQ offphase: %d => (%d,%d)\n",offphaseold,meanIold,meanQold); - - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphaseold); - - offgainold=4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgainold); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { - meanIold+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; - meanQold+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - - meanIold/=RXDCLENGTH; - meanQold/=RXDCLENGTH; - printf("[BRF] TX IQ (offgain): %d => (%d,%d)\n",offgainold,meanIold,meanQold); - - offgain=-4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgain); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; - meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - printf("[BRF] TX IQ (offgain): %d => (%d,%d)\n",offgain,meanI,meanQ); - - cnt=0; - while (cnt++ < 13) { - - offgainnew=(offgainold+offgain)>>1; - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - printf("[BRF] TX IQ (offgain): ([%d,%d]) => %d : %d\n",offgainold,offgain,offgainnew,meanI*meanI+meanQ*meanQ); - - meanIold = meanI; - meanQold = meanQ; - offgainold = offgain; - } - offgain = offgainnew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgain); - - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on fs/8 (Image of TX signal in +ve frequencies) - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; - meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; - j+=2; - } - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - - // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); - } - - printf("[BRF] TX IQ offgain: %d => (%d,%d)\n",offgainold,meanIold,meanQold); - - bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgainold); - } - - // RX IQ imbalance - for (loop=0;loop<2;loop++) { - offphaseold=4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphaseold); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on -3fs/8 (Image of TX signal in -ve frequencies) - for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { - meanIold+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; - meanQold+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; - } - - meanIold/=RXDCLENGTH; - meanQold/=RXDCLENGTH; - printf("[BRF] RX IQ (offphase): %d => (%d,%d)\n",offphaseold,meanIold,meanQold); - - offphase=-4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphase); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + // meanIold/=RXDCLENGTH; + // meanQold/=RXDCLENGTH; + printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQold,meanIold,meanQold); + + offQ=-2048; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQ); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); } - // project on -3fs/8 (Image of TX signal in -ve frequencies) - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; - meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + switch (i&3) { + case 0: + meanI+=calib_buff[j++]; + break; + case 1: + meanQ+=calib_buff[j++]; + break; + case 2: + meanI-=calib_buff[j++]; + break; + case 3: + meanQ-=calib_buff[j++]; + break; + } } - - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - printf("[BRF] RX IQ (offphase): %d => (%d,%d)\n",offphase,meanI,meanQ); - + // meanI/=RXDCLENGTH; + // meanQ/=RXDCLENGTH; + printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + cnt=0; - while (cnt++ < 13) { - - offphasenew=(offphaseold+offphase)>>1; - printf("[BRF] RX IQ (offphase): ([%d,%d]) => %d : %d\n",offphaseold,offphase,offphasenew,meanI*meanI+meanQ*meanQ); - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - - - meanIold = meanI; - meanQold = meanQ; - offphaseold = offphase; - } - offphase = offphasenew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphase); - - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on -3fs/8 (Image of TX signal in -ve frequencies) - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; - meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; - } - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - - // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + while (cnt++ < 12) { + + offQnew=(offQold+offQ)>>1; + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + printf("[BRF] TX DC (offQ): ([%d,%d]) => %d : %d\n",offQold,offQ,offQnew,meanI*meanI+meanQ*meanQ); + + meanIold = meanI; + meanQold = meanQ; + offQold = offQ; + } + offQ = offQnew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQ); + + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + switch (i&3) { + case 0: + meanI+=calib_buff[j++]; + break; + case 1: + meanQ+=calib_buff[j++]; + break; + case 2: + meanI-=calib_buff[j++]; + break; + case 3: + meanQ-=calib_buff[j++]; + break; + } + } + // meanI/=RXDCLENGTH; + // meanQ/=RXDCLENGTH; + // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); } - - printf("[BRF] RX IQ offphase: %d => (%d,%d)\n",offphaseold,meanIold,meanQold); - - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphaseold); - - offgainold=4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgainold); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0,0); - } - // project on -3fs/8 (Image of TX signal in +ve frequencies) - for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) { - meanIold+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; - meanQold+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; - } - - meanIold/=RXDCLENGTH; - meanQold/=RXDCLENGTH; - printf("[BRF] RX IQ (offgain): %d => (%d,%d)\n",offgainold,meanIold,meanQold); - - offgain=-4096; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgain); - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on 3fs/8 (Image of TX signal in -ve frequencies) - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; - meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; + + printf("[BRF] TX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold); + + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_LMS_DCOFF_Q,offQold); + + // TX IQ imbalance + for (loop=0; loop<2; loop++) { + offphaseold=4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphaseold); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanIold=meanQold=i=j=0; i<RXDCLENGTH; i++) { + meanIold+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQold+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + + meanIold/=RXDCLENGTH; + meanQold/=RXDCLENGTH; + printf("[BRF] TX IQ (offphase): %d => (%d,%d)\n",offphaseold,meanIold,meanQold); + + offphase=-4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphase); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + printf("[BRF] TX IQ (offphase): %d => (%d,%d)\n",offphase,meanI,meanQ); + + cnt=0; + while (cnt++ < 13) { + + offphasenew=(offphaseold+offphase)>>1; + printf("[BRF] TX IQ (offphase): ([%d,%d]) => %d : %d\n",offphaseold,offphase,offphasenew,meanI*meanI+meanQ*meanQ); + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + + + meanIold = meanI; + meanQold = meanQ; + offphaseold = offphase; + } + offphase = offphasenew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphase); + + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + + // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + } + + printf("[BRF] TX IQ offphase: %d => (%d,%d)\n",offphaseold,meanIold,meanQold); + + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_PHASE,offphaseold); + + offgainold=4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgainold); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanIold=meanQold=i=j=0; i<RXDCLENGTH; i++) { + meanIold+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQold+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + + meanIold/=RXDCLENGTH; + meanQold/=RXDCLENGTH; + printf("[BRF] TX IQ (offgain): %d => (%d,%d)\n",offgainold,meanIold,meanQold); + + offgain=-4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgain); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + printf("[BRF] TX IQ (offgain): %d => (%d,%d)\n",offgain,meanI,meanQ); + + cnt=0; + while (cnt++ < 13) { + + offgainnew=(offgainold+offgain)>>1; + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + printf("[BRF] TX IQ (offgain): ([%d,%d]) => %d : %d\n",offgainold,offgain,offgainnew,meanI*meanI+meanQ*meanQ); + + meanIold = meanI; + meanQold = meanQ; + offgainold = offgain; + } + offgain = offgainnew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgain); + + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on fs/8 (Image of TX signal in +ve frequencies) + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + meanI+= (calib_buff[j]*cos_fsover8[i&7] - calib_buff[j+1]*cos_fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_fsover8[(i+2)&7] + calib_buff[j+1]*cos_fsover8[i&7])>>11; + j+=2; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + + // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + } + + printf("[BRF] TX IQ offgain: %d => (%d,%d)\n",offgainold,meanIold,meanQold); + + bladerf_set_correction(brf->dev,BLADERF_MODULE_TX,BLADERF_CORR_FPGA_GAIN,offgainold); } - - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - printf("[BRF] RX IQ (offgain): %d => (%d,%d)\n",offgain,meanI,meanQ); - - cnt=0; - while (cnt++ < 13) { - - offgainnew=(offgainold+offgain)>>1; - if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { - printf("[BRF] RX IQ (offgain): ([%d,%d]) => %d : %d\n",offgainold,offgain,offgainnew,meanI*meanI+meanQ*meanQ); - - meanIold = meanI; - meanQold = meanQ; - offgainold = offgain; - } - offgain = offgainnew; - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgain); - - for (i=0;i<10;i++) { - trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); - trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); - } - // project on -3fs/8 (Image of TX signal in -ve frequencies) - for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) { - meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; - meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; - j+=2; - } - meanI/=RXDCLENGTH; - meanQ/=RXDCLENGTH; - - // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + + // RX IQ imbalance + for (loop=0; loop<2; loop++) { + offphaseold=4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphaseold); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on -3fs/8 (Image of TX signal in -ve frequencies) + for (meanIold=meanQold=i=j=0; i<RXDCLENGTH; i++) { + meanIold+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQold+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + + meanIold/=RXDCLENGTH; + meanQold/=RXDCLENGTH; + printf("[BRF] RX IQ (offphase): %d => (%d,%d)\n",offphaseold,meanIold,meanQold); + + offphase=-4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphase); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on -3fs/8 (Image of TX signal in -ve frequencies) + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + printf("[BRF] RX IQ (offphase): %d => (%d,%d)\n",offphase,meanI,meanQ); + + cnt=0; + while (cnt++ < 13) { + + offphasenew=(offphaseold+offphase)>>1; + printf("[BRF] RX IQ (offphase): ([%d,%d]) => %d : %d\n",offphaseold,offphase,offphasenew,meanI*meanI+meanQ*meanQ); + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + + + meanIold = meanI; + meanQold = meanQ; + offphaseold = offphase; + } + offphase = offphasenew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphase); + + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on -3fs/8 (Image of TX signal in -ve frequencies) + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + + // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + } + + printf("[BRF] RX IQ offphase: %d => (%d,%d)\n",offphaseold,meanIold,meanQold); + + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_PHASE,offphaseold); + + offgainold=4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgainold); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0,0); + } + // project on -3fs/8 (Image of TX signal in +ve frequencies) + for (meanIold=meanQold=i=j=0; i<RXDCLENGTH; i++) { + meanIold+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQold+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + + meanIold/=RXDCLENGTH; + meanQold/=RXDCLENGTH; + printf("[BRF] RX IQ (offgain): %d => (%d,%d)\n",offgainold,meanIold,meanQold); + + offgain=-4096; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgain); + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on 3fs/8 (Image of TX signal in -ve frequencies) + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + printf("[BRF] RX IQ (offgain): %d => (%d,%d)\n",offgain,meanI,meanQ); + + cnt=0; + while (cnt++ < 13) { + + offgainnew=(offgainold+offgain)>>1; + if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) { + printf("[BRF] RX IQ (offgain): ([%d,%d]) => %d : %d\n",offgainold,offgain,offgainnew,meanI*meanI+meanQ*meanQ); + + meanIold = meanI; + meanQold = meanQ; + offgainold = offgain; + } + offgain = offgainnew; + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgain); + + for (i=0; i<10; i++) { + trx_brf_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0); + trx_brf_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0); + } + // project on -3fs/8 (Image of TX signal in -ve frequencies) + for (meanI=meanQ=i=j=0; i<RXDCLENGTH; i++) { + meanI+= (calib_buff[j]*cos_3fsover8[i&7] - calib_buff[j+1]*cos_3fsover8[(i+2)&7])>>11; + meanQ+= (calib_buff[j]*cos_3fsover8[(i+2)&7] + calib_buff[j+1]*cos_3fsover8[i&7])>>11; + j+=2; + } + meanI/=RXDCLENGTH; + meanQ/=RXDCLENGTH; + + // printf("[BRF] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ); + } + + printf("[BRF] RX IQ offgain: %d => (%d,%d)\n",offgainold,meanIold,meanQold); + + bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgainold); } - - printf("[BRF] RX IQ offgain: %d => (%d,%d)\n",offgainold,meanIold,meanQold); - - bladerf_set_correction(brf->dev,BLADERF_MODULE_RX,BLADERF_CORR_FPGA_GAIN,offgainold); - } - - bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->tx_freq[0]); - bladerf_set_loopback(brf->dev,BLADERF_LB_NONE); - bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, (unsigned int) device->openair0_cfg->rx_gain[0]-device->openair0_cfg[0].rx_gain_offset[0]); - bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->tx_gain[0]); - // LOG_M("blade_rf_test.m","rxs",calib_buff,RXDCLENGTH,1,1); + + bladerf_set_frequency(brf->dev,BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->tx_freq[0]); + bladerf_set_loopback(brf->dev,BLADERF_LB_NONE); + bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, (unsigned int) device->openair0_cfg->rx_gain[0]-device->openair0_cfg[0].rx_gain_offset[0]); + bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, (unsigned int) device->openair0_cfg->tx_gain[0]); + // LOG_M("blade_rf_test.m","rxs",calib_buff,RXDCLENGTH,1,1); } -/*! \brief Initialize Openair BLADERF target. It returns 0 if OK +/*! \brief Initialize Openair BLADERF target. It returns 0 if OK * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application * \returns 0 on success */ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { - int status; - brf_state_t *brf = (brf_state_t*)malloc(sizeof(brf_state_t)); - memset(brf, 0, sizeof(brf_state_t)); - /* 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) { - case 30720000: - openair0_cfg->samples_per_packet = 2048; - openair0_cfg->tx_sample_advance = 0; - break; - case 15360000: - openair0_cfg->samples_per_packet = 2048; - openair0_cfg->tx_sample_advance = 0; - break; - case 7680000: - openair0_cfg->samples_per_packet = 1024; - openair0_cfg->tx_sample_advance = 0; - break; - case 1920000: - openair0_cfg->samples_per_packet = 256; - openair0_cfg->tx_sample_advance = 50; - break; - default: - printf("Error: unknown sampling rate %f\n",openair0_cfg->sample_rate); - 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 - brf->num_buffers = 128; - // the size of the underlying stream buffers, in samples - brf->buffer_size = (unsigned int) openair0_cfg->samples_per_packet;//*sizeof(int32_t); // buffer size = 4096 for sample_len of 1024 - brf->num_transfers = 16; - brf->rx_timeout_ms = 0; - brf->tx_timeout_ms = 0; - brf->sample_rate=(unsigned int)openair0_cfg->sample_rate; - - memset(&brf->meta_rx, 0, sizeof(brf->meta_rx)); - memset(&brf->meta_tx, 0, sizeof(brf->meta_tx)); - - printf("\n[BRF] sampling_rate %d, num_buffers %d, buffer_size %d, num transfer %d, timeout_ms (rx %d, tx %d)\n", - brf->sample_rate, brf->num_buffers, brf->buffer_size,brf->num_transfers, brf->rx_timeout_ms, brf->tx_timeout_ms); - - if ((status=bladerf_open(&brf->dev, "")) != 0 ) { - fprintf(stderr,"Failed to open brf device: %s\n",bladerf_strerror(status)); - brf_error(status); - } - printf("[BRF] init dev %p\n", brf->dev); - switch(bladerf_device_speed(brf->dev)){ - case BLADERF_DEVICE_SPEED_SUPER: - printf("[BRF] Device operates at max speed\n"); - break; - default: - printf("[BRF] Device does not operates at max speed, change the USB port\n"); - brf_error(BLADERF_ERR_UNSUPPORTED); - } - // RX - // Example of CLI output: RX Frequency: 2539999999Hz - - - if ((status=bladerf_set_gain_mode(brf->dev, BLADERF_MODULE_RX, BLADERF_GAIN_MGC))) { - fprintf(stderr, "[BRF] Failed to disable AGC\n"); - brf_error(status); - } - - if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_freq[0])) != 0){ - fprintf(stderr,"Failed to set RX frequency: %s\n",bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set RX frequency to %u\n",(unsigned int)openair0_cfg->rx_freq[0]); - - - - unsigned int actual_value=0; - if ((status=bladerf_set_sample_rate(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->sample_rate, &actual_value)) != 0){ - fprintf(stderr,"Failed to set RX sample rate: %s\n", bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] set RX sample rate to %u, %u\n", (unsigned int) openair0_cfg->sample_rate, actual_value); - - - if ((status=bladerf_set_bandwidth(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_bw*2, &actual_value)) != 0){ - fprintf(stderr,"Failed to set RX bandwidth: %s\n", bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] set RX bandwidth to %u, %u\n",(unsigned int)openair0_cfg->rx_bw*2, actual_value); - - set_rx_gain_offset(&openair0_cfg[0],0); - if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, (int) openair0_cfg->rx_gain[0]-openair0_cfg[0].rx_gain_offset[0])) != 0) { - fprintf(stderr,"Failed to set RX gain: %s\n",bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] set RX gain to %d (%d)\n",(int)(openair0_cfg->rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]),(int)openair0_cfg[0].rx_gain_offset[0]); - - // TX - - if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->tx_freq[0])) != 0){ - fprintf(stderr,"Failed to set TX frequency: %s\n",bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] set TX Frequency to %u\n", (unsigned int) openair0_cfg->tx_freq[0]); - - if ((status=bladerf_set_sample_rate(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->sample_rate, NULL)) != 0){ - fprintf(stderr,"Failed to set TX sample rate: %s\n", bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] set TX sampling rate to %u \n", (unsigned int) openair0_cfg->sample_rate); - - if ((status=bladerf_set_bandwidth(brf->dev, BLADERF_MODULE_TX,(unsigned int)openair0_cfg->tx_bw*2, NULL)) != 0){ - fprintf(stderr, "Failed to set TX bandwidth: %s\n", bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] set TX bandwidth to %u \n", (unsigned int) openair0_cfg->tx_bw*2); - - if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, (int) openair0_cfg->tx_gain[0])) != 0) { - fprintf(stderr,"Failed to set TX gain: %s\n",bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] set the TX gain to %d\n", (int)openair0_cfg->tx_gain[0]); - - - /* Configure the device's TX module for use with the sync interface. - * SC16 Q11 samples *with* metadata are used. */ - if ((status=bladerf_sync_config(brf->dev, BLADERF_MODULE_TX,BLADERF_FORMAT_SC16_Q11_META,brf->num_buffers,brf->buffer_size,brf->num_transfers,brf->tx_timeout_ms)) != 0 ) { - fprintf(stderr,"Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] configured TX sync interface \n"); - -/* Configure the device's RX module for use with the sync interface. - * SC16 Q11 samples *with* metadata are used. */ - if ((status=bladerf_sync_config(brf->dev, BLADERF_MODULE_RX, BLADERF_FORMAT_SC16_Q11_META,brf->num_buffers,brf->buffer_size,brf->num_transfers,brf->rx_timeout_ms)) != 0 ) { - fprintf(stderr,"Failed to configure RX sync interface: %s\n", bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] configured Rx sync interface \n"); - - - /* We must always enable the TX module after calling bladerf_sync_config(), and - * before attempting to TX samples via bladerf_sync_tx(). */ - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, true)) != 0) { - fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status)); - brf_error(status); - } else - printf("[BRF] TX module enabled \n"); - - /* We must always enable the RX module after calling bladerf_sync_config(), and - * before attempting to RX samples via bladerf_sync_rx(). */ - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true)) != 0) { - fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] RX module enabled \n"); - - // calibrate - - if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_LPF_TUNING)) != 0 || - (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_TX_LPF)) != 0 || - (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_RX_LPF)) != 0 || - (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_RXVGA2)) != 0) { - fprintf(stderr, "[BRF] error calibrating\n"); - brf_error(status); - } else - printf("[BRF] calibration OK\n"); - - bladerf_log_set_verbosity(get_brf_log_level(openair0_cfg->log_level)); - - printf("BLADERF: Initializing openair0_device\n"); - device->Mod_id = num_devices++; - device->type = BLADERF_DEV; - device->trx_start_func = trx_brf_start; - device->trx_end_func = trx_brf_end; - device->trx_read_func = trx_brf_read; - device->trx_write_func = trx_brf_write; - device->trx_get_stats_func = trx_brf_get_stats; - device->trx_reset_stats_func = trx_brf_reset_stats; - device->trx_stop_func = trx_brf_stop; - device->trx_set_freq_func = trx_brf_set_freq; - device->trx_set_gains_func = trx_brf_set_gains; - device->openair0_cfg = openair0_cfg; - device->priv = (void *)brf; - - calibrate_rf(device); - - // memcpy((void*)&device->openair0_cfg,(void*)&openair0_cfg[0],sizeof(openair0_config_t)); - - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, false)) != 0) { - fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status)); - abort(); - } - if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, false)) != 0) { - fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); - abort(); - } - - return 0; + int status; + brf_state_t *brf = (brf_state_t*)malloc(sizeof(brf_state_t)); + memset(brf, 0, sizeof(brf_state_t)); + /* 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) { + case 30720000: + openair0_cfg->samples_per_packet = 2048; + openair0_cfg->tx_sample_advance = 0; + break; + case 15360000: + openair0_cfg->samples_per_packet = 2048; + openair0_cfg->tx_sample_advance = 0; + break; + case 7680000: + openair0_cfg->samples_per_packet = 1024; + openair0_cfg->tx_sample_advance = 0; + break; + case 1920000: + openair0_cfg->samples_per_packet = 256; + openair0_cfg->tx_sample_advance = 50; + break; + default: + printf("Error: unknown sampling rate %f\n",openair0_cfg->sample_rate); + 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 + brf->num_buffers = 128; + // the size of the underlying stream buffers, in samples + brf->buffer_size = (unsigned int) openair0_cfg->samples_per_packet;//*sizeof(int32_t); // buffer size = 4096 for sample_len of 1024 + brf->num_transfers = 16; + brf->rx_timeout_ms = 0; + brf->tx_timeout_ms = 0; + brf->sample_rate=(unsigned int)openair0_cfg->sample_rate; + + memset(&brf->meta_rx, 0, sizeof(brf->meta_rx)); + memset(&brf->meta_tx, 0, sizeof(brf->meta_tx)); + + printf("\n[BRF] sampling_rate %u, num_buffers %u, buffer_size %u, num transfer %u, timeout_ms (rx %u, tx %u)\n", + brf->sample_rate, brf->num_buffers, brf->buffer_size,brf->num_transfers, brf->rx_timeout_ms, brf->tx_timeout_ms); + + if ((status=bladerf_open(&brf->dev, "")) != 0 ) { + fprintf(stderr,"Failed to open brf device: %s\n",bladerf_strerror(status)); + brf_error(status); + } + printf("[BRF] init dev %p\n", brf->dev); + switch(bladerf_device_speed(brf->dev)) { + case BLADERF_DEVICE_SPEED_SUPER: + printf("[BRF] Device operates at max speed\n"); + break; + default: + printf("[BRF] Device does not operates at max speed, change the USB port\n"); + brf_error(BLADERF_ERR_UNSUPPORTED); + } + // RX + // Example of CLI output: RX Frequency: 2539999999Hz + + + if ((status=bladerf_set_gain_mode(brf->dev, BLADERF_MODULE_RX, BLADERF_GAIN_MGC))) { + fprintf(stderr, "[BRF] Failed to disable AGC\n"); + brf_error(status); + } + + if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_freq[0])) != 0) { + fprintf(stderr,"Failed to set RX frequency: %s\n",bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set RX frequency to %u\n",(unsigned int)openair0_cfg->rx_freq[0]); + + + + unsigned int actual_value=0; + if ((status=bladerf_set_sample_rate(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->sample_rate, &actual_value)) != 0) { + fprintf(stderr,"Failed to set RX sample rate: %s\n", bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set RX sample rate to %u, %u\n", (unsigned int) openair0_cfg->sample_rate, actual_value); + + + if ((status=bladerf_set_bandwidth(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_bw*2, &actual_value)) != 0) { + fprintf(stderr,"Failed to set RX bandwidth: %s\n", bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set RX bandwidth to %u, %u\n",(unsigned int)openair0_cfg->rx_bw*2, actual_value); + + set_rx_gain_offset(&openair0_cfg[0],0); + if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_RX, (int) openair0_cfg->rx_gain[0]-openair0_cfg[0].rx_gain_offset[0])) != 0) { + fprintf(stderr,"Failed to set RX gain: %s\n",bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set RX gain to %d (%d)\n",(int)(openair0_cfg->rx_gain[0]-openair0_cfg[0].rx_gain_offset[0]),(int)openair0_cfg[0].rx_gain_offset[0]); + + // TX + + if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->tx_freq[0])) != 0) { + fprintf(stderr,"Failed to set TX frequency: %s\n",bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set TX Frequency to %u\n", (unsigned int) openair0_cfg->tx_freq[0]); + + if ((status=bladerf_set_sample_rate(brf->dev, BLADERF_MODULE_TX, (unsigned int) openair0_cfg->sample_rate, NULL)) != 0) { + fprintf(stderr,"Failed to set TX sample rate: %s\n", bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set TX sampling rate to %u \n", (unsigned int) openair0_cfg->sample_rate); + + if ((status=bladerf_set_bandwidth(brf->dev, BLADERF_MODULE_TX,(unsigned int)openair0_cfg->tx_bw*2, NULL)) != 0) { + fprintf(stderr, "Failed to set TX bandwidth: %s\n", bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set TX bandwidth to %u \n", (unsigned int) openair0_cfg->tx_bw*2); + + if ((status=bladerf_set_gain(brf->dev, BLADERF_MODULE_TX, (int) openair0_cfg->tx_gain[0])) != 0) { + fprintf(stderr,"Failed to set TX gain: %s\n",bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] set the TX gain to %d\n", (int)openair0_cfg->tx_gain[0]); + + + /* Configure the device's TX module for use with the sync interface. + * SC16 Q11 samples *with* metadata are used. */ + if ((status=bladerf_sync_config(brf->dev, BLADERF_MODULE_TX,BLADERF_FORMAT_SC16_Q11_META,brf->num_buffers,brf->buffer_size,brf->num_transfers,brf->tx_timeout_ms)) != 0 ) { + fprintf(stderr,"Failed to configure TX sync interface: %s\n", bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] configured TX sync interface \n"); + + /* Configure the device's RX module for use with the sync interface. + * SC16 Q11 samples *with* metadata are used. */ + if ((status=bladerf_sync_config(brf->dev, BLADERF_MODULE_RX, BLADERF_FORMAT_SC16_Q11_META,brf->num_buffers,brf->buffer_size,brf->num_transfers,brf->rx_timeout_ms)) != 0 ) { + fprintf(stderr,"Failed to configure RX sync interface: %s\n", bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] configured Rx sync interface \n"); + + + /* We must always enable the TX module after calling bladerf_sync_config(), and + * before attempting to TX samples via bladerf_sync_tx(). */ + if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, true)) != 0) { + fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] TX module enabled \n"); + + /* We must always enable the RX module after calling bladerf_sync_config(), and + * before attempting to RX samples via bladerf_sync_rx(). */ + if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true)) != 0) { + fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); + brf_error(status); + } else + printf("[BRF] RX module enabled \n"); + + // calibrate + + if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_LPF_TUNING)) != 0 || + (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_TX_LPF)) != 0 || + (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_RX_LPF)) != 0 || + (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_RXVGA2)) != 0) { + fprintf(stderr, "[BRF] error calibrating\n"); + brf_error(status); + } else + printf("[BRF] calibration OK\n"); + + bladerf_log_set_verbosity(get_brf_log_level(openair0_cfg->log_level)); + + printf("BLADERF: Initializing openair0_device\n"); + device->Mod_id = num_devices++; + device->type = BLADERF_DEV; + device->trx_start_func = trx_brf_start; + device->trx_end_func = trx_brf_end; + device->trx_read_func = trx_brf_read; + device->trx_write_func = trx_brf_write; + device->trx_get_stats_func = trx_brf_get_stats; + device->trx_reset_stats_func = trx_brf_reset_stats; + device->trx_stop_func = trx_brf_stop; + device->trx_set_freq_func = trx_brf_set_freq; + device->trx_set_gains_func = trx_brf_set_gains; + device->openair0_cfg = openair0_cfg; + device->priv = (void *)brf; + + calibrate_rf(device); + + // memcpy((void*)&device->openair0_cfg,(void*)&openair0_cfg[0],sizeof(openair0_config_t)); + + if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, false)) != 0) { + fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status)); + abort(); + } + if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, false)) != 0) { + fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status)); + abort(); + } + + return 0; } -/*! \brief bladeRF error report - * \param status +/*! \brief bladeRF error report + * \param status * \returns 0 on success */ int brf_error(int status) { - fprintf(stderr, "[BRF] brf_error: %s\n", bladerf_strerror(status)); - exit(-1); - return status; // or status error code + fprintf(stderr, "[BRF] brf_error: %s\n", bladerf_strerror(status)); + exit(-1); + return status; // or status error code } @@ -1153,61 +1154,61 @@ int brf_error(int status) { */ struct bladerf * open_bladerf_from_serial(const char *serial) { - int status; - struct bladerf *dev; - struct bladerf_devinfo info; - /* Initialize all fields to "don't care" wildcard values. - * - * Immediately passing this to bladerf_open_with_devinfo() would cause - * libbladeRF to open any device on any available backend. */ - bladerf_init_devinfo(&info); - /* Specify the desired device's serial number, while leaving all other - * fields in the info structure wildcard values */ - strncpy(info.serial, serial, BLADERF_SERIAL_LENGTH - 1); - info.serial[BLADERF_SERIAL_LENGTH - 1] = '\0'; - status = bladerf_open_with_devinfo(&dev, &info); - - if (status == BLADERF_ERR_NODEV) { - printf("No devices available with serial=%s\n", serial); - return NULL; - } else if (status != 0) { - fprintf(stderr, "Failed to open device with serial=%s (%s)\n", serial, bladerf_strerror(status)); - return NULL; - } else { - return dev; - } + int status; + struct bladerf *dev; + struct bladerf_devinfo info; + /* Initialize all fields to "don't care" wildcard values. + * + * Immediately passing this to bladerf_open_with_devinfo() would cause + * libbladeRF to open any device on any available backend. */ + bladerf_init_devinfo(&info); + /* Specify the desired device's serial number, while leaving all other + * fields in the info structure wildcard values */ + strncpy(info.serial, serial, BLADERF_SERIAL_LENGTH - 1); + info.serial[BLADERF_SERIAL_LENGTH - 1] = '\0'; + status = bladerf_open_with_devinfo(&dev, &info); + + if (status == BLADERF_ERR_NODEV) { + printf("No devices available with serial=%s\n", serial); + return NULL; + } else if (status != 0) { + fprintf(stderr, "Failed to open device with serial=%s (%s)\n", serial, bladerf_strerror(status)); + return NULL; + } else { + return dev; + } } /*! \brief Get BladeRF log level * \param log_level log level * \returns log level of BLADERF device */ -int get_brf_log_level(int log_level){ - - int level=BLADERF_LOG_LEVEL_INFO; - return BLADERF_LOG_LEVEL_INFO; - switch(log_level) { - case LOG_DEBUG: - level=BLADERF_LOG_LEVEL_DEBUG; - break; - case LOG_INFO: - level= BLADERF_LOG_LEVEL_INFO; - break; - case LOG_WARNING: - level=BLADERF_LOG_LEVEL_WARNING; - break; - case LOG_ERR: - level=BLADERF_LOG_LEVEL_ERROR; - break; - case LOG_CRIT: - level=BLADERF_LOG_LEVEL_CRITICAL; - break; - case LOG_EMERG: - level = BLADERF_LOG_LEVEL_SILENT; - break; - default: - break; - } - return level; +int get_brf_log_level(int log_level) { + + int level=BLADERF_LOG_LEVEL_INFO; + return BLADERF_LOG_LEVEL_INFO; + switch(log_level) { + case LOG_DEBUG: + level=BLADERF_LOG_LEVEL_DEBUG; + break; + case LOG_INFO: + level= BLADERF_LOG_LEVEL_INFO; + break; + case LOG_WARNING: + level=BLADERF_LOG_LEVEL_WARNING; + break; + case LOG_ERR: + level=BLADERF_LOG_LEVEL_ERROR; + break; + case LOG_CRIT: + level=BLADERF_LOG_LEVEL_CRITICAL; + break; + case LOG_EMERG: + level = BLADERF_LOG_LEVEL_SILENT; + break; + default: + break; + } + return level; } /*@}*/ diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index b62eb9d2dfe3853101aaee71fe082bb5f71cd764..3f81816aa1022de2a623cb8bc865cadb0f9e74cd 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -/*! \file common_lib.c - * \brief common APIs for different RF frontend device +/*! \file common_lib.c + * \brief common APIs for different RF frontend device * \author HongliangXU, Navid Nikaein * \date 2015 * \version 0.2 @@ -37,108 +37,124 @@ #include "common_lib.h" #include "common/utils/load_module_shlib.h" +#include "targets/RT/USER/lte-softmodem.h" int set_device(openair0_device *device) { - switch (device->type) { - - case EXMIMO_DEV: - printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case USRP_B200_DEV: - printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case USRP_X300_DEV: - printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case BLADERF_DEV: - printf("[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case LMSSDR_DEV: - printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case IRIS_DEV: - printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - case NONE_DEV: - printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - break; - default: - printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - return -1; + case EXMIMO_DEV: + printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case USRP_B200_DEV: + printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case USRP_X300_DEV: + printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case BLADERF_DEV: + printf("[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case LMSSDR_DEV: + printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case IRIS_DEV: + printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + case NONE_DEV: + printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; + + default: + printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + return -1; } + return 0; } int set_transport(openair0_device *device) { - switch (device->transp_type) { - - case ETHERNET_TP: - printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - return 0; - break; - case NONE_TP: - printf("[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - return 0; - break; - default: - printf("[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); - return -1; - break; + case ETHERNET_TP: + printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + return 0; + break; + + case NONE_TP: + printf("[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + return 0; + break; + + default: + printf("[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + return -1; + break; } - } typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *); /* look for the interface library and load it */ -int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * cfg, uint8_t flag) { - +int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *cfg, uint8_t flag) { loader_shlibfunc_t shlib_fdesc[1]; int ret=0; char *libname; - if (flag == RAU_LOCAL_RADIO_HEAD) { - libname=OAI_RF_LIBNAME; - shlib_fdesc[0].fname="device_init"; - } else { - libname=OAI_TP_LIBNAME; - shlib_fdesc[0].fname="transport_init"; - } + + if ( IS_SOFTMODEM_BASICSIM ) { + libname=OAI_BASICSIM_LIBNAME; + shlib_fdesc[0].fname="device_init"; + } else if ( IS_SOFTMODEM_RFSIM ) { + libname=OAI_RFSIM_LIBNAME; + shlib_fdesc[0].fname="device_init"; + } else if (flag == RAU_LOCAL_RADIO_HEAD) { + libname=OAI_RF_LIBNAME; + shlib_fdesc[0].fname="device_init"; + } else { + libname=OAI_TP_LIBNAME; + shlib_fdesc[0].fname="transport_init"; + } + ret=load_module_shlib(libname,shlib_fdesc,1,NULL); + if (ret < 0) { - fprintf(stderr,"Library %s couldn't be loaded\n",libname); + fprintf(stderr,"Library %s couldn't be loaded\n",libname); } else { - ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); - } - return ret; + ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); + } + + return ret; } int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) { - int rc=0; rc=load_lib(device, openair0_cfg, NULL,RAU_LOCAL_RADIO_HEAD ); - if ( rc >= 0) { - if ( set_device(device) < 0) { + if ( rc >= 0) { + if ( set_device(device) < 0) { fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__); - return -1; - } + return -1; + } } + return rc; } -int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params) { +int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params) { int rc; rc=load_lib(device, openair0_cfg, eth_params, RAU_REMOTE_RADIO_HEAD); - if ( rc >= 0) { + + if ( rc >= 0) { if ( set_transport(device) < 0) { fprintf(stderr, "%s %d:Unsupported transport protocol\n",__FILE__, __LINE__); - return -1; - } + return -1; + } } - return rc; + return rc; } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 084ef9fcd9fbc629e6381f2d4a5ef025696f06ec..0af6fa9c5edb89be8dfd193c1692a0f072ea5f90 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -/*! \file common_lib.h - * \brief common APIs for different RF frontend device +/*! \file common_lib.h + * \brief common APIs for different RF frontend device * \author HongliangXU, Navid Nikaein * \date 2015 * \version 0.2 @@ -39,19 +39,22 @@ #define OAI_RF_LIBNAME "oai_device" /* name of shared library implementing the transport */ #define OAI_TP_LIBNAME "oai_transpro" - +/* name of shared library implementing the basic/rf simulator */ +#define OAI_RFSIM_LIBNAME "rfsimulator" +/* name of shared library implementing the basic/rf simulator */ +#define OAI_BASICSIM_LIBNAME "tcp_bridge_oai" /* flags for BBU to determine whether the attached radio head is local or remote */ #define RAU_LOCAL_RADIO_HEAD 0 #define RAU_REMOTE_RADIO_HEAD 1 #ifndef MAX_CARDS -#define MAX_CARDS 8 + #define MAX_CARDS 8 #endif typedef int64_t openair0_timestamp; typedef volatile int64_t openair0_vtimestamp; - + /*!\brief structrue holds the parameters to configure USRP devices*/ typedef struct openair0_device_t openair0_device; @@ -120,16 +123,16 @@ typedef enum { /*!\brief openair0 device host type */ typedef enum { MIN_HOST_TYPE = 0, - /*!\brief device functions within a RAU */ + /*!\brief device functions within a RAU */ RAU_HOST, - /*!\brief device functions within a RRU */ + /*!\brief device functions within a RRU */ RRU_HOST, MAX_HOST_TYPE -}host_type_t; +} host_type_t; -/*! \brief RF Gain clibration */ +/*! \brief RF Gain clibration */ typedef struct { //! Frequency for which RX chain was calibrated double freq; @@ -157,7 +160,7 @@ typedef struct { duplex_mode_t duplex_mode; //! number of downlink resource blocks int num_rb_dl; - //! number of samples per frame + //! number of samples per frame unsigned int samples_per_frame; //! the sample rate for both transmit and receive. double sample_rate; @@ -172,9 +175,9 @@ typedef struct { //! number of TX channels (=TX antennas) int tx_num_channels; //! \brief RX base addresses for mmapped_dma - int32_t* rxbase[4]; + int32_t *rxbase[4]; //! \brief TX base addresses for mmapped_dma - int32_t* txbase[4]; + int32_t *txbase[4]; //! \brief Center frequency in Hz for RX. //! index: [0..rx_num_channels[ double rx_freq[4]; @@ -185,7 +188,7 @@ typedef struct { //! \brief Pointer to Calibration table for RX gains rx_gain_calib_table_t *rx_gain_calib_table; - //! mode for rxgain (ExpressMIMO2) + //! mode for rxgain (ExpressMIMO2) rx_gain_t rxg_mode[4]; //! \brief Gain for RX in dB. //! index: [0..rx_num_channels] @@ -199,14 +202,14 @@ typedef struct { double rx_bw; //! TX bandwidth in Hz double tx_bw; - //! clock source + //! clock source clock_source_t clock_source; //! Manual SDR IP address char *sdr_addrs; //! Auto calibration flag int autocal[4]; //! rf devices work with x bits iqs when oai have its own iq format - //! the two following parameters are used to convert iqs + //! the two following parameters are used to convert iqs int iq_txshift; int iq_rxrescale; //! Configuration file for LMS7002M @@ -219,10 +222,10 @@ typedef struct { unsigned int sf_read_delay; // read delay in replay mode unsigned int sf_write_delay; // write delay in replay mode unsigned int eth_mtu; // ethernet MTU -#endif +#endif } openair0_config_t; -/*! \brief RF mapping */ +/*! \brief RF mapping */ typedef struct { //! card id int card; @@ -269,14 +272,14 @@ struct openair0_device_t { /*!brief Component Carrier ID of this device */ int CC_id; - + /*!brief Type of this device */ dev_type_t type; /*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */ transport_type_t transp_type; - /*!brief Type of the device's host (RAU/RRU) */ + /*!brief Type of the device's host (RAU/RRU) */ host_type_t host_type; /* !brief RF frontend parameters set by application */ @@ -298,25 +301,25 @@ struct openair0_device_t { /*! \brief Called to send a request message between RAU-RRU on control port @param device pointer to the device structure specific to the RF hardware target @param msg pointer to the message structure passed between RAU-RRU - @param msg_len length of the message - */ + @param msg_len length of the message + */ int (*trx_ctlsend_func)(openair0_device *device, void *msg, ssize_t msg_len); /*! \brief Called to receive a reply message between RAU-RRU on control port @param device pointer to the device structure specific to the RF hardware target @param msg pointer to the message structure passed between RAU-RRU - @param msg_len length of the message - */ + @param msg_len length of the message + */ int (*trx_ctlrecv_func)(openair0_device *device, void *msg, ssize_t msg_len); /*! \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 timestamp The timestamp at whicch the first sample MUST be sent @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple anteannas @param flags flags must be set to TRUE if timestamp parameter needs to be applied - */ + */ int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags); /*! \brief Receive samples from hardware. @@ -332,55 +335,55 @@ struct openair0_device_t { */ int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id); - /*! \brief print the device statistics + /*! \brief print the device statistics * \param device the hardware to use * \returns 0 on success */ int (*trx_get_stats_func)(openair0_device *device); - /*! \brief Reset device statistics + /*! \brief Reset device statistics * \param device the hardware to use - * \returns 0 in success + * \returns 0 in success */ int (*trx_reset_stats_func)(openair0_device *device); - /*! \brief Terminate operation of the transceiver -- free all associated resources + /*! \brief Terminate operation of the transceiver -- free all associated resources * \param device the hardware to use */ void (*trx_end_func)(openair0_device *device); - /*! \brief Stop operation of the transceiver + /*! \brief Stop operation of the transceiver */ int (*trx_stop_func)(openair0_device *device); /* Functions API related to UE*/ - /*! \brief Set RX feaquencies + /*! \brief Set RX feaquencies * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application - * \param exmimo_dump_config dump EXMIMO configuration - * \returns 0 in success + * \param exmimo_dump_config dump EXMIMO configuration + * \returns 0 in success */ - int (*trx_set_freq_func)(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config); - + int (*trx_set_freq_func)(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config); + /*! \brief Set gains * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application - * \returns 0 in success + * \returns 0 in success */ - int (*trx_set_gains_func)(openair0_device* device, openair0_config_t *openair0_cfg); + int (*trx_set_gains_func)(openair0_device *device, openair0_config_t *openair0_cfg); /*! \brief RRU Configuration callback * \param idx RU index * \param arg pointer to capabilities or configuration */ - void (*configure_rru)(int idx, void* arg); + void (*configure_rru)(int idx, void *arg); }; /* type of device init function, implemented in shared lib */ typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg); /* type of transport init function, implemented in shared lib */ -typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params); +typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params); #ifdef __cplusplus extern "C" @@ -388,23 +391,23 @@ extern "C" #endif - /*! \brief Initialize openair RF target. It returns 0 if OK */ - int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg); - /*! \brief Initialize transport protocol . It returns 0 if OK */ - int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params); +/*! \brief Initialize openair RF target. It returns 0 if OK */ +int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg); +/*! \brief Initialize transport protocol . It returns 0 if OK */ +int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params); - - /*! \brief Get current timestamp of USRP - * \param device the hardware to use - */ - openair0_timestamp get_usrp_time(openair0_device *device); - /*! \brief Set RX frequencies - * \param device the hardware to use - * \param openair0_cfg RF frontend parameters set by application - * \returns 0 in success - */ - int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg); +/*! \brief Get current timestamp of USRP + * \param device the hardware to use + */ +openair0_timestamp get_usrp_time(openair0_device *device); + +/*! \brief Set RX frequencies + * \param device the hardware to use + * \param openair0_cfg RF frontend parameters set by application + * \returns 0 in success + */ +int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg); /*@}*/ diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c index acb4c2ec9bfb7a8a7d6708c283356842f181ecf6..2c8e55d14f0bbe43961965aeaee161627701b921 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c @@ -138,7 +138,7 @@ int eth_socket_init_raw(openair0_device *device) { return 0; } - +/* 09/03/2019: fix obvious inconsistencies, but this code hasn't be tested for sure */ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) { int bytes_sent=0; @@ -148,7 +148,12 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi //sendto_flag|=flags; eth->tx_nsamps=nsamps; - + int pktsize; + if (eth->compression == ALAW_COMPRESS) { + pktsize = RAW_PACKET_SIZE_BYTES_ALAW(nsamps); + } else { + pktsize = RAW_PACKET_SIZE_BYTES(nsamps); + } for (i=0;i<cc;i++) { /* buff[i] points to the position in tx buffer where the payload to be sent is buff2 points to the position in tx buffer where the packet header will be placed */ @@ -162,44 +167,27 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi bytes_sent = 0; memcpy(buff2,(void*)ð->ehd,MAC_HEADER_SIZE_BYTES); *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t))=1+(i<<1); - *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp; - - int sent_byte; - + *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp; /*printf("[RRU]write mod_%d %d , len %d, buff %p \n", Mod_id,eth->sockfd[Mod_id],RAW_PACKET_SIZE_BYTES(nsamps), buff2);*/ - while(bytes_sent < sent_byte) { -#if DEBUG - printf("------- TX ------: buff2 current position=%d remaining_bytes=%d bytes_sent=%d \n", - (void *)(buff2+bytes_sent), - sent_byte - bytes_sent, - bytes_sent); -#endif + while(bytes_sent < pktsize) { + /* Send packet */ bytes_sent += send(eth->sockfdd, buff2, - sent_byte, + pktsize, sendto_flag); if ( bytes_sent == -1) { eth->num_tx_errors++; perror("ETHERNET WRITE: "); exit(-1); } else { -#if DEBUG - printf("------- TX ------: nu=%x an_id=%d ts%d bytes_sent=%d\n", - *(uint8_t *)(buff2+ETH_ALEN), - *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t)), - *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)), - bytes_sent); - - dump_packet((device->host_type == RAU_HOST)? "RAU":"RRU", buff2, sent_byte, TX_FLAG); -#endif - eth->tx_actual_nsamps=bytes_sent>>2; - eth->tx_count++; + eth->tx_actual_nsamps=bytes_sent>>2; + eth->tx_count++; } } diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c index 108c4ca069e07ee71c7b3625cb5b5b8f5c9740ad..392cad2ee7af364e0a4189d8c473c75d814fac37 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/*! \file ethernet_lib.c +/*! \file ethernet_lib.c * \brief API to stream I/Q samples over standard ethernet * \author add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp * \date 2015 @@ -55,113 +55,113 @@ int dest_addr_len[MAX_INST]; int trx_eth_start(openair0_device *device) { - eth_state_t *eth = (eth_state_t*)device->priv; - - /* initialize socket */ - if (eth->flags == ETH_RAW_MODE) { - printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n"); - if (eth_socket_init_raw(device)!=0) return -1; - /* RRU gets device configuration - RAU sets device configuration*/ + eth_state_t *eth = (eth_state_t*)device->priv; - printf("Setting Timenout to 999999 usecs\n"); - if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; + /* initialize socket */ + if (eth->flags == ETH_RAW_MODE) { + printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n"); + if (eth_socket_init_raw(device)!=0) return -1; + /* RRU gets device configuration - RAU sets device configuration*/ - /* - if (device->host_type == RAU_HOST) { - if(eth_set_dev_conf_raw(device)!=0) return -1; - } else { - if(eth_get_dev_conf_raw(device)!=0) return -1; - }*/ + printf("Setting Timenout to 999999 usecs\n"); + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; - /* adjust MTU wrt number of samples per packet */ - if(eth->compression == ALAW_COMPRESS) { - if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES_ALAW(device->openair0_cfg->samples_per_packet))!=0) return -1; - } else { - if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1; - } - if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; - } else if (eth->flags == ETH_RAW_IF4p5_MODE) { + /* + if (device->host_type == RAU_HOST) { + if(eth_set_dev_conf_raw(device)!=0) return -1; + } else { + if(eth_get_dev_conf_raw(device)!=0) return -1; + }*/ - printf("Setting ETHERNET to ETH_RAW_IF4p5_MODE\n"); - if (eth_socket_init_raw(device)!=0) return -1; + /* adjust MTU wrt number of samples per packet */ + if(eth->compression == ALAW_COMPRESS) { + if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES_ALAW(device->openair0_cfg->samples_per_packet))!=0) return -1; + } else { + if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1; + } + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; + } else if (eth->flags == ETH_RAW_IF4p5_MODE) { - printf("Setting Timenout to 999999 usecs\n"); - if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; + printf("Setting ETHERNET to ETH_RAW_IF4p5_MODE\n"); + if (eth_socket_init_raw(device)!=0) return -1; - /* - if (device->host_type == RAU_HOST) { - if(eth_set_dev_conf_raw_IF4p5(device)!=0) return -1; - } else { - if(eth_get_dev_conf_raw_IF4p5(device)!=0) return -1; - } - */ + printf("Setting Timenout to 999999 usecs\n"); + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; - /* adjust MTU wrt number of samples per packet */ - if(ethernet_tune (device,MTU_SIZE,RAW_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; + /* + if (device->host_type == RAU_HOST) { + if(eth_set_dev_conf_raw_IF4p5(device)!=0) return -1; + } else { + if(eth_get_dev_conf_raw_IF4p5(device)!=0) return -1; + } + */ - if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; - } else if (eth->flags == ETH_UDP_IF4p5_MODE) { - printf("Setting ETHERNET to UDP_IF4p5_MODE\n"); - if (eth_socket_init_udp(device)!=0) return -1; + /* adjust MTU wrt number of samples per packet */ + if(ethernet_tune (device,MTU_SIZE,RAW_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; - printf("Setting Timeout to 999999 usecs\n"); - if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; + } else if (eth->flags == ETH_UDP_IF4p5_MODE) { + printf("Setting ETHERNET to UDP_IF4p5_MODE\n"); + if (eth_socket_init_udp(device)!=0) return -1; - /* - if (device->host_type == RAU_HOST) { - if(eth_set_dev_conf_udp(device)!=0) return -1; - } else { - if(eth_get_dev_conf_udp(device)!=0) return -1; - } - */ + printf("Setting Timeout to 999999 usecs\n"); + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; - /* adjust MTU wrt number of samples per packet */ - if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; - + /* + if (device->host_type == RAU_HOST) { + if(eth_set_dev_conf_udp(device)!=0) return -1; + } else { + if(eth_get_dev_conf_udp(device)!=0) return -1; + } + */ + /* adjust MTU wrt number of samples per packet */ + if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; - - } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) { - printf("Setting ETHERNET to RAW_IF5_MODE\n"); - if (eth_socket_init_raw(device)!=0) return -1; - if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; - } else { - printf("Setting ETHERNET to UDP_IF5_MODE\n"); - if (eth_socket_init_udp(device)!=0) return -1; - /* - if (device->host_type == RAU_HOST) { - if(eth_set_dev_conf_udp(device)!=0) return -1; + + } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) { + printf("Setting ETHERNET to RAW_IF5_MODE\n"); + if (eth_socket_init_raw(device)!=0) return -1; + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; + } else { - if(eth_get_dev_conf_udp(device)!=0) return -1; - }*/ + printf("Setting ETHERNET to UDP_IF5_MODE\n"); + if (eth_socket_init_udp(device)!=0) return -1; + + /* + if (device->host_type == RAU_HOST) { + if(eth_set_dev_conf_udp(device)!=0) return -1; + } else { + if(eth_get_dev_conf_udp(device)!=0) return -1; + }*/ + + /* adjust MTU wrt number of samples per packet */ + if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; + + if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; + } + /* apply additional configuration */ + if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1; + if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0) return -1; + if(ethernet_tune (device, KERNEL_SND_BUF_MAX_SIZE, 200000000)!=0) return -1; + if(ethernet_tune (device, KERNEL_RCV_BUF_MAX_SIZE, 200000000)!=0) return -1; - /* adjust MTU wrt number of samples per packet */ - if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; - - if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; - } - /* apply additional configuration */ - if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1; - if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0) return -1; - if(ethernet_tune (device, KERNEL_SND_BUF_MAX_SIZE, 200000000)!=0) return -1; - if(ethernet_tune (device, KERNEL_RCV_BUF_MAX_SIZE, 200000000)!=0) return -1; - - return 0; + return 0; } void trx_eth_end(openair0_device *device) { - eth_state_t *eth = (eth_state_t*)device->priv; - /* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */ - if ( close(eth->sockfdd) <0 ) { - perror("ETHERNET: Failed to close socket"); - exit(0); - } else { - printf("[%s] socket has been successfully closed.\n",(device->host_type == RAU_HOST)? "RAU":"RRU"); - } + eth_state_t *eth = (eth_state_t*)device->priv; + /* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */ + if ( close(eth->sockfdd) <0 ) { + perror("ETHERNET: Failed to close socket"); + exit(0); + } else { + printf("[%s] socket has been successfully closed.\n",(device->host_type == RAU_HOST)? "RAU":"RRU"); + } } @@ -187,282 +187,282 @@ int trx_eth_reset_stats(openair0_device* device) { int ethernet_tune(openair0_device *device, unsigned int option, int value) { - - eth_state_t *eth = (eth_state_t*)device->priv; - struct timeval timeout; - struct ifreq ifr; - char system_cmd[256]; - int rname[] = { CTL_NET, NET_CORE, NET_CORE_RMEM_MAX }; - int wname[] = { CTL_NET, NET_CORE, NET_CORE_WMEM_MAX }; - int namelen=3; - int newval[1]; - int newlen=sizeof(newval); - int ret=0; - // int i=0; - - /****************** socket level options ************************/ - switch(option) { - case SND_BUF_SIZE: /* transmit socket buffer size */ - if (setsockopt(eth->sockfdd, - SOL_SOCKET, - SO_SNDBUF, - &value,sizeof(value))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf("send buffer size= %d bytes\n",value); - } - break; - - case RCV_BUF_SIZE: /* receive socket buffer size */ - if (setsockopt(eth->sockfdd, - SOL_SOCKET, - SO_RCVBUF, - &value,sizeof(value))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf("receive bufffer size= %d bytes\n",value); - } - break; - - case RCV_TIMEOUT: - timeout.tv_sec = value/1000000; - timeout.tv_usec = value%1000000;//less than rt_period? - if (setsockopt(eth->sockfdc, - SOL_SOCKET, - SO_RCVTIMEO, - (char *)&timeout,sizeof(timeout))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec); - } - if (setsockopt(eth->sockfdd, - SOL_SOCKET, - SO_RCVTIMEO, - (char *)&timeout,sizeof(timeout))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec); - } - break; - - case SND_TIMEOUT: - timeout.tv_sec = value/1000000000; - timeout.tv_usec = value%1000000000;//less than rt_period? - if (setsockopt(eth->sockfdc, - SOL_SOCKET, - SO_SNDTIMEO, - (char *)&timeout,sizeof(timeout))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec); - } - if (setsockopt(eth->sockfdd, - SOL_SOCKET, - SO_SNDTIMEO, - (char *)&timeout,sizeof(timeout))) { - perror("[ETHERNET] setsockopt()"); - } else { - printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec); - } - break; - - + + eth_state_t *eth = (eth_state_t*)device->priv; + struct timeval timeout; + struct ifreq ifr; + char system_cmd[256]; + int rname[] = { CTL_NET, NET_CORE, NET_CORE_RMEM_MAX }; + int wname[] = { CTL_NET, NET_CORE, NET_CORE_WMEM_MAX }; + int namelen=3; + int newval[1]; + int newlen=sizeof(newval); + int ret=0; + // int i=0; + + /****************** socket level options ************************/ + switch(option) { + case SND_BUF_SIZE: /* transmit socket buffer size */ + if (setsockopt(eth->sockfdd, + SOL_SOCKET, + SO_SNDBUF, + &value,sizeof(value))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf("send buffer size= %d bytes\n",value); + } + break; + + case RCV_BUF_SIZE: /* receive socket buffer size */ + if (setsockopt(eth->sockfdd, + SOL_SOCKET, + SO_RCVBUF, + &value,sizeof(value))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf("receive bufffer size= %d bytes\n",value); + } + break; + + case RCV_TIMEOUT: + timeout.tv_sec = value/1000000; + timeout.tv_usec = value%1000000;//less than rt_period? + if (setsockopt(eth->sockfdc, + SOL_SOCKET, + SO_RCVTIMEO, + (char *)&timeout,sizeof(timeout))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec); + } + if (setsockopt(eth->sockfdd, + SOL_SOCKET, + SO_RCVTIMEO, + (char *)&timeout,sizeof(timeout))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec); + } + break; + + case SND_TIMEOUT: + timeout.tv_sec = value/1000000000; + timeout.tv_usec = value%1000000000;//less than rt_period? + if (setsockopt(eth->sockfdc, + SOL_SOCKET, + SO_SNDTIMEO, + (char *)&timeout,sizeof(timeout))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec); + } + if (setsockopt(eth->sockfdd, + SOL_SOCKET, + SO_SNDTIMEO, + (char *)&timeout,sizeof(timeout))) { + perror("[ETHERNET] setsockopt()"); + } else { + printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec); + } + break; + + /******************* interface level options *************************/ - case MTU_SIZE: /* change MTU of the eth interface */ - ifr.ifr_addr.sa_family = AF_INET; - strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)); - ifr.ifr_mtu =value; - if (ioctl(eth->sockfdd,SIOCSIFMTU,(caddr_t)&ifr) < 0 ) - perror ("[ETHERNET] Can't set the MTU"); - else - printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name,ifr.ifr_mtu); - break; - - case TX_Q_LEN: /* change TX queue length of eth interface */ - ifr.ifr_addr.sa_family = AF_INET; - strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)); - ifr.ifr_qlen =value; - if (ioctl(eth->sockfdd,SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 ) - perror ("[ETHERNET] Can't set the txqueuelen"); - else - printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name,ifr.ifr_qlen); - break; - + case MTU_SIZE: /* change MTU of the eth interface */ + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)); + ifr.ifr_mtu =value; + if (ioctl(eth->sockfdd,SIOCSIFMTU,(caddr_t)&ifr) < 0 ) + perror ("[ETHERNET] Can't set the MTU"); + else + printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name,ifr.ifr_mtu); + break; + + case TX_Q_LEN: /* change TX queue length of eth interface */ + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)); + ifr.ifr_qlen =value; + if (ioctl(eth->sockfdd,SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 ) + perror ("[ETHERNET] Can't set the txqueuelen"); + else + printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name,ifr.ifr_qlen); + break; + /******************* device level options *************************/ - case COALESCE_PAR: - ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs %d",eth->if_name,value); - if (ret > 0) { - ret=system(system_cmd); - if (ret == -1) { - fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); - } else { - printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret)); - } - printf("[ETHERNET] Coalesce parameters %s\n",system_cmd); - } else { - perror("[ETHERNET] Can't set coalesce parameters\n"); + case COALESCE_PAR: + ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs %d",eth->if_name,value); + if (ret > 0) { + ret=system(system_cmd); + if (ret == -1) { + fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); + } else { + printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret)); + } + printf("[ETHERNET] Coalesce parameters %s\n",system_cmd); + } else { + perror("[ETHERNET] Can't set coalesce parameters\n"); + } + break; + + case PAUSE_PAR: + if (value==1) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",eth->if_name); + else if (value==0) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg on rx on tx on",eth->if_name); + else break; + if (ret > 0) { + ret=system(system_cmd); + if (ret == -1) { + fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); + } else { + printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret)); + } + printf("[ETHERNET] Pause parameters %s\n",system_cmd); + } else { + perror("[ETHERNET] Can't set pause parameters\n"); + } + break; + + case RING_PAR: + ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s val %d",eth->if_name,value); + if (ret > 0) { + ret=system(system_cmd); + if (ret == -1) { + fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); + } else { + printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret)); + } + printf("[ETHERNET] Ring parameters %s\n",system_cmd); + } else { + perror("[ETHERNET] Can't set ring parameters\n"); + } + break; + case KERNEL_RCV_BUF_MAX_SIZE: + newval[0] = value; + ret=sysctl(rname, namelen, NULL, 0, newval, newlen); + if (ret) { + fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno)); + } else { + printf("[ETHERNET] Kernel network receive buffer max size is set to %u\n",(unsigned int)newval[0]); + } + break; + case KERNEL_SND_BUF_MAX_SIZE: + newval[0] = value; + ret=sysctl(wname, namelen, NULL, 0, newval, newlen); + if (ret) { + fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno)); + } else { + printf("[ETHERNET] Kernel network send buffer max size is set to %u\n",(unsigned int)newval[0]); + } + break; + + default: + break; } - break; - - case PAUSE_PAR: - if (value==1) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",eth->if_name); - else if (value==0) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg on rx on tx on",eth->if_name); - else break; - if (ret > 0) { - ret=system(system_cmd); - if (ret == -1) { - fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); - } else { - printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret)); - } - printf("[ETHERNET] Pause parameters %s\n",system_cmd); + + return 0; +} + + +int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) { + + eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t)); + memset(eth, 0, sizeof(eth_state_t)); + + if (eth_params->transp_preference == 1) { + eth->flags = ETH_RAW_MODE; + } else if (eth_params->transp_preference == 0) { + eth->flags = ETH_UDP_MODE; + } else if (eth_params->transp_preference == 3) { + eth->flags = ETH_RAW_IF4p5_MODE; + } else if (eth_params->transp_preference == 2) { + eth->flags = ETH_UDP_IF4p5_MODE; + } else if (eth_params->transp_preference == 4) { + eth->flags = ETH_RAW_IF5_MOBIPASS; } else { - perror("[ETHERNET] Can't set pause parameters\n"); + printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference); + eth->flags = ETH_RAW_MODE; } - break; - - case RING_PAR: - ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s val %d",eth->if_name,value); - if (ret > 0) { - ret=system(system_cmd); - if (ret == -1) { - fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno)); - } else { - printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret)); - } - printf("[ETHERNET] Ring parameters %s\n",system_cmd); + + if (eth_params->if_compress == 0) { + eth->compression = NO_COMPRESS; + } else if (eth_params->if_compress == 1) { + eth->compression = ALAW_COMPRESS; } else { - perror("[ETHERNET] Can't set ring parameters\n"); - } - break; - case KERNEL_RCV_BUF_MAX_SIZE: - newval[0] = value; - ret=sysctl(rname, namelen, NULL, 0, newval, newlen); - if (ret) { - fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno)); - } else{ - printf("[ETHERNET] Kernel network receive buffer max size is set to %u\n",newval[0]); + printf("transport_init: Unknown compression scheme %d - default to ALAW", eth_params->if_compress); + eth->compression = ALAW_COMPRESS; } - break; - case KERNEL_SND_BUF_MAX_SIZE: - newval[0] = value; - ret=sysctl(wname, namelen, NULL, 0, newval, newlen); - if (ret) { - fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno)); - } else{ - printf("[ETHERNET] Kernel network send buffer max size is set to %u\n",newval[0]); + + printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == RAU_HOST) ? "RAU": "RRU")); + device->Mod_id = 0;//num_devices_eth++; + device->transp_type = ETHERNET_TP; + device->trx_start_func = trx_eth_start; + device->trx_get_stats_func = trx_eth_get_stats; + device->trx_reset_stats_func = trx_eth_reset_stats; + device->trx_end_func = trx_eth_end; + device->trx_stop_func = trx_eth_stop; + device->trx_set_freq_func = trx_eth_set_freq; + device->trx_set_gains_func = trx_eth_set_gains; + + if (eth->flags == ETH_RAW_MODE) { + device->trx_write_func = trx_eth_write_raw; + device->trx_read_func = trx_eth_read_raw; + } else if (eth->flags == ETH_UDP_MODE) { + device->trx_write_func = trx_eth_write_udp; + device->trx_read_func = trx_eth_read_udp; + device->trx_ctlsend_func = trx_eth_ctlsend_udp; + device->trx_ctlrecv_func = trx_eth_ctlrecv_udp; + } else if (eth->flags == ETH_RAW_IF4p5_MODE) { + device->trx_write_func = trx_eth_write_raw_IF4p5; + device->trx_read_func = trx_eth_read_raw_IF4p5; + } else if (eth->flags == ETH_UDP_IF4p5_MODE) { + device->trx_write_func = trx_eth_write_udp_IF4p5; + device->trx_read_func = trx_eth_read_udp_IF4p5; + device->trx_ctlsend_func = trx_eth_ctlsend_udp; + device->trx_ctlrecv_func = trx_eth_ctlrecv_udp; + } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) { + device->trx_write_func = trx_eth_write_raw_IF4p5; + device->trx_read_func = trx_eth_read_raw_IF5_mobipass; + } else { + //device->trx_write_func = trx_eth_write_udp_IF4p5; + //device->trx_read_func = trx_eth_read_udp_IF4p5; } - break; - - default: - break; - } - - return 0; -} + eth->if_name = eth_params->local_if_name; + device->priv = eth; -int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) { + /* 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; - eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t)); - memset(eth, 0, sizeof(eth_state_t)); - - if (eth_params->transp_preference == 1) { - eth->flags = ETH_RAW_MODE; - } else if (eth_params->transp_preference == 0) { - eth->flags = ETH_UDP_MODE; - } else if (eth_params->transp_preference == 3) { - eth->flags = ETH_RAW_IF4p5_MODE; - } else if (eth_params->transp_preference == 2) { - eth->flags = ETH_UDP_IF4p5_MODE; - } else if (eth_params->transp_preference == 4) { - eth->flags = ETH_RAW_IF5_MOBIPASS; - } else { - printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference); - eth->flags = ETH_RAW_MODE; - } - - if (eth_params->if_compress == 0) { - eth->compression = NO_COMPRESS; - } else if (eth_params->if_compress == 1) { - eth->compression = ALAW_COMPRESS; - } else { - printf("transport_init: Unknown compression scheme %d - default to ALAW", eth_params->if_compress); - eth->compression = ALAW_COMPRESS; - } - - printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == RAU_HOST) ? "RAU": "RRU")); - device->Mod_id = 0;//num_devices_eth++; - device->transp_type = ETHERNET_TP; - device->trx_start_func = trx_eth_start; - device->trx_get_stats_func = trx_eth_get_stats; - device->trx_reset_stats_func = trx_eth_reset_stats; - device->trx_end_func = trx_eth_end; - device->trx_stop_func = trx_eth_stop; - device->trx_set_freq_func = trx_eth_set_freq; - device->trx_set_gains_func = trx_eth_set_gains; - - if (eth->flags == ETH_RAW_MODE) { - device->trx_write_func = trx_eth_write_raw; - device->trx_read_func = trx_eth_read_raw; - } else if (eth->flags == ETH_UDP_MODE) { - device->trx_write_func = trx_eth_write_udp; - device->trx_read_func = trx_eth_read_udp; - device->trx_ctlsend_func = trx_eth_ctlsend_udp; - device->trx_ctlrecv_func = trx_eth_ctlrecv_udp; - } else if (eth->flags == ETH_RAW_IF4p5_MODE) { - device->trx_write_func = trx_eth_write_raw_IF4p5; - device->trx_read_func = trx_eth_read_raw_IF4p5; - } else if (eth->flags == ETH_UDP_IF4p5_MODE) { - device->trx_write_func = trx_eth_write_udp_IF4p5; - device->trx_read_func = trx_eth_read_udp_IF4p5; - device->trx_ctlsend_func = trx_eth_ctlsend_udp; - device->trx_ctlrecv_func = trx_eth_ctlrecv_udp; - } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) { - device->trx_write_func = trx_eth_write_raw_IF4p5; - device->trx_read_func = trx_eth_read_raw_IF5_mobipass; - } else { - //device->trx_write_func = trx_eth_write_udp_IF4p5; - //device->trx_read_func = trx_eth_read_udp_IF4p5; - } - - 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; - } - }*/ + /* 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; + device->openair0_cfg=&openair0_cfg[0]; + return 0; } diff --git a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c index 7d23cdeb8929391659e668f60c4edf118cd01891..f12af629b7f08924e818de904c3b88346e5452ee 100644 --- a/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c +++ b/targets/ARCH/EXMIMO/USERSPACE/LIB/openair0_lib.c @@ -444,7 +444,7 @@ static void *watchdog_thread(void *arg) { (diff > 16)&& (first_acquisition==0)) {// we're too late so exit exm->watchdog_exit = 1; - printf("exiting, too late to keep up - diff = %d\n", diff); + printf("exiting, too late to keep up - diff = %u\n", diff); } first_acquisition=0; @@ -625,7 +625,7 @@ int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, voi if (cfg->mmapped_dma == 0) { // if buff is not the dma buffer, do a memcpy, otherwise do nothing for (i=0;i<cc;i++) { #ifdef DEBUG_EXMIMO - printf("copying to %p (%lu), from %llu\n",buff[i]+(ntot*sizeof(int)),ntot*sizeof(int),(exm->last_ts_rx % exm->samples_per_frame)); + printf("copying to %p (%zu), from %llu\n",buff[i]+(ntot*sizeof(int)),ntot*sizeof(int),(exm->last_ts_rx % exm->samples_per_frame)); #endif if ((n+(exm->last_ts_rx%exm->samples_per_frame))<exm->samples_per_frame) { memcpy(buff[i]+(ntot*sizeof(int)), @@ -733,7 +733,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { if (ret == -3) printf("Error mapping RX or TX buffer"); - + free(exm); return(ret); } @@ -752,6 +752,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { // check if the software matches firmware if (p_exmimo_id->board_swrev!=BOARD_SWREV_CNTL2) { printf("Software revision %d and firmware revision %d do not match. Please update either the firmware or the software!\n",BOARD_SWREV_CNTL2,p_exmimo_id->board_swrev); + free(exm); return(-1); } } @@ -905,7 +906,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) p_exmimo_config->rf.rx_gain[ant][0] = 30 - (rxg_max[ant] - (int)openair0_cfg[card].rx_gain[ant]); //was measured at rxgain=30; } else { - printf("openair0: RX RF gain too high, reduce by %d dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_max[ant]); + printf("openair0: RX RF gain too high, reduce by %u dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_max[ant]); exit(-1); } break; @@ -916,7 +917,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) p_exmimo_config->rf.rx_gain[ant][0] = 30 - (rxg_med[ant] - (int)openair0_cfg[card].rx_gain[ant]); //was measured at rxgain=30; } else { - printf("openair0: RX RF gain too high, reduce by %d dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_med[ant]); + printf("openair0: RX RF gain too high, reduce by %u dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_med[ant]); exit(-1); } break; @@ -927,7 +928,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag) p_exmimo_config->rf.rx_gain[ant][0] = 30 - (rxg_byp[ant] - (int)openair0_cfg[card].rx_gain[ant]); //was measured at rxgain=30; } else { - printf("openair0: RX RF gain too high, reduce by %d dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_byp[ant]); + printf("openair0: RX RF gain too high, reduce by %u dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_byp[ant]); exit(-1); } break; diff --git a/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw.c b/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw.c index 1b2445fa72e512cb290a12ab3ebf80c97c3ab138..febf221c5be715a6be12a7d89cbf0f98c737e94f 100644 --- a/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw.c +++ b/targets/ARCH/EXMIMO/USERSPACE/OAI_FW_INIT/updatefw.c @@ -211,22 +211,25 @@ void find_and_transfer_section(char* section_name, unsigned int verboselevel) { int nbread; unsigned int secnb = 0; + if(p_elfimage == NULL) { + fprintf(stderr, "%s %d:Error, firmware file not opened\n",__FILE__,__LINE__); + } for (secnb = 0 ; secnb < elf_Ehdr.e_shnum; secnb++) { get_elf_section_header(&elf_Shdr, p_elfimage, secnb); if (!strcmp(SecNameStnTable + elf_Shdr.sh_name, section_name)) { if (verboselevel >= VERBOSE_LEVEL_SECTION_DETAILS) - printf("Info: ok, found section %s (as section nb. %d)\n", SecNameStnTable + elf_Shdr.sh_name, secnb); + printf("Info: ok, found section %s (as section nb. %u)\n", SecNameStnTable + elf_Shdr.sh_name, secnb); /* Check that section size is a multiple of 4 bytes. */ if (elf_Shdr.sh_size % 4) { - fprintf(stderr, "Error: section %s has a non-multiple-of-4-bytes size (%d).\n", - SecNameStnTable + elf_Shdr.sh_name, elf_Shdr.sh_size); + fprintf(stderr, "Error: section %s has a non-multiple-of-4-bytes size (%lu).\n", + SecNameStnTable + elf_Shdr.sh_name, (unsigned long)elf_Shdr.sh_size); fclose(p_elfimage); exit(-1); } else if (verboselevel >= VERBOSE_LEVEL_SECTION_DETAILS) { - printf("Info: ok, section %s has size %d bytes (multiple of 4 bytes).\n", - SecNameStnTable + elf_Shdr.sh_name, elf_Shdr.sh_size); + printf("Info: ok, section %s has size %lu bytes (multiple of 4 bytes).\n", + SecNameStnTable + elf_Shdr.sh_name, (unsigned long)elf_Shdr.sh_size); } /* Dynamically allocate a chunk of memory to store the section into. */ @@ -245,13 +248,13 @@ void find_and_transfer_section(char* section_name, unsigned int verboselevel) { } if (!section_content) { - fprintf(stderr, "Error: could not dynamically allocate %d bytes for section %s.\n", - elf_Shdr.sh_size, SecNameStnTable + elf_Shdr.sh_name); + fprintf(stderr, "Error: could not dynamically allocate %lu bytes for section %s.\n", + (unsigned long)elf_Shdr.sh_size, (SecNameStnTable + elf_Shdr.sh_name)); fclose(p_elfimage); exit(-1); } else if (verboselevel >= VERBOSE_LEVEL_IOCTL) { - printf("Info: ok, dynamically allocated a %d bytes buffer for section %s.\n", - elf_Shdr.sh_size, SecNameStnTable + elf_Shdr.sh_name); + printf("Info: ok, dynamically allocated a %lu bytes buffer for section %s.\n", + (unsigned long)elf_Shdr.sh_size, SecNameStnTable + elf_Shdr.sh_name); } /* Position the file cursor at the begining of proper section. */ @@ -260,13 +263,13 @@ void find_and_transfer_section(char* section_name, unsigned int verboselevel) { nbread = fread(section_content, elf_Shdr.sh_size, 1, p_elfimage); if (nbread != 1) { - fprintf(stderr, "Error: could not read %d bytes from ELF file into dynamic buffer.\n", elf_Shdr.sh_size); + fprintf(stderr, "Error: could not read %lu bytes from ELF file into dynamic buffer.\n", (unsigned long)elf_Shdr.sh_size); free(section_content); fclose(p_elfimage); exit(-1); } else if (verboselevel >= VERBOSE_LEVEL_IOCTL) { - printf("Info: ok, copied content of section %s into dynamic buffer (%d bytes copied).\n", - SecNameStnTable + elf_Shdr.sh_name, elf_Shdr.sh_size); + printf("Info: ok, copied content of section %s into dynamic buffer (%lu bytes copied).\n", + SecNameStnTable + elf_Shdr.sh_name, (unsigned long)elf_Shdr.sh_size); } /* Open the special device file. */ @@ -324,12 +327,15 @@ void find_and_clear_section_bss(unsigned int verboselevel) { int ifile; unsigned int secnb = 0; + if(p_elfimage == NULL) { + fprintf(stderr, "%s %d:Error, firmware file not opened\n",__FILE__,__LINE__); + } for (secnb = 0 ; secnb < elf_Ehdr.e_shnum; secnb++) { get_elf_section_header(&elf_Shdr, p_elfimage, secnb); if (!strcmp(SecNameStnTable + elf_Shdr.sh_name, ".bss")) { if (verboselevel >= VERBOSE_LEVEL_SECTION_DETAILS) - printf("Info: ok, found section %s (as section nb. %d)\n", SecNameStnTable + elf_Shdr.sh_name, secnb); + printf("Info: ok, found section %s (as section nb. %u)\n", SecNameStnTable + elf_Shdr.sh_name, secnb); /* Open the special device file. */ if (!pflag) { @@ -491,6 +497,10 @@ int main(int argc, char** argv) { /* Open firmware file in READ_ONLY mode. */ filename = p_str_fwn; + if (filename == NULL) { + fprintf(stderr, "%s %d: No filename specified\n", __FILE__, __LINE__); + exit(-1); + } p_elfimage = fopen(filename, READ_FILE_MODE); if (p_elfimage == NULL) { @@ -505,6 +515,7 @@ int main(int argc, char** argv) { /* Get informations from header file */ if (!(get_elf_header(&elf_Ehdr, p_elfimage))) { fprintf(stderr, "Error : file doesn't match expected format.\n"); + fclose(p_elfimage); exit(-1); } @@ -522,9 +533,10 @@ int main(int argc, char** argv) { /* copy the string table into global variable */ if (StringSec_size > MAX_SIZE_STRING_TABLE) { - fprintf(stderr, "Error: section name string table too big (%d > %d);" + fprintf(stderr, "Error: section name string table too big (%ld > %d);" " increase max. allowed value in source code and recompile\n", StringSec_size, MAX_SIZE_STRING_TABLE); + fclose(p_elfimage); exit(-1); } @@ -626,7 +638,7 @@ int main(int argc, char** argv) { if (verboselevel >= VERBOSE_LEVEL_MAIN_STEPS) printf("Info: entering action #5 (Jump to firmware/set stack-pointer).\n"); if (verboselevel >= VERBOSE_LEVEL_SECTION_DETAILS) - printf("Info: Firmware entry point = 0x%08x, setting stack pointer = 0x%08x.\n", elf_Ehdr.e_entry, stackpointer); + printf("Info: Firmware entry point = 0x%08x, setting stack pointer = 0x%08x.\n", (unsigned int)elf_Ehdr.e_entry, stackpointer); /* Open the special device file. */ if (!pflag) { diff --git a/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/oarf_send_frame.cc b/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/oarf_send_frame.cc index 1ebe3aeb4e306784f25d5d5f9430f2a495d9628c..8874b22c5ee4d57509c8213da293359d92d485eb 100644 --- a/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/oarf_send_frame.cc +++ b/targets/ARCH/EXMIMO/USERSPACE/OCTAVE/oarf_send_frame.cc @@ -116,7 +116,7 @@ DEFUN_DLD (oarf_send_frame, args, nargout,"Send frame") for (i=0;i<4;i++) { resampling_factor[i] = (openair0_exmimo_pci[card].exmimo_config_ptr)->framing.resampling_factor[i]; - printf("card %d, ant %d, resampling %d\n",card,i,resampling_factor[i]); + printf("card %d, ant %d, resampling %u\n",card,i,resampling_factor[i]); } for (i=0;i<numcols;i++){ diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc b/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc index 79d0a5b7a8447b457cbdc8255e6db434bba76045..b79e3cec746031f7e72e56af734d170bb0ce7da7 100644 --- a/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc +++ b/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc @@ -1,4 +1,3 @@ IRIS_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.o IRIS_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp IRIS_CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON - diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp index 7abdf65498acf4c4eff9064481b2961f4ec07fe1..5b20d8a8c71be4ba9ea850ff25474e1d8798abd8 100644 --- a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp +++ b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp @@ -35,7 +35,8 @@ #define SAMPLE_RATE_DOWN 1 /*! \brief Iris Configuration */ -typedef struct { +extern "C" { + typedef struct { // -------------------------------- // variables for Iris configuration @@ -78,8 +79,8 @@ typedef struct { //! timestamp of RX packet openair0_timestamp rx_timestamp; -} iris_state_t; - + } iris_state_t; +} /*! \brief Called to start the Iris lime transceiver. Return 0 if OK, < 0 if error @param device pointer to the device structure specific to the RF hardware target */ @@ -151,13 +152,15 @@ trx_iris_write(openair0_device *device, openair0_timestamp timestamp, void **buf iris_state_t *s = (iris_state_t *) device->priv; int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) -#ifdef __AVX2__ + #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; __m256i buff_tx[2][nsamps2]; -#else + #else nsamps2 = (nsamps+3)>>2; __m128i buff_tx[2][nsamps2]; -#endif + #endif +#else + #error unsupported CPU architecture, iris device cannot be built #endif // bring RX data into 12 LSBs for softmodem RX @@ -332,8 +335,8 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp ((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4); #else ((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4); -#endif -#endif +#endif +#endif } } } @@ -531,7 +534,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { args["driver"] = "iris"; char *iris_addrs = device->openair0_cfg[0].sdr_addrs; if (iris_addrs == NULL) - { + { s->iris.push_back(SoapySDR::Device::make(args)); } else @@ -692,20 +695,20 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { } - + printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate() / 1e6)); int tx_filt_bw = openair0_cfg[0].tx_bw; int rx_filt_bw = openair0_cfg[0].rx_bw; #ifdef MOVE_DC //the filter is centered around the carrier, so we have to expand it if we have moved the DC tone. - tx_filt_bw *= 3; - rx_filt_bw *= 3; + tx_filt_bw *= 3; + rx_filt_bw *= 3; #endif /* Setting TX/RX BW */ for (i = 0; i < s->tx_num_channels; i++) { if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) { s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, tx_filt_bw); - printf("Setting tx bandwidth on channel %lu/%lu: BW %f (readback %f)\n", i, + printf("Setting tx bandwidth on channel %zu/%lu: BW %f (readback %f)\n", i, s->iris[r]->getNumChannels(SOAPY_SDR_TX), tx_filt_bw / 1e6, s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6); } @@ -713,7 +716,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { for (i = 0; i < s->rx_num_channels; i++) { if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) { s->iris[r]->setBandwidth(SOAPY_SDR_RX, i, rx_filt_bw); - printf("Setting rx bandwidth on channel %lu/%lu : BW %f (readback %f)\n", i, + printf("Setting rx bandwidth on channel %zu/%lu : BW %f (readback %f)\n", i, s->iris[r]->getNumChannels(SOAPY_SDR_RX), rx_filt_bw / 1e6, s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6); } @@ -776,7 +779,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { std::cout << "Front end detected: " << s->iris[r]->getHardwareInfo()["frontend"] << "\n"; for (i = 0; i < s->rx_num_channels; i++) { if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) { - printf("RX Channel %lu\n", i); + printf("RX Channel %zu\n", i); printf("Actual RX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_RX, i) / 1e6)); printf("Actual RX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_RX, i) / 1e9)); printf("Actual RX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i))); @@ -794,7 +797,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { for (i = 0; i < s->tx_num_channels; i++) { if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) { - printf("TX Channel %lu\n", i); + printf("TX Channel %zu\n", i); printf("Actual TX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_TX, i) / 1e6)); printf("Actual TX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_TX, i) / 1e9)); printf("Actual TX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i))); @@ -845,8 +848,3 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { } } /*@}*/ - - - - - diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 563e3755b78d712729a37bcd3787046400aadd72..df4cc2ff02585274d5bcfc269c27738fddeb4e87 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -28,7 +28,12 @@ #include <pthread.h> #include <unistd.h> #include <stdio.h> +#include <uhd/version.hpp> +#if UHD_VERSION < 3110000 #include <uhd/utils/thread_priority.hpp> +#else +#include <uhd/utils/thread.hpp> +#endif #include <uhd/usrp/multi_usrp.hpp> #include <uhd/version.hpp> #include <boost/lexical_cast.hpp> @@ -183,7 +188,7 @@ static int sync_to_gps(openair0_device *device) { num_gps_locked++; std::cout << boost::format("GPS Locked\n"); } else { - std::cerr << "WARNING: GPS not locked - time will not be accurate until locked" << std::endl; + LOG_W(HW,"WARNING: GPS not locked - time will not be accurate until locked\n"); } //Set to GPS time @@ -438,16 +443,18 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, int nsamps2; // aligned to upper 32 or 16 byte boundary #if defined(__x86_64) || defined(__i386__) -#ifdef __AVX2__ - nsamps2 = (nsamps+7)>>3; - __m256i buff_tx[2][nsamps2]; -#else + #ifdef __AVX2__ + nsamps2 = (nsamps+7)>>3; + __m256i buff_tx[2][nsamps2]; + #else nsamps2 = (nsamps+3)>>2; __m128i buff_tx[2][nsamps2]; -#endif + #endif #elif defined(__arm__) nsamps2 = (nsamps+3)>>2; int16x8_t buff_tx[2][nsamps2]; +#else + #error Unsupported CPU architecture, USRP device cannot be built #endif // bring RX data into 12 LSBs for softmodem RX @@ -722,6 +729,7 @@ void *freq_thread(void *arg) { usrp_state_t *s = (usrp_state_t *)device->priv; s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]); s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]); + return NULL; } /*! \brief Set frequencies (TX/RX). Spawns a thread to handle the frequency change to not block the calling thread * \param device the hardware to use @@ -1071,16 +1079,16 @@ extern "C" { uhd::device_addrs_t device_adds = uhd::device::find(args); if (device_adds.size() == 0) { - std::cerr<<"No USRP Device Found. " << std::endl; + LOG_E(HW,"No USRP Device Found.\n "); free(s); return -1; } else if (device_adds.size() > 1) { - std::cerr<<"More than one USRP Device Found. Please specify device more precisely in config file." << std::endl; + LOG_E(HW,"More than one USRP Device Found. Please specify device more precisely in config file.\n"); free(s); return -1; } - std::cerr << "Found USRP " << device_adds[0].get("type") << "\n"; + LOG_I(HW,"Found USRP %s\n", device_adds[0].get("type").c_str()); double usrp_master_clock; if (device_adds[0].get("type") == "b200") { @@ -1088,7 +1096,7 @@ extern "C" { device->type = USRP_B200_DEV; usrp_master_clock = 30.72e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); - args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ; + args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=7680, recv_frame_size=7680" ; } if (device_adds[0].get("type") == "n3xx") { @@ -1285,8 +1293,9 @@ extern "C" { samples/=10000; LOG_I(PHY,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples); - if ( samples < max ) + if ( samples < max ) { stream_args_rx.args["spp"] = str(boost::format("%d") % samples ); + } LOG_I(PHY,"rx_max_num_samps %zu\n", s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); diff --git a/targets/ARCH/rfsimulator/README.md b/targets/ARCH/rfsimulator/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ebe7d72ee05860907e1c3b5315bb84270d0879b6 --- /dev/null +++ b/targets/ARCH/rfsimulator/README.md @@ -0,0 +1,71 @@ +## General + +This is a RF simulator that allows to test OAI without a RF board. +It replaces a actual RF board driver. + +As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound) + +## build + + No specific build is required, use the [oai softmodem build procedure](../../../doc/BUILD.md) + +After any regular build, you can compile the driver +```bash +cd <the_compilation_dir_from_bouild_oai_script>/build +make rfsimulator +``` +Then, you can use it freely + +# Usage +Setting the env variable RFSIMULATOR enables the RF board simulator +It should the set to "enb" in the eNB + +## 4G case +For the UE, it should be set to the IP address of the eNB +example: + +```bash +sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50 --rfsim +``` +For the eNodeB, use a valid configuration file setup for USRP board tests and start the softmodem as usual, but adding the `--rfsim` option. + + + +```bash +sudo RFSIMULATOR=enb ./lte-softmodem -O <config file> --rfsim +``` + + + +Except this, the UE and the eNB can be used as it the RF is real + +If you reach 'RA not active' on UE, be careful to generate a valid SIM +```bash +$OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o . +``` +This simulator can also be used with the `--noS1` option, in this case you must run the eNodeB and the UE on different PCs. + +## 5G case + +After regular build, add the simulation driver +(don't use ./build_oai -w SIMU until we merge 4G and 5G branches) +```bash +cd ran_build/build +make rfsimulator +``` +### Launch gNB in one window +```bash +sudo RFSIMULATOR=enb ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD +``` +### Launch UE in another window +```bash +sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000 +``` +Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine +In UE, you can add "-d" to get the softscope + +## Caveacts + +Still issues in power control: txgain, rxgain are not used + + diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c new file mode 100644 index 0000000000000000000000000000000000000000..a17327b03ecc5791cadc7cef76fbecc9d3205da8 --- /dev/null +++ b/targets/ARCH/rfsimulator/simulator.c @@ -0,0 +1,475 @@ +/* + Author: Laurent THOMAS, Open Cells for Nokia + copyleft: OpenAirInterface Software Alliance and it's licence +*/ + +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <arpa/inet.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdbool.h> +#include <errno.h> +#include <sys/epoll.h> +#include <string.h> + +#include <common/utils/assertions.h> +#include <common/utils/LOG/log.h> +#include "common_lib.h" +#include <openair1/PHY/defs_eNB.h> +#include "openair1/PHY/defs_UE.h" + +#define PORT 4043 //TCP port for this simulator +#define CirSize 3072000 // 100ms is enough +#define sample_t uint32_t // 2*16 bits complex number +#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t)) +#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b))) +#define MAGICeNB 0xA5A5A5A5A5A5A5A5 +#define MAGICUE 0x5A5A5A5A5A5A5A5A + +typedef struct { + uint64_t magic; + uint32_t size; + uint32_t nbAnt; + uint64_t timestamp; +} transferHeader; + +typedef struct buffer_s { + int conn_sock; + bool alreadyRead; + uint64_t lastReceivedTS; + bool headerMode; + transferHeader th; + char *transferPtr; + uint64_t remainToTransfer; + char *circularBufEnd; + sample_t *circularBuf; +} buffer_t; + +typedef struct { + int listen_sock, epollfd; + uint64_t nextTimestamp; + uint64_t typeStamp; + uint64_t initialAhead; + char *ip; + buffer_t buf[FD_SETSIZE]; +} rfsimulator_state_t; + +void allocCirBuf(rfsimulator_state_t *bridge, int sock) { + buffer_t *ptr=&bridge->buf[sock]; + AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, ""); + ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1); + ptr->conn_sock=sock; + ptr->headerMode=true; + ptr->transferPtr=(char *)&ptr->th; + ptr->remainToTransfer=sizeof(transferHeader); + int sendbuff=1000*1000*10; + AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, ""); + struct epoll_event ev= {0}; + ev.events = EPOLLIN | EPOLLRDHUP; + ev.data.fd = sock; + AssertFatal(epoll_ctl(bridge->epollfd, EPOLL_CTL_ADD, sock, &ev) != -1, ""); +} + +void removeCirBuf(rfsimulator_state_t *bridge, int sock) { + AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, ""); + close(sock); + free(bridge->buf[sock].circularBuf); + memset(&bridge->buf[sock], 0, sizeof(buffer_t)); + bridge->buf[sock].conn_sock=-1; +} + +void socketError(rfsimulator_state_t *bridge, int sock) { + if (bridge->buf[sock].conn_sock!=-1) { + LOG_W(HW,"Lost socket \n"); + removeCirBuf(bridge, sock); + + if (bridge->typeStamp==MAGICUE) + exit(1); + } +} + + +#define helpTxt "\ +\x1b[31m\ +rfsimulator: error: you have to run one UE and one eNB\n\ +For this, export RFSIMULATOR=enb (eNB case) or \n\ + RFSIMULATOR=<an ip address> (UE case)\n\ +\x1b[m" + +enum blocking_t { + notBlocking, + blocking +}; + +void setblocking(int sock, enum blocking_t active) { + int opts; + AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,""); + + if (active==blocking) + opts = opts & ~O_NONBLOCK; + else + opts = opts | O_NONBLOCK; + + AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, ""); +} + +static bool flushInput(rfsimulator_state_t *t); + +void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { + char *buf = _buf; + int l; + setblocking(fd, notBlocking); + + while (count) { + l = write(fd, buf, count); + + if (l <= 0) { + if (errno==EINTR) + continue; + + if(errno==EAGAIN) { + flushInput(t); + continue; + } else + return; + } + + count -= l; + buf += l; + } +} + +int server_start(openair0_device *device) { + rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; + t->typeStamp=MAGICeNB; + AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); + int enable = 1; + AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, ""); + struct sockaddr_in addr = { +sin_family: + AF_INET, +sin_port: + htons(PORT), +sin_addr: + { s_addr: INADDR_ANY } + }; + bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr)); + AssertFatal(listen(t->listen_sock, 5) == 0, ""); + struct epoll_event ev; + ev.events = EPOLLIN; + ev.data.fd = t->listen_sock; + AssertFatal(epoll_ctl(t->epollfd, EPOLL_CTL_ADD, t->listen_sock, &ev) != -1, ""); + return 0; +} + +int start_ue(openair0_device *device) { + rfsimulator_state_t *t = device->priv; + t->typeStamp=MAGICUE; + int sock; + AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); + struct sockaddr_in addr = { +sin_family: + AF_INET, +sin_port: + htons(PORT), +sin_addr: + { s_addr: INADDR_ANY } + }; + addr.sin_addr.s_addr = inet_addr(t->ip); + bool connected=false; + + while(!connected) { + LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", t->ip, PORT); + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + LOG_I(HW,"rfsimulator: connection established\n"); + connected=true; + } + + perror("rfsimulator"); + sleep(1); + } + + setblocking(sock, notBlocking); + allocCirBuf(t, sock); + t->buf[sock].alreadyRead=true; // UE will start blocking on read + return 0; +} + +int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) { + rfsimulator_state_t *t = device->priv; + + for (int i=0; i<FD_SETSIZE; i++) { + buffer_t *ptr=&t->buf[i]; + + if (ptr->conn_sock >= 0 ) { + transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp}; + fullwrite(ptr->conn_sock,&header, sizeof(header), t); + sample_t tmpSamples[nsamps][nbAnt]; + + 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]; + } + + if (ptr->conn_sock >= 0 ) + fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t); + } + } + + LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n", + nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) ); + return nsamps; +} + +static bool flushInput(rfsimulator_state_t *t) { + // Process all incoming events on sockets + // store the data in lists + struct epoll_event events[FD_SETSIZE]= {0}; + int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 200); + + if ( nfds==-1 ) { + if ( errno==EINTR || errno==EAGAIN ) + return false; + else + AssertFatal(false,"error in epoll_wait\n"); + } + + for (int nbEv = 0; nbEv < nfds; ++nbEv) { + int fd=events[nbEv].data.fd; + + if (events[nbEv].events & EPOLLIN && fd == t->listen_sock) { + int conn_sock; + AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, ""); + setblocking(conn_sock, notBlocking); + allocCirBuf(t, conn_sock); + LOG_I(HW,"A ue connected\n"); + } else { + if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) { + socketError(t,fd); + continue; + } + + buffer_t *b=&t->buf[fd]; + + if ( b->circularBuf == NULL ) { + LOG_E(HW, "received data on not connected socket %d\n", events[nbEv].data.fd); + continue; + } + + int blockSz; + + if ( b->headerMode) + blockSz=b->remainToTransfer; + else + blockSz= b->transferPtr+b->remainToTransfer < b->circularBufEnd ? + b->remainToTransfer : + b->circularBufEnd - 1 - b->transferPtr ; + + int sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT); + + if ( sz < 0 ) { + if ( errno != EAGAIN ) { + LOG_E(HW,"socket failed %s\n", strerror(errno)); + abort(); + } + } else if ( sz == 0 ) + continue; + + AssertFatal((b->remainToTransfer-=sz) >= 0, ""); + b->transferPtr+=sz; + + if (b->transferPtr==b->circularBufEnd - 1) + b->transferPtr=(char *)b->circularBuf; + + // check the header and start block transfer + if ( b->headerMode==true && b->remainToTransfer==0) { + AssertFatal( (t->typeStamp == MAGICUE && b->th.magic==MAGICeNB) || + (t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol"); + b->headerMode=false; + b->alreadyRead=true; + + if ( b->lastReceivedTS != b->th.timestamp) { + int nbAnt= b->th.nbAnt; + + for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) + for (int a=0; a < nbAnt; a++) + b->circularBuf[(index*nbAnt+a)%CirSize]=0; + + LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS ); + } + + b->lastReceivedTS=b->th.timestamp; + b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize]; + b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt); + } + + if ( b->headerMode==false ) { + b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt); + + if ( b->remainToTransfer==0) { + LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS); + + // First block in UE, resync with the eNB current TS + if ( t->nextTimestamp == 0 ) + t->nextTimestamp=b->lastReceivedTS-b->th.size; + + b->headerMode=true; + b->transferPtr=(char *)&b->th; + b->remainToTransfer=sizeof(transferHeader); + b->th.magic=-1; + } + } + } + } + + return nfds>0; +} + +int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { + if (nbAnt != 1) { + LOG_E(HW, "rfsimulator: only 1 antenna tested\n"); + exit(1); + } + + rfsimulator_state_t *t = device->priv; + LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps); + // deliver data from received data + // check if a UE is connected + int first_sock; + + for (first_sock=0; first_sock<FD_SETSIZE; first_sock++) + if (t->buf[first_sock].circularBuf != NULL ) + break; + + if ( first_sock == FD_SETSIZE ) { + // no connected device (we are eNB, no UE is connected) + if (!flushInput(t)) { + for (int x=0; x < nbAnt; x++) + memset(samplesVoid[x],0,sampleToByte(nsamps,1)); + + t->nextTimestamp+=nsamps; + LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp); + *ptimestamp = t->nextTimestamp-nsamps; + return nsamps; + } + } else { + bool have_to_wait; + + do { + have_to_wait=false; + + for ( int sock=0; sock<FD_SETSIZE; sock++) + if ( t->buf[sock].circularBuf && + t->buf[sock].alreadyRead && //>= t->initialAhead && + (t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) { + have_to_wait=true; + break; + } + + if (have_to_wait) + /*printf("Waiting on socket, current last ts: %ld, expected at least : %ld\n", + ptr->lastReceivedTS, + t->nextTimestamp+nsamps); + */ + flushInput(t); + } while (have_to_wait); + } + + // Clear the output buffer + for (int a=0; a<nbAnt; a++) + memset(samplesVoid[a],0,sampleToByte(nsamps,1)); + + // Add all input signal in the output buffer + for (int sock=0; sock<FD_SETSIZE; sock++) { + buffer_t *ptr=&t->buf[sock]; + + if ( ptr->circularBuf && ptr->alreadyRead ) { + for (int a=0; a<nbAnt; a++) { + sample_t *out=(sample_t *)samplesVoid[a]; + + for ( int i=0; i < nsamps; i++ ) + out[i]+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize]<<1; + } + } + } + + *ptimestamp = t->nextTimestamp; // return the time of the first sample + t->nextTimestamp+=nsamps; + LOG_D(HW,"Rx to upper layer: %d from %ld to %ld, energy in first antenna %d\n", + nsamps, + *ptimestamp, t->nextTimestamp, + signal_energy(samplesVoid[0], nsamps)); + return nsamps; +} + + +int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) { + abort(); + return 0; +} +int rfsimulator_reply(openair0_device *device, void *msg, ssize_t msg_len) { + abort(); + return 0; +} +int rfsimulator_get_stats(openair0_device *device) { + return 0; +} +int rfsimulator_reset_stats(openair0_device *device) { + return 0; +} +void rfsimulator_end(openair0_device *device) {} +int rfsimulator_stop(openair0_device *device) { + return 0; +} +int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { + return 0; +} +int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { + return 0; +} + + +__attribute__((__visibility__("default"))) +int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { + //set_log(HW,OAILOG_DEBUG); + rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); + + if ((rfsimulator->ip=getenv("RFSIMULATOR")) == NULL ) { + LOG_E(HW,helpTxt); + exit(1); + } + + rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ? + MAGICeNB: + MAGICUE; + LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE"); + device->trx_start_func = rfsimulator->typeStamp == MAGICeNB ? + server_start : + start_ue; + device->trx_get_stats_func = rfsimulator_get_stats; + device->trx_reset_stats_func = rfsimulator_reset_stats; + device->trx_end_func = rfsimulator_end; + device->trx_stop_func = rfsimulator_stop; + device->trx_set_freq_func = rfsimulator_set_freq; + device->trx_set_gains_func = rfsimulator_set_gains; + device->trx_write_func = rfsimulator_write; + device->trx_read_func = rfsimulator_read; + /* let's pretend to be a b2x0 */ + device->type = USRP_B200_DEV; + device->openair0_cfg=&openair0_cfg[0]; + device->priv = rfsimulator; + + for (int i=0; i<FD_SETSIZE; i++) + rfsimulator->buf[i].conn_sock=-1; + + AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,""); + rfsimulator->initialAhead=openair0_cfg[0].sample_rate/1000; // One sub frame + return 0; +} diff --git a/targets/COMMON/MESSAGES/V2/flexsplit.proto b/targets/COMMON/MESSAGES/V2/flexsplit.proto new file mode 100644 index 0000000000000000000000000000000000000000..39f1656980a7da0bcda1df2d34a461a6c1df0705 --- /dev/null +++ b/targets/COMMON/MESSAGES/V2/flexsplit.proto @@ -0,0 +1,163 @@ +package protocol; + + +message fsp_header { + optional uint32 version = 1; + optional uint32 type = 2; + optional uint32 xid = 4; +} + +enum fsp_type { + // Discovery and maintenance messages + FSPT_HELLO = 0; + FSPT_ECHO_REQUEST = 1; + FSPT_ECHO_REPLY = 2; + FSPT_RLC_DATA_REQ = 3; + FSPT_RLC_DATA_REQ_ACK = 4; + FSPT_PDCP_DATA_IND = 5; + FSPT_PDCP_DATA_IND_ACK = 6; +} + +enum f1u_type { + // Discovery and maintenance messages + F1U_DL_DATA = 0; + F1U_DL_STATUS = 1; +} + + +message f1u_message{ + optional flexsplit_direction msg_dir = 100; + oneof msg{ + dl_user_data dl_data = 1; + dl_data_delivery_status dl_status = 2; + } +} + + + +message flexsplit_message { + optional flexsplit_direction msg_dir = 100; + oneof msg { + fsp_hello hello_msg = 1; + fsp_echo_request echo_request_msg = 2; + fsp_echo_reply echo_reply_msg = 3; + fspRlcDataReq data_req_msg = 4; + fspRlcDataReqAck data_req_ack = 5; + fspPdcpDataInd data_ind_msg = 6; + fspPdcpDataIndAck data_ind_ack = 7; + } +} + +enum flexsplit_direction { + //option allow_alias = true; + NOT_SET = 0; + INITIATING_MESSAGE = 1; + SUCCESSFUL_OUTCOME=2; + UNSUCCESSFUL_OUTCOME=3; +} + +enum flexsplit_err { + // message errors + NO_ERR = 0; + MSG_DEQUEUING = -1; + MSG_ENQUEUING = -2; + MSG_DECODING = -3; + MSG_ENCODING = -4; + MSG_BUILD = -5; + MSG_NOT_SUPPORTED = -6; + MSG_NOT_HANDLED = -7; + MSG_NOT_VALIDATED = -8; + MSG_OUT_DATED = -9; + + // other erros + UNEXPECTED = -100; +} + +message fsp_ctxt { + optional uint32 fsp_mod_id = 1; + optional bool fsp_enb_flag = 2; + optional uint32 fsp_instance = 3; + optional uint32 fsp_rnti = 4; + optional uint32 fsp_frame = 5; + optional uint32 fsp_subframe = 6; + optional uint32 fsp_eNB_index = 7; + +} + +message fspRlcPdu { + optional bytes fsp_pdu_data = 1; // Maximum PDU to be transfered +} + +message fspRlcData { + optional fsp_ctxt fsp_ctxt = 1; + optional bool fsp_srb_flag = 2; + optional bool fsp_mbms_flag = 3; + optional uint32 fsp_rb_id = 4; + optional uint32 fsp_muip = 5; + optional uint32 fsp_confirm = 6; + optional int32 fsp_sdu_buffer_size = 7; + optional fspRlcPdu fsp_pdu = 8; +} + +// +// Maintenance and discovery messages +// + +message fsp_hello { + optional fsp_header header = 1; +} + +message fsp_echo_request { + optional fsp_header header = 1; +// extensions 100 to 199; +} + + +message fsp_echo_reply { + optional fsp_header header = 1; +// extensions 100 to 199; +} + + +message fspRlcDataReq { + optional fsp_header header = 1; + optional uint32 eNB_id = 2; + optional fspRlcData pdcp_data = 3; +} + +message fspRlcDataReqAck { + optional fsp_header header = 1; + optional uint32 result = 2; +} + +message fspPdcpDataInd { + optional fsp_header header = 1; + optional uint32 eNB_id = 2; + optional fspRlcData rlc_data = 3; +} + +message fspPdcpDataIndAck { + optional fsp_header header = 1; + optional uint32 result = 2; +} + +message dl_data_header { + required uint32 fields = 1; +} + +message dl_user_data { + required dl_data_header header = 1; + required bytes pdu = 2; + required uint32 frame = 3; + required uint32 subframe = 4; + required uint32 rnti = 5; +} + + +message dl_data_delivery_status { + required dl_data_header header = 1; + required bytes pdu = 2; + required uint32 frame = 3; + required uint32 subframe = 4; + required uint32 rnti = 5; +} diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 3cb7d23467c3622617799de692350efe2eaddde4..cfc2bc22155235a41d439581d71d795450e53310 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -19,94 +19,77 @@ * contact@openairinterface.org */ -#if defined(ENABLE_ITTI) # include "intertask_interface.h" # include "create_tasks.h" # include "common/utils/LOG/log.h" # include "targets/RT/USER/lte-softmodem.h" +# include "common/ran_context.h" #ifdef OPENAIR2 - #if defined(ENABLE_USE_MME) #include "sctp_eNB_task.h" #include "x2ap_eNB.h" #include "s1ap_eNB.h" - #include "nas_ue_task.h" #include "udp_eNB_task.h" #include "gtpv1u_eNB_task.h" - /* temporary warning removale while implementing noS1 */ - /* as config option */ - #else - #ifdef EPC_MODE_ENABLED - #undef EPC_MODE_ENABLED - #endif - #define EPC_MODE_ENABLED 0 - #endif #if ENABLE_RAL #include "lteRALue.h" #include "lteRALenb.h" #endif #include "RRC/LTE/rrc_defs.h" #endif +# include "f1ap_cu_task.h" +# include "f1ap_du_task.h" # include "enb_app.h" +extern RAN_CONTEXT_t RC; int create_tasks(uint32_t enb_nb) { LOG_D(ENB_APP, "%s(enb_nb:%d\n", __FUNCTION__, enb_nb); - itti_wait_ready(1); + ngran_node_t type = RC.rrc[0]->node_type; + int rc; - if (enb_nb > 0) { - /* Last task to create, others task must be ready before its start */ - if (itti_create_task (TASK_ENB_APP, eNB_app_task, NULL) < 0) { - LOG_E(ENB_APP, "Create task for eNB APP failed\n"); - return -1; - } - } + if (enb_nb == 0) return 0; -# if defined(ENABLE_USE_MME) + LOG_I(ENB_APP, "Creating ENB_APP eNB Task\n"); + rc = itti_create_task (TASK_ENB_APP, eNB_app_task, NULL); + AssertFatal(rc >= 0, "Create task for eNB APP failed\n"); - if (EPC_MODE_ENABLED) { - if (enb_nb > 0) { - if (itti_create_task (TASK_X2AP, x2ap_task, NULL) < 0) { - LOG_E(X2AP, "Create task for X2AP failed\n"); - return -1; - } + LOG_I(RRC,"Creating RRC eNB Task\n"); + rc = itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL); + AssertFatal(rc >= 0, "Create task for RRC eNB failed\n"); - if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { - LOG_E(SCTP, "Create task for SCTP failed\n"); - return -1; - } - - if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) { - LOG_E(S1AP, "Create task for S1AP failed\n"); - return -1; - } + if (EPC_MODE_ENABLED) { + rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for SCTP failed\n"); + } - if(!(get_softmodem_params()->emulate_rf)) { - if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { - LOG_E(UDP_, "Create task for UDP failed\n"); - return -1; - } - } - if (itti_create_task (TASK_GTPV1_U, >pv1u_eNB_task, NULL) < 0) { - LOG_E(GTPU, "Create task for GTPV1U failed\n"); - return -1; - } + if (EPC_MODE_ENABLED && !NODE_IS_DU(type)) { + rc = itti_create_task(TASK_S1AP, s1ap_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for S1AP failed\n"); + if (!(get_softmodem_params()->emulate_rf)){ + rc = itti_create_task(TASK_UDP, udp_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for UDP failed\n"); } - } /* if (EPC_MODE_ENABLED) */ - -#endif + rc = itti_create_task(TASK_GTPV1_U, gtpv1u_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for GTPV1U failed\n"); + if (is_x2ap_enabled()) { + rc = itti_create_task(TASK_X2AP, x2ap_task, NULL); + AssertFatal(rc >= 0, "Create task for X2AP failed\n"); + } else { + LOG_I(X2AP, "X2AP is disabled.\n"); + } + } - if (enb_nb > 0) { - LOG_I(RRC,"Creating RRC eNB Task\n"); + if (NODE_IS_CU(type)) { + rc = itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL); + AssertFatal(rc >= 0, "Create task for CU F1AP failed\n"); + } - if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) { - LOG_E(RRC, "Create task for RRC eNB failed\n"); - return -1; - } + if (NODE_IS_DU(type)) { + rc = itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL); + AssertFatal(rc >= 0, "Create task for DU F1AP failed\n"); } - itti_wait_ready(0); return 0; } -#endif diff --git a/targets/COMMON/create_tasks_ue.c b/targets/COMMON/create_tasks_ue.c index 601b342ee88f9d5fec96182c4658fb735eaa9d5a..06f36641e73e695bc015c4fc7068b043e3a55a51 100644 --- a/targets/COMMON/create_tasks_ue.c +++ b/targets/COMMON/create_tasks_ue.c @@ -19,19 +19,16 @@ * contact@openairinterface.org */ -#if defined(ENABLE_ITTI) # include "intertask_interface.h" # include "create_tasks.h" # include "common/utils/LOG/log.h" #ifdef OPENAIR2 - #if defined(ENABLE_USE_MME) - #include "sctp_eNB_task.h" - #include "s1ap_eNB.h" - #include "nas_ue_task.h" - #include "udp_eNB_task.h" - #include "gtpv1u_eNB_task.h" - #endif + #include "sctp_eNB_task.h" + #include "s1ap_eNB.h" + #include "openair3/NAS/UE/nas_ue_task.h" + #include "udp_eNB_task.h" + #include "gtpv1u_eNB_task.h" #if ENABLE_RAL #include "lteRALue.h" #include "lteRALenb.h" @@ -43,24 +40,25 @@ int create_tasks_ue(uint32_t ue_nb) { LOG_D(ENB_APP, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb); itti_wait_ready(1); -# if defined(ENABLE_USE_MME) + + if (EPC_MODE_ENABLED) { # if defined(NAS_BUILT_IN_UE) - if (ue_nb > 0) { - nas_user_container_t *users = calloc(1, sizeof(*users)); + if (ue_nb > 0) { + nas_user_container_t *users = calloc(1, sizeof(*users)); - if (users == NULL) abort(); + if (users == NULL) abort(); - users->count = ue_nb; + users->count = ue_nb; - if (itti_create_task (TASK_NAS_UE, nas_ue_task, users) < 0) { - LOG_E(NAS, "Create task for NAS UE failed\n"); - return -1; + if (itti_create_task (TASK_NAS_UE, nas_ue_task, users) < 0) { + LOG_E(NAS, "Create task for NAS UE failed\n"); + return -1; + } } - } # endif -# endif + } /* EPC_MODE_ENABLED */ if (ue_nb > 0) { if (itti_create_task (TASK_RRC_UE, rrc_ue_task, NULL) < 0) { @@ -72,4 +70,4 @@ int create_tasks_ue(uint32_t ue_nb) { itti_wait_ready(0); return 0; } -#endif + diff --git a/targets/Makefile.common b/targets/Makefile.common index ac0771770ba8c4737370a8f7670a71be2dc1b01e..ecd5f3821a8e3fabd538948d73b25bee6a6b69df 100644 --- a/targets/Makefile.common +++ b/targets/Makefile.common @@ -45,7 +45,6 @@ ifeq ($(OPENSSL_FOUND), 0) @(warning "openssl library is not installed on your system, openssl lib needed, continuing with security disabled") SECU=0 else -CFLAGS += -DENABLE_SECURITY LIBS += $(OPENSSL_LIBS) $(NETTLE_LIBS) endif endif diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf index 86131b3e8e97e0b98fadfe7d6617a37f67a9e569..df60ee7fa8d6a9de6a627e4c42c9ca7b6dbd624d 100644 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf @@ -37,6 +37,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf index e87a37f9fb8cc5a3fd9e523307f0e18fc17a6bd6..f5dce0a178e72d21bb07356666b9e27d4806ead9 100644 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf @@ -49,6 +49,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf index af4f4236a7b2059f04193edd9d9be5eb56ff6eeb..d75837ff9793cc79d1aa9b0f6923818b954409a1 100644 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf @@ -36,6 +36,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf new file mode 100644 index 0000000000000000000000000000000000000000..38d3f5eac94756b771e33575de9969b9ce42c55b --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/cu.lte.conf @@ -0,0 +1,221 @@ +Active_eNBs = ( "eNB-CU-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = ( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-CU-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } ) + + nr_cellid = 12345678L + + tr_s_preference = "f1" + + local_s_if_name = "lo"; + remote_s_address = "192.168.12.4"; + local_s_address = "192.168.12.45"; + local_s_portc = 501; + remote_s_portc = 500; + local_s_portd = 601; + remote_s_portd = 600; + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNodeB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2665000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnable = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* + srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =; + */ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff= 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + /* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; + */ + + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( + { + ipv4 = "127.0.1.10"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : { + ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.1.30/24"; + ENB_INTERFACE_NAME_FOR_S1U = "lo"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.1.30/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "127.0.1.30/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +log_config = { + global_log_level = "info"; + global_log_verbosity = "medium"; + pdcp_log_level = "info"; + pdcp_log_verbosity = "high"; + rrc_log_level = "info"; + rrc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; + gtp_log_level = "info"; + gtp_log_verbosity = "medium"; +}; + +NETWORK_CONTROLLER : { + FLEXRAN_ENABLED = "yes"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/du.lte.band7.10MHz.if4p5.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/du.lte.band7.10MHz.if4p5.conf new file mode 100644 index 0000000000000000000000000000000000000000..8e786be5e9427af6de083dec009e3371f8e43e7a --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/du.lte.band7.10MHz.if4p5.conf @@ -0,0 +1,119 @@ +Active_eNBs = ( "eNB-Eurecom-DU"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_CU_ID = 0xe00; + + eNB_name = "eNB-Eurecom-DU"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } ) + + nr_cellid = 12345678L + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2665000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + } + ); + + + # ------- 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_if_name = "lo"; + remote_n_address = "127.0.0.4"; + local_n_address = "127.0.0.3"; + local_n_portc = 500; + remote_n_portc = 501; + local_n_portd = 600; + remote_n_portd = 601; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 10; + att_rx = 10; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + eNB_instances = [0]; + } +); + +log_config = { + global_log_level = "info"; + global_log_verbosity = "medium"; + hw_log_level = "info"; + hw_log_verbosity = "medium"; + phy_log_level = "info"; + phy_log_verbosity = "medium"; + mac_log_level = "info"; + mac_log_verbosity = "high"; + rlc_log_level = "info"; + rlc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; +}; + +NETWORK_CONTROLLER : { + FLEXRAN_ENABLED = "yes"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf index d33a9dc41fbc88cb8fb01675ef77ee9e888fe9d9..1f5aeaf777100ed1818b887615c7a07e4ee3949b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf @@ -13,7 +13,7 @@ eNBs = eNB_name = "eNB_Eurecom_LTEBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = "1"; + tracking_area_code = 1; plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2;} ); @@ -48,23 +48,23 @@ eNBs = prach_zero_correlation = 1; prach_freq_offset = 1; pucch_delta_shift = 1; - pucch_nRB_CQI = 1; - pucch_nCS_AN = 0; - pucch_n1_AN = 32; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; pdsch_referenceSignalPower = -27; pdsch_p_b = 0; pusch_n_SB = 1; pusch_enable64QAM = "DISABLE"; pusch_hoppingMode = "interSubFrame"; - pusch_hoppingOffset = 0; + pusch_hoppingOffset = 0; pusch_groupHoppingEnabled = "ENABLE"; pusch_groupAssignment = 0; pusch_sequenceHoppingEnabled = "DISABLE"; pusch_nDMRS1 = 1; phich_duration = "NORMAL"; phich_resource = "ONESIXTH"; - srs_enable = "DISABLE"; - /* srs_BandwidthConfig =; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; srs_SubframeConfig =; srs_ackNackST =; srs_MaxUpPts =;*/ @@ -73,14 +73,14 @@ eNBs = pusch_alpha = "AL1"; pucch_p0_Nominal = -104; msg3_delta_Preamble = 6; - pucch_deltaF_Format1 = "deltaF2"; - pucch_deltaF_Format1b = "deltaF3"; - pucch_deltaF_Format2 = "deltaF0"; - pucch_deltaF_Format2a = "deltaF0"; - pucch_deltaF_Format2b = "deltaF0"; - - rach_numberOfRA_Preambles = "n64"; #64 - rach_preamblesGroupAConfig = "DISABLE"; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = "n64"; #64 + rach_preamblesGroupAConfig = "DISABLE"; /* rach_sizeOfRA_PreamblesGroupA = ; rach_messageSizeGroupA = ; @@ -105,7 +105,7 @@ eNBs = ue_TransmissionMode = "tm1"; # eMTC Parameters - emtc_parameters : + emtc_parameters : { eMTC_configured = 1; #hyperSFN_r13 = 0; @@ -115,7 +115,7 @@ eNBs = #SIB1 schedulingInfoSIB1_BR_r13 = 4; - #system_info_value_tag_SI = + #system_info_value_tag_SI = #( # { # systemInfoValueTagSi_r13 = 0; @@ -124,7 +124,7 @@ eNBs = cellSelectionInfoCE_r13 = "ENABLE"; q_RxLevMinCE_r13 = -70; - bandwidthReducedAccessRelatedInfo_r13 = "ENABLE" + bandwidthReducedAccessRelatedInfo_r13 = "ENABLE" si_WindowLength_BR_r13 = "ms20"; #0 si_RepetitionPattern_r13 = "everyRF"; #0 @@ -136,7 +136,7 @@ eNBs = } ); - fdd_DownlinkOrTddSubframeBitmapBR_r13 = "subframePattern40-r13"; + fdd_DownlinkOrTddSubframeBitmapBR_r13 = "subframePattern40-r13"; fdd_DownlinkOrTddSubframeBitmapBR_val_r13 = 0xFFFFFFFFFF; startSymbolBR_r13 = 2; si_HoppingConfigCommon_r13 = "off"; #1; # Note: 1==OFF ! @@ -157,14 +157,14 @@ eNBs = rach_numberOfRA_Preambles = 60; #14 rach_powerRampingStep = 4; - rach_preambleInitialReceivedTargetPower = -110; + rach_preambleInitialReceivedTargetPower = -110; rach_preambleTransMax = 10; rach_raResponseWindowSize = 10; rach_macContentionResolutionTimer = 64; rach_maxHARQ_Msg3Tx = 4; # max size for this array is 4 - rach_CE_LevelInfoList_r13 = + rach_CE_LevelInfoList_r13 = ( { firstPreamble_r13 = 60; @@ -175,7 +175,7 @@ eNBs = } ); - # BCCH CONFIG + # BCCH CONFIG bcch_modificationPeriodCoeff = 2; #PCCH Config @@ -189,7 +189,7 @@ eNBs = prach_zero_correlation = 1; prach_freq_offset = 1; - #PDSCH Config Common + #PDSCH Config Common pdsch_referenceSignalPower = -27 pdsch_p_b = 0; @@ -213,22 +213,22 @@ eNBs = pusch_p0_Nominal = -96; pusch_alpha = "AL1"; pucch_p0_Nominal = -104; - pucch_deltaF_Format1 = "deltaF0"; - pucch_deltaF_Format1b = "deltaF3"; - pucch_deltaF_Format2 = "deltaF0"; - pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format1 = "deltaF0"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; pucch_deltaF_Format2b = "deltaF0"; msg3_delta_Preamble = 6; prach_ConfigCommon_v1310 = "ENABLE"; - + mpdcch_startSF_CSS_RA_r13 = "fdd-r13"; mpdcch_startSF_CSS_RA_r13_val = "v1"; #0 prach_HoppingOffset_r13 = 0; - + pdsch_maxNumRepetitionCEmodeA_r13 = "r16"; #0 #pdsch_maxNumRepetitionCEmodeB_r13 = "r384"; # NULL - 2 @@ -245,7 +245,7 @@ eNBs = ); # max size for this array is 4 - prach_parameters_ce_r13 = + prach_parameters_ce_r13 = ( { prach_config_index_br = 3; @@ -255,17 +255,17 @@ eNBs = numRepetitionPerPreambleAttempt_r13 = 1; #0 mpdcch_NumRepetition_RA_r13 = 1; #0 prach_HoppingConfig_r13 = 0; #1 - max_available_narrow_band = [3]; + max_available_narrow_band = [3]; } ); - n1PUCCH_AN_InfoList_r13 = + n1PUCCH_AN_InfoList_r13 = ( { - pucch_info_value = 0; + pucch_info_value = 33; } ); - + ue_TimersAndConstants_t300 = "ms1000"; ue_TimersAndConstants_t301 = "ms400"; @@ -283,21 +283,21 @@ eNBs = } - pucch_NumRepetitionCE_Msg4_Level0_r13 = "n1"; #0 + pucch_NumRepetitionCE_Msg4_Level0_r13 = "n1"; #0 #pucch_NumRepetitionCE_Msg4_Level1_r13 = "n2"; #1 #pucch_NumRepetitionCE_Msg4_Level2_r13 = "n16"; #2 #pucch_NumRepetitionCE_Msg4_Level3_r13 = "n32"; #3 - sib2_freq_hoppingParameters_r13 : + sib2_freq_hoppingParameters_r13 : { #sib2_mpdcch_pdsch_hoppingNB_r13 = "nb2"; #0 #sib2_interval_DLHoppingConfigCommonModeA_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) - #sib2_interval_DLHoppingConfigCommonModeA_r13_val = "int1"; + #sib2_interval_DLHoppingConfigCommonModeA_r13_val = "int1"; #sib2_interval_DLHoppingConfigCommonModeB_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) - #sib2_interval_DLHoppingConfigCommonModeB_r13_val = "int2"; + #sib2_interval_DLHoppingConfigCommonModeB_r13_val = "int2"; sib2_interval_ULHoppingConfigCommonModeA_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) - sib2_interval_ULHoppingConfigCommonModeA_r13_val = "int4"; #2 + sib2_interval_ULHoppingConfigCommonModeA_r13_val = "int4"; #2 # sib2_interval_ULHoppingConfigCommonModeB_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) # sib2_interval_ULHoppingConfigCommonModeB_r13_val = "int2"; #0 @@ -305,11 +305,11 @@ eNBs = } rach_preamblesGroupAConfig = "DISABLE"; - + phich_duration = "NORMAL"; phich_resource = "ONESIXTH"; srs_enable = "DISABLE"; - + } @@ -360,6 +360,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { @@ -394,25 +399,25 @@ eNBs = ); MACRLCs = ( - { + { num_cc = 1; tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; phy_test_mode = 0; puSch10xSnr = 200; puCch10xSnr = 200; - } + } ); L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_rf = "yes" nb_tx = 1 nb_rx = 1 @@ -423,7 +428,7 @@ RUs = ( max_rxgain = 125; eNB_instances = [0]; } -); +); log_config : { @@ -442,4 +447,3 @@ log_config : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf index 8c080b7d1059c6cc4bfd03808b24f3fba1779bef..60142d8fe64cfa363c141bb8b71943c1269e4c4e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf @@ -142,6 +142,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf index 77993457ab9b452bfa5ba7a390791cea6010375f..addd70ca712f7e25f01ea6dc01eb5f361557e14f 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf @@ -178,6 +178,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eno1"; @@ -200,18 +205,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 200; puCch10xSnr = 200; - } + } ); L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_rf = "yes" nb_tx = 1 nb_rx = 1 @@ -223,7 +228,7 @@ RUs = ( eNB_instances = [0]; #sdr_addrs = "RF3C000025"; } -); +); NETWORK_CONTROLLER : { @@ -261,4 +266,3 @@ THREAD_STRUCT = ( rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf index 83954a00d52c3e2522371336db87fb6b574ff051..993acae34e95b894877aa7f88923d398b2d6a2c4 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf @@ -142,6 +142,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf index 764d7886e2a62a37b34c7e31dcb59384fa9b41b5..201a0c1839a10abf6cdb4e0a7c2ed9772835c736 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf @@ -178,6 +178,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eno1"; @@ -200,18 +205,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 200; puCch10xSnr = 200; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_rf = "yes" nb_tx = 1; nb_rx = 1; @@ -223,7 +228,7 @@ RUs = ( eNB_instances = [0]; #sdr_addrs = "RF3E000025"; } -); +); NETWORK_CONTROLLER : { @@ -261,4 +266,3 @@ THREAD_STRUCT = ( rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf index 728492ee835aaf2607ea6aefd09eb5a7be2cc880..ac417c7e3a81cd7a7b11548d5d4c5b84d4c8fc82 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf @@ -145,6 +145,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth6"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf index ca85c6538f221587faad1657be2b207468047ff6..3507906affeb8abd3a1d112f2029cbc987a74faa 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf @@ -178,6 +178,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; @@ -200,18 +205,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 200; puCch10xSnr = 200; - } + } ); L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_rf = "yes" nb_tx = 1 nb_rx = 1 @@ -223,7 +228,7 @@ RUs = ( eNB_instances = [0]; sdr_addrs = "RF3E000028"; } -); +); NETWORK_CONTROLLER : { @@ -261,4 +266,3 @@ THREAD_STRUCT = ( rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf index 823c5fb1c3e7ec1c9e04fd42fe3cee6af3afac72..a683326639c9b7fc92c1431c4b679aa1437e9073 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf @@ -179,6 +179,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf index 476d4903f1c5b04e16b3caa927c68ed2e057fc76..5e750cb62652f2946d0c83116a897b91a5bd8f75 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf @@ -179,6 +179,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index 83834bfeca6d51a6c8866d95d31d3ef680eed9aa..4b3ac5ffad271d03d782ce1249249fe3ad9c3f1a 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -172,27 +172,61 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "10.64.93.19"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; - ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_INTERFACE_NAME_FOR_S1_MME = "eno1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "10.64.45.62/23"; + ENB_INTERFACE_NAME_FOR_S1U = "eno1"; + ENB_IPV4_ADDRESS_FOR_S1U = "10.64.45.62/23"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 - }; + }; + } ); +DU = ( + { + DU_INTERFACE_NAME_FOR_F1U = "lo"; + DU_IPV4_ADDRESS_FOR_F1U = "127.0.0.1/16"; + DU_PORT_FOR_F1U = 22100; + F1_U_DU_TRANSPORT_TYPE = "TCP"; + } + ); + +CU = ( + { + CU_INTERFACE_NAME_FOR_F1U = "lo"; + CU_IPV4_ADDRESS_FOR_F1U = "127.0.0.1"; //Address to search the DU + CU_PORT_FOR_F1U = 22100; + F1_U_CU_TRANSPORT_TYPE = "TCP"; // One of TCP/UDP/SCTP + DU_TYPE = "LTE"; + }//, +// { +// CU_INTERFACE_NAME_FOR_F1U = "eth0"; +// CU_IPV4_ADDRESS_FOR_F1U = "10.64.93.142"; //Address to search the DU +// CU_PORT_FOR_F1U = 2211; +// F1_U_CU_TRANSPORT_TYPE = "TCP"; // One of TCP/UDP/SCTP +// DU_TYPE = "WiFi"; +// } + ); + + CU_BALANCING = "ALL"; + MACRLCs = ( { num_cc = 1; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf index 403e5f24f54cb114dfd9e971f5d2a9541c7625e7..497db9a306bab96faad656f7139cc904aff33243 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf @@ -146,6 +146,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf index 7eb16a3b7a9f0f0da3fdd706c254211c6cf53d01..ae2ba73782d6161d6576cbae55545986d087aa3b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf @@ -148,6 +148,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf index 47047e5626cbf9e170515b920507b665030dfe25..f7be9e28d95f8a94535bd21cf38f3b7677f85744 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf @@ -148,6 +148,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "vboxnet0"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf index 472d84c7e2319d84d3436081f91839cd44b72160..9d71b10740cc3ba7e036835735c3b058a29a106c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf @@ -179,6 +179,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { #ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf index d989ac8b1087ec181e1da88ffca01aee0130ed7f..ec20ac3abff08d69e88d8f35657c865867b85a8b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf @@ -148,6 +148,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf index 1c651c22d50b6a8738331557ab28e182362acd46..14587b2d875267661daa123216a4ebf6b512c979 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf @@ -105,8 +105,7 @@ eNBs = ue_TimersAndConstants_n310 = 20; ue_TimersAndConstants_n311 = 1; ue_TransmissionMode = 1; - # IRT MS addition: - # mbms_dedicated_serving_cell = "ENABLE" + mbms_dedicated_serving_cell = "ENABLE" } ); @@ -150,6 +149,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 9db1684bd27b7c351d7459d0319d6ab649f3608d..8ae3d8956c9f7154b45cc1cb9dc7772313d93026 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -48,7 +48,7 @@ #include "PHY/defs_eNB.h" #include "SCHED/sched_eNB.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" - +#include "nfapi/oai_integration/vendor_ext.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -80,14 +80,8 @@ #include "UTIL/OTG/otg_extern.h" #endif -#if defined(ENABLE_ITTI) - #if defined(ENABLE_USE_MME) - #include "s1ap_eNB.h" - #ifdef PDCP_USE_NETLINK - #include "SIMULATION/ETH_TRANSPORT/proto.h" - #endif - #endif -#endif +#include "s1ap_eNB.h" +#include "SIMULATION/ETH_TRANSPORT/proto.h" #include "T.h" @@ -104,11 +98,6 @@ struct timing_info_t { // Fix per CC openair rf/if device update // extern openair0_device openair0; - -#if defined(ENABLE_ITTI) - extern volatile int start_eNB; - extern volatile int start_UE; -#endif extern volatile int oai_exit; extern int transmission_mode; @@ -150,7 +139,7 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #endif -extern uint8_t nfapi_mode; + extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); @@ -161,14 +150,17 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name) { start_meas(&softmodem_stats_rxtx_sf); //L1_rxtx_proc_t *L1_proc_tx = &eNB->proc.L1_proc_tx; - // ******************************************************************* - #if defined(PRE_SCD_THREAD) - RU_t *ru = RC.ru[0]; + RU_t *ru = RC.ru[0]; #endif - if (nfapi_mode == 1) { + if (eNB ==NULL) { + LOG_D(PHY,"%s:%d: rxtx invalid argument, eNB pointer is NULL",__FILE__,__LINE__); + return -1; + } + + if (NFAPI_MODE==NFAPI_MODE_PNF) { // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick uint16_t frame = proc->frame_rx; uint16_t subframe = proc->subframe_rx; @@ -196,7 +188,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name } } - if (nfapi_mode == 1 && eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0) { + if (NFAPI_MODE==NFAPI_MODE_PNF && eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0) { LOG_E(PHY, "eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols == 0"); return 0; } @@ -206,7 +198,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx)); // if this is IF5 or 3GPP_eNB - if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) { + if (eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) { wakeup_prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx); @@ -216,47 +208,46 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name release_UE_in_freeList(eNB->Mod_id); // UE-specific RX processing for subframe n - if (nfapi_mode == 0 || nfapi_mode == 1) { + if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { phy_procedures_eNB_uespec_RX(eNB, proc); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, 1 ); - #if defined(PRE_SCD_THREAD) - if (nfapi_mode == 2){ - new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use; - dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; - -// L2-emulator can work only one eNB. -// memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); -// memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); - memcpy(&pre_scd_eNB_UE_stats,&RC.mac[0]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); - memcpy(&pre_scd_activeUE, &RC.mac[0]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); - - if (pthread_mutex_lock(&ru->proc.mutex_pre_scd)!= 0) { - LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n"); - exit_fun("error locking mutex_time"); - } - ru->proc.instance_pre_scd++; + if (NFAPI_MODE==NFAPI_MODE_VNF) { + new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use; + dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; + // L2-emulator can work only one eNB. + // memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); + // memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + memcpy(&pre_scd_eNB_UE_stats,&RC.mac[0]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); + memcpy(&pre_scd_activeUE, &RC.mac[0]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + + if (pthread_mutex_lock(&ru->proc.mutex_pre_scd)!= 0) { + LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n"); + exit_fun("error locking mutex_time"); + } - if (ru->proc.instance_pre_scd == 0) { - if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" ); - exit_fun( "ERROR pthread_cond_signal cond_pre_scd" ); - } - }else{ - LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n", - proc->frame_rx,proc->subframe_rx,ru->proc.instance_pre_scd ); - } + ru->proc.instance_pre_scd++; - if (pthread_mutex_unlock(&ru->proc.mutex_pre_scd)!= 0) { - LOG_E( PHY, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n"); - exit_fun("error unlocking mutex_pre_scd"); + if (ru->proc.instance_pre_scd == 0) { + if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" ); + exit_fun( "ERROR pthread_cond_signal cond_pre_scd" ); } + } else { + LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n", + proc->frame_rx,proc->subframe_rx,ru->proc.instance_pre_scd ); } -#endif + if (pthread_mutex_unlock(&ru->proc.mutex_pre_scd)!= 0) { + LOG_E( PHY, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n"); + exit_fun("error unlocking mutex_pre_scd"); + } + } + +#endif pthread_mutex_lock(&eNB->UL_INFO_mutex); eNB->UL_INFO.frame = proc->frame_rx; eNB->UL_INFO.subframe = proc->subframe_rx; @@ -321,9 +312,8 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name } -static void* L1_thread_tx(void* param) { - - L1_proc_t *eNB_proc = (L1_proc_t*)param; +static void *L1_thread_tx(void *param) { + L1_proc_t *eNB_proc = (L1_proc_t *)param; L1_rxtx_proc_t *proc = &eNB_proc->L1_proc_tx; PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; char thread_name[100]; @@ -334,7 +324,8 @@ static void* L1_thread_tx(void* param) { while (!oai_exit) { if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt,thread_name)<0) break; - if (oai_exit) break; + + if (oai_exit) break; // ***************************************** // TX processing for subframe n+4 @@ -346,8 +337,6 @@ static void* L1_thread_tx(void* param) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_ENB,proc->frame_tx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_ENB,proc->frame_rx); phy_procedures_eNB_TX(eNB, proc, 1); - - pthread_mutex_lock( &proc->mutex ); proc->instance_cnt = -1; @@ -356,6 +345,7 @@ static void* L1_thread_tx(void* param) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); } + pthread_mutex_unlock( &proc->mutex ); wakeup_txfh(proc,eNB); } @@ -369,29 +359,25 @@ static void* L1_thread_tx(void* param) { * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void* L1_thread( void* param ) { - +static void *L1_thread( void *param ) { static int eNB_thread_rxtx_status; //L1_proc_t *eNB_proc = (L1_proc_t*)param; L1_rxtx_proc_t *proc; // Working - if(nfapi_mode ==2){ - proc = (L1_rxtx_proc_t*)param; - } - else{ - L1_proc_t *eNB_proc = (L1_proc_t*)param; + if(NFAPI_MODE==NFAPI_MODE_VNF) { + proc = (L1_rxtx_proc_t *)param; + } else { + L1_proc_t *eNB_proc = (L1_proc_t *)param; proc = &eNB_proc->L1_proc; } PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; - char thread_name[100]; cpu_set_t cpuset; CPU_ZERO(&cpuset); // set default return value eNB_thread_rxtx_status = 0; - sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.L1_proc == proc ? 0 : 1); thread_top_init(thread_name,1,470000,500000,500000); pthread_setname_np( pthread_self(),"rxtx processing"); @@ -417,10 +403,12 @@ static void* L1_thread( void* param ) { } if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) phy_procedures_eNB_TX(eNB, proc, 1); + if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break; - if (nfapi_mode!=2){ - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB); - else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(proc,eNB); + + if (NFAPI_MODE!=NFAPI_MODE_VNF) { + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB); + else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(proc,eNB); } } // while !oai_exit @@ -430,8 +418,7 @@ static void* L1_thread( void* param ) { return &eNB_thread_rxtx_status; } -void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru) -{ +void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru) { L1_proc_t *proc = &eNB->proc; L1_rxtx_proc_t *L1_proc = &proc->L1_proc; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; @@ -441,7 +428,6 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t if (!oai_exit) { T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); - L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti); L1_proc->frame_rx = ru_proc->frame_rx; L1_proc->subframe_rx = ru_proc->subframe_rx; @@ -449,6 +435,7 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead)%10; if (rxtx(eNB,L1_proc,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id); + ru_proc->timestamp_tx = L1_proc->timestamp_tx; ru_proc->subframe_tx = L1_proc->subframe_tx; ru_proc->frame_tx = L1_proc->frame_tx; @@ -456,11 +443,8 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t } int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { - RU_t *ru; RU_proc_t *ru_proc; - - struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; @@ -469,19 +453,22 @@ int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx); return(-1); } + pthread_mutex_lock(&eNB->proc.mutex_RU_tx); eNB->proc.RU_mask_tx = 0; pthread_mutex_unlock(&eNB->proc.mutex_RU_tx); + if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1); - for(int i=0; i<eNB->num_RU; i++) - { + for(int i=0; i<eNB->num_RU; i++) { ru = eNB->RU_list[i]; ru_proc = &ru->proc; + if (ru_proc->instance_cnt_eNBs == 0) { LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx); return(-1); } + if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs ); exit_fun( "error locking mutex_eNB" ); @@ -493,14 +480,13 @@ int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { ru_proc->subframe_tx = proc->subframe_tx; ru_proc->frame_tx = proc->frame_tx; - // the thread can now be woken up if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); return(-1); } - + pthread_mutex_unlock( &ru_proc->mutex_eNBs ); } @@ -508,30 +494,24 @@ int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { } int wakeup_tx(PHY_VARS_eNB *eNB) { - L1_proc_t *proc=&eNB->proc; - L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx; L1_rxtx_proc_t *L1_proc = &proc->L1_proc; - - struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; - - + if (pthread_mutex_timedlock(&L1_proc_tx->mutex,&wait) != 0) { LOG_E(PHY, "[SCHED][eNB] ERROR locking mutex for eNB L1_thread_tx\n"); exit_fun("ERROR pthread_lock"); return(-1); } - while(L1_proc_tx->instance_cnt == 0){ + + while(L1_proc_tx->instance_cnt == 0) { pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex); } L1_proc_tx->instance_cnt = 0; - - L1_proc_tx->subframe_rx = L1_proc->subframe_rx; L1_proc_tx->frame_rx = L1_proc->frame_rx; L1_proc_tx->subframe_tx = L1_proc->subframe_tx; @@ -544,18 +524,15 @@ int wakeup_tx(PHY_VARS_eNB *eNB) { exit_fun( "ERROR pthread_cond_signal" ); return(-1); } - + pthread_mutex_unlock( &L1_proc_tx->mutex); return(0); } int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { - L1_proc_t *proc=&eNB->proc; RU_proc_t *ru_proc=&ru->proc; - L1_rxtx_proc_t *L1_proc=&proc->L1_proc; - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; int i; struct timespec wait; @@ -583,7 +560,6 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { wait.tv_sec=0; wait.tv_nsec=5000000L; - if (L1_proc->instance_cnt == 0) { LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",L1_proc->frame_rx,L1_proc->subframe_rx); return(-1); @@ -598,9 +574,8 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { } ++L1_proc->instance_cnt; - - // We have just received and processed the common part of a subframe, say n. - // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired + // We have just received and processed the common part of a subframe, say n. + // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired // transmitted timestamp of the next TX slot (first). // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti, @@ -623,7 +598,6 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { } void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { - L1_proc_t *proc = &eNB->proc; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int i; @@ -686,7 +660,6 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { - L1_proc_t *proc = &eNB->proc; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int i; @@ -758,7 +731,6 @@ static void *eNB_thread_prach( void *param ) { static int eNB_thread_prach_status; PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; L1_proc_t *proc = &eNB->proc; - // set default return value eNB_thread_prach_status = 0; thread_top_init("eNB_thread_prach",1,500000,1000000,20000000); @@ -795,7 +767,6 @@ static void *eNB_thread_prach_br( void *param ) { static int eNB_thread_prach_status; PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; L1_proc_t *proc = &eNB->proc; - // set default return value eNB_thread_prach_status = 0; thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000); @@ -876,7 +847,6 @@ void init_eNB_proc(int inst) { LOG_I(PHY,"Initializing eNB processes instance:%d CC_id %d \n",inst,CC_id); #endif proc = &eNB->proc; - L1_proc = &proc->L1_proc; L1_proc_tx = &proc->L1_proc_tx; L1_proc->instance_cnt = -1; @@ -886,14 +856,12 @@ void init_eNB_proc(int inst) { proc->instance_cnt_prach = -1; proc->instance_cnt_asynch_rxtx = -1; proc->instance_cnt_synch = -1; - proc->CC_id = CC_id; - + proc->CC_id = CC_id; proc->first_rx =1; proc->first_tx =1; proc->RU_mask_tx = (1<<eNB->num_RU)-1; proc->RU_mask =0; proc->RU_mask_prach =0; - pthread_mutex_init( &eNB->UL_INFO_mutex, NULL); pthread_mutex_init( &L1_proc->mutex, NULL); pthread_mutex_init( &L1_proc_tx->mutex, NULL); @@ -903,7 +871,6 @@ void init_eNB_proc(int inst) { pthread_mutex_init( &L1_proc_tx->mutex_RUs, NULL); pthread_cond_init( &L1_proc->cond_RUs, NULL); pthread_cond_init( &L1_proc_tx->cond_RUs, NULL); - pthread_mutex_init( &proc->mutex_prach, NULL); pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_RU,NULL); @@ -941,10 +908,10 @@ void init_eNB_proc(int inst) { LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); - if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { + if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) { pthread_create( &L1_proc->pthread, attr0, L1_thread, proc ); pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc); - } else if (nfapi_mode == 2) { // this is neccesary in VNF or L2 FAPI simulator. + } else if (NFAPI_MODE==NFAPI_MODE_VNF) { // this is neccesary in VNF or L2 FAPI simulator. // Original Code from Fujitsu w/ old structure/field name //pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); //pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); @@ -956,7 +923,6 @@ void init_eNB_proc(int inst) { #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); #endif - AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void *)eNB); @@ -997,7 +963,6 @@ void kill_eNB_proc(int inst) { for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { eNB=RC.eNB[inst][CC_id]; - proc = &eNB->proc; L1_proc = &proc->L1_proc; L1_proc_tx = &proc->L1_proc_tx; @@ -1009,12 +974,11 @@ void kill_eNB_proc(int inst) { LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); - if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { + if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) { pthread_mutex_lock(&L1_proc->mutex); L1_proc->instance_cnt = 0; pthread_cond_signal(&L1_proc->cond); pthread_mutex_unlock(&L1_proc->mutex); - pthread_mutex_lock(&L1_proc_tx->mutex); L1_proc_tx->instance_cnt = 0; pthread_cond_signal(&L1_proc_tx->cond); @@ -1042,12 +1006,13 @@ void kill_eNB_proc(int inst) { LOG_I(PHY, "Destroying UL_INFO mutex\n"); pthread_mutex_destroy(&eNB->UL_INFO_mutex); - if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { + if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) { LOG_I(PHY, "Joining L1_proc mutex/cond\n"); - pthread_join( L1_proc->pthread, (void**)&status ); + pthread_join( L1_proc->pthread, (void **)&status ); LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n"); - pthread_join( L1_proc_tx->pthread, (void**)&status ); + pthread_join( L1_proc_tx->pthread, (void **)&status ); } + LOG_I(PHY, "Destroying L1_proc mutex/cond\n"); pthread_mutex_destroy( &L1_proc->mutex ); pthread_cond_destroy( &L1_proc->cond ); @@ -1058,7 +1023,6 @@ void kill_eNB_proc(int inst) { pthread_cond_destroy( &L1_proc_tx->cond ); pthread_mutex_destroy( &L1_proc_tx->mutex_RUs ); pthread_cond_destroy( &L1_proc_tx->cond_RUs ); - pthread_attr_destroy(&proc->attr_prach); pthread_attr_destroy(&proc->attr_asynch_rxtx); pthread_attr_destroy(&L1_proc->attr); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 0583c689e66c85ab1e48ce0fe9cb2c6184e46eac..93a2440b9453cd43ebd4b371a9a521ff25ee246a 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1,32 +1,23 @@ -/******************************************************************************* - OpenAirInterface - Copyright(c) 1999 - 2014 Eurecom - - OpenAirInterface is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - - OpenAirInterface is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with OpenAirInterface.The full GNU General Public License is - included in this distribution in the file called "COPYING". If not, - see <http://www.gnu.org/licenses/>. - - Contact Information - OpenAirInterface Admin: openair_admin@eurecom.fr - OpenAirInterface Tech : openair_tech@eurecom.fr - OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr - - Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE - -*******************************************************************************/ - +/* + * 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 lte-enb.c * \brief Top-level threads for eNodeB * \author R. Knopp, F. Kaltenberger, Navid Nikaein @@ -84,13 +75,14 @@ #include "PHY_INTERFACE/phy_interface.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "UTIL/OTG/otg_tx.h" #include "UTIL/OTG/otg_externs.h" #include "UTIL/MATH/oml.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "enb_config.h" -#include "targets/RT/USER/lte-softmodem.h" +#include "targets/RT/USER/lte-softmodem.h" //#include "PHY/TOOLS/time_meas.h" /* these variables have to be defined before including ENB_APP/enb_paramdef.h */ @@ -101,17 +93,13 @@ static int DEFENBS[] = {0}; #include "common/config/config_userapi.h" #ifndef OPENAIR2 -#include "UTIL/OTG/otg_extern.h" + #include "UTIL/OTG/otg_extern.h" #endif -#if defined(ENABLE_ITTI) -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -#ifdef PDCP_USE_NETLINK -# include "SIMULATION/ETH_TRANSPORT/proto.h" -#endif -# endif -#endif +#include "s1ap_eNB.h" +#include "SIMULATION/ETH_TRANSPORT/proto.h" + + #include "T.h" @@ -122,22 +110,22 @@ extern int emulate_rf; extern int numerology; extern clock_source_t clock_source; extern uint8_t dlsch_ue_select_tbl_in_use; -extern uint8_t nfapi_mode; + extern PARALLEL_CONF_t get_thread_parallel_conf(void); extern WORKER_CONF_t get_thread_worker_conf(void); -extern void phy_init_RU(RU_t*); -extern void phy_free_RU(RU_t*); +extern void phy_init_RU(RU_t *); +extern void phy_free_RU(RU_t *); void stop_RU(int nb_ru); void do_ru_sync(RU_t *ru); void configure_ru(int idx, - void *arg); + void *arg); void configure_rru(int idx, - void *arg); + void *arg); int attach_rru(RU_t *ru); @@ -146,7 +134,7 @@ int connect_rau(RU_t *ru); extern uint16_t sf_ahead; #if defined(PRE_SCD_THREAD) -void init_ru_vnf(void); + void init_ru_vnf(void); #endif @@ -156,74 +144,65 @@ void init_ru_vnf(void); extern void wait_eNBs(void); int attach_rru(RU_t *ru) { - ssize_t msg_len,len; RRU_CONFIG_msg_t rru_config_msg; int received_capabilities=0; - wait_eNBs(); + // Wait for capabilities while (received_capabilities==0) { - - memset((void*)&rru_config_msg,0,sizeof(rru_config_msg)); - rru_config_msg.type = RAU_tick; + memset((void *)&rru_config_msg,0,sizeof(rru_config_msg)); + rru_config_msg.type = RAU_tick; rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE; LOG_I(PHY,"Sending RAU tick to RRU %d\n",ru->idx); AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), - "RU %d cannot access remote radio\n",ru->idx); - + "RU %d cannot access remote radio\n",ru->idx); msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); - // wait for answer with timeout + // wait for answer with timeout if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, - &rru_config_msg, - msg_len))<0) { - LOG_I(PHY,"Waiting for RRU %d\n",ru->idx); - } - else if (rru_config_msg.type == RRU_capabilities) { + &rru_config_msg, + msg_len))<0) { + LOG_I(PHY,"Waiting for RRU %d\n",ru->idx); + } else if (rru_config_msg.type == RRU_capabilities) { AssertFatal(rru_config_msg.len==msg_len,"Received capabilities with incorrect length (%d!=%d)\n",(int)rru_config_msg.len,(int)msg_len); LOG_I(PHY,"Received capabilities from RRU %d (len %d/%d, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)\n",ru->idx, - (int)rru_config_msg.len,(int)msg_len, - ((RRU_capabilities_t*)&rru_config_msg.msg[0])->num_bands, - ((RRU_capabilities_t*)&rru_config_msg.msg[0])->max_pdschReferenceSignalPower[0], - ((RRU_capabilities_t*)&rru_config_msg.msg[0])->max_rxgain[0], - ((RRU_capabilities_t*)&rru_config_msg.msg[0])->nb_tx[0], - ((RRU_capabilities_t*)&rru_config_msg.msg[0])->nb_rx[0]); + (int)rru_config_msg.len,(int)msg_len, + ((RRU_capabilities_t *)&rru_config_msg.msg[0])->num_bands, + ((RRU_capabilities_t *)&rru_config_msg.msg[0])->max_pdschReferenceSignalPower[0], + ((RRU_capabilities_t *)&rru_config_msg.msg[0])->max_rxgain[0], + ((RRU_capabilities_t *)&rru_config_msg.msg[0])->nb_tx[0], + ((RRU_capabilities_t *)&rru_config_msg.msg[0])->nb_rx[0]); received_capabilities=1; - } - else { - LOG_E(PHY,"Received incorrect message %d from RRU %d\n",rru_config_msg.type,ru->idx); + } else { + LOG_E(PHY,"Received incorrect message %d from RRU %d\n",rru_config_msg.type,ru->idx); } } + configure_ru(ru->idx, - (RRU_capabilities_t *)&rru_config_msg.msg[0]); - + (RRU_capabilities_t *)&rru_config_msg.msg[0]); rru_config_msg.type = RRU_config; rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); LOG_I(PHY,"Sending Configuration to RRU %d (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n",ru->idx, - ((RRU_config_t *)&rru_config_msg.msg[0])->num_bands, - ((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->rx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_tx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_rx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_DL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_UL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->threequarter_fs[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_FreqOffset[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]); - - + ((RRU_config_t *)&rru_config_msg.msg[0])->num_bands, + ((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->rx_freq[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->att_tx[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->att_rx[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_DL[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_UL[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->threequarter_fs[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->prach_FreqOffset[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]); AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), - "RU %d failed send configuration to remote radio\n",ru->idx); - + "RU %d failed send configuration to remote radio\n",ru->idx); return 0; } int connect_rau(RU_t *ru) { - RRU_CONFIG_msg_t rru_config_msg; - ssize_t msg_len; + ssize_t msg_len; int tick_received = 0; int configuration_received = 0; RRU_capabilities_t *cap; @@ -232,85 +211,86 @@ int connect_rau(RU_t *ru) { // wait for RAU_tick while (tick_received == 0) { - msg_len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE; if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, - &rru_config_msg, - msg_len))<0) { - LOG_I(PHY,"Waiting for RAU\n"); - } - else { + &rru_config_msg, + msg_len))<0) { + LOG_I(PHY,"Waiting for RAU\n"); + } else { if (rru_config_msg.type == RAU_tick) { - LOG_I(PHY,"Tick received from RAU\n"); - tick_received = 1; - } - else LOG_E(PHY,"Received erroneous message (%d)from RAU, expected RAU_tick\n",rru_config_msg.type); + LOG_I(PHY,"Tick received from RAU\n"); + tick_received = 1; + } else LOG_E(PHY,"Received erroneous message (%d)from RAU, expected RAU_tick\n",rru_config_msg.type); } } // send capabilities - - rru_config_msg.type = RRU_capabilities; + rru_config_msg.type = RRU_capabilities; rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); - cap = (RRU_capabilities_t*)&rru_config_msg.msg[0]; + cap = (RRU_capabilities_t *)&rru_config_msg.msg[0]; LOG_I(PHY,"Sending Capabilities (len %d, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)\n", - (int)rru_config_msg.len,ru->num_bands,ru->max_pdschReferenceSignalPower,ru->max_rxgain,ru->nb_tx,ru->nb_rx); + (int)rru_config_msg.len,ru->num_bands,ru->max_pdschReferenceSignalPower,ru->max_rxgain,ru->nb_tx,ru->nb_rx); + switch (ru->function) { - case NGFI_RRU_IF4p5: - cap->FH_fmt = OAI_IF4p5_only; - break; - case NGFI_RRU_IF5: - cap->FH_fmt = OAI_IF5_only; - break; - case MBP_RRU_IF5: - cap->FH_fmt = MBP_IF5; - break; - default: - AssertFatal(1==0,"RU_function is unknown %d\n",RC.ru[0]->function); - break; + case NGFI_RRU_IF4p5: + cap->FH_fmt = OAI_IF4p5_only; + break; + + case NGFI_RRU_IF5: + cap->FH_fmt = OAI_IF5_only; + break; + + case MBP_RRU_IF5: + cap->FH_fmt = MBP_IF5; + break; + + default: + AssertFatal(1==0,"RU_function is unknown %d\n",RC.ru[0]->function); + break; } + cap->num_bands = ru->num_bands; - for (i=0;i<ru->num_bands;i++) { - LOG_I(PHY,"Band %d: nb_rx %d nb_tx %d pdschReferenceSignalPower %d rxgain %d\n", - ru->band[i],ru->nb_rx,ru->nb_tx,ru->max_pdschReferenceSignalPower,ru->max_rxgain); + + for (i=0; i<ru->num_bands; i++) { + LOG_I(PHY,"Band %d: nb_rx %d nb_tx %d pdschReferenceSignalPower %d rxgain %d\n", + ru->band[i],ru->nb_rx,ru->nb_tx,ru->max_pdschReferenceSignalPower,ru->max_rxgain); cap->band_list[i] = ru->band[i]; cap->nb_rx[i] = ru->nb_rx; cap->nb_tx[i] = ru->nb_tx; cap->max_pdschReferenceSignalPower[i] = ru->max_pdschReferenceSignalPower; cap->max_rxgain[i] = ru->max_rxgain; } - AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), - "RU %d failed send capabilities to RAU\n",ru->idx); + AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), + "RU %d failed send capabilities to RAU\n",ru->idx); // wait for configuration rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); - while (configuration_received == 0) { + while (configuration_received == 0) { if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, - &rru_config_msg, - rru_config_msg.len))<0) { - LOG_I(PHY,"Waiting for configuration from RAU\n"); - } - else { + &rru_config_msg, + rru_config_msg.len))<0) { + LOG_I(PHY,"Waiting for configuration from RAU\n"); + } else { LOG_I(PHY,"Configuration received from RAU (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL %d,3/4FS %d, prach_FO %d, prach_CI %d)\n", - ((RRU_config_t *)&rru_config_msg.msg[0])->num_bands, - ((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->rx_freq[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_tx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->att_rx[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_DL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_UL[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->threequarter_fs[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_FreqOffset[0], - ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]); - + ((RRU_config_t *)&rru_config_msg.msg[0])->num_bands, + ((RRU_config_t *)&rru_config_msg.msg[0])->band_list[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->tx_freq[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->rx_freq[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->att_tx[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->att_rx[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_DL[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->N_RB_UL[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->threequarter_fs[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->prach_FreqOffset[0], + ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]); configure_rru(ru->idx, - (void*)&rru_config_msg.msg[0]); + (void *)&rru_config_msg.msg[0]); configuration_received = 1; } } + return 0; } /*************************************************************/ @@ -319,43 +299,44 @@ int connect_rau(RU_t *ru) { // southbound IF5 fronthaul for 16-bit OAI format static inline void fh_if5_south_out(RU_t *ru) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); + send_IF5(ru, ru->proc.timestamp_tx, ru->proc.subframe_tx, &ru->seqno, IF5_RRH_GW_DL); } // southbound IF5 fronthaul for Mobipass packet format static inline void fh_if5_mobipass_south_out(RU_t *ru) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - send_IF5(ru, ru->proc.timestamp_tx, ru->proc.subframe_tx, &ru->seqno, IF5_MOBIPASS); + + send_IF5(ru, ru->proc.timestamp_tx, ru->proc.subframe_tx, &ru->seqno, IF5_MOBIPASS); } // southbound IF4p5 fronthaul static inline void fh_if4p5_south_out(RU_t *ru) { if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); + LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.subframe_tx); - if (subframe_select(&ru->frame_parms,ru->proc.subframe_tx)!=SF_UL) + + if (subframe_select(&ru->frame_parms,ru->proc.subframe_tx)!=SF_UL) send_IF4p5(ru,ru->proc.frame_tx, ru->proc.subframe_tx, IF4p5_PDLFFT); } /*************************************************************/ /* Input Fronthaul from south RCC/RAU */ -// Synchronous if5 from south +// Synchronous if5 from south void fh_if5_south_in(RU_t *ru,int *frame, int *subframe) { - LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; RU_proc_t *proc = &ru->proc; - - recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); - + recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - + if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe){ + if (proc->subframe_rx != *subframe) { LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); exit_fun("Exiting"); } - + if (proc->frame_rx != *frame) { LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,*frame); exit_fun("Exiting"); @@ -363,45 +344,44 @@ void fh_if5_south_in(RU_t *ru,int *frame, int *subframe) { } else { proc->first_rx = 0; *frame = proc->frame_rx; - *subframe = proc->subframe_rx; - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); + *subframe = proc->subframe_rx; + } + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); } -// Synchronous if4p5 from south +// Synchronous if4p5 from south void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) { - LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; RU_proc_t *proc = &ru->proc; int f,sf; - - uint16_t packet_type; uint32_t symbol_number=0; uint32_t symbol_mask_full; - if ((fp->frame_type == TDD) && (subframe_select(fp,*subframe)==SF_S)) - symbol_mask_full = (1<<fp->ul_symbols_in_S_subframe)-1; - else - symbol_mask_full = (1<<fp->symbols_per_tti)-1; + if ((fp->frame_type == TDD) && (subframe_select(fp,*subframe)==SF_S)) + symbol_mask_full = (1<<fp->ul_symbols_in_S_subframe)-1; + else + symbol_mask_full = (1<<fp->symbols_per_tti)-1; AssertFatal(proc->symbol_mask[*subframe]==0,"rx_fh_if4p5: proc->symbol_mask[%d] = %x\n",*subframe,proc->symbol_mask[*subframe]); + do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number); if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<<symbol_number); - else if (packet_type == IF4p5_PULTICK) { - if ((proc->first_rx==0) && (f!=*frame)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d\n",f,*frame); - if ((proc->first_rx==0) && (sf!=*subframe)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sf,*subframe,proc->first_rx); - break; - + else if (packet_type == IF4p5_PULTICK) { + if ((proc->first_rx==0) && (f!=*frame)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received frame %d != expected %d\n",f,*frame); + + if ((proc->first_rx==0) && (sf!=*subframe)) LOG_E(PHY,"rx_fh_if4p5: PULTICK received subframe %d != expected %d (first_rx %d)\n",sf,*subframe,proc->first_rx); + + break; } else if (packet_type == IF4p5_PRACH) { // nothing in RU for RAU } + LOG_D(PHY,"rx_fh_if4p5: subframe %d symbol mask %x\n",*subframe,proc->symbol_mask[*subframe]); - } while(proc->symbol_mask[*subframe] != symbol_mask_full); + } while(proc->symbol_mask[*subframe] != symbol_mask_full); //caculate timestamp_rx, timestamp_tx based on frame and subframe proc->subframe_rx = sf; @@ -410,12 +390,13 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) { // proc->timestamp_tx = proc->timestamp_rx + (4*fp->samples_per_tti); proc->subframe_tx = (sf+sf_ahead)%10; proc->frame_tx = (sf>(9-sf_ahead)) ? (f+1)&1023 : f; - + if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe){ + if (proc->subframe_rx != *subframe) { LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); exit_fun("Exiting"); } + if (proc->frame_rx != *frame) { LOG_E(PHY,"Received Timestamp (IF4p5) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,*frame); exit_fun("Exiting"); @@ -423,7 +404,7 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) { } else { proc->first_rx = 0; *frame = proc->frame_rx; - *subframe = proc->subframe_rx; + *subframe = proc->subframe_rx; } if (ru == RC.ru[0]) { @@ -433,7 +414,7 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); } - proc->symbol_mask[sf] = 0; + proc->symbol_mask[sf] = 0; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); LOG_D(PHY,"RU %d: fh_if4p5_south_in sleeping ...\n",ru->idx); usleep(100); @@ -449,99 +430,95 @@ void fh_slave_south_in(RU_t *ru,int *frame,int *subframe) { return; release_thread(&proc->mutex_FH,&proc->instance_cnt_FH,"rx_fh_slave_south_in"); - - } // asynchronous inbound if5 fronthaul from south (Mobipass) void fh_if5_south_asynch_in_mobipass(RU_t *ru,int *frame,int *subframe) { - RU_proc_t *proc = &ru->proc; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; - - recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_MOBIPASS); + recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_MOBIPASS); pthread_mutex_lock(&proc->mutex_asynch_rxtx); int offset_mobipass = 40120; pthread_mutex_lock(&proc->mutex_asynch_rxtx); proc->subframe_rx = ((proc->timestamp_rx-offset_mobipass)/fp->samples_per_tti)%10; proc->frame_rx = ((proc->timestamp_rx-offset_mobipass)/(fp->samples_per_tti*10))&1023; - proc->subframe_rx = (proc->timestamp_rx/fp->samples_per_tti)%10; proc->frame_rx = (proc->timestamp_rx/(10*fp->samples_per_tti))&1023; if (proc->first_rx == 1) { proc->first_rx =2; *subframe = proc->subframe_rx; - *frame = proc->frame_rx; + *frame = proc->frame_rx; LOG_E(PHY,"[Mobipass]timestamp_rx:%llu, frame_rx %d, subframe: %d\n",(unsigned long long int)proc->timestamp_rx,proc->frame_rx,proc->subframe_rx); - } - else { + } else { if (proc->subframe_rx != *subframe) { - proc->first_rx++; - LOG_E(PHY,"[Mobipass]timestamp:%llu, subframe_rx %d is not what we expect %d, first_rx:%d\n",(unsigned long long int)proc->timestamp_rx, proc->subframe_rx,*subframe, proc->first_rx); + proc->first_rx++; + LOG_E(PHY,"[Mobipass]timestamp:%llu, subframe_rx %d is not what we expect %d, first_rx:%d\n",(unsigned long long int)proc->timestamp_rx, proc->subframe_rx,*subframe, proc->first_rx); //exit_fun("Exiting"); } + if (proc->frame_rx != *frame) { - proc->first_rx++; - LOG_E(PHY,"[Mobipass]timestamp:%llu, frame_rx %d is not what we expect %d, first_rx:%d\n",(unsigned long long int)proc->timestamp_rx,proc->frame_rx,*frame, proc->first_rx); - // exit_fun("Exiting"); + proc->first_rx++; + LOG_E(PHY,"[Mobipass]timestamp:%llu, frame_rx %d is not what we expect %d, first_rx:%d\n",(unsigned long long int)proc->timestamp_rx,proc->frame_rx,*frame, proc->first_rx); + // exit_fun("Exiting"); } + // temporary solution - *subframe = proc->subframe_rx; - *frame = proc->frame_rx; + *subframe = proc->subframe_rx; + *frame = proc->frame_rx; } pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - - -} // eNodeB_3GPP_BBU +} // eNodeB_3GPP_BBU // asynchronous inbound if4p5 fronthaul from south void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *subframe) { - LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; RU_proc_t *proc = &ru->proc; - uint16_t packet_type; uint32_t symbol_number,symbol_mask,prach_rx; uint32_t got_prach_info=0; - symbol_number = 0; symbol_mask = (1<<fp->symbols_per_tti)-1; prach_rx = 0; do { // Blocking, we need a timeout on this !!!!!!!!!!!!!!!!!!!!!!! recv_IF4p5(ru, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number); + // grab first prach information for this new subframe if (got_prach_info==0) { prach_rx = is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx); got_prach_info = 1; } + if (proc->first_rx != 0) { *frame = proc->frame_rx; *subframe = proc->subframe_rx; proc->first_rx = 0; - } - else { + } else { if (proc->frame_rx != *frame) { - LOG_E(PHY,"frame_rx %d is not what we expect %d\n",proc->frame_rx,*frame); - exit_fun("Exiting"); + LOG_E(PHY,"frame_rx %d is not what we expect %d\n",proc->frame_rx,*frame); + exit_fun("Exiting"); } + if (proc->subframe_rx != *subframe) { - LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe); - exit_fun("Exiting"); + LOG_E(PHY,"subframe_rx %d is not what we expect %d\n",proc->subframe_rx,*subframe); + exit_fun("Exiting"); } } + if (packet_type == IF4p5_PULFFT) symbol_mask &= (~(1<<symbol_number)); else if (packet_type == IF4p5_PRACH) prach_rx &= (~0x1); + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) else if (packet_type == IF4p5_PRACH_BR_CE0) prach_rx &= (~0x2); else if (packet_type == IF4p5_PRACH_BR_CE1) prach_rx &= (~0x4); else if (packet_type == IF4p5_PRACH_BR_CE2) prach_rx &= (~0x8); else if (packet_type == IF4p5_PRACH_BR_CE3) prach_rx &= (~0x10); + #endif - } while( (symbol_mask > 0) || (prach_rx >0)); // haven't received all PUSCH symbols and PRACH information -} + } while( (symbol_mask > 0) || (prach_rx >0)); // haven't received all PUSCH symbols and PRACH information +} @@ -549,25 +526,22 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *subframe) { /*************************************************************/ /* Input Fronthaul from North RRU */ - -// RRU IF4p5 TX fronthaul receiver. Assumes an if_device on input and if or rf device on output + +// RRU IF4p5 TX fronthaul receiver. Assumes an if_device on input and if or rf device on output // receives one subframe's worth of IF4p5 OFDM symbols and OFDM modulates void fh_if4p5_north_in(RU_t *ru,int *frame,int *subframe) { - uint32_t symbol_number=0; uint32_t symbol_mask, symbol_mask_full; uint16_t packet_type; - - - /// **** incoming IF4p5 from remote RCC/RAU **** /// + /// **** incoming IF4p5 from remote RCC/RAU **** /// symbol_number = 0; symbol_mask = 0; symbol_mask_full = (1<<ru->frame_parms.symbols_per_tti)-1; - - do { + + do { recv_IF4p5(ru, frame, subframe, &packet_type, &symbol_number); symbol_mask = symbol_mask | (1<<symbol_number); - } while (symbol_mask != symbol_mask_full); + } while (symbol_mask != symbol_mask_full); // dump VCD output for first RU in list if (ru == RC.ru[0]) { @@ -577,15 +551,12 @@ void fh_if4p5_north_in(RU_t *ru,int *frame,int *subframe) { } void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { - LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; RU_proc_t *proc = &ru->proc; int subframe_tx,frame_tx; openair0_timestamp timestamp_tx; - - recv_IF5(ru, ×tamp_tx, *subframe, IF5_RRH_GW_DL); - // printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx); - + recv_IF5(ru, ×tamp_tx, *subframe, IF5_RRH_GW_DL); + // printf("Received subframe %d (TS %llu) from RCC\n",subframe_tx,timestamp_tx); subframe_tx = (timestamp_tx/fp->samples_per_tti)%10; frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023; @@ -593,50 +564,49 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { *subframe = subframe_tx; *frame = frame_tx; proc->first_tx = 0; - } - else { + } else { AssertFatal(subframe_tx == *subframe, "subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe); - AssertFatal(frame_tx == *frame, + AssertFatal(frame_tx == *frame, "frame_tx %d is not what we expect %d\n",frame_tx,*frame); } } void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { - LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; RU_proc_t *proc = &ru->proc; - uint16_t packet_type; uint32_t symbol_number,symbol_mask,symbol_mask_full; int subframe_tx,frame_tx; - LOG_D(PHY, "%s(ru:%p frame, subframe)\n", __FUNCTION__, ru); symbol_number = 0; symbol_mask = 0; symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<<fp->dl_symbols_in_S_subframe) : (1<<fp->symbols_per_tti))-1; - do { + + do { recv_IF4p5(ru, &frame_tx, &subframe_tx, &packet_type, &symbol_number); + if ((subframe_select(fp,subframe_tx) == SF_DL) && (symbol_number == 0)) start_meas(&ru->rx_fhaul); + LOG_D(PHY,"subframe %d (%d): frame %d, subframe %d, symbol %d\n", - *subframe,subframe_select(fp,*subframe),frame_tx,subframe_tx,symbol_number); + *subframe,subframe_select(fp,*subframe),frame_tx,subframe_tx,symbol_number); + if (proc->first_tx != 0) { *frame = frame_tx; *subframe = subframe_tx; proc->first_tx = 0; symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<<fp->dl_symbols_in_S_subframe) : (1<<fp->symbols_per_tti))-1; - } - else { + } else { AssertFatal(frame_tx == *frame, - "frame_tx %d is not what we expect %d\n",frame_tx,*frame); + "frame_tx %d is not what we expect %d\n",frame_tx,*frame); AssertFatal(subframe_tx == *subframe, - "subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe); + "subframe_tx %d is not what we expect %d\n",subframe_tx,*subframe); } + if (packet_type == IF4p5_PDLFFT) { symbol_mask = symbol_mask | (1<<symbol_number); - } - else AssertFatal(1==0,"Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n",packet_type); - } while (symbol_mask != symbol_mask_full); + } else AssertFatal(1==0,"Illegal IF4p5 packet type (should only be IF4p5_PDLFFT%d\n",packet_type); + } while (symbol_mask != symbol_mask_full); if (subframe_select(fp,subframe_tx) == SF_DL) stop_meas(&ru->rx_fhaul); @@ -646,36 +616,34 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) { if ((frame_tx == 0)&&(subframe_tx == 0)) proc->frame_tx_unwrap += 1024; proc->timestamp_tx = ((((uint64_t)frame_tx + (uint64_t)proc->frame_tx_unwrap) * 10) + (uint64_t)subframe_tx) * (uint64_t)fp->samples_per_tti; - LOG_D(PHY,"RU %d/%d TST %llu, frame %d, subframe %d\n",ru->idx,0,(long long unsigned int)proc->timestamp_tx,frame_tx,subframe_tx); - // dump VCD output for first RU in list + + // dump VCD output for first RU in list if (ru == RC.ru[0]) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, subframe_tx ); } if (ru->feptx_ofdm) ru->feptx_ofdm(ru); + if (ru->fh_south_out) ru->fh_south_out(ru); -} +} void fh_if5_north_out(RU_t *ru) { - RU_proc_t *proc=&ru->proc; uint8_t seqno=0; - - /// **** send_IF5 of rxdata to BBU **** /// - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); + /// **** send_IF5 of rxdata to BBU **** /// + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); send_IF5(ru, proc->timestamp_rx, proc->subframe_rx, &seqno, IF5_RRH_GW_UL); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 ); } // RRU IF4p5 northbound interface (RX) void fh_if4p5_north_out(RU_t *ru) { - RU_proc_t *proc=&ru->proc; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; const int subframe = proc->subframe_rx; + if (ru->idx==0) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU, proc->subframe_rx ); if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) { @@ -687,23 +655,22 @@ void fh_if4p5_north_out(RU_t *ru) { start_meas(&ru->tx_fhaul); send_IF4p5(ru, proc->frame_rx, proc->subframe_rx, IF4p5_PULFFT); stop_meas(&ru->tx_fhaul); - } /* add fail safe for late command */ typedef enum { - STATE_BURST_NORMAL = 0, - STATE_BURST_TERMINATE = 1, - STATE_BURST_STOP_1 = 2, - STATE_BURST_STOP_2 = 3, - STATE_BURST_RESTART = 4, + STATE_BURST_NORMAL = 0, + STATE_BURST_TERMINATE = 1, + STATE_BURST_STOP_1 = 2, + STATE_BURST_STOP_2 = 3, + STATE_BURST_RESTART = 4, } late_control_e; volatile late_control_e late_control=STATE_BURST_NORMAL; /* add fail safe for late command end */ -static void* emulatedRF_thread(void* param) { +static void *emulatedRF_thread(void *param) { RU_proc_t *proc = (RU_proc_t *) param; int microsec = 500; // length of time to sleep, in miliseconds struct timespec req = {0}; @@ -713,65 +680,63 @@ static void* emulatedRF_thread(void* param) { cpu_set_t cpuset; CPU_SET(1,&cpuset); pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - int policy; struct sched_param sparam; memset(&sparam, 0, sizeof(sparam)); sparam.sched_priority = sched_get_priority_max(SCHED_FIFO); - policy = SCHED_FIFO ; + policy = SCHED_FIFO ; pthread_setschedparam(pthread_self(), policy, &sparam); - wait_sync("emulatedRF_thread"); - while(!oai_exit){ + + while(!oai_exit) { nanosleep(&req, (struct timespec *)NULL); - if(proc->emulate_rf_busy ) - { + + if(proc->emulate_rf_busy ) { LOG_E(PHY,"rf being delayed in emulated RF\n"); } + proc->emulate_rf_busy = 1; pthread_mutex_lock(&proc->mutex_emulateRF); ++proc->instance_cnt_emulateRF; pthread_mutex_unlock(&proc->mutex_emulateRF); pthread_cond_signal(&proc->cond_emulateRF); } + return 0; } void rx_rf(RU_t *ru,int *frame,int *subframe) { - RU_proc_t *proc = &ru->proc; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; void *rxp[ru->nb_rx]; unsigned int rxs; int i; openair0_timestamp ts=0,old_ts=0; - + for (i=0; i<ru->nb_rx; i++) - rxp[i] = (void*)&ru->common.rxdata[i][*subframe*fp->samples_per_tti]; + rxp[i] = (void *)&ru->common.rxdata[i][*subframe*fp->samples_per_tti]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - old_ts = proc->timestamp_rx; - if(get_softmodem_params()->emulate_rf){ + + if(get_softmodem_params()->emulate_rf) { wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread"); release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread"); rxs = fp->samples_per_tti; - } - else{ + } else { rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &ts, - rxp, - fp->samples_per_tti, - ru->nb_rx); + &ts, + rxp, + fp->samples_per_tti, + ru->nb_rx); } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - proc->timestamp_rx = ts-ru->ts_offset; -// AssertFatal(rxs == fp->samples_per_tti, -// "rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs); - if(rxs != fp->samples_per_tti){ + // AssertFatal(rxs == fp->samples_per_tti, + // "rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs); + if(rxs != fp->samples_per_tti) { LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs); late_control=STATE_BURST_TERMINATE; } @@ -779,51 +744,47 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { if (proc->first_rx == 1) { ru->ts_offset = proc->timestamp_rx; proc->timestamp_rx = 0; - } - else { + } else { if (proc->timestamp_rx - old_ts != fp->samples_per_tti) { //LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset); ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); proc->timestamp_rx = ts-ru->ts_offset; } - } + proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; // synchronize first reception to frame 0 subframe 0 - #ifdef PHY_TX_THREAD proc->timestamp_phy_tx = proc->timestamp_rx+((sf_ahead-1)*fp->samples_per_tti); - proc->subframe_phy_tx = (proc->subframe_rx+(sf_ahead-1))%10; + proc->subframe_phy_tx = (proc->subframe_rx+(sf_ahead-1))%10; proc->frame_phy_tx = (proc->subframe_rx>(9-(sf_ahead-1))) ? (proc->frame_rx+1)&1023 : proc->frame_rx; #else proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti); proc->subframe_tx = (proc->subframe_rx+sf_ahead)%10; proc->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; #endif - //proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti); //proc->subframe_tx = (proc->subframe_rx+sf_ahead)%10; //proc->frame_tx = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; - LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, subframe %d\n", - ru->idx, - 0, - (unsigned long long int)proc->timestamp_rx, - (int)ru->ts_offset,proc->frame_rx,proc->subframe_rx); + ru->idx, + 0, + (unsigned long long int)proc->timestamp_rx, + (int)ru->ts_offset,proc->frame_rx,proc->subframe_rx); - // dump VCD output for first RU in list + // dump VCD output for first RU in list if (ru == RC.ru[0]) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_RU, proc->frame_rx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_RU, proc->subframe_rx ); } - + if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe){ + if (proc->subframe_rx != *subframe) { LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",(long long unsigned int)proc->timestamp_rx,proc->subframe_rx,*subframe); exit_fun("Exiting"); } - + if (proc->frame_rx != *frame) { LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",(long long unsigned int)proc->timestamp_rx,proc->frame_rx,*frame); exit_fun("Exiting"); @@ -831,130 +792,122 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { } else { proc->first_rx = 0; *frame = proc->frame_rx; - *subframe = proc->subframe_rx; + *subframe = proc->subframe_rx; } - + //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - - if (rxs != fp->samples_per_tti) - { + + if (rxs != fp->samples_per_tti) { #if defined(USRP_REC_PLAY) exit_fun("Exiting IQ record/playback"); -#else +#else //exit_fun( "problem receiving samples" ); LOG_E(PHY, "problem receiving samples"); -#endif +#endif } } void tx_rf(RU_t *ru) { - RU_proc_t *proc = &ru->proc; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; - void *txp[ru->nb_tx]; + void *txp[ru->nb_tx]; unsigned int txs; int i; - T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(proc->frame_tx), T_INT(proc->subframe_tx), T_INT(0), T_BUFFER(&ru->common.txdata[0][proc->subframe_tx * fp->samples_per_tti], fp->samples_per_tti * 4)); - lte_subframe_t SF_type = subframe_select(fp,proc->subframe_tx%10); lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10); - lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_tx+1)%10); int sf_extension = 0; if ((SF_type == SF_DL) || (SF_type == SF_S)) { - int siglen=fp->samples_per_tti,flags=1; - + if (SF_type == SF_S) { - siglen = fp->dl_symbols_in_S_subframe*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); + /* end_of_burst_delay is used to stop TX only "after a while". + * If we stop right after effective signal, with USRP B210 and + * B200mini, we observe a high EVM on the S subframe (on the + * PSS). + * A value of 400 (for 30.72MHz) solves this issue. This is + * the default. + */ + siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + + (fp->dl_symbols_in_S_subframe - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples) + + ru->end_of_burst_delay; flags=3; // end of burst } - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_DL)) { + + if (fp->frame_type == TDD && + SF_type == SF_DL && + prevSF_type == SF_UL) { flags = 2; // start of burst - sf_extension = ru->N_TA_offset; - } - - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_UL)) { - flags = 4; // start of burst and end of burst (only one DL SF between two UL) - sf_extension = ru->N_TA_offset; - } + sf_extension = ru->sf_extension; + } + #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ - sf_extension = (sf_extension)&0xfffffff8; + sf_extension = (sf_extension)&0xfffffff8; #else - sf_extension = (sf_extension)&0xfffffffc; + sf_extension = (sf_extension)&0xfffffffc; #endif #elif defined(__arm__) - sf_extension = (sf_extension)&0xfffffffc; + sf_extension = (sf_extension)&0xfffffffc; #endif - + for (i=0; i<ru->nb_tx; i++) - txp[i] = (void*)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_tti)-sf_extension]; + txp[i] = (void *)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_tti)-sf_extension]; /* add fail safe for late command */ - if(late_control!=STATE_BURST_NORMAL){//stop burst + if(late_control!=STATE_BURST_NORMAL) { //stop burst switch (late_control) { - case STATE_BURST_TERMINATE: - flags=10; // end of burst and no time spec - late_control=STATE_BURST_STOP_1; - break; - - case STATE_BURST_STOP_1: - flags=0; // no send - late_control=STATE_BURST_STOP_2; - return;//no send - break; - - case STATE_BURST_STOP_2: - flags=0; // no send - late_control=STATE_BURST_RESTART; - return;//no send - break; - - case STATE_BURST_RESTART: - flags=2; // start burst - late_control=STATE_BURST_NORMAL; - break; - default: - LOG_D(PHY,"[TXPATH] RU %d late_control %d not implemented\n",ru->idx, late_control); - break; + case STATE_BURST_TERMINATE: + flags=10; // end of burst and no time spec + late_control=STATE_BURST_STOP_1; + break; + + case STATE_BURST_STOP_1: + flags=0; // no send + late_control=STATE_BURST_STOP_2; + return;//no send + break; + + case STATE_BURST_STOP_2: + flags=0; // no send + late_control=STATE_BURST_RESTART; + return;//no send + break; + + case STATE_BURST_RESTART: + flags=2; // start burst + late_control=STATE_BURST_NORMAL; + break; + + default: + LOG_D(PHY,"[TXPATH] RU %d late_control %d not implemented\n",ru->idx, late_control); + break; } } - /* add fail safe for late command end */ + /* add fail safe for late command end */ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers - txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - ru->nb_tx, - flags); - + proc->timestamp_tx+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, + txp, + siglen+sf_extension, + ru->nb_tx, + flags); LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, - (long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx); + (long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - - -// AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen); - if( (txs != siglen+sf_extension) && (late_control==STATE_BURST_NORMAL) ){ /* add fail safe for late command */ + + // AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen); + if( (txs != siglen+sf_extension) && (late_control==STATE_BURST_NORMAL) ) { /* add fail safe for late command */ late_control=STATE_BURST_TERMINATE; LOG_E(PHY,"TX : Timeout (sent %d/%d) state =%d\n",txs, siglen,late_control); } @@ -968,51 +921,39 @@ void tx_rf(RU_t *ru) { * \param param is a \ref L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void* ru_thread_asynch_rxtx( void* param ) { - +static void *ru_thread_asynch_rxtx( void *param ) { static int ru_thread_asynch_rxtx_status; - - RU_t *ru = (RU_t*)param; + RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; - - - - int subframe=0, frame=0; - + int subframe=0, frame=0; thread_top_init("ru_thread_asynch_rxtx",1,870000,1000000,1000000); - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe - wait_sync("ru_thread_asynch_rxtx"); - // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe printf( "waiting for devices (ru_thread_asynch_rx)\n"); - wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch"); - printf( "devices ok (ru_thread_asynch_rx)\n"); + while (!oai_exit) { + if (oai_exit) break; - while (!oai_exit) { - - if (oai_exit) break; - - if (subframe==9) { + if (subframe==9) { subframe=0; frame++; frame&=1023; } else { subframe++; - } + } + LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n"); - // asynchronous receive from south (Mobipass) + + // asynchronous receive from south (Mobipass) if (ru->fh_south_asynch_in) ru->fh_south_asynch_in(ru,&frame,&subframe); // asynchronous receive from north (RRU IF4/IF5) else if (ru->fh_north_asynch_in) { - if (subframe_select(&ru->frame_parms,subframe)!=SF_UL) - ru->fh_north_asynch_in(ru,&frame,&subframe); - } - else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n"); + if (subframe_select(&ru->frame_parms,subframe)!=SF_UL) + ru->fh_north_asynch_in(ru,&frame,&subframe); + } else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n"); } ru_thread_asynch_rxtx_status=0; @@ -1023,15 +964,14 @@ static void* ru_thread_asynch_rxtx( void* param ) { void wakeup_slaves(RU_proc_t *proc) { - int i; struct timespec wait; - wait.tv_sec=0; wait.tv_nsec=5000000L; - - for (i=0;i<proc->num_slaves;i++) { + + for (i=0; i<proc->num_slaves; i++) { RU_proc_t *slave_proc = proc->slave_proc[i]; + // wake up slave FH thread // lock the FH mutex and make sure the thread is ready if (pthread_mutex_timedlock(&slave_proc->mutex_FH,&wait) != 0) { @@ -1039,27 +979,26 @@ void wakeup_slaves(RU_proc_t *proc) { exit_fun( "error locking mutex_rxtx" ); break; } - + int cnt_slave = ++slave_proc->instance_cnt_FH; slave_proc->frame_rx = proc->frame_rx; slave_proc->subframe_rx = proc->subframe_rx; slave_proc->timestamp_rx = proc->timestamp_rx; - slave_proc->timestamp_tx = proc->timestamp_tx; - + slave_proc->timestamp_tx = proc->timestamp_tx; pthread_mutex_unlock( &slave_proc->mutex_FH ); - + if (cnt_slave == 0) { // the thread was presumably waiting where it should and can now be woken up if (pthread_cond_signal(&slave_proc->cond_FH) != 0) { - LOG_E( PHY, "ERROR pthread_cond_signal for RU %d, slave RU %d\n",proc->ru->idx,slave_proc->ru->idx); - exit_fun( "ERROR pthread_cond_signal" ); - break; + LOG_E( PHY, "ERROR pthread_cond_signal for RU %d, slave RU %d\n",proc->ru->idx,slave_proc->ru->idx); + exit_fun( "ERROR pthread_cond_signal" ); + break; } } else { LOG_W( PHY,"[RU] Frame %d, slave %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->ru->idx, cnt_slave); exit_fun( "FH thread busy" ); break; - } + } } } @@ -1068,16 +1007,12 @@ void wakeup_slaves(RU_proc_t *proc) { * \param param is a \ref RU_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void* ru_thread_prach( void* param ) { - +static void *ru_thread_prach( void *param ) { static int ru_thread_prach_status; - - RU_t *ru = (RU_t*)param; - RU_proc_t *proc = (RU_proc_t*)&ru->proc; - + RU_t *ru = (RU_t *)param; + RU_proc_t *proc = (RU_proc_t *)&ru->proc; // set default return value ru_thread_prach_status = 0; - thread_top_init("ru_thread_prach",1,500000,1000000,20000000); //wait_sync("ru_thread_prach"); @@ -1085,84 +1020,82 @@ static void* ru_thread_prach( void* param ) { usleep(1e6); LOG_I(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__); } + LOG_I(PHY,"%s() RU configured - RACH processing thread running\n", __FUNCTION__); while (!oai_exit) { - if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; + if (oai_exit) break; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); - if (ru->eNB_list[0]){ + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); + + if (ru->eNB_list[0]) { prach_procedures( ru->eNB_list[0] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0 #endif - ); - } - else { - rx_prach(NULL, - ru, - NULL, - NULL, - NULL, - proc->frame_prach, - 0 + ); + } else { + rx_prach(NULL, + ru, + NULL, + NULL, + NULL, + proc->frame_prach, + 0 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0 + ,0 #endif - ); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 ); + ); + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 ); + if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; } LOG_I(PHY, "Exiting RU thread PRACH\n"); - ru_thread_prach_status = 0; return &ru_thread_prach_status; } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -static void* ru_thread_prach_br( void* param ) { - +static void *ru_thread_prach_br( void *param ) { static int ru_thread_prach_status; - - RU_t *ru = (RU_t*)param; - RU_proc_t *proc = (RU_proc_t*)&ru->proc; - + RU_t *ru = (RU_t *)param; + RU_proc_t *proc = (RU_proc_t *)&ru->proc; // set default return value ru_thread_prach_status = 0; - thread_top_init("ru_thread_prach_br",1,500000,1000000,20000000); //wait_sync("ru_thread_prach_br"); while (!oai_exit) { - if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"ru_prach_thread_br") < 0) break; + if (oai_exit) break; + rx_prach(NULL, - ru, - NULL, + ru, + NULL, NULL, NULL, proc->frame_prach_br, 0, - 1); + 1); + if (release_thread(&proc->mutex_prach_br,&proc->instance_cnt_prach_br,"ru_prach_thread_br") < 0) break; } LOG_I(PHY, "Exiting RU thread PRACH BR\n"); - ru_thread_prach_status = 0; return &ru_thread_prach_status; } #endif -int wakeup_synch(RU_t *ru){ - +int wakeup_synch(RU_t *ru) { struct timespec wait; - wait.tv_sec=0; wait.tv_nsec=5000000L; @@ -1173,23 +1106,21 @@ int wakeup_synch(RU_t *ru){ exit_fun( "error locking mutex_synch" ); return(-1); } - + ++ru->proc.instance_cnt_synch; - + // the thread can now be woken up if (pthread_cond_signal(&ru->proc.cond_synch) != 0) { LOG_E( PHY, "[RU] ERROR pthread_cond_signal for RU synch thread\n"); exit_fun( "ERROR pthread_cond_signal" ); return(-1); } - - pthread_mutex_unlock( &ru->proc.mutex_synch ); + pthread_mutex_unlock( &ru->proc.mutex_synch ); return(0); } void do_ru_synch(RU_t *ru) { - LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; RU_proc_t *proc = &ru->proc; int i; @@ -1199,102 +1130,99 @@ void do_ru_synch(RU_t *ru) { int ic; // initialize the synchronization buffer to the common_vars.rxdata - for (int i=0;i<ru->nb_rx;i++) + for (int i=0; i<ru->nb_rx; i++) rxp[i] = &ru->common.rxdata[i][0]; double temp_freq1 = ru->rfdevice.openair0_cfg->rx_freq[0]; double temp_freq2 = ru->rfdevice.openair0_cfg->tx_freq[0]; - for (i=0;i<4;i++) { + + for (i=0; i<4; i++) { ru->rfdevice.openair0_cfg->rx_freq[i] = ru->rfdevice.openair0_cfg->tx_freq[i]; ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq1; } + ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0); - + while ((ru->in_synch ==0)&&(!oai_exit)) { // read in frame rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp, - fp->samples_per_tti*10, - ru->nb_rx); + &(proc->timestamp_rx), + rxp, + fp->samples_per_tti*10, + ru->nb_rx); + if (rxs != fp->samples_per_tti*10) LOG_E(PHY,"requested %d samples, got %d\n",fp->samples_per_tti*10,rxs); - + // wakeup synchronization processing thread wakeup_synch(ru); ic=0; - + while ((ic>=0)&&(!oai_exit)) { - // continuously read in frames, 1ms at a time, + // continuously read in frames, 1ms at a time, // until we are done with the synchronization procedure - for (i=0; i<ru->nb_rx; i++) - rxp2[i] = (void*)&dummy_rx[i][0]; - for (i=0;i<10;i++) - rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp2, - fp->samples_per_tti, - ru->nb_rx); + rxp2[i] = (void *)&dummy_rx[i][0]; + + for (i=0; i<10; i++) + rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, + &(proc->timestamp_rx), + rxp2, + fp->samples_per_tti, + ru->nb_rx); + pthread_mutex_lock(&ru->proc.mutex_synch); ic = ru->proc.instance_cnt_synch; pthread_mutex_unlock(&ru->proc.mutex_synch); } // ic>=0 } // in_synch==0 - // read in rx_offset samples + + // read in rx_offset samples LOG_I(PHY,"Resynchronizing by %d samples\n",ru->rx_offset); rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, - &(proc->timestamp_rx), - rxp, - ru->rx_offset, - ru->nb_rx); - for (i=0;i<4;i++) { + &(proc->timestamp_rx), + rxp, + ru->rx_offset, + ru->nb_rx); + + for (i=0; i<4; i++) { ru->rfdevice.openair0_cfg->rx_freq[i] = temp_freq1; ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq2; } ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0); - } void wakeup_L1s(RU_t *ru) { - int i; PHY_VARS_eNB **eNB_list = ru->eNB_list; - LOG_D(PHY,"wakeup_L1s (num %d) for RU %d ru->eNB_top:%p\n",ru->num_eNB,ru->idx, ru->eNB_top); - if (ru->num_eNB==1 && ru->eNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) { // call eNB function directly - char string[20]; sprintf(string,"Incoming RU %d",ru->idx); LOG_D(PHY,"RU %d Call eNB_top\n",ru->idx); ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string,ru); ru->proc.emulate_rf_busy = 0; - } - else { - + } else { LOG_D(PHY,"ru->num_eNB:%d\n", ru->num_eNB); - for (i=0;i<ru->num_eNB;i++) - { + for (i=0; i<ru->num_eNB; i++) { LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->wakeup_rxtx); - if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0) - { + + if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0) { LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx); } + ru->proc.emulate_rf_busy = 0; } } } static inline int wakeup_prach_ru(RU_t *ru) { - struct timespec wait; - wait.tv_sec=0; wait.tv_nsec=5000000L; @@ -1303,6 +1231,7 @@ static inline int wakeup_prach_ru(RU_t *ru) { exit_fun( "error locking mutex_rxtx" ); return(-1); } + if (ru->proc.instance_cnt_prach==-1) { ++ru->proc.instance_cnt_prach; ru->proc.frame_prach = ru->proc.frame_rx; @@ -1313,21 +1242,19 @@ static inline int wakeup_prach_ru(RU_t *ru) { ru->eNB_list[0]->proc.frame_prach = ru->proc.frame_rx; ru->eNB_list[0]->proc.subframe_prach = ru->proc.subframe_rx; } + LOG_D(PHY,"RU %d: waking up PRACH thread\n",ru->idx); // the thread can now be woken up AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n"); - } - else LOG_W(PHY,"RU prach thread busy, skipping\n"); - pthread_mutex_unlock( &ru->proc.mutex_prach ); + } else LOG_W(PHY,"RU prach thread busy, skipping\n"); + pthread_mutex_unlock( &ru->proc.mutex_prach ); return(0); } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) static inline int wakeup_prach_ru_br(RU_t *ru) { - struct timespec wait; - wait.tv_sec=0; wait.tv_nsec=5000000L; @@ -1336,62 +1263,59 @@ static inline int wakeup_prach_ru_br(RU_t *ru) { exit_fun( "error locking mutex_rxtx" ); return(-1); } + if (ru->proc.instance_cnt_prach_br==-1) { ++ru->proc.instance_cnt_prach_br; ru->proc.frame_prach_br = ru->proc.frame_rx; ru->proc.subframe_prach_br = ru->proc.subframe_rx; - LOG_D(PHY,"RU %d: waking up PRACH thread\n",ru->idx); // the thread can now be woken up AssertFatal(pthread_cond_signal(&ru->proc.cond_prach_br) == 0, "ERROR pthread_cond_signal for RU prach thread BR\n"); - } - else LOG_W(PHY,"RU prach thread busy, skipping\n"); - pthread_mutex_unlock( &ru->proc.mutex_prach_br ); + } else LOG_W(PHY,"RU prach thread busy, skipping\n"); + pthread_mutex_unlock( &ru->proc.mutex_prach_br ); return(0); } #endif // this is for RU with local RF unit void fill_rf_config(RU_t *ru, char *rf_config_file) { - int i; - LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; openair0_config_t *cfg = &ru->openair0_cfg; //printf("////////////////numerology in config = %d\n",numerology); int numerology = get_softmodem_params()->numerology; + if(fp->N_RB_DL == 100) { - if(numerology == 0){ + if(numerology == 0) { if (fp->threequarter_fs) { cfg->sample_rate=23.04e6; - cfg->samples_per_frame = 230400; + cfg->samples_per_frame = 230400; cfg->tx_bw = 10e6; cfg->rx_bw = 10e6; - } - else { + } else { cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; + cfg->samples_per_frame = 307200; cfg->tx_bw = 10e6; cfg->rx_bw = 10e6; } - }else if(numerology == 1){ - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 307200; + } else if(numerology == 1) { + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 307200; cfg->tx_bw = 20e6; cfg->rx_bw = 20e6; - }else if(numerology == 2){ - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 307200; + } else if(numerology == 2) { + cfg->sample_rate=122.88e6; + cfg->samples_per_frame = 307200; cfg->tx_bw = 40e6; cfg->rx_bw = 40e6; - }else{ - printf("Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology); - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; + } else { + printf("Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology); + cfg->sample_rate=30.72e6; + cfg->samples_per_frame = 307200; cfg->tx_bw = 10e6; cfg->rx_bw = 10e6; - } + } } else if(fp->N_RB_DL == 50) { cfg->sample_rate=15.36e6; cfg->samples_per_frame = 153600; @@ -1407,8 +1331,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->samples_per_frame = 19200; cfg->tx_bw = 1.5e6; cfg->rx_bw = 1.5e6; - } - else AssertFatal(1==0,"Unknown N_RB_DL %d\n",fp->N_RB_DL); + } else AssertFatal(1==0,"Unknown N_RB_DL %d\n",fp->N_RB_DL); if (fp->frame_type==TDD) cfg->duplex_mode = duplex_mode_TDD; @@ -1422,20 +1345,16 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->clock_source=get_softmodem_params()->clock_source; for (i=0; i<ru->nb_tx; i++) { - cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; - cfg->tx_gain[i] = (double)ru->att_tx; cfg->rx_gain[i] = ru->max_rxgain-(double)ru->att_rx; - - cfg->configFilename = rf_config_file; printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", - i, cfg->tx_gain[i], - cfg->rx_gain[i], - cfg->tx_freq[i], - cfg->rx_freq[i]); + i, cfg->tx_gain[i], + cfg->rx_gain[i], + cfg->tx_freq[i], + cfg->rx_freq[i]); } } @@ -1444,239 +1363,248 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { rf_map specifies for each antenna port, on which rf chain the mapping should start. Multiple antennas are mapped to successive RF chains on the same card. */ int setup_RU_buffers(RU_t *ru) { - - int i,j; + int i,j; int card,ant; - //uint16_t N_TA_offset = 0; - LTE_DL_FRAME_PARMS *frame_parms; - + if (ru) { frame_parms = &ru->frame_parms; printf("setup_RU_buffers: frame_parms = %p\n",frame_parms); } else { - printf("RU[%d] not initialized\n", ru->idx); + printf("RU not initialized (NULL pointer)\n"); return(-1); } - - + if (frame_parms->frame_type == TDD) { if (frame_parms->N_RB_DL == 100) ru->N_TA_offset = 624; else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2; else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4; -#if BASIC_SIMULATOR - /* this is required for the basic simulator in TDD mode - * TODO: find a proper cleaner solution - */ + + if(IS_SOFTMODEM_BASICSIM) + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ + ru->N_TA_offset = 0; + + if (frame_parms->N_RB_DL == 100) /* no scaling to do */; + else if (frame_parms->N_RB_DL == 50) { + ru->sf_extension /= 2; + ru->end_of_burst_delay /= 2; + } else if (frame_parms->N_RB_DL == 25) { + ru->sf_extension /= 4; + ru->end_of_burst_delay /= 4; + } else { + printf("not handled, todo\n"); + exit(1); + } + } else { ru->N_TA_offset = 0; -#endif - } + ru->sf_extension = 0; + ru->end_of_burst_delay = 0; + } + if (ru->openair0_cfg.mmapped_dma == 1) { // replace RX signal buffers with mmaped HW versions - for (i=0; i<ru->nb_rx; i++) { card = i/4; ant = i%4; printf("Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); free(ru->common.rxdata[i]); ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant]; - printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]); + for (j=0; j<16; j++) { - printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]); - ru->common.rxdata[i][j] = 16-j; + printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]); + ru->common.rxdata[i][j] = 16-j; } } - + for (i=0; i<ru->nb_tx; i++) { card = i/4; ant = i%4; printf("Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); free(ru->common.txdata[i]); ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant]; - printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]); - + for (j=0; j<16; j++) { - printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]); - ru->common.txdata[i][j] = 16-j; + printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]); + ru->common.txdata[i][j] = 16-j; } } - } - else { // not memory-mapped DMA + } else { // not memory-mapped DMA //nothing to do, everything already allocated in lte_init } + return(0); } -static void* ru_stats_thread(void* param) { - - RU_t *ru = (RU_t*)param; +static void *ru_stats_thread(void *param) { + RU_t *ru = (RU_t *)param; wait_sync("ru_stats_thread"); while (!oai_exit) { - sleep(1); - if (opp_enabled) { - if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL); - if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); - if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); - if (ru->fh_north_out) { - print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL); - print_meas(&ru->compression,"compression",NULL,NULL); - print_meas(&ru->transport,"transport",NULL,NULL); - } - } + sleep(1); + + if (opp_enabled) { + if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL); + + if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); + + if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); + + if (ru->fh_north_out) { + print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL); + print_meas(&ru->compression,"compression",NULL,NULL); + print_meas(&ru->transport,"transport",NULL,NULL); + } + } } + return(NULL); } #ifdef PHY_TX_THREAD -int first_phy_tx = 1; -volatile int16_t phy_tx_txdataF_end; -volatile int16_t phy_tx_end; + int first_phy_tx = 1; + volatile int16_t phy_tx_txdataF_end; + volatile int16_t phy_tx_end; #endif -static void* ru_thread_tx( void* param ) { - RU_t *ru = (RU_t*)param; +static void *ru_thread_tx( void *param ) { + RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; PHY_VARS_eNB *eNB; L1_proc_t *eNB_proc; L1_rxtx_proc_t *L1_proc; - cpu_set_t cpuset; CPU_ZERO(&cpuset); - - thread_top_init("ru_thread_tx",1,400000,500000,500000); - //CPU_SET(5, &cpuset); //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); //wait_sync("ru_thread_tx"); - wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); - - printf( "ru_thread_tx ready\n"); - while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX,sched_getcpu()); - if (oai_exit) break; + while (!oai_exit) { + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD_TX,sched_getcpu()); + if (oai_exit) break; LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n"); // wait until eNBs are finished subframe RX n and TX n+4 wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); + if (oai_exit) break; - + // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru); - + // do OFDM if needed if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); - if(!(get_softmodem_params()->emulate_rf)){ + + if(!(get_softmodem_params()->emulate_rf)) { // do outgoing fronthaul (south) if needed if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); - + if (ru->fh_north_out) ru->fh_north_out(ru); - } + } + release_thread(&proc->mutex_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); - for(int i = 0; i<ru->num_eNB; i++) - { + + for(int i = 0; i<ru->num_eNB; i++) { eNB = ru->eNB_list[i]; eNB_proc = &eNB->proc; L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &eNB_proc->L1_proc_tx : &eNB_proc->L1_proc; pthread_mutex_lock(&eNB_proc->mutex_RU_tx); - for (int j=0;j<eNB->num_RU;j++) { + + for (int j=0; j<eNB->num_RU; j++) { if (ru == eNB->RU_list[j]) { if ((eNB_proc->RU_mask_tx&(1<<j)) > 0) LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", - eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx); + eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx); + eNB_proc->RU_mask_tx |= (1<<j); } } + if (eNB_proc->RU_mask_tx != (1<<eNB->num_RU)-1) { // not all RUs have provided their information so return pthread_mutex_unlock(&eNB_proc->mutex_RU_tx); - } - else { // all RUs TX are finished so send the ready signal to eNB processing + } else { // all RUs TX are finished so send the ready signal to eNB processing eNB_proc->RU_mask_tx = 0; pthread_mutex_unlock(&eNB_proc->mutex_RU_tx); - pthread_mutex_lock( &L1_proc->mutex_RUs); L1_proc->instance_cnt_RUs = 0; + // the thread can now be woken up if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); } + pthread_mutex_unlock( &L1_proc->mutex_RUs ); } } } + release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); return 0; } -static void* ru_thread( void* param ) { - +static void *ru_thread( void *param ) { static int ru_thread_status; - - RU_t *ru = (RU_t*)param; + RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; int ret; int subframe =9; - int frame =1023; + int frame =1023; cpu_set_t cpuset; CPU_ZERO(&cpuset); - - // set default return value ru_thread_status = 0; #if defined(PRE_SCD_THREAD) dlsch_ue_select_tbl_in_use = 1; #endif - - // set default return value thread_top_init("ru_thread",1,400000,500000,500000); - //CPU_SET(1, &cpuset); //pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); pthread_setname_np( pthread_self(),"ru thread"); LOG_I(PHY,"thread ru created id=%ld\n", syscall(__NR_gettid)); - LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]); - if(get_softmodem_params()->emulate_rf){ + if(get_softmodem_params()->emulate_rf) { fill_rf_config(ru,ru->rf_config_file); init_frame_parms(&ru->frame_parms,1); phy_init_RU(ru); + if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); } - } - else{ + } else { // Start IF device if any if (ru->start_if) { LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx); AssertFatal(ru->start_if(ru,NULL) == 0, "Could not start the IF device\n"); + if (ru->if_south == LOCAL_RF) ret = connect_rau(ru); else ret = attach_rru(ru); + AssertFatal(ret==0,"Cannot connect to radio\n"); } - if (ru->if_south == LOCAL_RF) { // configure RF parameters only - fill_rf_config(ru,ru->rf_config_file); - init_frame_parms(&ru->frame_parms,1); - phy_init_RU(ru); - - - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + + if (ru->if_south == LOCAL_RF) { // configure RF parameters only + fill_rf_config(ru,ru->rf_config_file); + init_frame_parms(&ru->frame_parms,1); + phy_init_RU(ru); + ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); } + if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); } } @@ -1685,174 +1613,173 @@ static void* ru_thread( void* param ) { RC.ru_mask &= ~(1<<ru->idx); pthread_cond_signal(&RC.ru_cond); pthread_mutex_unlock(&RC.ru_mutex); - - pthread_mutex_lock(&proc->mutex_FH1); proc->instance_cnt_FH1 = 0; pthread_mutex_unlock(&proc->mutex_FH1); pthread_cond_signal(&proc->cond_FH1); - wait_sync("ru_thread"); - if(!(get_softmodem_params()->emulate_rf)){ + if(!(get_softmodem_params()->emulate_rf)) { // Start RF device if any if (ru->start_rf) { if (ru->start_rf(ru) != 0) LOG_E(HW,"Could not start the RF device\n"); else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); - } - else LOG_I(PHY,"RU %d no rf device\n",ru->idx); - + } else LOG_I(PHY,"RU %d no rf device\n",ru->idx); + // if an asnych_rxtx thread exists // wakeup the thread because the devices are ready at this point - + if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) { pthread_mutex_lock(&proc->mutex_asynch_rxtx); proc->instance_cnt_asynch_rxtx=0; pthread_mutex_unlock(&proc->mutex_asynch_rxtx); pthread_cond_signal(&proc->cond_asynch_rxtx); - } - else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx); - + } else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx); + // if this is a slave RRU, try to synchronize on the DL frequency if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru); } - - - // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices while (!oai_exit) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_RU_THREAD,sched_getcpu()); // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // They are set on the first rx/tx in the underly FH routines. - if (subframe==9) { + if (subframe==9) { subframe=0; frame++; frame&=1023; } else { subframe++; - } + } // synchronization on input FH interface, acquire signals/data and block if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe); else AssertFatal(1==0, "No fronthaul interface at south port"); #ifdef PHY_TX_THREAD - if(first_phy_tx == 0) - { - phy_tx_end = 0; - phy_tx_txdataF_end = 0; - if(pthread_mutex_lock(&ru->proc.mutex_phy_tx) != 0){ - LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for phy tx thread (IC %d)\n", ru->proc.instance_cnt_phy_tx); - exit_fun( "error locking mutex_rxtx" ); - } - if (ru->proc.instance_cnt_phy_tx==-1) { - ++ru->proc.instance_cnt_phy_tx; - - // the thread can now be woken up - AssertFatal(pthread_cond_signal(&ru->proc.cond_phy_tx) == 0, "ERROR pthread_cond_signal for phy_tx thread\n"); - }else{ - LOG_E(PHY,"phy tx thread busy, skipping\n"); - ++ru->proc.instance_cnt_phy_tx; - } - pthread_mutex_unlock( &ru->proc.mutex_phy_tx ); + + if(first_phy_tx == 0) { + phy_tx_end = 0; + phy_tx_txdataF_end = 0; + + if(pthread_mutex_lock(&ru->proc.mutex_phy_tx) != 0) { + LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for phy tx thread (IC %d)\n", ru->proc.instance_cnt_phy_tx); + exit_fun( "error locking mutex_rxtx" ); + } + + if (ru->proc.instance_cnt_phy_tx==-1) { + ++ru->proc.instance_cnt_phy_tx; + // the thread can now be woken up + AssertFatal(pthread_cond_signal(&ru->proc.cond_phy_tx) == 0, "ERROR pthread_cond_signal for phy_tx thread\n"); + } else { + LOG_E(PHY,"phy tx thread busy, skipping\n"); + ++ru->proc.instance_cnt_phy_tx; + } + + pthread_mutex_unlock( &ru->proc.mutex_phy_tx ); } else { - phy_tx_end = 1; - phy_tx_txdataF_end = 1; + phy_tx_end = 1; + phy_tx_txdataF_end = 1; } + first_phy_tx = 0; #endif - - - LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", + LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n", ru->do_prach, is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx), proc->frame_rx,proc->subframe_rx); + if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) { wakeup_prach_ru(ru); } + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) { wakeup_prach_ru_br(ru); } + #endif // adjust for timing offset between RU if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023; - // do RX front-end processing (frequency-shift, dft) if needed if (ru->feprx) ru->feprx(ru); // At this point, all information for subframe has been received on FH interface // If this proc is to provide synchronization, do so wakeup_slaves(proc); - #if defined(PRE_SCD_THREAD) new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use; dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + if (pthread_mutex_lock(&ru->proc.mutex_pre_scd)!= 0) { - LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n"); - exit_fun("error locking mutex_time"); + LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n"); + exit_fun("error locking mutex_time"); } ru->proc.instance_pre_scd++; if (ru->proc.instance_pre_scd == 0) { - if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" ); - exit_fun( "ERROR pthread_cond_signal cond_pre_scd" ); - } - }else{ - LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n", - frame,subframe,ru->proc.instance_pre_scd ); + if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" ); + exit_fun( "ERROR pthread_cond_signal cond_pre_scd" ); + } + } else { + LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n", + frame,subframe,ru->proc.instance_pre_scd ); } if (pthread_mutex_unlock(&ru->proc.mutex_pre_scd)!= 0) { - LOG_E( PHY, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n"); - exit_fun("error unlocking mutex_pre_scd"); + LOG_E( PHY, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n"); + exit_fun("error unlocking mutex_pre_scd"); } + #endif // wakeup all eNB processes waiting for this RU if (ru->num_eNB>0) wakeup_L1s(ru); - + #ifndef PHY_TX_THREAD - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0){ + + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_eNB==0) { // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru); - + // do OFDM if needed if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); - if(!(get_softmodem_params()->emulate_rf)){ + + if(!(get_softmodem_params()->emulate_rf)) { // do outgoing fronthaul (south) if needed if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); - + if (ru->fh_north_out) ru->fh_north_out(ru); } + proc->emulate_rf_busy = 0; } + #else struct timespec time_req, time_rem; time_req.tv_sec = 0; time_req.tv_nsec = 10000; - while((!oai_exit)&&(phy_tx_end == 0)){ - nanosleep(&time_req,&time_rem); - continue; + while((!oai_exit)&&(phy_tx_end == 0)) { + nanosleep(&time_req,&time_rem); + continue; } + #endif } - printf( "Exiting ru_thread \n"); - if (!(get_softmodem_params()->emulate_rf)){ + if (!(get_softmodem_params()->emulate_rf)) { if (ru->stop_rf != NULL) { if (ru->stop_rf(ru) != 0) LOG_E(HW,"Could not stop the RF device\n"); @@ -1862,75 +1789,65 @@ static void* ru_thread( void* param ) { ru_thread_status = 0; return &ru_thread_status; - } // This thread run the initial synchronization like a UE void *ru_thread_synch(void *arg) { - - RU_t *ru = (RU_t*)arg; + RU_t *ru = (RU_t *)arg; LTE_DL_FRAME_PARMS *fp=&ru->frame_parms; int32_t sync_pos,sync_pos2; uint32_t peak_val; uint32_t sync_corr[307200] __attribute__((aligned(32))); static int ru_thread_synch_status; - - thread_top_init("ru_thread_synch",0,5000000,10000000,10000000); - wait_sync("ru_thread_synch"); - // initialize variables for PSS detection lte_sync_time_init(&ru->frame_parms); while (!oai_exit) { - // wait to be woken up if (wait_on_condition(&ru->proc.mutex_synch,&ru->proc.cond_synch,&ru->proc.instance_cnt_synch,"ru_thread_synch")<0) break; // if we're not in synch, then run initial synch - if (ru->in_synch == 0) { + if (ru->in_synch == 0) { // run intial synch like UE LOG_I(PHY,"Running initial synchronization\n"); - sync_pos = lte_sync_time_eNB(ru->common.rxdata, - fp, - fp->samples_per_tti*5, - &peak_val, - sync_corr); + fp, + fp->samples_per_tti*5, + &peak_val, + sync_corr); LOG_I(PHY,"RU synch: %d, val %d\n",sync_pos,peak_val); if (sync_pos >= 0) { - if (sync_pos >= fp->nb_prefix_samples) - sync_pos2 = sync_pos - fp->nb_prefix_samples; - else - sync_pos2 = sync_pos + (fp->samples_per_tti*10) - fp->nb_prefix_samples; - - if (fp->frame_type == FDD) { - - // PSS is hypothesized in last symbol of first slot in Frame - int sync_pos_slot = (fp->samples_per_tti>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples; - - if (sync_pos2 >= sync_pos_slot) - ru->rx_offset = sync_pos2 - sync_pos_slot; - else - ru->rx_offset = (fp->samples_per_tti*10) + sync_pos2 - sync_pos_slot; - } - else { - - } - - LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,ru->rx_offset); - - if (LOG_DEBUGFLAG(RU)) { - if ((peak_val > 300000) && (sync_pos > 0)) { - LOG_M("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_tti*5,1,2); - LOG_M("ru_rx.m","rxs",&(ru->eNB_list[0]->common_vars.rxdata[0][0]),fp->samples_per_tti*10,1,1); - exit(-1); - } + if (sync_pos >= fp->nb_prefix_samples) + sync_pos2 = sync_pos - fp->nb_prefix_samples; + else + sync_pos2 = sync_pos + (fp->samples_per_tti*10) - fp->nb_prefix_samples; + + if (fp->frame_type == FDD) { + // PSS is hypothesized in last symbol of first slot in Frame + int sync_pos_slot = (fp->samples_per_tti>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples; + + if (sync_pos2 >= sync_pos_slot) + ru->rx_offset = sync_pos2 - sync_pos_slot; + else + ru->rx_offset = (fp->samples_per_tti*10) + sync_pos2 - sync_pos_slot; + } else { } - ru->in_synch=1; + + LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,ru->rx_offset); + + if (LOG_DEBUGFLAG(RU)) { + if ((peak_val > 300000) && (sync_pos > 0)) { + LOG_M("ru_sync.m","sync",(void *)&sync_corr[0],fp->samples_per_tti*5,1,2); + LOG_M("ru_rx.m","rxs",&(ru->eNB_list[0]->common_vars.rxdata[0][0]),fp->samples_per_tti*10,1,1); + exit(-1); + } + } + + ru->in_synch=1; } } @@ -1939,64 +1856,67 @@ void *ru_thread_synch(void *arg) { ru_thread_synch_status = 0; return &ru_thread_synch_status; - } #if defined(PRE_SCD_THREAD) -void* pre_scd_thread( void* param ){ - static int eNB_pre_scd_status; - protocol_ctxt_t ctxt; - int frame; - int subframe; - int min_rb_unit[MAX_NUM_CCs]; - int CC_id; - int Mod_id; - RU_t *ru = (RU_t*)param; - - // L2-emulator can work only one eNB - if( nfapi_mode == 2) - Mod_id = 0; - else - Mod_id = ru->eNB_list[0]->Mod_id; - - frame = 0; - subframe = 4; - thread_top_init("pre_scd_thread",0,870000,1000000,1000000); - - while (!oai_exit) { - if(oai_exit){ - break; - } - pthread_mutex_lock(&ru->proc.mutex_pre_scd ); - if (ru->proc.instance_pre_scd < 0) { - pthread_cond_wait(&ru->proc.cond_pre_scd, &ru->proc.mutex_pre_scd); - } - pthread_mutex_unlock(&ru->proc.mutex_pre_scd); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, Mod_id, ENB_FLAG_YES, - NOT_A_RNTI, frame, subframe,Mod_id); - pdcp_run(&ctxt); +void *pre_scd_thread( void *param ) { + static int eNB_pre_scd_status; + protocol_ctxt_t ctxt; + int frame; + int subframe; + int min_rb_unit[MAX_NUM_CCs]; + int CC_id; + int Mod_id; + RU_t *ru = (RU_t *)param; + + // L2-emulator can work only one eNB + if( NFAPI_MODE==NFAPI_MODE_VNF) + Mod_id = 0; + else + Mod_id = ru->eNB_list[0]->Mod_id; + + frame = 0; + subframe = 4; + thread_top_init("pre_scd_thread",0,870000,1000000,1000000); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + while (!oai_exit) { + if(oai_exit) { + break; + } - rrc_rx_tx(&ctxt, CC_id); - min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); - } + pthread_mutex_lock(&ru->proc.mutex_pre_scd ); - pre_scd_nb_rbs_required(Mod_id, frame, subframe,min_rb_unit,pre_nb_rbs_required[new_dlsch_ue_select_tbl_in_use]); + if (ru->proc.instance_pre_scd < 0) { + pthread_cond_wait(&ru->proc.cond_pre_scd, &ru->proc.mutex_pre_scd); + } - if (subframe==9) { - subframe=0; - frame++; - frame&=1023; - } else { - subframe++; - } - pthread_mutex_lock(&ru->proc.mutex_pre_scd ); - ru->proc.instance_pre_scd--; - pthread_mutex_unlock(&ru->proc.mutex_pre_scd); + pthread_mutex_unlock(&ru->proc.mutex_pre_scd); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, Mod_id, ENB_FLAG_YES, + NOT_A_RNTI, frame, subframe,Mod_id); + pdcp_run(&ctxt); + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + rrc_rx_tx(&ctxt, CC_id); + min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); + } + + pre_scd_nb_rbs_required(Mod_id, frame, subframe,min_rb_unit,pre_nb_rbs_required[new_dlsch_ue_select_tbl_in_use]); + + if (subframe==9) { + subframe=0; + frame++; + frame&=1023; + } else { + subframe++; } - eNB_pre_scd_status = 0; - return &eNB_pre_scd_status; + + pthread_mutex_lock(&ru->proc.mutex_pre_scd ); + ru->proc.instance_pre_scd--; + pthread_mutex_unlock(&ru->proc.mutex_pre_scd); + } + + eNB_pre_scd_status = 0; + return &eNB_pre_scd_status; } #endif @@ -2006,111 +1926,106 @@ void* pre_scd_thread( void* param ){ * \param param is a \ref L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void* eNB_thread_phy_tx( void* param ) { +static void *eNB_thread_phy_tx( void *param ) { static int eNB_thread_phy_tx_status; - - - RU_t *ru = (RU_t*)param; + RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; PHY_VARS_eNB **eNB_list = ru->eNB_list; - L1_rxtx_proc_t L1_proc; - // set default return value eNB_thread_phy_tx_status = 0; - thread_top_init("eNB_thread_phy_tx",1,500000L,1000000L,20000000L); - while (!oai_exit) { - if (oai_exit) break; - if (wait_on_condition(&proc->mutex_phy_tx,&proc->cond_phy_tx,&proc->instance_cnt_phy_tx,"eNB_phy_tx_thread") < 0) break; LOG_D(PHY,"Running eNB phy tx procedures\n"); - if(ru->num_eNB == 1){ - L1_proc.subframe_tx = proc->subframe_phy_tx; - L1_proc.frame_tx = proc->frame_phy_tx; - phy_procedures_eNB_TX(eNB_list[0], &L1_proc, 1); - phy_tx_txdataF_end = 1; - if(pthread_mutex_lock(&ru->proc.mutex_rf_tx) != 0){ - LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for rf tx thread (IC %d)\n", ru->proc.instance_cnt_rf_tx); - exit_fun( "error locking mutex_rf_tx" ); - } - if (ru->proc.instance_cnt_rf_tx==-1) { - ++ru->proc.instance_cnt_rf_tx; - ru->proc.frame_tx = proc->frame_phy_tx; - ru->proc.subframe_tx = proc->subframe_phy_tx; - ru->proc.timestamp_tx = proc->timestamp_phy_tx; - - // the thread can now be woken up - AssertFatal(pthread_cond_signal(&ru->proc.cond_rf_tx) == 0, "ERROR pthread_cond_signal for rf_tx thread\n"); - }else{ - LOG_E(PHY,"rf tx thread busy, skipping\n"); - late_control=STATE_BURST_TERMINATE; - } - pthread_mutex_unlock( &ru->proc.mutex_rf_tx ); + + if(ru->num_eNB == 1) { + L1_proc.subframe_tx = proc->subframe_phy_tx; + L1_proc.frame_tx = proc->frame_phy_tx; + phy_procedures_eNB_TX(eNB_list[0], &L1_proc, 1); + phy_tx_txdataF_end = 1; + + if(pthread_mutex_lock(&ru->proc.mutex_rf_tx) != 0) { + LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for rf tx thread (IC %d)\n", ru->proc.instance_cnt_rf_tx); + exit_fun( "error locking mutex_rf_tx" ); + } + + if (ru->proc.instance_cnt_rf_tx==-1) { + ++ru->proc.instance_cnt_rf_tx; + ru->proc.frame_tx = proc->frame_phy_tx; + ru->proc.subframe_tx = proc->subframe_phy_tx; + ru->proc.timestamp_tx = proc->timestamp_phy_tx; + // the thread can now be woken up + AssertFatal(pthread_cond_signal(&ru->proc.cond_rf_tx) == 0, "ERROR pthread_cond_signal for rf_tx thread\n"); + } else { + LOG_E(PHY,"rf tx thread busy, skipping\n"); + late_control=STATE_BURST_TERMINATE; + } + + pthread_mutex_unlock( &ru->proc.mutex_rf_tx ); } + if (release_thread(&proc->mutex_phy_tx,&proc->instance_cnt_phy_tx,"eNB_thread_phy_tx") < 0) break; + phy_tx_end = 1; } LOG_I(PHY, "Exiting eNB thread PHY TX\n"); - eNB_thread_phy_tx_status = 0; return &eNB_thread_phy_tx_status; } -static void* rf_tx( void* param ) { +static void *rf_tx( void *param ) { static int rf_tx_status; - - RU_t *ru = (RU_t*)param; + RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; - // set default return value rf_tx_status = 0; - thread_top_init("rf_tx",1,500000L,1000000L,20000000L); - - while (!oai_exit) { + while (!oai_exit) { if (oai_exit) break; - if (wait_on_condition(&proc->mutex_rf_tx,&proc->cond_rf_tx,&proc->instance_cnt_rf_tx,"rf_tx_thread") < 0) break; LOG_D(PHY,"Running eNB rf tx procedures\n"); - if(ru->num_eNB == 1){ - // do TX front-end processing if needed (precoding and/or IDFTs) - if (ru->feptx_prec) ru->feptx_prec(ru); - // do OFDM if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); - if(!emulate_rf){ - // do outgoing fronthaul (south) if needed - if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); - - if (ru->fh_north_out) ru->fh_north_out(ru); - } + + if(ru->num_eNB == 1) { + // do TX front-end processing if needed (precoding and/or IDFTs) + if (ru->feptx_prec) ru->feptx_prec(ru); + + // do OFDM if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); + + if(!emulate_rf) { + // do outgoing fronthaul (south) if needed + if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); + + if (ru->fh_north_out) ru->fh_north_out(ru); + } } + if (release_thread(&proc->mutex_rf_tx,&proc->instance_cnt_rf_tx,"rf_tx") < 0) break; - if(proc->instance_cnt_rf_tx >= 0){ + + if(proc->instance_cnt_rf_tx >= 0) { late_control=STATE_BURST_TERMINATE; LOG_E(PHY,"detect rf tx busy change mode TX failsafe\n"); } } LOG_I(PHY, "Exiting rf TX\n"); - rf_tx_status = 0; return &rf_tx_status; } #endif - + int start_if(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB) { return(ru->ifdevice.trx_start_func(&ru->ifdevice)); } @@ -2119,8 +2034,7 @@ int start_rf(RU_t *ru) { return(ru->rfdevice.trx_start_func(&ru->rfdevice)); } -int stop_rf(RU_t *ru) -{ +int stop_rf(RU_t *ru) { ru->rfdevice.trx_end_func(&ru->rfdevice); return 0; } @@ -2136,7 +2050,6 @@ extern void kill_fep_thread(RU_t *ru); extern void kill_feptx_thread(RU_t *ru); void init_RU_proc(RU_t *ru) { - int i=0; RU_proc_t *proc; pthread_attr_t *attr_FH=NULL,*attr_FH1=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_synch=NULL,*attr_emulateRF=NULL; @@ -2145,13 +2058,11 @@ void init_RU_proc(RU_t *ru) { pthread_attr_t *attr_prach_br=NULL; #endif char name[100]; - #ifndef OCP_FRAMEWORK LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]); #endif proc = &ru->proc; - memset((void*)proc,0,sizeof(RU_proc_t)); - + memset((void *)proc,0,sizeof(RU_proc_t)); proc->ru = ru; proc->instance_cnt_prach = -1; proc->instance_cnt_synch = -1; @@ -2166,8 +2077,8 @@ void init_RU_proc(RU_t *ru) { proc->num_slaves = 0; proc->frame_tx_unwrap = 0; - for (i=0;i<10;i++) proc->symbol_mask[i]=0; - + for (i=0; i<10; i++) proc->symbol_mask[i]=0; + pthread_mutex_init( &proc->mutex_prach, NULL); pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_synch,NULL); @@ -2175,7 +2086,6 @@ void init_RU_proc(RU_t *ru) { pthread_mutex_init( &proc->mutex_FH1,NULL); pthread_mutex_init( &proc->mutex_emulateRF,NULL); pthread_mutex_init( &proc->mutex_eNBs, NULL); - pthread_cond_init( &proc->cond_prach, NULL); pthread_cond_init( &proc->cond_FH, NULL); pthread_cond_init( &proc->cond_FH1, NULL); @@ -2183,7 +2093,6 @@ void init_RU_proc(RU_t *ru) { pthread_cond_init( &proc->cond_asynch_rxtx, NULL); pthread_cond_init( &proc->cond_synch,NULL); pthread_cond_init( &proc->cond_eNBs, NULL); - pthread_attr_init( &proc->attr_FH); pthread_attr_init( &proc->attr_FH1); pthread_attr_init( &proc->attr_emulateRF); @@ -2191,14 +2100,12 @@ void init_RU_proc(RU_t *ru) { pthread_attr_init( &proc->attr_synch); pthread_attr_init( &proc->attr_asynch_rxtx); pthread_attr_init( &proc->attr_fep); - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) proc->instance_cnt_prach_br = -1; pthread_mutex_init( &proc->mutex_prach_br, NULL); pthread_cond_init( &proc->cond_prach_br, NULL); pthread_attr_init( &proc->attr_prach_br); -#endif - +#endif #ifdef PHY_TX_THREAD proc->instance_cnt_phy_tx = -1; pthread_mutex_init( &proc->mutex_phy_tx, NULL); @@ -2207,7 +2114,6 @@ void init_RU_proc(RU_t *ru) { pthread_mutex_init( &proc->mutex_rf_tx, NULL); pthread_cond_init( &proc->cond_rf_tx, NULL); #endif - #ifndef DEADLINE_SCHEDULER attr_FH = &proc->attr_FH; attr_FH1 = &proc->attr_FH1; @@ -2219,65 +2125,57 @@ void init_RU_proc(RU_t *ru) { attr_prach_br = &proc->attr_prach_br; #endif #endif - - pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru ); - + pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void *)ru ); #if defined(PRE_SCD_THREAD) - proc->instance_pre_scd = -1; - pthread_mutex_init( &proc->mutex_pre_scd, NULL); - pthread_cond_init( &proc->cond_pre_scd, NULL); - pthread_create(&proc->pthread_pre_scd, NULL, pre_scd_thread, (void*)ru); - pthread_setname_np(proc->pthread_pre_scd, "pre_scd_thread"); + proc->instance_pre_scd = -1; + pthread_mutex_init( &proc->mutex_pre_scd, NULL); + pthread_cond_init( &proc->cond_pre_scd, NULL); + pthread_create(&proc->pthread_pre_scd, NULL, pre_scd_thread, (void *)ru); + pthread_setname_np(proc->pthread_pre_scd, "pre_scd_thread"); #endif - #ifdef PHY_TX_THREAD - pthread_create( &proc->pthread_phy_tx, NULL, eNB_thread_phy_tx, (void*)ru ); - pthread_setname_np( proc->pthread_phy_tx, "phy_tx_thread" ); - pthread_create( &proc->pthread_rf_tx, NULL, rf_tx, (void*)ru ); + pthread_create( &proc->pthread_phy_tx, NULL, eNB_thread_phy_tx, (void *)ru ); + pthread_setname_np( proc->pthread_phy_tx, "phy_tx_thread" ); + pthread_create( &proc->pthread_rf_tx, NULL, rf_tx, (void *)ru ); #endif if(get_softmodem_params()->emulate_rf) - pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc ); + pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void *)proc ); if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) - pthread_create( &proc->pthread_FH1, attr_FH1, ru_thread_tx, (void*)ru ); + pthread_create( &proc->pthread_FH1, attr_FH1, ru_thread_tx, (void *)ru ); if (ru->function == NGFI_RRU_IF4p5) { - pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - pthread_create( &proc->pthread_prach_br, attr_prach_br, ru_thread_prach_br, (void*)ru ); + pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void *)ru ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + pthread_create( &proc->pthread_prach_br, attr_prach_br, ru_thread_prach_br, (void *)ru ); #endif - if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void*)ru); - - + + if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void *)ru); + if ((ru->if_timing == synch_to_other) || - (ru->function == NGFI_RRU_IF5) || - (ru->function == NGFI_RRU_IF4p5)) - { - pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, ru_thread_asynch_rxtx, (void*)ru ); - } - + (ru->function == NGFI_RRU_IF5) || + (ru->function == NGFI_RRU_IF4p5)) { + pthread_create( &proc->pthread_asynch_rxtx, attr_asynch, ru_thread_asynch_rxtx, (void *)ru ); + } + snprintf( name, sizeof(name), "ru_thread_FH %d", ru->idx ); pthread_setname_np( proc->pthread_FH, name ); - - } - else if (ru->function == eNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF + } else if (ru->function == eNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__); - pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); + pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void *)ru ); } - if (get_thread_worker_conf() == WORKER_ENABLE) { - init_fep_thread(ru,NULL); + if (get_thread_worker_conf() == WORKER_ENABLE) { + init_fep_thread(ru,NULL); init_feptx_thread(ru,NULL); - } - if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void*)ru); - + } + + if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void *)ru); } -void kill_RU_proc(RU_t *ru) -{ +void kill_RU_proc(RU_t *ru) { RU_proc_t *proc = &ru->proc; - #if defined(PRE_SCD_THREAD) pthread_mutex_lock(&proc->mutex_pre_scd); ru->proc.instance_pre_scd = 0; @@ -2305,57 +2203,52 @@ void kill_RU_proc(RU_t *ru) #endif if (get_thread_worker_conf() == WORKER_ENABLE) { - LOG_D(PHY, "killing FEP thread\n"); - kill_fep_thread(ru); - LOG_D(PHY, "killing FEP TX thread\n"); - kill_feptx_thread(ru); + LOG_D(PHY, "killing FEP thread\n"); + kill_fep_thread(ru); + LOG_D(PHY, "killing FEP TX thread\n"); + kill_feptx_thread(ru); } pthread_mutex_lock(&proc->mutex_FH); proc->instance_cnt_FH = 0; pthread_cond_signal(&proc->cond_FH); pthread_mutex_unlock(&proc->mutex_FH); - pthread_mutex_lock(&proc->mutex_FH1); proc->instance_cnt_FH1 = 0; pthread_cond_signal(&proc->cond_FH1); pthread_mutex_unlock(&proc->mutex_FH1); - pthread_mutex_lock(&proc->mutex_prach); proc->instance_cnt_prach = 0; pthread_cond_signal(&proc->cond_prach); pthread_mutex_unlock(&proc->mutex_prach); - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_mutex_lock(&proc->mutex_prach_br); proc->instance_cnt_prach_br = 0; pthread_cond_signal(&proc->cond_prach_br); pthread_mutex_unlock(&proc->mutex_prach_br); #endif - pthread_mutex_lock(&proc->mutex_synch); proc->instance_cnt_synch = 0; pthread_cond_signal(&proc->cond_synch); pthread_mutex_unlock(&proc->mutex_synch); - pthread_mutex_lock(&proc->mutex_eNBs); proc->instance_cnt_eNBs = 1; // cond_eNBs is used by both ru_thread and ru_thread_tx, so we need to send // a broadcast to wake up both threads pthread_cond_broadcast(&proc->cond_eNBs); pthread_mutex_unlock(&proc->mutex_eNBs); - pthread_mutex_lock(&proc->mutex_asynch_rxtx); proc->instance_cnt_asynch_rxtx = 0; pthread_cond_signal(&proc->cond_asynch_rxtx); pthread_mutex_unlock(&proc->mutex_asynch_rxtx); - LOG_D(PHY, "Joining pthread_FH\n"); pthread_join(proc->pthread_FH, NULL); + if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { LOG_D(PHY, "Joining pthread_FHTX\n"); pthread_join(proc->pthread_FH1, NULL); } + if (ru->function == NGFI_RRU_IF4p5) { LOG_D(PHY, "Joining pthread_prach\n"); pthread_join(proc->pthread_prach, NULL); @@ -2363,6 +2256,7 @@ void kill_RU_proc(RU_t *ru) LOG_D(PHY, "Joining pthread_prach_br\n"); pthread_join(proc->pthread_prach_br, NULL); #endif + if (ru->is_slave) { LOG_D(PHY, "Joining pthread_\n"); pthread_join(proc->pthread_synch, NULL); @@ -2375,6 +2269,7 @@ void kill_RU_proc(RU_t *ru) pthread_join(proc->pthread_asynch_rxtx, NULL); } } + if (opp_enabled) { LOG_D(PHY, "Joining ru_stats_thread\n"); pthread_join(ru->ru_stats_thread, NULL); @@ -2386,21 +2281,18 @@ void kill_RU_proc(RU_t *ru) pthread_mutex_destroy(&proc->mutex_FH); pthread_mutex_destroy(&proc->mutex_FH1); pthread_mutex_destroy(&proc->mutex_eNBs); - pthread_cond_destroy(&proc->cond_prach); pthread_cond_destroy(&proc->cond_FH); pthread_cond_destroy(&proc->cond_FH1); pthread_cond_destroy(&proc->cond_asynch_rxtx); pthread_cond_destroy(&proc->cond_synch); pthread_cond_destroy(&proc->cond_eNBs); - pthread_attr_destroy(&proc->attr_FH); pthread_attr_destroy(&proc->attr_FH1); pthread_attr_destroy(&proc->attr_prach); pthread_attr_destroy(&proc->attr_synch); pthread_attr_destroy(&proc->attr_asynch_rxtx); pthread_attr_destroy(&proc->attr_fep); - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_mutex_destroy(&proc->mutex_prach_br); pthread_cond_destroy(&proc->cond_prach_br); @@ -2409,15 +2301,14 @@ void kill_RU_proc(RU_t *ru) } int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { - FH_fmt_options_t fmt = cap->FH_fmt; - int i; int found_band=0; - LOG_I(PHY,"RRU %d, num_bands %d, looking for band %d\n",ru->idx,cap->num_bands,ru->frame_parms.eutra_band); - for (i=0;i<cap->num_bands;i++) { + + for (i=0; i<cap->num_bands; i++) { LOG_I(PHY,"band %d on RRU %d\n",cap->band_list[i],ru->idx); + if (ru->frame_parms.eutra_band == cap->band_list[i]) { found_band=1; break; @@ -2430,22 +2321,29 @@ int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { } switch (ru->if_south) { - case LOCAL_RF: - AssertFatal(1==0, "This RU should not have a local RF, exiting\n"); - return(0); - break; - case REMOTE_IF5: - if (fmt == OAI_IF5_only || fmt == OAI_IF5_and_IF4p5) return(0); - break; - case REMOTE_IF4p5: - if (fmt == OAI_IF4p5_only || fmt == OAI_IF5_and_IF4p5) return(0); - break; - case REMOTE_MBP_IF5: - if (fmt == MBP_IF5) return(0); - break; - default: - LOG_I(PHY,"No compatible Fronthaul interface found for RRU %d\n", ru->idx); - return(-1); + case LOCAL_RF: + AssertFatal(1==0, "This RU should not have a local RF, exiting\n"); + return(0); + break; + + case REMOTE_IF5: + if (fmt == OAI_IF5_only || fmt == OAI_IF5_and_IF4p5) return(0); + + break; + + case REMOTE_IF4p5: + if (fmt == OAI_IF4p5_only || fmt == OAI_IF5_and_IF4p5) return(0); + + break; + + case REMOTE_MBP_IF5: + if (fmt == MBP_IF5) return(0); + + break; + + default: + LOG_I(PHY,"No compatible Fronthaul interface found for RRU %d\n", ru->idx); + return(-1); } return(-1); @@ -2458,32 +2356,29 @@ char rru_formats[3][20] = {"OAI_IF5","MBP_IF5","OAI_IF4p5"}; char ru_if_formats[4][20] = {"LOCAL_RF","REMOTE_OAI_IF5","REMOTE_MBP_IF5","REMOTE_OAI_IF4p5"}; void configure_ru(int idx, - void *arg) { - + void *arg) { RU_t *ru = RC.ru[idx]; RRU_config_t *config = (RRU_config_t *)arg; - RRU_capabilities_t *capabilities = (RRU_capabilities_t*)arg; + RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg; int ret; - LOG_I(PHY, "Received capabilities from RRU %d\n",idx); - if (capabilities->FH_fmt < MAX_FH_FMTs) LOG_I(PHY, "RU FH options %s\n",rru_format_options[capabilities->FH_fmt]); - AssertFatal((ret=check_capabilities(ru,capabilities)) == 0, - "Cannot configure RRU %d, check_capabilities returned %d\n", idx,ret); + ret=check_capabilities(ru,capabilities); + AssertFatal((ret == 0), + "Cannot configure RRU %d, check_capabilities returned %d\n", idx,ret); // take antenna capabilities of RRU ru->nb_tx = capabilities->nb_tx[0]; ru->nb_rx = capabilities->nb_rx[0]; - // Pass configuration to RRU LOG_I(PHY, "Using %s fronthaul (%d), band %d \n",ru_if_formats[ru->if_south],ru->if_south,ru->frame_parms.eutra_band); - // wait for configuration + // wait for configuration config->FH_fmt = ru->if_south; config->num_bands = 1; config->band_list[0] = ru->frame_parms.eutra_band; - config->tx_freq[0] = ru->frame_parms.dl_CarrierFreq; - config->rx_freq[0] = ru->frame_parms.ul_CarrierFreq; + config->tx_freq[0] = ru->frame_parms.dl_CarrierFreq; + config->rx_freq[0] = ru->frame_parms.ul_CarrierFreq; config->tdd_config[0] = ru->frame_parms.tdd_config; config->tdd_config_S[0] = ru->frame_parms.tdd_config_S; config->att_tx[0] = ru->att_tx; @@ -2491,19 +2386,21 @@ void configure_ru(int idx, config->N_RB_DL[0] = ru->frame_parms.N_RB_DL; config->N_RB_UL[0] = ru->frame_parms.N_RB_UL; config->threequarter_fs[0] = ru->frame_parms.threequarter_fs; + if (ru->if_south==REMOTE_IF4p5) { config->prach_FreqOffset[0] = ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset; config->prach_ConfigIndex[0] = ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex; LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n", - config->prach_FreqOffset[0],config->prach_ConfigIndex[0]); - + config->prach_FreqOffset[0],config->prach_ConfigIndex[0]); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int i; - for (i=0;i<4;i++) { + + for (i=0; i<4; i++) { config->emtc_prach_CElevel_enable[0][i] = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i]; config->emtc_prach_FreqOffset[0][i] = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[i]; config->emtc_prach_ConfigIndex[0][i] = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i]; } + #endif } @@ -2512,325 +2409,312 @@ void configure_ru(int idx, } void configure_rru(int idx, - void *arg) { - + void *arg) { RRU_config_t *config = (RRU_config_t *)arg; RU_t *ru = RC.ru[idx]; - ru->frame_parms.eutra_band = config->band_list[0]; ru->frame_parms.dl_CarrierFreq = config->tx_freq[0]; ru->frame_parms.ul_CarrierFreq = config->rx_freq[0]; + if (ru->frame_parms.dl_CarrierFreq == ru->frame_parms.ul_CarrierFreq) { LOG_I(PHY,"Setting RRU to TDD frame type\n"); ru->frame_parms.frame_type = TDD; ru->frame_parms.tdd_config = config->tdd_config[0]; - ru->frame_parms.tdd_config_S = config->tdd_config_S[0]; - } - else ru->frame_parms.frame_type = FDD; + ru->frame_parms.tdd_config_S = config->tdd_config_S[0]; + } else ru->frame_parms.frame_type = FDD; + ru->att_tx = config->att_tx[0]; ru->att_rx = config->att_rx[0]; ru->frame_parms.N_RB_DL = config->N_RB_DL[0]; ru->frame_parms.N_RB_UL = config->N_RB_UL[0]; ru->frame_parms.threequarter_fs = config->threequarter_fs[0]; ru->frame_parms.pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0]; + if (ru->function==NGFI_RRU_IF4p5) { ru->frame_parms.att_rx = ru->att_rx; ru->frame_parms.att_tx = ru->att_tx; - LOG_I(PHY,"Setting ru->function to NGFI_RRU_IF4p5, prach_FrequOffset %d, prach_ConfigIndex %d, att (%d,%d)\n", - config->prach_FreqOffset[0],config->prach_ConfigIndex[0],ru->att_tx,ru->att_rx); - ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = config->prach_FreqOffset[0]; - ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex = config->prach_ConfigIndex[0]; + config->prach_FreqOffset[0],config->prach_ConfigIndex[0],ru->att_tx,ru->att_rx); + ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = config->prach_FreqOffset[0]; + ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex = config->prach_ConfigIndex[0]; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - for (int i=0;i<4;i++) { + + for (int i=0; i<4; i++) { ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i] = config->emtc_prach_CElevel_enable[0][i]; ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[i] = config->emtc_prach_FreqOffset[0][i]; ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i] = config->emtc_prach_ConfigIndex[0][i]; } + #endif } - - init_frame_parms(&ru->frame_parms,1); + init_frame_parms(&ru->frame_parms,1); fill_rf_config(ru,ru->rf_config_file); - - phy_init_RU(ru); - } void init_precoding_weights(PHY_VARS_eNB *eNB) { - int layer,ru_id,aa,re,ue,tb; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; RU_t *ru; LTE_eNB_DLSCH_t *dlsch; // init precoding weigths - for (ue=0;ue<NUMBER_OF_UE_MAX;ue++) { - for (tb=0;tb<2;tb++) { + for (ue=0; ue<NUMBER_OF_UE_MAX; ue++) { + for (tb=0; tb<2; tb++) { dlsch = eNB->dlsch[ue][tb]; + for (layer=0; layer<4; layer++) { - int nb_tx=0; - for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { - ru = RC.ru[ru_id]; - nb_tx+=ru->nb_tx; - } - dlsch->ue_spec_bf_weights[layer] = (int32_t**)malloc16(nb_tx*sizeof(int32_t*)); - - for (aa=0; aa<nb_tx; aa++) { - dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(fp->ofdm_symbol_size*sizeof(int32_t)); - for (re=0;re<fp->ofdm_symbol_size; re++) { - dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff; - } - } + int nb_tx=0; + + for (ru_id=0; ru_id<RC.nb_RU; ru_id++) { + ru = RC.ru[ru_id]; + nb_tx+=ru->nb_tx; + } + + dlsch->ue_spec_bf_weights[layer] = (int32_t **)malloc16(nb_tx*sizeof(int32_t *)); + + for (aa=0; aa<nb_tx; aa++) { + dlsch->ue_spec_bf_weights[layer][aa] = (int32_t *)malloc16(fp->ofdm_symbol_size*sizeof(int32_t)); + + for (re=0; re<fp->ofdm_symbol_size; re++) { + dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff; + } + } } } } } -void set_function_spec_param(RU_t *ru) -{ +void set_function_spec_param(RU_t *ru) { int ret; switch (ru->if_south) { - case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) - if (ru->function == NGFI_RRU_IF5) { // IF5 RRU - ru->do_prach = 0; // no prach processing in RU - ru->fh_north_in = NULL; // no shynchronous incoming fronthaul from north - ru->fh_north_out = fh_if5_north_out; // need only to do send_IF5 reception - ru->fh_south_out = tx_rf; // send output to RF - ru->fh_north_asynch_in = fh_if5_north_asynch_in; // TX packets come asynchronously - ru->feprx = NULL; // nothing (this is a time-domain signal) - ru->feptx_ofdm = NULL; // nothing (this is a time-domain signal) - ru->feptx_prec = NULL; // nothing (this is a time-domain signal) - ru->start_if = start_if; // need to start the if interface for if5 - ru->ifdevice.host_type = RRU_HOST; - ru->rfdevice.host_type = RRU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - reset_meas(&ru->rx_fhaul); - reset_meas(&ru->tx_fhaul); - reset_meas(&ru->compression); - reset_meas(&ru->transport); + case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) + if (ru->function == NGFI_RRU_IF5) { // IF5 RRU + ru->do_prach = 0; // no prach processing in RU + ru->fh_north_in = NULL; // no shynchronous incoming fronthaul from north + ru->fh_north_out = fh_if5_north_out; // need only to do send_IF5 reception + ru->fh_south_out = tx_rf; // send output to RF + ru->fh_north_asynch_in = fh_if5_north_asynch_in; // TX packets come asynchronously + ru->feprx = NULL; // nothing (this is a time-domain signal) + ru->feptx_ofdm = NULL; // nothing (this is a time-domain signal) + ru->feptx_prec = NULL; // nothing (this is a time-domain signal) + ru->start_if = start_if; // need to start the if interface for if5 + ru->ifdevice.host_type = RRU_HOST; + ru->rfdevice.host_type = RRU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + reset_meas(&ru->rx_fhaul); + reset_meas(&ru->tx_fhaul); + reset_meas(&ru->compression); + reset_meas(&ru->transport); + ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + } else if (ru->function == NGFI_RRU_IF4p5) { + ru->do_prach = 1; // do part of prach processing in RU + ru->fh_north_in = NULL; // no synchronous incoming fronthaul from north + ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception + ru->fh_south_out = tx_rf; // send output to RF + ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously + ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full :ru_fep_full_2thread; // RX DFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) + ru->feptx_prec = NULL; + ru->start_if = start_if; // need to start the if interface for if4p5 + ru->ifdevice.host_type = RRU_HOST; + ru->rfdevice.host_type = RRU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + reset_meas(&ru->rx_fhaul); + reset_meas(&ru->tx_fhaul); + reset_meas(&ru->compression); + reset_meas(&ru->transport); + ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + + if (ret<0) { + printf("Exiting, cannot initialize transport protocol\n"); + exit(-1); + } + + malloc_IF4p5_buffer(ru); + } else if (ru->function == eNodeB_3GPP) { + ru->do_prach = 0; // no prach processing in RU + ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : ru_fep_full_2thread; // RX DFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding + ru->feptx_prec = feptx_prec; // this is fep with idft and precoding + ru->fh_north_in = NULL; // no incoming fronthaul from north + ru->fh_north_out = NULL; // no outgoing fronthaul to north + ru->start_if = NULL; // no if interface + ru->rfdevice.host_type = RAU_HOST; + } + + ru->fh_south_in = rx_rf; // local synchronous RF RX + ru->fh_south_out = tx_rf; // local synchronous RF TX + ru->start_rf = start_rf; // need to start the local RF interface + ru->stop_rf = stop_rf; + printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); + /* + if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise + fill_rf_config(ru,rf_config_file); + init_frame_parms(&ru->frame_parms,1); + phy_init_RU(ru); + } + + ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + if (setup_RU_buffers(ru)!=0) { + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); + }*/ + break; + + case REMOTE_IF5: // the remote unit is IF5 RRU + ru->do_prach = 0; + ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : fep_full; // this is frequency-shift + DFTs + ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs + + if (ru->if_timing == synch_to_other) { + ru->fh_south_in = fh_slave_south_in; // synchronize to master + ru->fh_south_out = fh_if5_mobipass_south_out; // use send_IF5 for mobipass + ru->fh_south_asynch_in = fh_if5_south_asynch_in_mobipass; // UL is asynchronous + } else { + ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception + ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission + ru->fh_south_asynch_in = NULL; // no asynchronous UL + } + ru->start_rf = NULL; // no local RF + ru->stop_rf = NULL; + ru->start_if = start_if; // need to start if interface for IF5 + ru->ifdevice.host_type = RAU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + ru->ifdevice.configure_rru = configure_ru; ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + if (ret<0) { printf("Exiting, cannot initialize transport protocol\n"); exit(-1); } - } - else if (ru->function == NGFI_RRU_IF4p5) { - ru->do_prach = 1; // do part of prach processing in RU - ru->fh_north_in = NULL; // no synchronous incoming fronthaul from north - ru->fh_north_out = fh_if4p5_north_out; // send_IF4p5 on reception - ru->fh_south_out = tx_rf; // send output to RF - ru->fh_north_asynch_in = fh_if4p5_north_asynch_in; // TX packets come asynchronously - ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full :ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft only (no precoding in RRU) - ru->feptx_prec = NULL; - ru->start_if = start_if; // need to start the if interface for if4p5 - ru->ifdevice.host_type = RRU_HOST; - ru->rfdevice.host_type = RRU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - reset_meas(&ru->rx_fhaul); - reset_meas(&ru->tx_fhaul); - reset_meas(&ru->compression); - reset_meas(&ru->transport); - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); + break; + + case REMOTE_IF4p5: + ru->do_prach = 0; + ru->feprx = NULL; // DFTs + ru->feptx_prec = feptx_prec; // Precoding operation + ru->feptx_ofdm = NULL; // no OFDM mod + ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception + ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission + ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in : NULL; // asynchronous UL if synch_to_other + ru->fh_north_out = NULL; + ru->fh_north_asynch_in = NULL; + ru->start_rf = NULL; // no local RF + ru->stop_rf = NULL; + ru->start_if = start_if; // need to start if interface for IF4p5 + ru->ifdevice.host_type = RAU_HOST; + ru->ifdevice.eth_params = &ru->eth_params; + ru->ifdevice.configure_rru = configure_ru; + ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + if (ret<0) { printf("Exiting, cannot initialize transport protocol\n"); exit(-1); } - malloc_IF4p5_buffer(ru); - } - else if (ru->function == eNodeB_3GPP) { - ru->do_prach = 0; // no prach processing in RU - ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : ru_fep_full_2thread; // RX DFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // this is fep with idft and precoding - ru->feptx_prec = feptx_prec; // this is fep with idft and precoding - ru->fh_north_in = NULL; // no incoming fronthaul from north - ru->fh_north_out = NULL; // no outgoing fronthaul to north - ru->start_if = NULL; // no if interface - ru->rfdevice.host_type = RAU_HOST; - } - ru->fh_south_in = rx_rf; // local synchronous RF RX - ru->fh_south_out = tx_rf; // local synchronous RF TX - ru->start_rf = start_rf; // need to start the local RF interface - ru->stop_rf = stop_rf; - printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); -/* - if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise - fill_rf_config(ru,rf_config_file); - init_frame_parms(&ru->frame_parms,1); - phy_init_RU(ru); - } - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); - }*/ - break; - - case REMOTE_IF5: // the remote unit is IF5 RRU - ru->do_prach = 0; - ru->feprx = (get_thread_worker_conf() == WORKER_DISABLE) ? fep_full : fep_full; // this is frequency-shift + DFTs - ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_DISABLE) ? feptx_ofdm : feptx_ofdm_2thread; // need to do transmit Precoding + IDFTs - if (ru->if_timing == synch_to_other) { - ru->fh_south_in = fh_slave_south_in; // synchronize to master - ru->fh_south_out = fh_if5_mobipass_south_out; // use send_IF5 for mobipass - ru->fh_south_asynch_in = fh_if5_south_asynch_in_mobipass; // UL is asynchronous - } - else { - ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception - ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission - ru->fh_south_asynch_in = NULL; // no asynchronous UL - } - ru->start_rf = NULL; // no local RF - ru->stop_rf = NULL; - ru->start_if = start_if; // need to start if interface for IF5 - ru->ifdevice.host_type = RAU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; - - ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - break; - - case REMOTE_IF4p5: - ru->do_prach = 0; - ru->feprx = NULL; // DFTs - ru->feptx_prec = feptx_prec; // Precoding operation - ru->feptx_ofdm = NULL; // no OFDM mod - ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception - ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission - ru->fh_south_asynch_in = (ru->if_timing == synch_to_other) ? fh_if4p5_south_in : NULL; // asynchronous UL if synch_to_other - ru->fh_north_out = NULL; - ru->fh_north_asynch_in = NULL; - ru->start_rf = NULL; // no local RF - ru->stop_rf = NULL; - ru->start_if = start_if; // need to start if interface for IF4p5 - ru->ifdevice.host_type = RAU_HOST; - ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; - - ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); - if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); - exit(-1); - } - - malloc_IF4p5_buffer(ru); - - break; + malloc_IF4p5_buffer(ru); + break; - default: - LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south); - break; + default: + LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south); + break; } // switch on interface type } //extern void RCconfig_RU(void); void init_RU(char *rf_config_file) { - int ru_id; RU_t *ru; PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL; int i; int CC_id; - // create status mask RC.ru_mask = 0; pthread_mutex_init(&RC.ru_mutex,NULL); pthread_cond_init(&RC.ru_cond,NULL); - // read in configuration file) printf("configuring RU from file\n"); RCconfig_RU(); LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs()); if (RC.nb_CC != 0) - for (i=0;i<RC.nb_L1_inst;i++) - for (CC_id=0;CC_id<RC.nb_CC[i];CC_id++) RC.eNB[i][CC_id]->num_RU=0; + for (i=0; i<RC.nb_L1_inst; i++) + for (CC_id=0; CC_id<RC.nb_CC[i]; CC_id++) RC.eNB[i][CC_id]->num_RU=0; LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); - for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { + + for (ru_id=0; ru_id<RC.nb_RU; ru_id++) { LOG_D(PHY,"Process RC.ru[%d]\n",ru_id); ru = RC.ru[ru_id]; ru->rf_config_file = rf_config_file; - ru->idx = ru_id; + ru->idx = ru_id; ru->ts_offset = 0; // use eNB_list[0] as a reference for RU frame parameters // NOTE: multiple CC_id are not handled here yet! - if (ru->num_eNB > 0) { LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); - if (ru->eNB_list[0] == 0) - { + if (ru->eNB_list[0] == 0) { LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__); ru->eNB_list[0] = RC.eNB[0][0]; ru->num_eNB=1; - // - // DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU - // - - } - else - { + // + // DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU + // + } else { LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__); } } + eNB0 = ru->eNB_list[0]; LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); LOG_D(PHY, "eNB0:%p\n", eNB0); - if (eNB0) - { + + if (eNB0) { if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) AssertFatal(eNB0!=NULL,"eNB0 is null!\n"); if (eNB0) { LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx); - memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); - + memcpy((void *)&ru->frame_parms,(void *)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); // attach all RU to all eNBs in its list/ LOG_D(PHY,"ru->num_eNB:%d eNB0->num_RU:%d\n", ru->num_eNB, eNB0->num_RU); - for (i=0;i<ru->num_eNB;i++) { + + for (i=0; i<ru->num_eNB; i++) { eNB0 = ru->eNB_list[i]; eNB0->RU_list[eNB0->num_RU++] = ru; } } } - LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); + LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); set_function_spec_param(ru); LOG_I(PHY,"Starting ru_thread %d\n",ru_id); - init_RU_proc(ru); - - - } // for ru_id // sleep(1); LOG_D(HW,"[lte-softmodem.c] RU threads created\n"); - - } -void stop_RU(int nb_ru) -{ +void stop_RU(int nb_ru) { for (int inst = 0; inst < nb_ru; inst++) { LOG_I(PHY, "Stopping RU %d processing threads\n", inst); kill_RU_proc(RC.ru[inst]); @@ -2841,107 +2725,89 @@ void stop_RU(int nb_ru) //This funtion is for initializing ru pointer for L2 FAPI simulator. #if defined(PRE_SCD_THREAD) void init_ru_vnf(void) { - int ru_id; RU_t *ru; RU_proc_t *proc; -// PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL; + // PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL; int i; int CC_id; - - dlsch_ue_select_tbl_in_use = 1; - - // create status mask RC.ru_mask = 0; pthread_mutex_init(&RC.ru_mutex,NULL); pthread_cond_init(&RC.ru_cond,NULL); - // read in configuration file) printf("configuring RU from file\n"); RCconfig_RU(); LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs()); if (RC.nb_CC != 0) - for (i=0;i<RC.nb_L1_inst;i++) - for (CC_id=0;CC_id<RC.nb_CC[i];CC_id++) RC.eNB[i][CC_id]->num_RU=0; + for (i=0; i<RC.nb_L1_inst; i++) + for (CC_id=0; CC_id<RC.nb_CC[i]; CC_id++) RC.eNB[i][CC_id]->num_RU=0; LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); - for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { + + for (ru_id=0; ru_id<RC.nb_RU; ru_id++) { LOG_D(PHY,"Process RC.ru[%d]\n",ru_id); ru = RC.ru[ru_id]; -// ru->rf_config_file = rf_config_file; - ru->idx = ru_id; + // ru->rf_config_file = rf_config_file; + ru->idx = ru_id; ru->ts_offset = 0; // use eNB_list[0] as a reference for RU frame parameters // NOTE: multiple CC_id are not handled here yet! if (ru->num_eNB > 0) { -// LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); - - if (ru->eNB_list[0] == 0) - { + // LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); + if (ru->eNB_list[0] == 0) { LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__); ru->eNB_list[0] = RC.eNB[0][0]; ru->num_eNB=1; - // - // DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU - // - } - else - { + // + // DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU + // + } else { LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__); } } -// frame_parms is not used in L2 FAPI simulator -/* - eNB0 = ru->eNB_list[0]; - LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); - LOG_D(PHY, "eNB0:%p\n", eNB0); - if (eNB0) - { - if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) - AssertFatal(eNB0!=NULL,"eNB0 is null!\n"); - - if (eNB0) { - LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx); - memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); - - // attach all RU to all eNBs in its list/ - LOG_D(PHY,"ru->num_eNB:%d eNB0->num_RU:%d\n", ru->num_eNB, eNB0->num_RU); - for (i=0;i<ru->num_eNB;i++) { - eNB0 = ru->eNB_list[i]; - eNB0->RU_list[eNB0->num_RU++] = ru; + // frame_parms is not used in L2 FAPI simulator + /* + eNB0 = ru->eNB_list[0]; + LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); + LOG_D(PHY, "eNB0:%p\n", eNB0); + if (eNB0) + { + if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) + AssertFatal(eNB0!=NULL,"eNB0 is null!\n"); + + if (eNB0) { + LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx); + memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + + // attach all RU to all eNBs in its list/ + LOG_D(PHY,"ru->num_eNB:%d eNB0->num_RU:%d\n", ru->num_eNB, eNB0->num_RU); + for (i=0;i<ru->num_eNB;i++) { + eNB0 = ru->eNB_list[i]; + eNB0->RU_list[eNB0->num_RU++] = ru; + } + } } - } - } -*/ + */ LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); - -// set_function_spec_param(ru); + // set_function_spec_param(ru); LOG_I(PHY,"Starting ru_thread %d\n",ru_id); - -// init_RU_proc(ru); - + // init_RU_proc(ru); proc = &ru->proc; - memset((void*)proc,0,sizeof(RU_proc_t)); - + memset((void *)proc,0,sizeof(RU_proc_t)); proc->instance_pre_scd = -1; pthread_mutex_init( &proc->mutex_pre_scd, NULL); pthread_cond_init( &proc->cond_pre_scd, NULL); - pthread_create(&proc->pthread_pre_scd, NULL, pre_scd_thread, (void*)ru); + pthread_create(&proc->pthread_pre_scd, NULL, pre_scd_thread, (void *)ru); pthread_setname_np(proc->pthread_pre_scd, "pre_scd_thread"); - } // for ru_id - - // sleep(1); LOG_D(HW,"[lte-softmodem.c] RU threads created\n"); - - } #endif @@ -2949,42 +2815,30 @@ void init_ru_vnf(void) { /* --------------------------------------------------------*/ /* from here function to use configuration module */ void RCconfig_RU(void) { - int j = 0; int i = 0; - - paramdef_t RUParams[] = RUPARAMS_DESC; paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; + config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL); - - config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL); - - if ( RUParamList.numelt > 0) { - - RC.ru = (RU_t**)malloc(RC.nb_RU*sizeof(RU_t*)); - - - - + RC.ru = (RU_t **)malloc(RC.nb_RU*sizeof(RU_t *)); RC.ru_mask=(1<<RC.nb_RU) - 1; printf("Set RU mask to %lx\n",RC.ru_mask); for (j = 0; j < RC.nb_RU; j++) { - - RC.ru[j] = (RU_t*)malloc(sizeof(RU_t)); - memset((void*)RC.ru[j],0,sizeof(RU_t)); + RC.ru[j] = (RU_t *)malloc(sizeof(RU_t)); + memset((void *)RC.ru[j],0,sizeof(RU_t)); RC.ru[j]->idx = j; - printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]); - RC.ru[j]->if_timing = synch_to_ext_device; + if (RC.nb_L1_inst >0) RC.ru[j]->num_eNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; else - RC.ru[j]->num_eNB = 0; - for (i=0;i<RC.ru[j]->num_eNB;i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; + RC.ru[j]->num_eNB = 0; + + for (i=0; i<RC.ru[j]->num_eNB; i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) { RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr)); @@ -3006,91 +2860,93 @@ void RCconfig_RU(void) { } if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { - if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = eNodeB_3GPP; - printf("Setting function for RU %d to eNodeB_3GPP\n",j); - } - else { - RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); - RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); + if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = eNodeB_3GPP; + printf("Setting function for RU %d to eNodeB_3GPP\n",j); + } else { + RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); + RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); - if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j); - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j); - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j); - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = NGFI_RRU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); - } - } - RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; - RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); - RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; - for (i=0;i<RC.ru[j]->num_bands;i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; + if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j); + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j); + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j); + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { + RC.ru[j]->if_south = LOCAL_RF; + RC.ru[j]->function = NGFI_RRU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); + } + } + + RC.ru[j]->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; + RC.ru[j]->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); + RC.ru[j]->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; + /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */ + RC.ru[j]->sf_extension = *(RUParamList.paramarray[j][RU_SF_EXTENSION_IDX].uptr); + RC.ru[j]->end_of_burst_delay = *(RUParamList.paramarray[j][RU_END_OF_BURST_DELAY_IDX].uptr); + + for (i=0; i<RC.ru[j]->num_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; } //strcmp(local_rf, "yes") == 0 else { - printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr)); - - RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); - RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); - RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); - RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); - RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); - if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { - RC.ru[j]->if_south = REMOTE_IF4p5; - RC.ru[j]->function = NGFI_RAU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { - RC.ru[j]->if_south = REMOTE_IF4p5; - RC.ru[j]->function = NGFI_RAU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->if_timing = synch_to_other; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS; - } + printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr)); + RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); + RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); + RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); + RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); + RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); + RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); + RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); + + if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { + RC.ru[j]->if_south = REMOTE_IF4p5; + RC.ru[j]->function = NGFI_RAU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { + RC.ru[j]->if_south = REMOTE_IF4p5; + RC.ru[j]->function = NGFI_RAU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) { + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->if_timing = synch_to_other; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS; + } } /* strcmp(local_rf, "yes") != 0 */ RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); - RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); }// j=0..num_rus } else { - RC.nb_RU = 0; + RC.nb_RU = 0; } // setting != NULL return; - } diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c index 814800ccfcb6bb1572197d856fba2cd79cc841d6..242d0b76d70fabf9f1c0dda109f0d045b899781b 100644 --- a/targets/RT/USER/lte-softmodem-common.c +++ b/targets/RT/USER/lte-softmodem-common.c @@ -58,6 +58,8 @@ void get_common_options(void) { uint32_t noS1; uint32_t nokrnmod; uint32_t nonbiot; + uint32_t rfsim; + uint32_t basicsim; paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; checkedparam_t cmdline_log_CheckParams[] = CMDLINE_LOGPARAMS_CHECK_DESC; @@ -90,7 +92,29 @@ void get_common_options(void) { set_softmodem_optmask(SOFTMODEM_NONBIOT_BIT); } + if (rfsim) { + set_softmodem_optmask(SOFTMODEM_RFSIM_BIT); + } + + if (basicsim) { + set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT); + } + +#if BASIC_SIMULATOR + set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT); +#endif + if(parallel_config != NULL) set_parallel_conf(parallel_config); if(worker_config != NULL) set_worker_conf(worker_config); } + +unsigned int is_nos1exec(char *exepath) { + if ( strcmp( basename(exepath), "lte-softmodem-nos1") == 0) + return 1; + + if ( strcmp( basename(exepath), "lte-uesoftmodem-nos1") == 0) + return 1; + + return 0; +} diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index b349b06a06b3cfae572bd77bfaa53344f3d6ed45..80b9c3a3fd4e07fb3283335412d1ef2a2e787d39 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -64,7 +64,7 @@ #include "LAYER2/MAC/mac_proto.h" #include "RRC/LTE/rrc_vars.h" #include "PHY_INTERFACE/phy_interface_vars.h" - +#include "nfapi/oai_integration/vendor_ext.h" #ifdef SMBV #include "PHY/TOOLS/smbv.h" unsigned short config_frames[4] = {2,9,11,13}; @@ -82,9 +82,9 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "UTIL/OTG/otg_vars.h" #endif -#if defined(ENABLE_ITTI) - #include "create_tasks.h" -#endif + +#include "create_tasks.h" + #include "PHY/INIT/phy_init.h" @@ -107,15 +107,11 @@ unsigned short config_frames[4] = {2,9,11,13}; static pthread_t forms_thread; //xforms #endif //XFORMS -#ifndef ENABLE_USE_MME - #define EPC_MODE_ENABLED 0 -#endif pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex -uint8_t nfapi_mode = 0; // Default to monolithic mode uint16_t sf_ahead=4; @@ -136,7 +132,7 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int UE_scan = 1; int UE_scan_carrier = 0; runmode_t mode = normal_txrx; -int simL1flag; + FILE *input_fd=NULL; @@ -482,7 +478,7 @@ void wait_eNBs(void) { printf("eNB L1 are configured\n"); } -#if defined(ENABLE_ITTI) + /* * helper function to terminate a certain ITTI task */ @@ -578,7 +574,26 @@ int restart_L1L2(module_id_t enb_id) { pthread_mutex_unlock(&sync_mutex); return 0; } -#endif + +void init_pdcp(void) { + if (!NODE_IS_DU(RC.rrc[0]->node_type)) { + pdcp_layer_init(); + uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? + (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; + if (IS_SOFTMODEM_NOS1) + pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; + pdcp_module_init(pdcp_initmask); + + if (NODE_IS_CU(RC.rrc[0]->node_type)) { + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req); + } else { + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); + } + } else { + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind); + } +} static void wait_nfapi_init(char *thread_name) { printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); @@ -596,7 +611,7 @@ int main( int argc, char **argv ) { #if defined (XFORMS) void *status; #endif - int CC_id; + int CC_id = 0; int ru_id; #if defined (XFORMS) int ret; @@ -612,6 +627,11 @@ int main( int argc, char **argv ) { printf("Reading in command-line options\n"); get_options (); + if (is_nos1exec(argv[0]) ) + set_softmodem_optmask(SOFTMODEM_NOS1_BIT); + + EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; + if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); exit(-1); @@ -629,8 +649,7 @@ int main( int argc, char **argv ) { } cpuf=get_cpu_freq_GHz(); -#if defined(ENABLE_ITTI) - printf("ITTI init, useMME: %i\n" ,EPC_MODE_ENABLED); + printf("ITTI init, useMME: %i\n",EPC_MODE_ENABLED); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); // initialize mscgen log after ITTI @@ -639,15 +658,7 @@ int main( int argc, char **argv ) { } MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); -#endif init_opt(); -#ifdef PDCP_USE_NETLINK - printf("PDCP netlink\n"); - netlink_init(); -#if defined(PDCP_USE_NETLINK_QUEUES) - pdcp_netlink_init(); -#endif -#endif // to make a graceful exit when ctrl-c is pressed signal(SIGSEGV, signal_handler); signal(SIGINT, signal_handler); @@ -660,282 +671,235 @@ int main( int argc, char **argv ) { LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); printf("Runtime table\n"); fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); -#ifndef DEADLINE_SCHEDULER - printf("NO deadline scheduler\n"); - /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */ - cpu_set_t cpuset; - int s; - char cpu_affinity[1024]; - CPU_ZERO(&cpuset); -#ifdef CPU_AFFINITY - - if (get_nprocs() > 2) { - CPU_SET(0, &cpuset); - s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - - if (s != 0) { - perror( "pthread_setaffinity_np"); - exit_fun("Error setting processor affinity"); - } - - LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n"); - } - -#endif - /* Check the actual affinity mask assigned to the thread */ - s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (s != 0) { - perror( "pthread_getaffinity_np"); - exit_fun("Error getting processor affinity "); - } - - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); + /* Read configuration */ + if (RC.nb_inst > 0) { + read_config_and_init(); - for (int j = 0; j < CPU_SETSIZE; j++) { - if (CPU_ISSET(j, &cpuset)) { - char temp[1024]; - sprintf(temp, " CPU_%d ", j); - strcat(cpu_affinity, temp); + /* Start the agent. If it is turned off in the configuration, it won't start */ + RCconfig_flexran(); + for (i = 0; i < RC.nb_inst; i++) { + flexran_agent_start(i); } - } - LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); -#endif -#if defined(ENABLE_ITTI) + /* initializes PDCP and sets correct RLC Request/PDCP Indication callbacks + * for monolithic/F1 modes */ + init_pdcp(); - if (RC.nb_inst > 0) { - // don't create if node doesn't connect to RRC/S1/GTP if (create_tasks(1) < 0) { printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode + exit(-1); } - printf("ITTI tasks created\n"); + for (int enb_id = 0; enb_id < RC.nb_inst; enb_id++) { + MessageDef *msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ); + RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; + itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); + } } else { - printf("No ITTI, Initializing L1\n"); + printf("RC.nb_inst = 0, Initializing L1\n"); RCconfig_L1(); } -#endif - /* Start the agent. If it is turned off in the configuration, it won't start */ - RCconfig_flexran(); - - for (i = 0; i < RC.nb_L1_inst; i++) { - flexran_agent_start(i); + if (RC.nb_inst > 0 && NODE_IS_CU(RC.rrc[0]->node_type)) { + protocol_ctxt_t ctxt; + ctxt.module_id = 0 ; + ctxt.instance = 0; + ctxt.rnti = 0; + ctxt.enb_flag = 1; + pdcp_run(&ctxt); } - // init UE_PF_PO and mutex lock - pthread_mutex_init(&ue_pf_po_mutex, NULL); - memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*MAX_MOBILES_PER_ENB*MAX_NUM_CCs); - mlockall(MCL_CURRENT | MCL_FUTURE); - pthread_cond_init(&sync_cond,NULL); - pthread_mutex_init(&sync_mutex, NULL); -#ifdef XFORMS - int UE_id; - printf("XFORMS\n"); - - if (get_softmodem_params()->do_forms==1) { - fl_initialize (&argc, argv, NULL, 0, 0); - form_stats_l2 = create_form_stats_form(); - fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats"); - form_stats = create_form_stats_form(); - fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); - - for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) { - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - form_enb[CC_id][UE_id] = create_lte_phy_scope_enb(); - sprintf (title, "LTE UL SCOPE eNB for CC_id %d, UE %d",CC_id,UE_id); - fl_show_form (form_enb[CC_id][UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - - if (otg_enabled) { - fl_set_button(form_enb[CC_id][UE_id]->button_0,1); - fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON"); - } else { - fl_set_button(form_enb[CC_id][UE_id]->button_0,0); - fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic OFF"); - } - } // CC_id - } // UE_id - - ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); - - if (ret == 0) - pthread_setname_np( forms_thread, "xforms" ); - - printf("Scope thread created, ret=%d\n",ret); - } - -#endif - rt_sleep_ns(10*100000000ULL); - - if (nfapi_mode) { - printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); + /* start threads if only L1 or not a CU */ + if (RC.nb_inst == 0 || !NODE_IS_CU(RC.rrc[0]->node_type)) { + // init UE_PF_PO and mutex lock + pthread_mutex_init(&ue_pf_po_mutex, NULL); + memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*MAX_MOBILES_PER_ENB*MAX_NUM_CCs); + mlockall(MCL_CURRENT | MCL_FUTURE); pthread_cond_init(&sync_cond,NULL); pthread_mutex_init(&sync_mutex, NULL); - } - - const char *nfapi_mode_str = "<UNKNOWN>"; - - switch(nfapi_mode) { - case 0: - nfapi_mode_str = "MONOLITHIC"; - break; - - case 1: - nfapi_mode_str = "PNF"; - break; - - case 2: - nfapi_mode_str = "VNF"; - break; - - default: - nfapi_mode_str = "<UNKNOWN NFAPI MODE>"; - break; - } +#ifdef XFORMS + int UE_id; + printf("XFORMS\n"); + + if (get_softmodem_params()->do_forms==1) { + fl_initialize (&argc, argv, NULL, 0, 0); + form_stats_l2 = create_form_stats_form(); + fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats"); + form_stats = create_form_stats_form(); + fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); + + for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) { + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + form_enb[CC_id][UE_id] = create_lte_phy_scope_enb(); + sprintf (title, "LTE UL SCOPE eNB for CC_id %d, UE %d",CC_id,UE_id); + fl_show_form (form_enb[CC_id][UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); + + if (otg_enabled) { + fl_set_button(form_enb[CC_id][UE_id]->button_0,1); + fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON"); + } else { + fl_set_button(form_enb[CC_id][UE_id]->button_0,0); + fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic OFF"); + } + } // CC_id + } // UE_id + + ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); + + if (ret == 0) + pthread_setname_np( forms_thread, "xforms" ); + + printf("Scope thread created, ret=%d\n",ret); + } - printf("NFAPI MODE:%s\n", nfapi_mode_str); +#endif + rt_sleep_ns(10*100000000ULL); + if (NFAPI_MODE!=NFAPI_MONOLITHIC) { + LOG_I(ENB_APP,"NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); + pthread_cond_init(&sync_cond,NULL); + pthread_mutex_init(&sync_mutex, NULL); + } -if (nfapi_mode==2) {// VNF + if (NFAPI_MODE==NFAPI_MODE_VNF) {// VNF #if defined(PRE_SCD_THREAD) - init_ru_vnf(); // ru pointer is necessary for pre_scd. + init_ru_vnf(); // ru pointer is necessary for pre_scd. #endif - wait_nfapi_init("main?"); - } + wait_nfapi_init("main?"); + } + LOG_I(ENB_APP,"START MAIN THREADS\n"); + // start the main threads + number_of_cards = 1; + printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); - printf("START MAIN THREADS\n"); - // start the main threads - number_of_cards = 1; - printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); + if (RC.nb_L1_inst > 0) { + printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync); + init_eNB(get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync); + // for (inst=0;inst<RC.nb_L1_inst;inst++) + // for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0); + } - if (RC.nb_L1_inst > 0) { - printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync); - init_eNB(get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync); - // for (inst=0;inst<RC.nb_L1_inst;inst++) - // for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0); - } + printf("wait_eNBs()\n"); + wait_eNBs(); + printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); - printf("wait_eNBs()\n"); - wait_eNBs(); + // RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator. + // but RU thread deals with pre_scd and this is necessary in VNF and simulator. + // some initialization is necessary and init_ru_vnf do this. + if (RC.nb_RU >0 && NFAPI_MODE!=NFAPI_MODE_VNF) { + printf("Initializing RU threads\n"); + init_RU(get_softmodem_params()->rf_config_file); - printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); - - // RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator. - // but RU thread deals with pre_scd and this is necessary in VNF and simulator. - // some initialization is necessary and init_ru_vnf do this. - if (RC.nb_RU >0 && nfapi_mode != 2) { - printf("Initializing RU threads\n"); - init_RU(get_softmodem_params()->rf_config_file); - for (ru_id=0;ru_id<RC.nb_RU;ru_id++) { - RC.ru[ru_id]->rf_map.card=0; - RC.ru[ru_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); + for (ru_id=0; ru_id<RC.nb_RU; ru_id++) { + RC.ru[ru_id]->rf_map.card=0; + RC.ru[ru_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); + } } - } - config_sync_var=0; + config_sync_var=0; - if (nfapi_mode==1) { // PNF - wait_nfapi_init("main?"); - } + if (NFAPI_MODE==NFAPI_MODE_PNF) { // PNF + wait_nfapi_init("main?"); + } - printf("wait RUs\n"); - fflush(stdout); - fflush(stderr); - wait_RUs(); - printf("ALL RUs READY!\n"); - printf("RC.nb_RU:%d\n", RC.nb_RU); - // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration) - printf("ALL RUs ready - init eNBs\n"); - - if (nfapi_mode != 1 && nfapi_mode != 2) { - printf("Not NFAPI mode - call init_eNB_afterRU()\n"); - init_eNB_afterRU(); - } else { - printf("NFAPI mode - DO NOT call init_eNB_afterRU()\n"); + printf("wait RUs\n"); + // CI -- Flushing the std outputs for the previous marker to show on the eNB / RRU log file + fflush(stdout); + fflush(stderr); + // end of CI modifications + wait_RUs(); + LOG_I(ENB_APP,"RC.nb_RU:%d\n", RC.nb_RU); + // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration) + printf("ALL RUs ready - init eNBs\n"); + + if (NFAPI_MODE!=NFAPI_MODE_PNF && NFAPI_MODE!=NFAPI_MODE_VNF) { + LOG_I(ENB_APP,"Not NFAPI mode - call init_eNB_afterRU()\n"); + init_eNB_afterRU(); + } else { + LOG_I(ENB_APP,"NFAPI mode - DO NOT call init_eNB_afterRU()\n"); + } + + LOG_UI(ENB_APP,"ALL RUs ready - ALL eNBs ready\n"); + // connect the TX/RX buffers + sleep(1); /* wait for thread activation */ + LOG_I(ENB_APP,"Sending sync to all threads\n"); + pthread_mutex_lock(&sync_mutex); + sync_var=0; + pthread_cond_broadcast(&sync_cond); + pthread_mutex_unlock(&sync_mutex); + config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); } - printf("ALL RUs ready - ALL eNBs ready\n"); - // connect the TX/RX buffers - sleep(1); /* wait for thread activation */ - printf("Sending sync to all threads\n"); - pthread_mutex_lock(&sync_mutex); - sync_var=0; - pthread_cond_broadcast(&sync_cond); - pthread_mutex_unlock(&sync_mutex); - config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); // wait for end of program - printf("TYPE <CTRL-C> TO TERMINATE\n"); + LOG_UI(ENB_APP,"TYPE <CTRL-C> TO TERMINATE\n"); + // CI -- Flushing the std outputs for the previous marker to show on the eNB / DU / CU log file + fflush(stdout); + fflush(stderr); + // end of CI modifications //getchar(); -#if defined(ENABLE_ITTI) - printf("Entering ITTI signals handler\n"); itti_wait_tasks_end(); - printf("Returned from ITTI signal handler\n"); oai_exit=1; - printf("oai_exit=%d\n",oai_exit); -#else - - while (oai_exit==0) - rt_sleep_ns(100000000ULL); - - printf("Terminating application - oai_exit=%d\n",oai_exit); -#endif + LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit); // stop threads -#ifdef XFORMS - printf("waiting for XFORMS thread\n"); - - if (get_softmodem_params()->do_forms==1) { - pthread_join(forms_thread,&status); - fl_hide_form(form_stats->stats_form); - fl_free_form(form_stats->stats_form); - fl_hide_form(form_stats_l2->stats_form); - fl_free_form(form_stats_l2->stats_form); - for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) { - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - fl_hide_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); - fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); + if (RC.nb_inst == 0 || !NODE_IS_CU(RC.rrc[0]->node_type)) { + int UE_id; +#ifdef XFORMS + printf("waiting for XFORMS thread\n"); + + if (get_softmodem_params()->do_forms==1) { + pthread_join(forms_thread,&status); + fl_hide_form(form_stats->stats_form); + fl_free_form(form_stats->stats_form); + fl_hide_form(form_stats_l2->stats_form); + fl_free_form(form_stats_l2->stats_form); + + for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) { + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + fl_hide_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); + fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); + } } } - } #endif - printf("stopping MODEM threads\n"); - stop_eNB(NB_eNB_INST); - stop_RU(RC.nb_RU); - - /* release memory used by the RU/eNB threads (incomplete), after all - * threads have been stopped (they partially use the same memory) */ - for (int inst = 0; inst < NB_eNB_INST; inst++) { - for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) { - free_transport(RC.eNB[inst][cc_id]); - phy_free_lte_eNB(RC.eNB[inst][cc_id]); + LOG_I(ENB_APP,"stopping MODEM threads\n"); + stop_eNB(NB_eNB_INST); + stop_RU(RC.nb_RU); + + /* release memory used by the RU/eNB threads (incomplete), after all + * threads have been stopped (they partially use the same memory) */ + for (int inst = 0; inst < NB_eNB_INST; inst++) { + for (int cc_id = 0; cc_id < RC.nb_CC[inst]; cc_id++) { + free_transport(RC.eNB[inst][cc_id]); + phy_free_lte_eNB(RC.eNB[inst][cc_id]); + } } - } - - for (int inst = 0; inst < RC.nb_RU; inst++) { - phy_free_RU(RC.ru[inst]); - } - free_lte_top(); - end_configmodule(); - pthread_cond_destroy(&sync_cond); - pthread_mutex_destroy(&sync_mutex); - pthread_cond_destroy(&nfapi_sync_cond); - pthread_mutex_destroy(&nfapi_sync_mutex); - pthread_mutex_destroy(&ue_pf_po_mutex); - - for(ru_id=0; ru_id<RC.nb_RU; ru_id++) { - if (RC.ru[ru_id]->rfdevice.trx_end_func) { - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - RC.ru[ru_id]->rfdevice.trx_end_func = NULL; + for (int inst = 0; inst < RC.nb_RU; inst++) { + phy_free_RU(RC.ru[inst]); } - if (RC.ru[ru_id]->ifdevice.trx_end_func) { - RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); - RC.ru[ru_id]->ifdevice.trx_end_func = NULL; + free_lte_top(); + end_configmodule(); + pthread_cond_destroy(&sync_cond); + pthread_mutex_destroy(&sync_mutex); + pthread_cond_destroy(&nfapi_sync_cond); + pthread_mutex_destroy(&nfapi_sync_mutex); + pthread_mutex_destroy(&ue_pf_po_mutex); + + for(ru_id=0; ru_id<RC.nb_RU; ru_id++) { + if (RC.ru[ru_id]->rfdevice.trx_end_func) { + RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); + RC.ru[ru_id]->rfdevice.trx_end_func = NULL; + } + + if (RC.ru[ru_id]->ifdevice.trx_end_func) { + RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); + RC.ru[ru_id]->ifdevice.trx_end_func = NULL; + } } } diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 85ee4765f09b283577845ec4e9a7e6a0355d263c..5900889e6d49e308406d8aa674a084c6ae2db60b 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -33,15 +33,9 @@ #include "SIMULATION/ETH_TRANSPORT/proto.h" #include "flexran_agent.h" - -#if defined(ENABLE_ITTI) - #if defined(ENABLE_USE_MME) - #include "s1ap_eNB.h" - #ifdef PDCP_USE_NETLINK - #include "SIMULATION/ETH_TRANSPORT/proto.h" - #endif - #endif -#endif +#include "s1ap_eNB.h" +#include "SIMULATION/ETH_TRANSPORT/proto.h" +#include "proto_agent.h" /* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */ #define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n" @@ -94,6 +88,7 @@ #define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n" #define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n" #define CONFIG_HLP_NOS1 "Disable s1 interface\n" +#define CONFIG_HLP_RFSIM "Run in rf simulator mode (also known as basic simulator)\n" #define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" @@ -206,7 +201,9 @@ {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \ {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ - {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \ + {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \ + {"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_INT, 0}, \ + {"basicsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&basicsim, defintval:0, TYPE_INT, 0}, \ {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ } @@ -245,6 +242,9 @@ #define SOFTMODEM_NOS1_BIT (1<<0) #define SOFTMODEM_NOKRNMOD_BIT (1<<1) #define SOFTMODEM_NONBIOT_BIT (1<<2) +#define SOFTMODEM_RFSIM_BIT (1<<10) +#define SOFTMODEM_BASICSIM_BIT (1<<11) +#define SOFTMODEM_SIML1_BIT (1<<12) typedef struct { uint64_t optmask; THREAD_STRUCT thread_struct; @@ -265,11 +265,14 @@ typedef struct { #define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) #define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) #define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT) +#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT) +#define IS_SOFTMODEM_BASICSIM ( get_softmodem_optmask() & SOFTMODEM_BASICSIM_BIT) +#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT) extern uint64_t get_softmodem_optmask(void); extern uint64_t set_softmodem_optmask(uint64_t bitmask); extern void get_common_options(void); extern softmodem_params_t *get_softmodem_params(void); - +extern unsigned int is_nos1exec(char *exepath) ; uint64_t get_pdcp_optmask(void); extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 1fe1d4c06b1feeec523976666c80c5f58dad5cb7..0a6df786829ea23f212b2e0a0651e4679c9c0388 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -53,6 +53,7 @@ #include <inttypes.h> #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "UTIL/OTG/otg_tx.h" #include "UTIL/OTG/otg_externs.h" #include "UTIL/MATH/oml.h" @@ -63,7 +64,7 @@ #include "T.h" extern double cpuf; -extern uint8_t nfapi_mode; + #define FRAME_PERIOD 100000000ULL #define DAQ_PERIOD 66667ULL @@ -80,12 +81,12 @@ void init_UE_threads_stub(int); void init_UE_single_thread_stub(int); void *UE_thread(void *arg); void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correction, int phy_test, int UE_scan, int UE_scan_carrier, runmode_t mode,int rxgain,int txpowermax,LTE_DL_FRAME_PARMS *fp); -void init_UE_stub(int nb_inst,int,int,char*); -void init_UE_stub_single_thread(int nb_inst,int,int,char*); +void init_UE_stub(int nb_inst,int,int,char *); +void init_UE_stub_single_thread(int nb_inst,int,int,char *); int init_timer_thread(void); extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); extern void multicast_link_start(void (*rx_handlerP) (unsigned int, char *), - unsigned char _multicast_group, char *multicast_ifname); + unsigned char _multicast_group, char *multicast_ifname); extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); @@ -93,7 +94,7 @@ extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind); extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP); -extern int simL1flag; + extern uint16_t sf_ahead; //extern int tx_req_UE_MAC1(); @@ -169,21 +170,18 @@ struct sched_param sched_param_UE_thread; void get_uethreads_params(void) { paramdef_t cmdline_threadsparams[] =CMDLINE_UETHREADSPARAMS_DESC; - - config_process_cmdline( cmdline_threadsparams,sizeof(cmdline_threadsparams)/sizeof(paramdef_t),NULL); } void phy_init_lte_ue_transport(PHY_VARS_UE *ue,int absraction_flag); -PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t UE_id, - uint8_t abstraction_flag) +PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t UE_id, + uint8_t abstraction_flag) { - - PHY_VARS_UE* ue = (PHY_VARS_UE *)malloc(sizeof(PHY_VARS_UE)); + PHY_VARS_UE *ue = (PHY_VARS_UE *)malloc(sizeof(PHY_VARS_UE)); memset(ue,0,sizeof(PHY_VARS_UE)); if (frame_parms!=(LTE_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in @@ -195,13 +193,12 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, ue->mac_enabled = 1; // In phy_stub_UE (MAC-to-MAC) mode these init functions don't need to get called. Is this correct? - if (nfapi_mode!=3) - { - // initialize all signal buffers - init_lte_ue_signal(ue,1,abstraction_flag); - // intialize transport - init_lte_ue_transport(ue,abstraction_flag); - } + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + // initialize all signal buffers + init_lte_ue_signal(ue,1,abstraction_flag); + // intialize transport + init_lte_ue_transport(ue,abstraction_flag); + } return(ue); } @@ -211,9 +208,9 @@ char uecap_xer[1024]; -void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) { - +void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char *name) { #ifdef DEADLINE_SCHEDULER + if (sched_runtime!=0) { struct sched_attr attr= {0}; attr.size = sizeof(attr); @@ -222,60 +219,64 @@ void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_ attr.sched_deadline = sched_deadline; attr.sched_period = 0; AssertFatal(sched_setattr(0, &attr, 0) == 0, - "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno)); + "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno)); LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n", - name, (unsigned long)gettid(), sched_getcpu()); + name, (unsigned long)gettid(), sched_getcpu()); } + #else + if (CPU_COUNT(cpuset) > 0) AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), ""); + struct sched_param sp; sp.sched_priority = sched_fifo; AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, - "Can't set thread priority, Are you root?\n"); + "Can't set thread priority, Are you root?\n"); /* Check the actual affinity mask assigned to the thread */ cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE); + if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) { - char txt[512]={0}; + char txt[512]= {0}; + for (int j = 0; j < CPU_SETSIZE; j++) if (CPU_ISSET(j, cset)) - sprintf(txt+strlen(txt), " %d ", j); + sprintf(txt+strlen(txt), " %d ", j); + printf("CPU Affinity of thread %s is %s\n", name, txt); } + CPU_FREE(cset); #endif - } void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correction, int phy_test, int UE_scan, int UE_scan_carrier, runmode_t mode,int rxgain,int txpowermax,LTE_DL_FRAME_PARMS *fp0) { - PHY_VARS_UE *UE; int inst; int ret; LTE_DL_FRAME_PARMS *fp; - LOG_I(PHY,"UE : Calling Layer 2 for initialization\n"); - l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL, - 0,// cba_group_active - 0); // HO flag + 0,// cba_group_active + 0); // HO flag + + if (PHY_vars_UE_g==NULL) PHY_vars_UE_g = (PHY_VARS_UE ***)calloc(1+nb_inst,sizeof(PHY_VARS_UE **)); + + for (inst=0; inst<nb_inst; inst++) { + if (PHY_vars_UE_g[inst]==NULL) PHY_vars_UE_g[inst] = (PHY_VARS_UE **)calloc(1+MAX_NUM_CCs,sizeof(PHY_VARS_UE *)); - if (PHY_vars_UE_g==NULL) PHY_vars_UE_g = (PHY_VARS_UE***)calloc(1+nb_inst,sizeof(PHY_VARS_UE**)); - - for (inst=0;inst<nb_inst;inst++) { - if (PHY_vars_UE_g[inst]==NULL) PHY_vars_UE_g[inst] = (PHY_VARS_UE**)calloc(1+MAX_NUM_CCs,sizeof(PHY_VARS_UE*)); LOG_I(PHY,"Allocating UE context %d\n",inst); - if (simL1flag == 0) PHY_vars_UE_g[inst][0] = init_ue_vars(fp0,inst,0); + if ( !IS_SOFTMODEM_SIML1 ) PHY_vars_UE_g[inst][0] = init_ue_vars(fp0,inst,0); else { // needed for memcopy below. these are not used in the RU, but needed for UE - RC.ru[0]->frame_parms.nb_antennas_rx = fp0->nb_antennas_rx; - RC.ru[0]->frame_parms.nb_antennas_tx = fp0->nb_antennas_tx; - PHY_vars_UE_g[inst][0] = init_ue_vars(&RC.ru[0]->frame_parms,inst,0); + RC.ru[0]->frame_parms.nb_antennas_rx = fp0->nb_antennas_rx; + RC.ru[0]->frame_parms.nb_antennas_tx = fp0->nb_antennas_tx; + PHY_vars_UE_g[inst][0] = init_ue_vars(&RC.ru[0]->frame_parms,inst,0); } + // turn off timing control loop in UE PHY_vars_UE_g[inst][0]->no_timing_correction = timing_correction; - UE = PHY_vars_UE_g[inst][0]; fp = &UE->frame_parms; printf("PHY_vars_UE_g[0][0] = %p\n",UE); @@ -290,7 +291,6 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti UE->pusch_config_dedicated[i].betaOffset_ACK_Index = 0; UE->pusch_config_dedicated[i].betaOffset_RI_Index = 0; UE->pusch_config_dedicated[i].betaOffset_CQI_Index = 2; - UE->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; UE->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); UE->scheduling_request_config[i].dsr_TransMax = sr_n4; @@ -305,69 +305,75 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti if (UE->mac_enabled == 1) { UE->pdcch_vars[0][0]->crnti = 0x1234; UE->pdcch_vars[1][0]->crnti = 0x1234; - }else { + } else { UE->pdcch_vars[0][0]->crnti = 0x1235; UE->pdcch_vars[1][0]->crnti = 0x1235; } + UE->rx_total_gain_dB = rxgain; UE->tx_power_max_dBm = txpowermax; - UE->frame_parms.nb_antennas_tx = fp0->nb_antennas_tx; - UE->frame_parms.nb_antennas_rx = fp0->nb_antennas_rx; + UE->frame_parms.nb_antennas_rx = fp0->nb_antennas_rx; if (fp->frame_type == TDD) { switch (fp->N_RB_DL) { + case 100: + if (fp->threequarter_fs) UE->N_TA_offset = (624*3)/4; + else UE->N_TA_offset = 624; - case 100: - if (fp->threequarter_fs) UE->N_TA_offset = (624*3)/4; - else UE->N_TA_offset = 624; - break; - case 75: - UE->N_TA_offset = (624*3)/4; - break; - case 50: - UE->N_TA_offset = 624/2; - break; - case 25: - UE->N_TA_offset = 624/4; - break; - case 15: - UE->N_TA_offset = 624/8; - break; - case 6: - UE->N_TA_offset = 624/16; - break; - default: - AssertFatal(1==0,"illegal N_RB_DL %d\n",fp->N_RB_DL); - break; + break; + + case 75: + UE->N_TA_offset = (624*3)/4; + break; + + case 50: + UE->N_TA_offset = 624/2; + break; + + case 25: + UE->N_TA_offset = 624/4; + break; + + case 15: + UE->N_TA_offset = 624/8; + break; + + case 6: + UE->N_TA_offset = 624/16; + break; + + default: + AssertFatal(1==0,"illegal N_RB_DL %d\n",fp->N_RB_DL); + break; } - } - else UE->N_TA_offset = 0; + } else UE->N_TA_offset = 0; -#if BASIC_SIMULATOR - /* this is required for the basic simulator in TDD mode - * TODO: find a proper cleaner solution - */ - UE->N_TA_offset = 0; -#endif + if( IS_SOFTMODEM_BASICSIM) + /* this is required for the basic simulator in TDD mode + * TODO: find a proper cleaner solution + */ + UE->N_TA_offset = 0; + + if (IS_SOFTMODEM_SIML1 ) init_ue_devices(UE); - if (simL1flag == 1) init_ue_devices(UE); LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); init_UE_threads(inst); - if (simL1flag == 0) { + if (!IS_SOFTMODEM_SIML1 ) { ret = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]); - if (ret !=0){ - exit_fun("Error loading device library"); + + if (ret !=0) { + exit_fun("Error loading device library"); } } + UE->rfdevice.host_type = RAU_HOST; // UE->rfdevice.type = NONE_DEV; - AssertFatal(0 == pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, - (void*)UE), ""); + (void *)UE), ""); } printf("UE threads created by %ld\n", gettid()); @@ -376,31 +382,24 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti // Initiating all UEs within a single set of threads for PHY_STUB. Future extensions -> multiple // set of threads for multiple UEs. void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface) { - int inst; - LOG_I(PHY,"UE : Calling Layer 2 for initialization, nb_inst: %d \n", nb_inst); - l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL, - 0,// cba_group_active - 0); // HO flag - - for (inst=0;inst<nb_inst;inst++) { + 0,// cba_group_active + 0); // HO flag + for (inst=0; inst<nb_inst; inst++) { LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]); // PHY_vars_UE_g[inst][0] = init_ue_vars(NULL,inst,0); } + init_timer_thread(); init_UE_single_thread_stub(nb_inst); - - printf("UE threads created \n"); - LOG_I(PHY,"Starting multicast link on %s\n",emul_iface); - if(nfapi_mode!=3) - multicast_link_start(ue_stub_rx_handler,0,emul_iface); - + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) + multicast_link_start(ue_stub_rx_handler,0,emul_iface); } @@ -408,36 +407,29 @@ void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, void init_UE_stub(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface) { - int inst; - LOG_I(PHY,"UE : Calling Layer 2 for initialization\n"); - l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL, - 0,// cba_group_active - 0); // HO flag - - for (inst=0;inst<nb_inst;inst++) { + 0,// cba_group_active + 0); // HO flag + for (inst=0; inst<nb_inst; inst++) { LOG_I(PHY,"Initializing memory for UE instance %d (%p)\n",inst,PHY_vars_UE_g[inst]); PHY_vars_UE_g[inst][0] = init_ue_vars(NULL,inst,0); } - init_timer_thread(); - for (inst=0;inst<nb_inst;inst++) { + init_timer_thread(); + for (inst=0; inst<nb_inst; inst++) { LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); init_UE_threads_stub(inst); } printf("UE threads created \n"); - LOG_I(PHY,"Starting multicast link on %s\n",emul_iface); - if(nfapi_mode !=3) - multicast_link_start(ue_stub_rx_handler,0,emul_iface); - - + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) + multicast_link_start(ue_stub_rx_handler,0,emul_iface); } @@ -450,11 +442,10 @@ void init_UE_stub(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_ifa * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void *UE_thread_synch(void *arg) -{ +static void *UE_thread_synch(void *arg) { static int UE_thread_synch_retval; int i ; - PHY_VARS_UE *UE = (PHY_VARS_UE*) arg; + PHY_VARS_UE *UE = (PHY_VARS_UE *) arg; int current_band = 0; int current_offset = 0; sync_mode_t sync_mode = pbch; @@ -463,30 +454,28 @@ static void *UE_thread_synch(void *arg) int found; int freq_offset=0; char threadname[128]; - printf("UE_thread_sync in with PHY_vars_UE %p\n",arg); - cpu_set_t cpuset; CPU_ZERO(&cpuset); + if ( threads.iq != -1 ) CPU_SET(threads.iq, &cpuset); + // this thread priority must be lower that the main acquisition thread sprintf(threadname, "sync UE %d\n", UE->Mod_id); init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname); - printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch); ind = 0; found = 0; - if (UE->UE_scan == 0) { do { current_band = eutra_bands[ind].band; printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min); if ((eutra_bands[ind].dl_min <= UE->frame_parms.dl_CarrierFreq) && (eutra_bands[ind].dl_max >= UE->frame_parms.dl_CarrierFreq)) { - for (i=0; i<4; i++) - uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; + for (i=0; i<4; i++) + uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min; found = 1; break; @@ -501,241 +490,240 @@ static void *UE_thread_synch(void *arg) return &UE_thread_synch_retval; } + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", UE->frame_parms.dl_CarrierFreq, UE->frame_parms.ul_CarrierFreq,oai_exit, + openair0_cfg[0].rx_num_channels); - LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", UE->frame_parms.dl_CarrierFreq, UE->frame_parms.ul_CarrierFreq,oai_exit, openair0_cfg[0].rx_num_channels); - - for (i=0;i<openair0_cfg[UE->rf_map.card].rx_num_channels;i++) { + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq; openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq; openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + if (uplink_frequency_offset[CC_id][i] != 0) // - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; else //FDD - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; + openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; } sync_mode = pbch; - } else if (UE->UE_scan == 1) { current_band=0; for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min; uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = - bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; + bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min; openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = - downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; } } -/* - while (sync_var<0) - pthread_cond_wait(&sync_cond, &sync_mutex); - pthread_mutex_unlock(&sync_mutex); -*/ + /* + while (sync_var<0) + pthread_cond_wait(&sync_cond, &sync_mutex); + pthread_mutex_unlock(&sync_mutex); + */ wait_sync("UE_thread_sync"); - printf("Started device, unlocked sync_mutex (UE_sync_thread)\n"); while (oai_exit==0) { AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + while (UE->proc.instance_cnt_synch < 0) // the thread waits here most of the time pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch ); + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); switch (sync_mode) { - case pss: - LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); - lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); - current_offset += 20000000; // increase by 20 MHz - - if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { - current_band++; - current_offset=0; - } + case pss: + LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset); + current_offset += 20000000; // increase by 20 MHz + + if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) { + current_band++; + current_offset=0; + } - if (current_band==bands_to_scan.nbands) { - current_band=0; - oai_exit=1; - } + if (current_band==bands_to_scan.nbands) { + current_band=0; + oai_exit=1; + } - for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { - downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; - uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset; + uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset; + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB; - if (UE->UE_scan_carrier) { - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - } + if (UE->UE_scan_carrier) { + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + } - break; + break; - case pbch: + case pbch: + LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); + + if (initial_sync( UE, UE->mode ) == 0) { + LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", + (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti, + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, + UE->UE_scan_carrier ); + + // rerun with new cell parameters and frequency-offset + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset); + else + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset); + + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; + downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; + freq_offset=0; + } + } -#if DISABLE_LOG_X - printf("[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); -#else - LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); -#endif - if (initial_sync( UE, UE->mode ) == 0) { - - LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n", - (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti, - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset, - UE->UE_scan_carrier ); - - - // rerun with new cell parameters and frequency-offset - for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset); - else - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset); - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i]; - downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i]; - freq_offset=0; - } - } - - // reconfigure for potentially different bandwidth - switch(UE->frame_parms.N_RB_DL) { - case 6: - openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; - openair0_cfg[UE->rf_map.card].rx_bw =.96e6; - openair0_cfg[UE->rf_map.card].tx_bw =.96e6; - // openair0_cfg[0].rx_gain[0] -= 12; - break; - case 25: - openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; - openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; - openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; - // openair0_cfg[0].rx_gain[0] -= 6; - break; - case 50: - openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; - openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; - openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; - // openair0_cfg[0].rx_gain[0] -= 3; - break; - case 100: - openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; - openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; - openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; - // openair0_cfg[0].rx_gain[0] -= 0; - break; - } - - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); - //UE->rfdevice.trx_stop_func(&UE->rfdevice); - sleep(1); - init_frame_parms(&UE->frame_parms,1); - /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { - LOG_E(HW,"Could not start the device\n"); - oai_exit=1; - }*/ - - if (UE->UE_scan_carrier == 1) { - - UE->UE_scan_carrier = 0; - } else { - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - UE->is_synchronized = 1; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - - if( UE->mode == rx_dump_frame ) { - FILE *fd; - if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present - if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } else { - LOG_E(PHY,"Cannot open file for writing\n"); - exit(0); - } - } else { - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - UE->is_synchronized = 0; - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - - } - } - } - } else { - // initial sync failed - // calculate new offset and try again - if (UE->UE_scan_carrier == 1) { - if (freq_offset >= 0) - freq_offset += 100; - freq_offset *= -1; - - if (abs(freq_offset) > 7500) { - LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); - FILE *fd; - if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { - fwrite((void*)&UE->common_vars.rxdata[0][0], - sizeof(int32_t), - 10*UE->frame_parms.samples_per_tti, - fd); - LOG_I(PHY,"Dummping Frame ... bye bye \n"); - fclose(fd); - exit(0); - } - AssertFatal(1==0,"No cell synchronization found, abandoning"); - return &UE_thread_synch_retval; // not reached - } - } -#if DISABLE_LOG_X - printf("[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); -#else - LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", - freq_offset, - UE->rx_total_gain_dB, - downlink_frequency[0][0]+freq_offset, - downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); -#endif + // reconfigure for potentially different bandwidth + switch(UE->frame_parms.N_RB_DL) { + case 6: + openair0_cfg[UE->rf_map.card].sample_rate =1.92e6; + openair0_cfg[UE->rf_map.card].rx_bw =.96e6; + openair0_cfg[UE->rf_map.card].tx_bw =.96e6; + // openair0_cfg[0].rx_gain[0] -= 12; + break; + + case 25: + openair0_cfg[UE->rf_map.card].sample_rate =7.68e6; + openair0_cfg[UE->rf_map.card].rx_bw =2.5e6; + openair0_cfg[UE->rf_map.card].tx_bw =2.5e6; + // openair0_cfg[0].rx_gain[0] -= 6; + break; + + case 50: + openair0_cfg[UE->rf_map.card].sample_rate =15.36e6; + openair0_cfg[UE->rf_map.card].rx_bw =5.0e6; + openair0_cfg[UE->rf_map.card].tx_bw =5.0e6; + // openair0_cfg[0].rx_gain[0] -= 3; + break; + + case 100: + openair0_cfg[UE->rf_map.card].sample_rate=30.72e6; + openair0_cfg[UE->rf_map.card].rx_bw=10.0e6; + openair0_cfg[UE->rf_map.card].tx_bw=10.0e6; + // openair0_cfg[0].rx_gain[0] -= 0; + break; + } - for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; - if (UE->UE_scan_carrier==1) - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } - UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - }// initial_sync=0 - break; - case si: - default: - break; + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); + //UE->rfdevice.trx_stop_func(&UE->rfdevice); + sleep(1); + init_frame_parms(&UE->frame_parms,1); + + /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { + LOG_E(HW,"Could not start the device\n"); + oai_exit=1; + }*/ + + if (UE->UE_scan_carrier == 1) { + UE->UE_scan_carrier = 0; + } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + UE->is_synchronized = 1; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + + if( UE->mode == rx_dump_frame ) { + FILE *fd; + + if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present + if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { + fwrite((void *)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } else { + LOG_E(PHY,"Cannot open file for writing\n"); + exit(0); + } + } else { + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + UE->is_synchronized = 0; + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + } + } + } + } else { + // initial sync failed + // calculate new offset and try again + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) + freq_offset += 100; + + freq_offset *= -1; + + if (abs(freq_offset) > 7500) { + LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" ); + FILE *fd; + + if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) { + fwrite((void *)&UE->common_vars.rxdata[0][0], + sizeof(int32_t), + 10*UE->frame_parms.samples_per_tti, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + } + + AssertFatal(1==0,"No cell synchronization found, abandoning"); + return &UE_thread_synch_retval; // not reached + } + } + + LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n", + freq_offset, + UE->rx_total_gain_dB, + downlink_frequency[0][0]+freq_offset, + downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset ); + + for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) { + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset; + openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + + if (UE->UE_scan_carrier==1) + openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; + } + + UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); + }// initial_sync=0 + + break; + + case si: + default: + break; } AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); // indicate readiness UE->proc.instance_cnt_synch--; AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 ); } // while !oai_exit @@ -749,15 +737,18 @@ static void *UE_thread_synch(void *arg) * \param arg is a pointer to a \ref PHY_VARS_UE structure. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -const char * get_connectionloss_errstr(int errcode) { - switch (errcode) { - case CONNECTION_LOST: - return "RRC Connection lost, returning to PRACH"; - case PHY_RESYNCH: - return "RRC Connection lost, trying to resynch"; - case RESYNCH: - return "return to PRACH and perform a contention-free access"; - }; +const char *get_connectionloss_errstr(int errcode) { + switch (errcode) { + case CONNECTION_LOST: + return "RRC Connection lost, returning to PRACH"; + + case PHY_RESYNCH: + return "RRC Connection lost, trying to resynch"; + + case RESYNCH: + return "return to PRACH and perform a contention-free access"; + }; + return "UNKNOWN RETURN CODE"; } @@ -766,9 +757,7 @@ static void *UE_thread_rxn_txnp4(void *arg) { struct rx_tx_thread_data *rtd = arg; UE_rxtx_proc_t *proc = rtd->proc; PHY_VARS_UE *UE = rtd->UE; - proc->subframe_rx=proc->sub_frame_start; - char threadname[256]; sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start); cpu_set_t cpuset; @@ -776,55 +765,56 @@ static void *UE_thread_rxn_txnp4(void *arg) { if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 ) CPU_SET(threads.one, &cpuset); + if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 ) CPU_SET(threads.two, &cpuset); + if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 ) CPU_SET(threads.three, &cpuset); + //CPU_SET(threads.three, &cpuset); - init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, - threadname); + init_thread(900000,1000000, FIFO_PRIORITY-1, &cpuset, + threadname); while (!oai_exit) { if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); exit_fun("nothing to add"); } + while (proc->instance_cnt_rxtx < 0) { // most of the time, the thread is waiting here pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); } - if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); - exit_fun("nothing to add"); - } + //printf("Processing sub frqme %d in %s\n", proc->subframe_rx, threadname); initRefTimes(t2); initRefTimes(t3); pickTime(current); updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)"); - // Process Rx data for one sub-frame lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - if ((sf_type == SF_DL) || - (UE->frame_parms.frame_type == FDD) || - (sf_type == SF_S)) { + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { if (UE->frame_parms.frame_type == TDD) { - LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", - threadname, - UE->frame_parms.tdd_config, - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n", + threadname, + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); } else { - LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", - threadname, - (UE->frame_parms.frame_type==FDD? "FDD": - (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + LOG_D(PHY, "%s,%s,%s: calling UE_RX\n", + threadname, + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); } + #ifdef UE_SLOT_PARALLELISATION phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); #else @@ -835,49 +825,46 @@ static void *UE_thread_rxn_txnp4(void *arg) { #if UE_TIMING_TRACE start_meas(&UE->generic_stat); #endif - if (UE->mac_enabled==1) { + if (UE->mac_enabled==1) { int ret = ue_scheduler(UE->Mod_id, - proc->frame_rx, - proc->subframe_rx, - proc->frame_tx, - proc->subframe_tx, - subframe_select(&UE->frame_parms,proc->subframe_tx), - 0, - 0/*FIXME CC_id*/); + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0/*FIXME CC_id*/); + if ( ret != CONNECTION_OK) { - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); } } + #if UE_TIMING_TRACE stop_meas(&UE->generic_stat); #endif - // Prepare the future Tx data if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || - (UE->frame_parms.frame_type == FDD) ) + (UE->frame_parms.frame_type == FDD) ) if (UE->mode != loop_through_memory) - phy_procedures_UE_TX(UE,proc,0,0,UE->mode); - - + phy_procedures_UE_TX(UE,proc,0,0,UE->mode); if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) && - (UE->frame_parms.frame_type == TDD)) + (UE->frame_parms.frame_type == TDD)) if (UE->mode != loop_through_memory) - phy_procedures_UE_S_TX(UE,0,0); + phy_procedures_UE_S_TX(UE,0,0); + updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)"); + proc->instance_cnt_rxtx--; - if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("noting to add"); + if ( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { + if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort(); } - proc->instance_cnt_rxtx--; -#if BASIC_SIMULATOR - if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort(); -#endif + if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) { LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" ); exit_fun("noting to add"); @@ -894,61 +881,57 @@ static void *UE_thread_rxn_txnp4(void *arg) { unsigned int emulator_absSF; void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) { - PHY_VARS_UE *UE; UE = PHY_vars_UE_g[0][0]; + UE_tport_t *pdu = (UE_tport_t *)rx_buffer; + SLSCH_t *slsch = (SLSCH_t *)&pdu->slsch; + SLDCH_t *sldch = (SLDCH_t *)&pdu->sldch; + + switch (((UE_tport_header_t *)rx_buffer)->packet_type) { + case TTI_SYNC: + emulator_absSF = ((UE_tport_header_t *)rx_buffer)->absSF; + wakeup_thread(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread"); + break; - UE_tport_t *pdu = (UE_tport_t*)rx_buffer; - SLSCH_t *slsch = (SLSCH_t*)&pdu->slsch; - SLDCH_t *sldch = (SLDCH_t*)&pdu->sldch; - - switch (((UE_tport_header_t*)rx_buffer)->packet_type) { - case TTI_SYNC: - emulator_absSF = ((UE_tport_header_t*)rx_buffer)->absSF; - wakeup_thread(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread"); - break; - case SLSCH: - - - LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLSCH packet\n",emulator_absSF/10,emulator_absSF%10); - LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLSCH payload (%d bytes) to MAC\n",num_bytes, - pdu->header.absSF/10,pdu->header.absSF%10, - slsch->payload_length); - printf("SLSCH:"); - for (int i=0;i<sizeof(SLSCH_t);i++) printf("%x ",((uint8_t*)slsch)[i]); - printf("\n"); - - ue_send_sl_sdu(0, - 0, - pdu->header.absSF/10, - pdu->header.absSF%10, - pdu->payload, - slsch->payload_length, - 0, - SL_DISCOVERY_FLAG_NO); - break; - - case SLDCH: - - - LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLDCH packet\n",emulator_absSF/10,emulator_absSF%10); - LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLDCH payload (%d bytes) to MAC\n",num_bytes, - pdu->header.absSF/10,pdu->header.absSF%10, - sldch->payload_length); - printf("SLDCH:"); - for (int i=0;i<sizeof(SLDCH_t);i++) printf("%x ",((uint8_t*)sldch)[i]); - printf("\n"); - - ue_send_sl_sdu(0, - 0, - pdu->header.absSF/10, - pdu->header.absSF%10, - sldch->payload, - sldch->payload_length, - 0, - SL_DISCOVERY_FLAG_YES); - break; + case SLSCH: + LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLSCH packet\n",emulator_absSF/10,emulator_absSF%10); + LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLSCH payload (%d bytes) to MAC\n",num_bytes, + pdu->header.absSF/10,pdu->header.absSF%10, + slsch->payload_length); + printf("SLSCH:"); + + for (int i=0; i<sizeof(SLSCH_t); i++) printf("%x ",((uint8_t *)slsch)[i]); + + printf("\n"); + ue_send_sl_sdu(0, + 0, + pdu->header.absSF/10, + pdu->header.absSF%10, + pdu->payload, + slsch->payload_length, + 0, + SL_DISCOVERY_FLAG_NO); + break; + case SLDCH: + LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLDCH packet\n",emulator_absSF/10,emulator_absSF%10); + LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLDCH payload (%d bytes) to MAC\n",num_bytes, + pdu->header.absSF/10,pdu->header.absSF%10, + sldch->payload_length); + printf("SLDCH:"); + + for (int i=0; i<sizeof(SLDCH_t); i++) printf("%x ",((uint8_t *)sldch)[i]); + + printf("\n"); + ue_send_sl_sdu(0, + 0, + pdu->header.absSF/10, + pdu->header.absSF%10, + sldch->payload, + sldch->payload_length, + 0, + SL_DISCOVERY_FLAG_YES); + break; } } @@ -962,17 +945,19 @@ void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) { */ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { - - thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); - - // for multipule UE's L2-emulator - //module_id_t Mod_id = 0; - - //int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames + thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); + // for multipule UE's L2-emulator + //module_id_t Mod_id = 0; + //int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames static __thread int UE_thread_rxtx_retval; struct rx_tx_thread_data *rtd = arg; - UE_rxtx_proc_t *proc = rtd->proc; + if (rtd == NULL) { + LOG_E( MAC, "[SCHED][UE] rx_tx_thread_data *rtd: NULL pointer\n" ); + exit_fun("nothing to add"); + } + + UE_rxtx_proc_t *proc = rtd->proc; // settings for nfapi-L2-emulator mode module_id_t ue_thread_id = rtd->ue_thread_id; uint16_t ue_index = 0; @@ -983,12 +968,9 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { uint8_t end_flag; proc = &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0]; phy_stub_ticking->num_single_thread[ue_thread_id] = -1; + UE = rtd->UE; - if (rtd != NULL) { - UE = rtd->UE; - } - - if(ue_thread_id == 0){ + if(ue_thread_id == 0) { phy_stub_ticking->ticking_var = -1; proc->subframe_rx=proc->sub_frame_start; // Initializations for nfapi-L2-emulator mode @@ -998,296 +980,287 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { tx_request_pdu_list = NULL; // waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1. - do{ + do { end_flag = 1; - for(uint16_t i = 0;i< NB_THREAD_INST;i++){ - if(phy_stub_ticking->num_single_thread[i] == 0){ + + for(uint16_t i = 0; i< NB_THREAD_INST; i++) { + if(phy_stub_ticking->num_single_thread[i] == 0) { end_flag = 0; } } - }while(end_flag == 0); + } while(end_flag == 0); sync_var=0; } - //PANOS: CAREFUL HERE! wait_sync("UE_phy_stub_single_thread_rxn_txnp4"); while (!oai_exit) { - if(ue_thread_id == 0){ - if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) { - LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("nothing to add"); - } - while (phy_stub_ticking->ticking_var < 0) { - // most of the time, the thread is waiting here - //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ) - LOG_D(MAC,"Waiting for ticking_var\n"); - pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking); - } - phy_stub_ticking->ticking_var--; - if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) { - LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); - exit_fun("nothing to add"); - } - - proc->subframe_rx=timer_subframe; - proc->frame_rx = timer_frame; - - // FDD and TDD tx timing settings. - // XXX:It is the result of timing adjustment in debug. - // It is necessary to investigate why this will work in the future. - proc->subframe_tx=(timer_subframe+sf_ahead)%10; - proc->frame_tx = proc->frame_rx + (proc->subframe_rx>(9-sf_ahead)?1:0); - //oai_subframe_ind(proc->frame_rx, proc->subframe_rx); - - if (UE != NULL) { - if (UE->frame_parms.frame_type == FDD) { - oai_subframe_ind(proc->frame_rx, proc->subframe_rx); - } else { - oai_subframe_ind(proc->frame_tx, proc->subframe_tx); + if(ue_thread_id == 0) { + if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) { + LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("nothing to add"); } - } else { - // Default will be FDD - oai_subframe_ind(proc->frame_rx, proc->subframe_rx); - } - - //Guessing that the next 4 lines are not needed for the phy_stub mode. - /*initRefTimes(t2); - initRefTimes(t3); - pickTime(current); - updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");*/ - - // Not sure whether we should put the memory allocation here and not sure how much memory - //we should allocate for each subframe cycle. - UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t)); + while (phy_stub_ticking->ticking_var < 0) { + // most of the time, the thread is waiting here + //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ) + LOG_D(MAC,"Waiting for ticking_var\n"); + pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking); + } - UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t)); - UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; + phy_stub_ticking->ticking_var--; + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) { + LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); + exit_fun("nothing to add"); + } - UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t)); - UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; + proc->subframe_rx=timer_subframe; + proc->frame_rx = timer_frame; + // FDD and TDD tx timing settings. + // XXX:It is the result of timing adjustment in debug. + // It is necessary to investigate why this will work in the future. + proc->subframe_tx=(timer_subframe+sf_ahead)%10; + proc->frame_tx = proc->frame_rx + (proc->subframe_rx>(9-sf_ahead)?1:0); + //oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + + if (UE != NULL) { + if (UE->frame_parms.frame_type == FDD) { + oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + } else { + oai_subframe_ind(proc->frame_tx, proc->subframe_tx); + } + } else { + // Default will be FDD + oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + } - UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_harq_indication_pdu_t)); - UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; + //Guessing that the next 4 lines are not needed for the phy_stub mode. + /*initRefTimes(t2); + initRefTimes(t3); + pickTime(current); + updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");*/ + // Not sure whether we should put the memory allocation here and not sure how much memory + //we should allocate for each subframe cycle. + UL_INFO = (UL_IND_t *)malloc(sizeof(UL_IND_t)); + UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t)); + UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; + UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t)); + UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; + UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_harq_indication_pdu_t)); + UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); + UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + UL_INFO->cqi_ind.cqi_pdu_list = (nfapi_cqi_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t)); + UL_INFO->cqi_ind.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t)); + UL_INFO->cqi_ind.number_of_cqis = 0; + + if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } - UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); - UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + memset(&phy_stub_ticking->num_single_thread[0],0,sizeof(int)*NB_THREAD_INST); + pthread_cond_broadcast(&phy_stub_ticking->cond_single_thread); - UL_INFO->cqi_ind.cqi_pdu_list = (nfapi_cqi_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t)); - UL_INFO->cqi_ind.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t)); - UL_INFO->cqi_ind.number_of_cqis = 0; + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } + } else { + if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } - if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { - LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); - exit_fun("nothing to add"); - } - memset(&phy_stub_ticking->num_single_thread[0],0,sizeof(int)*NB_THREAD_INST); - pthread_cond_broadcast(&phy_stub_ticking->cond_single_thread); + while (phy_stub_ticking->num_single_thread[ue_thread_id] < 0) { + // most of the time, the thread is waiting here + LOG_D(MAC,"Waiting for single_thread (ue_thread_id %d)\n",ue_thread_id); + pthread_cond_wait( &phy_stub_ticking->cond_single_thread, &phy_stub_ticking->mutex_single_thread); + } - if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) { - LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); - exit_fun("nothing to add"); - } - }else{ - if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { - LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); - exit_fun("nothing to add"); - } - while (phy_stub_ticking->num_single_thread[ue_thread_id] < 0) { - // most of the time, the thread is waiting here - LOG_D(MAC,"Waiting for single_thread (ue_thread_id %d)\n",ue_thread_id); - pthread_cond_wait( &phy_stub_ticking->cond_single_thread, &phy_stub_ticking->mutex_single_thread); - } - if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) { - LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); - exit_fun("nothing to add"); - } + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } } //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++) { for (ue_index=0; ue_index < ue_num; ue_index++) { - ue_Mod_id = ue_thread_id + NB_THREAD_INST*ue_index; - UE = PHY_vars_UE_g[ue_Mod_id][0]; - //LOG_D(MAC, "UE_phy_stub_single_thread_rxn_txnp4, NB_UE_INST:%d, Mod_id:%d \n", NB_UE_INST, Mod_id); - //UE = PHY_vars_UE_g[Mod_id][0]; - lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - if ((sf_type == SF_DL) || - (UE->frame_parms.frame_type == FDD) || - (sf_type == SF_S)) { - - if (UE->frame_parms.frame_type == TDD) { - LOG_D(PHY, "TDD%d,%s: calling UE_RX\n", - UE->frame_parms.tdd_config, - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } else { - LOG_D(PHY, "%s,%s: calling UE_RX\n", - (UE->frame_parms.frame_type==FDD? "FDD": - (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); - } + ue_Mod_id = ue_thread_id + NB_THREAD_INST*ue_index; + UE = PHY_vars_UE_g[ue_Mod_id][0]; + //LOG_D(MAC, "UE_phy_stub_single_thread_rxn_txnp4, NB_UE_INST:%d, Mod_id:%d \n", NB_UE_INST, Mod_id); + //UE = PHY_vars_UE_g[Mod_id][0]; + lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); + + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { + if (UE->frame_parms.frame_type == TDD) { + LOG_D(PHY, "TDD%d,%s: calling UE_RX\n", + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } else { + LOG_D(PHY, "%s,%s: calling UE_RX\n", + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + } + phy_procedures_UE_SL_RX(UE,proc); - phy_procedures_UE_SL_RX(UE,proc); - - if (dl_config_req!=NULL && tx_request_pdu_list!=NULL){ - //if(dl_config_req!= NULL) { - dl_config_req_UE_MAC(dl_config_req, ue_Mod_id); + if (dl_config_req!=NULL && tx_request_pdu_list!=NULL) { + //if(dl_config_req!= NULL) { + dl_config_req_UE_MAC(dl_config_req, ue_Mod_id); + } - } + if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) { + hi_dci0_req_UE_MAC(hi_dci0_req, ue_Mod_id); + } - if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ - hi_dci0_req_UE_MAC(hi_dci0_req, ue_Mod_id); + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) + phy_procedures_UE_SL_TX(UE,proc); } - if(nfapi_mode!=3) - phy_procedures_UE_SL_TX(UE,proc); - - } - #if UE_TIMING_TRACE - start_meas(&UE->generic_stat); + start_meas(&UE->generic_stat); #endif - if (UE->mac_enabled==1) { - - ret = ue_scheduler(ue_Mod_id, - proc->frame_rx, - proc->subframe_rx, - proc->frame_tx, - proc->subframe_tx, - subframe_select(&UE->frame_parms,proc->subframe_tx), - 0, - 0/*FIXME CC_id*/); - if ( ret != CONNECTION_OK) { - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); + if (UE->mac_enabled==1) { + ret = ue_scheduler(ue_Mod_id, + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0/*FIXME CC_id*/); + + if ( ret != CONNECTION_OK) { + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); + } } - } + #if UE_TIMING_TRACE - stop_meas(&UE->generic_stat); + stop_meas(&UE->generic_stat); #endif + // Prepare the future Tx data + + if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || + (UE->frame_parms.frame_type == FDD) ) + if (UE->mode != loop_through_memory) { + // We make the start of RA between consecutive UEs differ by 20 frames + //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) { + if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH && ue_Mod_id == next_Mod_id) { + next_ra_frame++; + + if(next_ra_frame > 200) { + // check if we have PRACH opportunity + if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1) { + // The one working strangely... + //if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) { + PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); + + if(prach_resources!=NULL ) { + UE_mac_inst[ue_Mod_id].ra_frame = proc->frame_rx; + LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id,proc->frame_tx, proc->subframe_tx); + fill_rach_indication_UE_MAC(ue_Mod_id, proc->frame_tx,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); + Msg1_transmitted(ue_Mod_id, 0, proc->frame_tx, 0); + UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE; + next_Mod_id = ue_Mod_id + 1; + //next_ra_frame = (proc->frame_rx + 20)%1000; + next_ra_frame = 0; + } - // Prepare the future Tx data + //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); + } + } + } // mode is PRACH - if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || - (UE->frame_parms.frame_type == FDD) ) - if (UE->mode != loop_through_memory){ - - // We make the start of RA between consecutive UEs differ by 20 frames - //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) { - if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH && ue_Mod_id == next_Mod_id) { - next_ra_frame++; - if(next_ra_frame > 200){ - // check if we have PRACH opportunity - - if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1) { - - // The one working strangely... - //if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) { - - PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); - if(prach_resources!=NULL ) { - UE_mac_inst[ue_Mod_id].ra_frame = proc->frame_rx; - LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id ,proc->frame_tx, proc->subframe_tx); - fill_rach_indication_UE_MAC(ue_Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); - Msg1_transmitted(ue_Mod_id, 0, proc->frame_tx, 0); - UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE; - next_Mod_id = ue_Mod_id + 1; - //next_ra_frame = (proc->frame_rx + 20)%1000; - next_ra_frame = 0; - } - - //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); - } + // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger + // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). + // Generate UL_indications which correspond to UL traffic. + if(ul_config_req!=NULL) { //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ + ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, ue_Mod_id); } - } // mode is PRACH - // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger - // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). - // Generate UL_indications which correspond to UL traffic. - if(ul_config_req!=NULL){ //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ - ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, ue_Mod_id); - } - } - - phy_procedures_UE_SL_RX(UE,proc); - + } + phy_procedures_UE_SL_RX(UE,proc); } //for (Mod_id=0; Mod_id<NB_UE_INST; Mod_id++) phy_stub_ticking->num_single_thread[ue_thread_id] = -1; // waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1. - if(ue_thread_id == 0){ - do{ + if(ue_thread_id == 0) { + do { end_flag = 1; - for(uint16_t i = 0;i< NB_THREAD_INST;i++){ - if(phy_stub_ticking->num_single_thread[i] == 0){ - end_flag = 0; + + for(uint16_t i = 0; i< NB_THREAD_INST; i++) { + if(phy_stub_ticking->num_single_thread[i] == 0) { + end_flag = 0; } } - }while(end_flag == 0); + } while(end_flag == 0); + + if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0) { + //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.2, SFN/SF of PNF counter:%d.%d, number_of_crcs: %d \n", timer_frame, timer_subframe, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); + oai_nfapi_crc_indication(&UL_INFO->crc_ind); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.21 \n"); + UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; + } + if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus>0) { + //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf)); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus); + oai_nfapi_rx_ind(&UL_INFO->rx_ind); - if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0) - { - //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); - //LOG_I(MAC, "ul_config_req_UE_MAC 2.2, SFN/SF of PNF counter:%d.%d, number_of_crcs: %d \n", timer_frame, timer_subframe, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); - oai_nfapi_crc_indication(&UL_INFO->crc_ind); - //LOG_I(MAC, "ul_config_req_UE_MAC 2.21 \n"); - UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; - } - if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus>0) - { - //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf)); - //LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus); - oai_nfapi_rx_ind(&UL_INFO->rx_ind); - for(uint8_t num_pdu = 0;num_pdu < UL_INFO->rx_ind.rx_indication_body.number_of_pdus;num_pdu++){ - free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[num_pdu].data); - } - //LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n"); - UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; + for(uint8_t num_pdu = 0; num_pdu < UL_INFO->rx_ind.rx_indication_body.number_of_pdus; num_pdu++) { + free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[num_pdu].data); + } + + //LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n"); + UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; } - if(UL_INFO->harq_ind.harq_indication_body.number_of_harqs>0) - { - //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs); - oai_nfapi_harq_indication(&UL_INFO->harq_ind); - //LOG_I(MAC, "ul_config_req_UE_MAC 2.41 \n"); - UL_INFO->harq_ind.harq_indication_body.number_of_harqs =0; + if(UL_INFO->harq_ind.harq_indication_body.number_of_harqs>0) { + //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs); + oai_nfapi_harq_indication(&UL_INFO->harq_ind); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.41 \n"); + UL_INFO->harq_ind.harq_indication_body.number_of_harqs =0; } - if(UL_INFO->sr_ind.sr_indication_body.number_of_srs>0) - { - //LOG_I(MAC, "ul_config_req_UE_MAC 2.5, SFN/SF of PNF counter:%d.%d, number_of_srs: %d \n", timer_frame, timer_subframe, UL_INFO->sr_ind.sr_indication_body.number_of_srs); - oai_nfapi_sr_indication(&UL_INFO->sr_ind); - //LOG_I(MAC, "ul_config_req_UE_MAC 2.51 \n"); - UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + + if(UL_INFO->sr_ind.sr_indication_body.number_of_srs>0) { + //LOG_I(MAC, "ul_config_req_UE_MAC 2.5, SFN/SF of PNF counter:%d.%d, number_of_srs: %d \n", timer_frame, timer_subframe, UL_INFO->sr_ind.sr_indication_body.number_of_srs); + oai_nfapi_sr_indication(&UL_INFO->sr_ind); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.51 \n"); + UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; } // Free UL_INFO messages //if(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list != NULL){ - free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list); - UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL; + free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list); + UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL; //} //if(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list != NULL){ - free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list); - UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL; + free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list); + UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL; //} //if(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list !=NULL){ - free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list); - UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL; + free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list); + UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL; //} //if(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list!=NULL){ - free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list); - UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL; + free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list); + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL; //} free(UL_INFO->cqi_ind.cqi_pdu_list); UL_INFO->cqi_ind.cqi_pdu_list = NULL; @@ -1297,43 +1270,48 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { UL_INFO = NULL; // De-allocate memory of nfapi requests copies before next subframe round - if(dl_config_req!=NULL){ - if(dl_config_req->vendor_extension!=NULL){ - free(dl_config_req->vendor_extension); - dl_config_req->vendor_extension = NULL; - } - if(dl_config_req->dl_config_request_body.dl_config_pdu_list!=NULL){ - free(dl_config_req->dl_config_request_body.dl_config_pdu_list); - dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL; - } - free(dl_config_req); - dl_config_req = NULL; - } - if(tx_request_pdu_list!=NULL){ - free(tx_request_pdu_list); - tx_request_pdu_list = NULL; + if(dl_config_req!=NULL) { + if(dl_config_req->vendor_extension!=NULL) { + free(dl_config_req->vendor_extension); + dl_config_req->vendor_extension = NULL; + } + + if(dl_config_req->dl_config_request_body.dl_config_pdu_list!=NULL) { + free(dl_config_req->dl_config_request_body.dl_config_pdu_list); + dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL; + } + + free(dl_config_req); + dl_config_req = NULL; } - if(ul_config_req!=NULL){ - if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ - free(ul_config_req->ul_config_request_body.ul_config_pdu_list); - ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; - } - free(ul_config_req); - ul_config_req = NULL; + + if(tx_request_pdu_list!=NULL) { + free(tx_request_pdu_list); + tx_request_pdu_list = NULL; } - if(hi_dci0_req!=NULL){ - if(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ - free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); - hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; - } - free(hi_dci0_req); - hi_dci0_req = NULL; + if(ul_config_req!=NULL) { + if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) { + free(ul_config_req->ul_config_request_body.ul_config_pdu_list); + ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; + } + + free(ul_config_req); + ul_config_req = NULL; } - } + if(hi_dci0_req!=NULL) { + if(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) { + free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; + } + free(hi_dci0_req); + hi_dci0_req = NULL; + } + } } + // thread finished free(arg); return &UE_thread_rxtx_retval; @@ -1351,34 +1329,32 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { */ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) { - - thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); - - module_id_t Mod_id = 0; + thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); + module_id_t Mod_id = 0; static __thread int UE_thread_rxtx_retval; struct rx_tx_thread_data *rtd = arg; UE_rxtx_proc_t *proc = rtd->proc; PHY_VARS_UE *UE = rtd->UE; - phy_stub_ticking->ticking_var = -1; proc->subframe_rx=proc->sub_frame_start; - // CAREFUL HERE! wait_sync("UE_phy_stub_thread_rxn_txnp4"); while (!oai_exit) { - if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) { LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" ); exit_fun("nothing to add"); } + while (phy_stub_ticking->ticking_var < 0) { // most of the time, the thread is waiting here //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ) LOG_D(MAC,"Waiting for ticking_var\n"); pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking); } + phy_stub_ticking->ticking_var--; + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) { LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" ); exit_fun("nothing to add"); @@ -1388,125 +1364,118 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) { proc->frame_rx = timer_frame; proc->subframe_tx=(timer_subframe+4)%10; proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); - - // Process Rx data for one sub-frame lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx); - if ((sf_type == SF_DL) || - (UE->frame_parms.frame_type == FDD) || - (sf_type == SF_S)) { + if ((sf_type == SF_DL) || + (UE->frame_parms.frame_type == FDD) || + (sf_type == SF_S)) { if (UE->frame_parms.frame_type == TDD) { - LOG_D(PHY, "TDD%d,%s: calling UE_RX\n", - UE->frame_parms.tdd_config, - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + LOG_D(PHY, "TDD%d,%s: calling UE_RX\n", + UE->frame_parms.tdd_config, + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); } else { - LOG_D(PHY, "%s,%s: calling UE_RX\n", - (UE->frame_parms.frame_type==FDD? "FDD": - (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), - (sf_type==SF_DL? "SF_DL" : - (sf_type==SF_UL? "SF_UL" : - (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); + LOG_D(PHY, "%s,%s: calling UE_RX\n", + (UE->frame_parms.frame_type==FDD? "FDD": + (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")), + (sf_type==SF_DL? "SF_DL" : + (sf_type==SF_UL? "SF_UL" : + (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE")))); } - phy_procedures_UE_SL_RX(UE,proc); - - oai_subframe_ind(timer_frame, timer_subframe); + oai_subframe_ind(timer_frame, timer_subframe); if(dl_config_req!= NULL) { - - dl_config_req_UE_MAC(dl_config_req, Mod_id); - + dl_config_req_UE_MAC(dl_config_req, Mod_id); } + //if(UE_mac_inst[Mod_id].hi_dci0_req!= NULL){ - if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ - hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id); - //if(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ - free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); - hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; - //} - free(hi_dci0_req); - hi_dci0_req = NULL; + if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) { + hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id); + //if(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ + free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; + //} + free(hi_dci0_req); + hi_dci0_req = NULL; + } else if(hi_dci0_req!=NULL) { + free(hi_dci0_req); + hi_dci0_req = NULL; } - else if(hi_dci0_req!=NULL){ - free(hi_dci0_req); - hi_dci0_req = NULL; - } - - if (nfapi_mode != 3) + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) phy_procedures_UE_SL_TX(UE,proc); - } #if UE_TIMING_TRACE start_meas(&UE->generic_stat); #endif - if (UE->mac_enabled==1) { + if (UE->mac_enabled==1) { int ret = ue_scheduler(UE->Mod_id, - proc->frame_rx, - proc->subframe_rx, - proc->frame_tx, - proc->subframe_tx, - subframe_select(&UE->frame_parms,proc->subframe_tx), - 0, - 0); + proc->frame_rx, + proc->subframe_rx, + proc->frame_tx, + proc->subframe_tx, + subframe_select(&UE->frame_parms,proc->subframe_tx), + 0, + 0); + if (ret != CONNECTION_OK) - LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", - UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); + LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n", + UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) ); } + #if UE_TIMING_TRACE stop_meas(&UE->generic_stat); #endif - // Prepare the future Tx data if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) || - (UE->frame_parms.frame_type == FDD) ) - if (UE->mode != loop_through_memory){ - - if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH) ) { - - // check if we have PRACH opportunity - - if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx)) { - PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); - if(prach_resources!=NULL) { - fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); - Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0); - UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE; - } - - //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); - } - } // mode is PRACH - // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger - // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). - // Generate UL_indications which correspond to UL traffic. - if(ul_config_req!= NULL && ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ - //LOG_I(MAC, "UE_phy_stub_thread_rxn_txnp4 ul_config_req is not NULL \n"); - ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id); - if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ - free(ul_config_req->ul_config_request_body.ul_config_pdu_list); - ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; - } - free(ul_config_req); - ul_config_req = NULL; - } - else if(ul_config_req!=NULL){ - free(ul_config_req); - ul_config_req = NULL; - } + (UE->frame_parms.frame_type == FDD) ) + if (UE->mode != loop_through_memory) { + if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH) ) { + // check if we have PRACH opportunity + if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx)) { + PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); + + if(prach_resources!=NULL) { + fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); + Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0); + UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE; + } + + //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); + } + } // mode is PRACH + + // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger + // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). + // Generate UL_indications which correspond to UL traffic. + if(ul_config_req!= NULL && ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) { + //LOG_I(MAC, "UE_phy_stub_thread_rxn_txnp4 ul_config_req is not NULL \n"); + ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id); + + if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) { + free(ul_config_req->ul_config_request_body.ul_config_pdu_list); + ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; + } + + free(ul_config_req); + ul_config_req = NULL; + } else if(ul_config_req!=NULL) { + free(ul_config_req); + ul_config_req = NULL; + } } phy_procedures_UE_SL_RX(UE,proc); - } + // thread finished free(arg); return &UE_thread_rxtx_retval; @@ -1525,39 +1494,34 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) { */ void *UE_thread(void *arg) { - - PHY_VARS_UE *UE = (PHY_VARS_UE *) arg; // int tx_enabled = 0; int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32))); openair0_timestamp timestamp,timestamp1; - void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; + void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; int start_rx_stream = 0; int i; int th_id; - static uint8_t thread_idx = 0; - cpu_set_t cpuset; CPU_ZERO(&cpuset); + if ( threads.iq != -1 ) CPU_SET(threads.iq, &cpuset); - init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, - "UHD Threads"); + init_thread(100000, 500000, FIFO_PRIORITY, &cpuset, + "UHD Threads"); /* while (sync_var<0) pthread_cond_wait(&sync_cond, &sync_mutex); pthread_mutex_unlock(&sync_mutex); */ - wait_sync("UE thread"); #ifdef NAS_UE MessageDef *message_p; message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); #endif - int sub_frame=-1; //int cumulated_shift=0; @@ -1567,12 +1531,11 @@ void *UE_thread(void *arg) { } while (!oai_exit) { -#if BASIC_SIMULATOR - while (!(UE->proc.instance_cnt_synch < 0)) { - printf("ue sync not ready\n"); - usleep(500*1000); - } -#endif + if (IS_SOFTMODEM_BASICSIM) + while (!(UE->proc.instance_cnt_synch < 0)) { + printf("ue sync not ready\n"); + usleep(500*1000); + } AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); int instance_cnt_synch = UE->proc.instance_cnt_synch; @@ -1581,217 +1544,242 @@ void *UE_thread(void *arg) { if (is_synchronized == 0) { if (instance_cnt_synch < 0) { // we can invoke the synch - // grab 10 ms of signal and wakeup synch thread - for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&UE->common_vars.rxdata[i][0]; - - if (UE->mode != loop_through_memory) - AssertFatal( UE->frame_parms.samples_per_tti*10 == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti*10, - UE->frame_parms.nb_antennas_rx), ""); - AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); - instance_cnt_synch = ++UE->proc.instance_cnt_synch; - if (instance_cnt_synch == 0) { - AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); - } else { - LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); - exit_fun("nothing to add"); - } - AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); + // grab 10 ms of signal and wakeup synch thread + for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) + rxp[i] = (void *)&UE->common_vars.rxdata[i][0]; + + if (UE->mode != loop_through_memory) + AssertFatal( UE->frame_parms.samples_per_tti*10 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti*10, + UE->frame_parms.nb_antennas_rx), ""); + + AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), ""); + instance_cnt_synch = ++UE->proc.instance_cnt_synch; + + if (instance_cnt_synch == 0) { + AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), ""); + } else { + LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" ); + exit_fun("nothing to add"); + } + + AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), ""); } else { #if OAISIM - (void)dummy_rx; /* avoid gcc warnings */ - usleep(500); + (void)dummy_rx; /* avoid gcc warnings */ + usleep(500); #else - // grab 10 ms of signal into dummy buffer - if (UE->mode != loop_through_memory) { - for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&dummy_rx[i][0]; - for (int sf=0; sf<10; sf++) - // printf("Reading dummy sf %d\n",sf); - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - UE->frame_parms.samples_per_tti, - UE->frame_parms.nb_antennas_rx); - } + + // grab 10 ms of signal into dummy buffer + if (UE->mode != loop_through_memory) { + for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) + rxp[i] = (void *)&dummy_rx[i][0]; + + for (int sf=0; sf<10; sf++) + // printf("Reading dummy sf %d\n",sf); + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + UE->frame_parms.samples_per_tti, + UE->frame_parms.nb_antennas_rx); + } + #endif - } - - } // UE->is_synchronized==0 - else { - if (start_rx_stream==0) { - start_rx_stream=1; - if (UE->mode != loop_through_memory) { - if (UE->no_timing_correction==0) { - LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); - AssertFatal(UE->rx_offset == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)UE->common_vars.rxdata, - UE->rx_offset, - UE->frame_parms.nb_antennas_rx),""); - } - UE->rx_offset=0; - UE->time_sync_cell=0; - //UE->proc.proc_rxtx[0].frame_rx++; - //UE->proc.proc_rxtx[1].frame_rx++; - for (th_id=0; th_id < RX_NB_TH; th_id++) { - UE->proc.proc_rxtx[th_id].frame_rx++; - } - - // read in first symbol - AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - (void**)UE->common_vars.rxdata, - UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, - UE->frame_parms.nb_antennas_rx),""); - slot_fep(UE,0, 0, 0, 0, 0); - } //UE->mode != loop_through_memory - else - rt_sleep_ns(1000*1000); + } + } // UE->is_synchronized==0 + else { + if (start_rx_stream==0) { + start_rx_stream=1; + + if (UE->mode != loop_through_memory) { + if (UE->no_timing_correction==0) { + LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode); + AssertFatal(UE->rx_offset == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void **)UE->common_vars.rxdata, + UE->rx_offset, + UE->frame_parms.nb_antennas_rx),""); + } + + UE->rx_offset=0; + UE->time_sync_cell=0; + + //UE->proc.proc_rxtx[0].frame_rx++; + //UE->proc.proc_rxtx[1].frame_rx++; + for (th_id=0; th_id < RX_NB_TH; th_id++) { + UE->proc.proc_rxtx[th_id].frame_rx++; + } + + // read in first symbol + AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + (void **)UE->common_vars.rxdata, + UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0, + UE->frame_parms.nb_antennas_rx),""); + slot_fep(UE,0, 0, 0, 0, 0); + } //UE->mode != loop_through_memory + else + rt_sleep_ns(1000*1000); + } else { + sub_frame++; + sub_frame%=10; + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx]; + // update thread index for received subframe + UE->current_thread_id[sub_frame] = thread_idx; + + if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) { + int t; + + for (t = 0; t < 2; t++) { + UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t]; + pthread_mutex_lock(&proc->mutex_rxtx); + + while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); + + pthread_mutex_unlock(&proc->mutex_rxtx); + } + } + + LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]); + thread_idx++; + + if(thread_idx>=RX_NB_TH) + thread_idx = 0; + + if (UE->mode != loop_through_memory) { + for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) + rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+ + UE->frame_parms.nb_prefix_samples0+ + sub_frame*UE->frame_parms.samples_per_tti]; + + for (i=0; i<UE->frame_parms.nb_antennas_tx; i++) + txp[i] = (void *)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti]; + + int readBlockSize, writeBlockSize; + + if (sub_frame<9) { + readBlockSize=UE->frame_parms.samples_per_tti; + writeBlockSize=UE->frame_parms.samples_per_tti; + } else { + // set TO compensation to zero + UE->rx_offset_diff = 0; + + // compute TO compensation that should be applied for this frame + + if (UE->no_timing_correction == 0) { + if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti && + UE->rx_offset > 0 ) + UE->rx_offset_diff = -1 ; + + if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti && + UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) + UE->rx_offset_diff = 1; + } + + LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset); + readBlockSize=UE->frame_parms.samples_per_tti - + UE->frame_parms.ofdm_symbol_size - + UE->frame_parms.nb_prefix_samples0 - + UE->rx_offset_diff; + writeBlockSize=UE->frame_parms.samples_per_tti - + UE->rx_offset_diff; + } + + AssertFatal(readBlockSize == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp, + rxp, + readBlockSize, + UE->frame_parms.nb_antennas_rx),""); + AssertFatal( writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp+ + (2*UE->frame_parms.samples_per_tti) - + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - + openair0_cfg[0].tx_sample_advance, + txp, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + 1),""); + + if( sub_frame==9) { + // read in first symbol of next frame and adjust for timing drift + int first_symbols=writeBlockSize-readBlockSize; + + if ( first_symbols > 0 ) + AssertFatal(first_symbols == + UE->rfdevice.trx_read_func(&UE->rfdevice, + ×tamp1, + (void **)UE->common_vars.rxdata, + first_symbols, + UE->frame_parms.nb_antennas_rx),""); + + if ( first_symbols <0 ) + LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); + } + + pickTime(gotIQs); + struct timespec tv= {0}; + tv.tv_nsec=10*1000; + if( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM) + tv.tv_sec=INT_MAX; + + // operate on thread sf mod 2 + if (pthread_mutex_timedlock(&proc->mutex_rxtx, &tv) !=0) { + if ( errno == ETIMEDOUT) { + LOG_E(PHY,"Missed real time\n"); + continue; } else { - sub_frame++; - sub_frame%=10; - UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx]; - // update thread index for received subframe - UE->current_thread_id[sub_frame] = thread_idx; - -#if BASIC_SIMULATOR - { - int t; - for (t = 0; t < 2; t++) { - UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t]; - pthread_mutex_lock(&proc->mutex_rxtx); - while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx ); - pthread_mutex_unlock(&proc->mutex_rxtx); - } - } -#endif - LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]); - - thread_idx++; - if(thread_idx>=RX_NB_TH) - thread_idx = 0; - - - if (UE->mode != loop_through_memory) { - for (i=0; i<UE->frame_parms.nb_antennas_rx; i++) - rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+ - UE->frame_parms.nb_prefix_samples0+ - sub_frame*UE->frame_parms.samples_per_tti]; - for (i=0; i<UE->frame_parms.nb_antennas_tx; i++) - txp[i] = (void*)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti]; - - int readBlockSize, writeBlockSize; - if (sub_frame<9) { - readBlockSize=UE->frame_parms.samples_per_tti; - writeBlockSize=UE->frame_parms.samples_per_tti; - } else { - // set TO compensation to zero - - UE->rx_offset_diff = 0; - - // compute TO compensation that should be applied for this frame - - if (UE->no_timing_correction == 0) { - if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti && - UE->rx_offset > 0 ) - UE->rx_offset_diff = -1 ; - if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti && - UE->rx_offset < 10*UE->frame_parms.samples_per_tti ) - UE->rx_offset_diff = 1; - } - - LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset); - readBlockSize=UE->frame_parms.samples_per_tti - - UE->frame_parms.ofdm_symbol_size - - UE->frame_parms.nb_prefix_samples0 - - UE->rx_offset_diff; - writeBlockSize=UE->frame_parms.samples_per_tti - - UE->rx_offset_diff; - } - - AssertFatal(readBlockSize == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, - rxp, - readBlockSize, - UE->frame_parms.nb_antennas_rx),""); - AssertFatal( writeBlockSize == - UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - (2*UE->frame_parms.samples_per_tti) - - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 - - openair0_cfg[0].tx_sample_advance, - txp, - writeBlockSize, - UE->frame_parms.nb_antennas_tx, - 1),""); - if( sub_frame==9) { - // read in first symbol of next frame and adjust for timing drift - int first_symbols=writeBlockSize-readBlockSize; - if ( first_symbols > 0 ) - AssertFatal(first_symbols == - UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp1, - (void**)UE->common_vars.rxdata, - first_symbols, - UE->frame_parms.nb_antennas_rx),""); - if ( first_symbols <0 ) - LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); - } - pickTime(gotIQs); - // operate on thread sf mod 2 - AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,""); - if(sub_frame == 0) { - //UE->proc.proc_rxtx[0].frame_rx++; - //UE->proc.proc_rxtx[1].frame_rx++; - for (th_id=0; th_id < RX_NB_TH; th_id++) { - UE->proc.proc_rxtx[th_id].frame_rx++; - } - } - //UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs); - //UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs); - for (th_id=0; th_id < RX_NB_TH; th_id++) { - UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs); - } - proc->subframe_rx=sub_frame; - proc->subframe_tx=(sub_frame+4)%10; - proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); - proc->timestamp_tx = timestamp+ - (4*UE->frame_parms.samples_per_tti)- - UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; - - proc->instance_cnt_rxtx++; - LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx); - if (proc->instance_cnt_rxtx != 0) { - LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx); - if (proc->instance_cnt_rxtx > 2) - exit_fun("instance_cnt_rxtx > 2"); - } - - AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,""); - AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); - initRefTimes(t1); - initStaticTime(lastTime); - updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)"); - pickStaticTime(lastTime); + LOG_E(PHY,"System error\n"); + abort(); + } + } - } else { - printf("Processing subframe %d",proc->subframe_rx); - getchar(); - } - } // start_rx_stream==1 - } // UE->is_synchronized==1 + //usleep(3000); + if(sub_frame == 0) { + //UE->proc.proc_rxtx[0].frame_rx++; + //UE->proc.proc_rxtx[1].frame_rx++; + for (th_id=0; th_id < RX_NB_TH; th_id++) { + UE->proc.proc_rxtx[th_id].frame_rx++; + } + } + + //UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs); + //UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs); + for (th_id=0; th_id < RX_NB_TH; th_id++) { + UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs); + } - } // while !oai_exit - return NULL; + proc->subframe_rx=sub_frame; + proc->subframe_tx=(sub_frame+4)%10; + proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); + proc->timestamp_tx = timestamp+ + (4*UE->frame_parms.samples_per_tti)- + UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0; + proc->instance_cnt_rxtx++; + LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx); + T(T_UE_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx)); + AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0,""); + AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,""); + initRefTimes(t1); + initStaticTime(lastTime); + updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)"); + pickStaticTime(lastTime); + } else { + printf("Processing subframe %d",proc->subframe_rx); + getchar(); + } + } // start_rx_stream==1 + } // UE->is_synchronized==1 + } // while !oai_exit + + return NULL; } @@ -1810,28 +1798,26 @@ void *UE_thread(void *arg) { void init_UE_threads(int inst) { struct rx_tx_thread_data *rtd; PHY_VARS_UE *UE; - AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); AssertFatal(PHY_vars_UE_g[inst]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); AssertFatal(PHY_vars_UE_g[inst][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); UE = PHY_vars_UE_g[inst][0]; - pthread_attr_init (&UE->proc.attr_ue); pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); - pthread_mutex_init(&UE->proc.mutex_synch,NULL); pthread_cond_init(&UE->proc.cond_synch,NULL); UE->proc.instance_cnt_synch = -1; UE->is_synchronized = 0; - // the threads are not yet active, therefore access is allowed without locking int nb_threads=RX_NB_TH; + for (int i=0; i<nb_threads; i++) { rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = UE; rtd->proc = &UE->proc.proc_rxtx[i]; - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); UE->proc.proc_rxtx[i].instance_cnt_rxtx = -1; @@ -1839,19 +1825,17 @@ void init_UE_threads(int inst) { UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd); - #ifdef UE_SLOT_PARALLELISATION //pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot0_dl_processing,NULL); //pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot0_dl_processing,NULL); //pthread_create(&UE->proc.proc_rxtx[i].pthread_slot0_dl_processing,NULL,UE_thread_slot0_dl_processing, rtd); - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot1_dl_processing,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot1_dl_processing,NULL); pthread_create(&UE->proc.proc_rxtx[i].pthread_slot1_dl_processing,NULL,UE_thread_slot1_dl_processing, rtd); #endif - } - pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); + + pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void *)UE); } @@ -1871,40 +1855,42 @@ void init_UE_single_thread_stub(int nb_inst) { struct rx_tx_thread_data *rtd; PHY_VARS_UE *UE; - for (int i=0; i<nb_inst; i++){ - AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); - AssertFatal(PHY_vars_UE_g[i]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); - AssertFatal(PHY_vars_UE_g[i][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); - if(nfapi_mode == 3){ + for (int i=0; i<nb_inst; i++) { + AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); + AssertFatal(PHY_vars_UE_g[i]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); + AssertFatal(PHY_vars_UE_g[i][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); + + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { #ifdef NAS_UE - MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); - itti_send_msg_to_task (TASK_NAS_UE, i + NB_eNB_INST, message_p); + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); + itti_send_msg_to_task (TASK_NAS_UE, i + NB_eNB_INST, message_p); #endif - } + } } - UE = PHY_vars_UE_g[0][0]; + UE = PHY_vars_UE_g[0][0]; pthread_attr_init (&UE->proc.attr_ue); pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); - // Don't need synch for phy_stub mode //pthread_mutex_init(&UE->proc.mutex_synch,NULL); //pthread_cond_init(&UE->proc.cond_synch,NULL); - // the threads are not yet active, therefore access is allowed without locking // In phy_stub_UE mode due to less heavy processing operations we don't need two threads //int nb_threads=RX_NB_TH; int nb_threads=1; - for(uint16_t ue_thread_id = 0;ue_thread_id < NB_THREAD_INST;ue_thread_id++){ + + for(uint16_t ue_thread_id = 0; ue_thread_id < NB_THREAD_INST; ue_thread_id++) { UE = PHY_vars_UE_g[ue_thread_id][0]; + for (int i=0; i<nb_threads; i++) { rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = UE; rtd->proc = &UE->proc.proc_rxtx[i]; rtd->ue_thread_id = ue_thread_id; - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); UE->proc.proc_rxtx[i].sub_frame_start=i; @@ -1913,6 +1899,7 @@ void init_UE_single_thread_stub(int nb_inst) { pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_single_thread_rxn_txnp4, rtd); } } + // Remove thread for UE_sync in phy_stub_UE mode. //pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); } @@ -1934,38 +1921,35 @@ void init_UE_single_thread_stub(int nb_inst) { void init_UE_threads_stub(int inst) { struct rx_tx_thread_data *rtd; PHY_VARS_UE *UE; - AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); AssertFatal(PHY_vars_UE_g[inst]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); AssertFatal(PHY_vars_UE_g[inst][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); UE = PHY_vars_UE_g[inst][0]; - pthread_attr_init (&UE->proc.attr_ue); pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN); - // Don't need synch for phy_stub mode //pthread_mutex_init(&UE->proc.mutex_synch,NULL); //pthread_cond_init(&UE->proc.cond_synch,NULL); - // the threads are not yet active, therefore access is allowed without locking // In phy_stub_UE mode due to less heavy processing operations we don't need two threads //int nb_threads=RX_NB_TH; int nb_threads=1; + for (int i=0; i<nb_threads; i++) { rtd = calloc(1, sizeof(struct rx_tx_thread_data)); + if (rtd == NULL) abort(); + rtd->UE = UE; rtd->proc = &UE->proc.proc_rxtx[i]; - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); UE->proc.proc_rxtx[i].sub_frame_start=i; UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_thread_rxn_txnp4, rtd); - - } + // Remove thread for UE_sync in phy_stub_UE mode. //pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); } @@ -1975,61 +1959,54 @@ void init_UE_threads_stub(int inst) { #ifdef OPENAIR2 void fill_ue_band_info(void) { - LTE_UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; int i,j; - bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; for (i=0; i<bands_to_scan.nbands; i++) { - for (j=0; j<sizeof (eutra_bands) / sizeof (eutra_bands[0]); j++) if (eutra_bands[j].band == UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) { - memcpy(&bands_to_scan.band_info[i], - &eutra_bands[j], - sizeof(eutra_band_t)); - - printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", - bands_to_scan.band_info[i].band, - UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, - bands_to_scan.band_info[i].dl_min, - bands_to_scan.band_info[i].dl_max, - bands_to_scan.band_info[i].ul_min, - bands_to_scan.band_info[i].ul_max, - (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); - break; + memcpy(&bands_to_scan.band_info[i], + &eutra_bands[j], + sizeof(eutra_band_t)); + printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n", + bands_to_scan.band_info[i].band, + UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA, + bands_to_scan.band_info[i].dl_min, + bands_to_scan.band_info[i].dl_max, + bands_to_scan.band_info[i].ul_min, + bands_to_scan.band_info[i].ul_max, + (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD"); + break; } } } #endif int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) { - int i, CC_id; LTE_DL_FRAME_PARMS *frame_parms; for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - AssertFatal( phy_vars_ue[CC_id] !=0, ""); frame_parms = &(phy_vars_ue[CC_id]->frame_parms); - // replace RX signal buffers with mmaped HW versions - rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) ); - txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) ); + rxdata = (int32_t **)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t *) ); + txdata = (int32_t **)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t *) ); for (i=0; i<frame_parms->nb_antennas_rx; i++) { LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n", - CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i ); + CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i ); free( phy_vars_ue[CC_id]->common_vars.rxdata[i] ); - rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + rxdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) ); phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD } for (i=0; i<frame_parms->nb_antennas_tx; i++) { LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n", - CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i ); + CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i ); free( phy_vars_ue[CC_id]->common_vars.txdata[i] ); - txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) ); + txdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) ); phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i]; } @@ -2038,6 +2015,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) // be careful when releasing memory! // because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes) } + return 0; } @@ -2050,7 +2028,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) // playing the role of nfapi-pnf. //02/02/2018 -static void* timer_thread( void* param ) { +static void *timer_thread( void *param ) { thread_top_init("timer_thread",1,870000L,1000000L,1000000L); timer_subframe =9; timer_frame =1023; @@ -2060,43 +2038,48 @@ static void* timer_thread( void* param ) { UE = PHY_vars_UE_g[0][0]; //double t_diff; int external_timer = 0; - - wait_sync("timer_thread"); - opp_enabled = 1; // first check if we are receiving timing indications - if(nfapi_mode==4) { - usleep(10000); - if (UE->instance_cnt_timer > 0) { - external_timer = 1; - int absSFm1 = ((emulator_absSF+10239)%10240); - timer_frame = absSFm1/10; - timer_subframe = absSFm1%10; - pthread_mutex_lock(&UE->timer_mutex); - UE->instance_cnt_timer = -1; - pthread_mutex_unlock(&UE->timer_mutex); - LOG_I(PHY,"Running with external timer\n"); - } - else LOG_I(PHY,"Running with internal timer\n"); + if(NFAPI_MODE==NFAPI_UE_STUB_OFFNET) { + usleep(10000); + + if (UE->instance_cnt_timer > 0) { + external_timer = 1; + int absSFm1 = ((emulator_absSF+10239)%10240); + timer_frame = absSFm1/10; + timer_subframe = absSFm1%10; + pthread_mutex_lock(&UE->timer_mutex); + UE->instance_cnt_timer = -1; + pthread_mutex_unlock(&UE->timer_mutex); + LOG_I(PHY,"Running with external timer\n"); + } else LOG_I(PHY,"Running with internal timer\n"); } struct timespec t_start; + struct timespec t_now; + struct timespec t_sleep; + uint64_t T_0; + uint64_t T_now; + uint64_t T_next_SF; + uint64_t T_sleep; + uint64_t sf_cnt = 0; //Total Subframe counter clock_gettime(CLOCK_MONOTONIC, &t_start); + T_0 = (uint64_t) t_start.tv_sec*1000000000 + t_start.tv_nsec; + LOG_D(MAC, "timer_thread(), T_0 value: %" PRId64 "\n", T_0); while (!oai_exit) { - // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // They are set on the first rx/tx in the underly FH routines. if (timer_subframe==9) { @@ -2110,74 +2093,72 @@ static void* timer_thread( void* param ) { //AssertFatal( 0 == pthread_cond_signal(&phy_stub_ticking->cond_ticking), ""); AssertFatal(pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) ==0,""); phy_stub_ticking->ticking_var++; + // This should probably be a call to pthread_cond_broadcast when we introduce support for multiple UEs (threads) - if(phy_stub_ticking->ticking_var == 0){ + if(phy_stub_ticking->ticking_var == 0) { //AssertFatal(phy_stub_ticking->ticking_var == 0,"phy_stub_ticking->ticking_var = %d", - //phy_stub_ticking->ticking_var); + //phy_stub_ticking->ticking_var); if (pthread_cond_signal(&phy_stub_ticking->cond_ticking) != 0) { - //LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); - LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n"); - exit_fun("nothing to add"); + //LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id); + LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n"); + exit_fun("nothing to add"); } - } - else - LOG_D(MAC, "timer_thread() Timing problem! ticking_var value:%d \n \n \n", phy_stub_ticking->ticking_var); + } else + LOG_D(MAC, "timer_thread() Timing problem! ticking_var value:%d \n \n \n", phy_stub_ticking->ticking_var); AssertFatal(pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) ==0,""); start_meas(&UE->timer_stats); - //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); // get initial time-stamp if (external_timer == 0) { - clock_gettime(CLOCK_MONOTONIC, &t_now); - sf_cnt++; - T_next_SF = T_0 + sf_cnt*1000000; - T_now =(uint64_t) t_now.tv_sec*1000000000 + t_now.tv_nsec; - if(T_now > T_next_SF){ - t_sleep.tv_sec =0; - t_sleep.tv_nsec =0; - } - else{ - T_sleep = T_next_SF - T_now; - t_sleep.tv_sec =0; - t_sleep.tv_nsec = (__syscall_slong_t) T_sleep; - } + clock_gettime(CLOCK_MONOTONIC, &t_now); + sf_cnt++; + T_next_SF = T_0 + sf_cnt*1000000; + T_now =(uint64_t) t_now.tv_sec*1000000000 + t_now.tv_nsec; + + if(T_now > T_next_SF) { + t_sleep.tv_sec =0; + t_sleep.tv_nsec =0; + } else { + T_sleep = T_next_SF - T_now; + t_sleep.tv_sec =0; + t_sleep.tv_nsec = (__syscall_slong_t) T_sleep; + } + nanosleep(&t_sleep, (struct timespec *)NULL); UE_tport_t pdu; pdu.header.packet_type = TTI_SYNC; pdu.header.absSF = (timer_frame*10)+timer_subframe; - if (nfapi_mode!=3){ - multicast_link_write_sock(0, - (char *)&pdu, - sizeof(UE_tport_header_t)); - } - } - else { + if (NFAPI_MODE != NFAPI_UE_STUB_PNF) { + multicast_link_write_sock(0, + (char *)&pdu, + sizeof(UE_tport_header_t)); + } + } else { wait_on_condition(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread"); release_thread(&UE->timer_mutex,&UE->instance_cnt_timer,"timer_thread"); } - /*stop_meas(&UE->timer_stats); t_diff = get_time_meas_us(&UE->timer_stats); stop_meas(&UE->timer_stats); t_diff = get_time_meas_us(&UE->timer_stats);*/ } + free(phy_stub_ticking); pthread_cond_destroy(&phy_stub_ticking->cond_ticking); pthread_mutex_destroy(&phy_stub_ticking->mutex_ticking); return 0; - } int init_timer_thread(void) { //PHY_VARS_UE *UE=PHY_vars_UE_g[0]; - PHY_VARS_UE *UE=PHY_vars_UE_g[0][0]; - phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking)); + PHY_VARS_UE *UE=PHY_vars_UE_g[0][0]; + phy_stub_ticking = (SF_ticking *)malloc(sizeof(SF_ticking)); pthread_mutex_init(&UE->timer_mutex,NULL); pthread_cond_init(&UE->timer_cond,NULL); UE->instance_cnt_timer = -1; @@ -2194,8 +2175,7 @@ int init_timer_thread(void) { /* HACK: this function is needed to compile the UE * fix it somehow */ -int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) -{ +int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) { printf("you cannot read this\n"); abort(); } diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 4910b09557acaa53d870d6269081eafab52919b1..19d51bb9d563968f905f53fd66d244c6283f73e5 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -68,6 +68,7 @@ #include "PHY_INTERFACE/phy_interface_vars.h" #include "common/utils/LOG/log.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "UTIL/OTG/otg_tx.h" #include "UTIL/OTG/otg_externs.h" #include "UTIL/MATH/oml.h" @@ -109,11 +110,9 @@ pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex -uint8_t nfapi_mode = 0; -#ifdef PDCP_USE_NETLINK + #ifdef UESIM_EXPANSION -uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; -#endif + uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; #endif uint16_t sf_ahead=2; int tddflag; @@ -143,7 +142,7 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int UE_scan = 1; int UE_scan_carrier = 0; -int simL1flag = 0; + int snr_dB=25; runmode_t mode = normal_txrx; @@ -204,7 +203,6 @@ extern void get_uethreads_params(void); int transmission_mode=1; - char *usrp_args=NULL; char *usrp_clksrc=NULL; @@ -324,12 +322,10 @@ void exit_function(const char *file, const char *function, const int line, const } sleep(1); //allow lte-softmodem threads to exit first -#if defined(ENABLE_ITTI) if(PHY_vars_UE_g != NULL ) itti_terminate_tasks (TASK_UNKNOWN); -#endif exit(1); } @@ -406,6 +402,8 @@ static void get_options(void) { char *loopfile=NULL; int dumpframe; int timingadv; + uint8_t nfapi_mode; + int simL1flag ; set_default_frame_parms(frame_parms); CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); /* unknown parameters on command line will be checked in main @@ -416,6 +414,10 @@ static void get_options(void) { paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC; config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL); config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL); + nfapi_setmode(nfapi_mode); + + if (simL1flag) + set_softmodem_optmask(SOFTMODEM_SIML1_BIT); if (loopfile != NULL) { printf("Input file for hardware emulation: %s",loopfile); @@ -448,7 +450,7 @@ static void get_options(void) { } UE_scan=0; - + if (tddflag > 0) { for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { frame_parms[CC_id]->frame_type = TDD; @@ -490,16 +492,6 @@ static void get_options(void) { rx_gain[0][CC_id] = rx_gain[0][0]; tx_gain[0][CC_id] = tx_gain[0][0]; } - - /* - if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) { - // Here the configuration file is the XER encoded UE capabilities - // Read it in and store in asn1c data structures - sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME")); - printf("%s\n",uecap_xer); - if(nfapi_mode!=3) - uecap_xer_in=1; - } *//* UE with config file */ } @@ -637,10 +629,7 @@ void init_openair0(LTE_DL_FRAME_PARMS *frame_parms,int rxgain) { - -#if defined(ENABLE_ITTI) -/* - * helper function to terminate a certain ITTI task +/* helper function to terminate a certain ITTI task */ void terminate_task(task_id_t task_id, module_id_t mod_id) { LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); @@ -650,11 +639,6 @@ void terminate_task(task_id_t task_id, module_id_t mod_id) { } - -#endif - - - static inline void wait_nfapi_init(char *thread_name) { printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); pthread_mutex_lock( &nfapi_sync_mutex ); @@ -675,16 +659,29 @@ int restart_L1L2(module_id_t enb_id) { return 0; } +void init_pdcp(void) { + uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT); + + if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) { + pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; + } + + if (IS_SOFTMODEM_NOKRNMOD) + pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; + + pdcp_module_init(pdcp_initmask); + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); +} + int main( int argc, char **argv ) { #if defined (XFORMS) void *status; #endif int CC_id; uint8_t abstraction_flag=0; -#ifdef PDCP_USE_NETLINK #ifdef UESIM_EXPANSION memset(inst_pdcp_list, 0, sizeof(inst_pdcp_list)); -#endif #endif // Default value for the number of UEs. It will hold, // if not changed from the command line option --num-ues @@ -693,11 +690,11 @@ int main( int argc, char **argv ) { #if defined (XFORMS) int ret; #endif + configmodule_interface_t *config_mod; + start_background_system(); + config_mod = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY); - start_background_system(); - - - if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { + if (config_mod == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } @@ -710,38 +707,29 @@ int main( int argc, char **argv ) { for (int i=0; i<MAX_NUM_CCs; i++) tx_max_power[i]=23; get_options (); + + if (is_nos1exec(argv[0]) ) + set_softmodem_optmask(SOFTMODEM_NOS1_BIT); + + EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; printf("Running with %d UE instances\n",NB_UE_INST); - if (NB_UE_INST > 1 && simL1flag != 1 && nfapi_mode != 3) { + if (NB_UE_INST > 1 && (!IS_SOFTMODEM_SIML1) && NFAPI_MODE!=NFAPI_UE_STUB_PNF) { printf("Running with more than 1 UE instance and simL1 is not active, this will result in undefined behaviour for now, exiting.\n"); abort(); } - - printf("NFAPI_MODE value: %d \n", nfapi_mode); - // Checking option of nums_ue_thread. - if(NB_THREAD_INST < 1){ + if(NB_THREAD_INST < 1) { printf("Running with 0 UE rxtx thread, exiting.\n"); abort(); } + // Checking option's relation between nums_ue_thread and num-ues - if(NB_UE_INST <NB_THREAD_INST ){ + if(NB_UE_INST <NB_THREAD_INST ) { printf("Number of UEs < number of UE rxtx threads, exiting.\n"); abort(); } - // Not sure if the following is needed here - /*if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { - if (UE_flag == 0) { - fprintf(stderr,"Getting configuration failed\n"); - exit(-1); - } - else { - printf("Setting nfapi mode to UE_STUB_OFFNET\n"); - nfapi_mode = 4; - } - }*/ - #if T_TRACER T_Config_Init(); @@ -751,7 +739,6 @@ int main( int argc, char **argv ) { cpuf=get_cpu_freq_GHz(); pthread_cond_init(&sync_cond,NULL); pthread_mutex_init(&sync_mutex, NULL); -#if defined(ENABLE_ITTI) printf("ITTI init\n"); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); @@ -761,22 +748,15 @@ int main( int argc, char **argv ) { } MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); -#endif init_opt(); -#ifdef PDCP_USE_NETLINK - printf("PDCP netlink\n"); - netlink_init(); -#if defined(PDCP_USE_NETLINK_QUEUES) - pdcp_netlink_init(); -#endif -#endif + + init_pdcp(); + //TTN for D2D -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) printf ("RRC control socket\n"); rrc_control_socket_init(); printf ("PDCP PC5S socket\n"); pdcp_pc5_socket_init(); -#endif // to make a graceful exit when ctrl-c is pressed signal(SIGSEGV, signal_handler); signal(SIGINT, signal_handler); @@ -797,7 +777,7 @@ int main( int argc, char **argv ) { NB_INST=1; - if(nfapi_mode == 3) { + if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE **)*NB_UE_INST); for (int i=0; i<NB_UE_INST; i++) { @@ -813,44 +793,10 @@ int main( int argc, char **argv ) { } } else init_openair0(frame_parms[0],(int)rx_gain[0][0]); - if (simL1flag==1) { - AssertFatal(NULL!=load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY), - "[SOFTMODEM] Error, configuration module init failed\n"); + if (IS_SOFTMODEM_SIML1 ) { RCConfig_sim(); } -// source code written in below moved to later to avoid keeping waiting for nfapi_sync_cond in wait_nfapi_init. -/* - // start the main UE threads - int eMBMS_active = 0; - - if (nfapi_mode==3) { // UE-STUB-PNF - config_sync_var=0; - wait_nfapi_init("main?"); - //Panos: Temporarily we will be using single set of threads for multiple UEs. - //init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface); - init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface); - } else { - init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,get_softmodem_params()->phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0], - frame_parms[0]); - } - - if (get_softmodem_params()->phy_test==0) { - printf("Filling UE band info\n"); - fill_ue_band_info(); - dl_phy_sync_success (0, 0, 0, 1); - } - - if (nfapi_mode!=3) { - number_of_cards = 1; - - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_vars_UE_g[0][CC_id]->rf_map.card=0; - PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); - } - } -*/ - cpuf=get_cpu_freq_GHz(); #ifndef DEADLINE_SCHEDULER printf("NO deadline scheduler\n"); @@ -882,7 +828,7 @@ int main( int argc, char **argv ) { exit_fun("Error getting processor affinity "); } - memset(cpu_affinity, 0 , sizeof(cpu_affinity)); + memset(cpu_affinity, 0, sizeof(cpu_affinity)); for (int j = 0; j < CPU_SETSIZE; j++) { if (CPU_ISSET(j, &cpuset)) { @@ -894,89 +840,46 @@ int main( int argc, char **argv ) { LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); #endif -#if defined(ENABLE_ITTI) + if (create_tasks_ue(NB_UE_INST) < 0) { printf("cannot create ITTI tasks\n"); exit(-1); // need a softer mode } - if(nfapi_mode==3) { // Here we should add another nfapi_mode for the case of Supervised LTE-D2D + if (NFAPI_MODE==NFAPI_UE_STUB_PNF) { // UE-STUB-PNF UE_config_stub_pnf(); } printf("ITTI tasks created\n"); -#endif mlockall(MCL_CURRENT | MCL_FUTURE); rt_sleep_ns(10*100000000ULL); - const char *nfapi_mode_str = "<UNKNOWN>"; - // start the main UE threads int eMBMS_active = 0; - switch(nfapi_mode) { - case 0: - nfapi_mode_str = "MONOLITHIC"; - break; - - case 1: - nfapi_mode_str = "PNF"; - break; - - case 2: - nfapi_mode_str = "VNF"; - break; - - case 3: - nfapi_mode_str = "UE_STUB_PNF"; - break; - - case 4: - nfapi_mode_str = "UE_STUB_OFFNET"; - break; - - default: - nfapi_mode_str = "<UNKNOWN NFAPI MODE>"; - break; - } - - printf("NFAPI MODE:%s\n", nfapi_mode_str); - - if (nfapi_mode==3) // UE-STUB-PNF - { - config_sync_var=0; - wait_nfapi_init("main?"); - //Panos: Temporarily we will be using single set of threads for multiple UEs. - //init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface); - init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface); - } - else { - init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,get_softmodem_params()->phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0], - frame_parms[0]); + if (NFAPI_MODE==NFAPI_UE_STUB_PNF) { // UE-STUB-PNF + config_sync_var=0; + wait_nfapi_init("main?"); + //Panos: Temporarily we will be using single set of threads for multiple UEs. + //init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface); + init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface); + } else { + init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,get_softmodem_params()->phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0], + frame_parms[0]); } - if (get_softmodem_params()->phy_test==0) { printf("Filling UE band info\n"); fill_ue_band_info(); dl_phy_sync_success (0, 0, 0, 1); } - if (nfapi_mode!=3){ - number_of_cards = 1; - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_vars_UE_g[0][CC_id]->rf_map.card=0; - PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); - } - } - // connect the TX/RX buffers + if (NFAPI_MODE != NFAPI_UE_STUB_PNF) { + number_of_cards = 1; - /* - if(nfapi_mode!=3) { - if (setup_ue_buffers(PHY_vars_UE_g[0],&openair0_cfg[0])!=0) { - printf("Error setting up eNB buffer\n"); - exit(-1); + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + PHY_vars_UE_g[0][CC_id]->rf_map.card=0; + PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); } } - */ if (input_fd) { printf("Reading in from file to antenna buffer %d\n",0); @@ -990,7 +893,7 @@ int main( int argc, char **argv ) { //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; - if (simL1flag==1) { + if (IS_SOFTMODEM_SIML1 ) { init_ocm((double)snr_dB,0); PHY_vars_UE_g[0][0]->no_timing_correction = 1; } diff --git a/targets/RT/USER/rfsim.h b/targets/RT/USER/rfsim.h index c5361724c92b77d37f866973c6d0c7feeeb7ea60..f263b1067c82014b70585843324f8bea1c8a56a7 100644 --- a/targets/RT/USER/rfsim.h +++ b/targets/RT/USER/rfsim.h @@ -31,6 +31,10 @@ void init_ocm(double snr_dB,double sinr_dB); void update_ocm(double snr_dB,double sinr_dB); +//extern pthread_mutex_t async_server_lock; +//extern pthread_cond_t async_server_notify; +//extern int async_server_shutdown; + void init_channel_vars(void); #endif diff --git a/targets/RT/USER/rt_wrapper.c b/targets/RT/USER/rt_wrapper.c index 443d183068e634ab97e751d7ed5f448edd820732..b55bafed1b00727416d7b94a30cbebd91ef084ef 100644 --- a/targets/RT/USER/rt_wrapper.c +++ b/targets/RT/USER/rt_wrapper.c @@ -125,7 +125,7 @@ void check_clock(void) if (clock_getres(clock_id, &res)) { printf("clock_getres failed"); } else { - printf("reported resolution = %llu ns\n", (long long int) ((int) 1e9 * res.tv_sec) + (long long int) res.tv_nsec); + printf("reported resolution = %lld ns\n", (long long int) ((int) 1e9 * res.tv_sec) + (long long int) res.tv_nsec); } } diff --git a/targets/TEST/PACKET_TRACER/pt.c b/targets/TEST/PACKET_TRACER/pt.c index 030b63ab907319283059e4b8bdd74a2ceb4814cc..510865d33e5ab3a802544522ecdd36fbe444e564 100644 --- a/targets/TEST/PACKET_TRACER/pt.c +++ b/targets/TEST/PACKET_TRACER/pt.c @@ -166,7 +166,8 @@ int input_text(char *file,char *sdu) printf("byte %d: %x (%s%s)\n",b_ind,byte,binary_table[byte>>4],binary_table[byte&0xf]); b_ind++; } - + if (fd) + fclose(fd); return(b_ind); } @@ -220,14 +221,14 @@ int parse_args(int argc, char** argv, args_t* args) case 'I': strcpy(args->input1_file,optarg); args->input1_sdu_len = input_text(args->input1_file,args->input1_sdu); - printf("Got sdu1 of length %d bytes\n",args->input1_sdu_len); + printf("Got sdu1 of length %u bytes\n",args->input1_sdu_len); args->input1_sdu_flag=1; break; case 'J': strcpy(args->input2_file,optarg); args->input2_sdu_len = input_text(args->input2_file,args->input2_sdu); - printf("Got sdu2 of length %d bytes\n",args->input2_sdu_len); + printf("Got sdu2 of length %u bytes\n",args->input2_sdu_len); args->input2_sdu_flag=1; break; @@ -530,7 +531,8 @@ int main (int argc, char **argv) if (args.input_sib == 0) { openair_rrc_lite_eNB_init(0); } else { - printf("Got SI from files (%d,%d,%d,%d,%d)\n",args.input_sib,args.input1_sdu_flag,args.input2_sdu_flag); + printf("Got SI from files (%d,%d,%d)\n", + args.input_sib,args.input1_sdu_flag,args.input2_sdu_flag); } openair_rrc_on(0,0); diff --git a/targets/TEST/PDCP/test_pdcp.c b/targets/TEST/PDCP/test_pdcp.c index a999bb254dfcbd80184740ebb694ad907b0fcd85..b62edf1215410921f3c9e27fbe7d4c55b9400fd3 100644 --- a/targets/TEST/PDCP/test_pdcp.c +++ b/targets/TEST/PDCP/test_pdcp.c @@ -249,7 +249,7 @@ BOOL test_pdcp_data_req(void) * information if we pass mem_block_ts via a linked list? */ - if (pdcp_test_pdu_buffer_size == 0 || pdcp_test_pdu_buffer == NULL) { + if (pdcp_test_pdu_buffer_size == 0 ) { msg("[TEST] PDU created by pdcp_data_req() is invalid!\n"); return FALSE; } diff --git a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c index d3efbe139f1293b330383249a81c8890fcecdd86..9f28fd7c78a6c3182fec9f763676e2e68ecd6dac 100644 --- a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c +++ b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c @@ -125,7 +125,7 @@ void pdcp_rlc_test_mac_rlc_loop (struct mac_data_ind *data_indP, struct mac_dat if (tb_src != NULL) { tb_size = ((struct mac_tb_req *) (tb_src->data))->tb_size_in_bits >> 3; - printf("[RLC-LOOP] FOUND TB SIZE IN BITS %d IN BYTES %d sizeof (mac_rlc_max_rx_header_size_t) %d\n", + printf("[RLC-LOOP] FOUND TB SIZE IN BITS %d IN BYTES %u sizeof (mac_rlc_max_rx_header_size_t) %d\n", ((struct mac_tb_req *) (tb_src->data))->tb_size_in_bits, tb_size, sizeof (mac_rlc_max_rx_header_size_t));