diff --git a/README.txt b/README.txt
index 8204bb0cb5..c65502325f 100644
--- a/README.txt
+++ b/README.txt
@@ -43,17 +43,36 @@ openairinterface5g
RELEASE NOTES:
-v0.1 -> Last stable commit on develop branch before enhancement-10-harmony
-v0.2 -> Merge of enhancement-10-harmony to include NGFI RRH + New Interface for RF/BBU
-v0.3 -> Last stable commit on develop branch before the merge of feature-131-new-license. This is the last commit with GPL License
-v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the license to OAI Public License V1.0
-v0.5 -> Merge of enhancement-10-harmony-lts. It includes fixes for Ubuntu 16.04 support
-v0.5.1 -> Merge of bugfix-137-uplink-fixes. It includes stablity fixes for eNB
-v0.5.2 -> Last version with old code for oaisim (abstraction mode works)
-v0.6 -> RRH functionality, UE greatly improved, better TDD support,
- a lot of bugs fixed. WARNING: oaisim in PHY abstraction mode does not
- work, you need to use v0.5.2 for that.
-v0.6.1 -> Mostly bugfixes. This is the last version without NFAPI.
+v1.1.0 -> July 2019. This version adds the following implemented features:
+ * Experimental support of LTE-M
+ - Single LTE-M UE attachment, legacy-LTE UE attachment is disabled
+ * X2 interface and handover (also X2-U interface)
+ - In FDD and TDD
+ * CU/DU split (F1 interface)
+ - Tested only in FDD
+ * CDRX
+ - Tested only in FDD
+ * Experimental eMBMS support (only on UE side)
+ * Experimental multi-RRU support
+ - Tested only in TDD
+ This version has an improved code quality:
+ * Simplification of the Build System
+ - A single build includes all full-stack simulators, S1/noS1 modes and one HW platform (such as USRP, BladeRF, ...)
+ * TUN interface is now used as default for the data plane
+ - for UE, eNB-noS1 and UE-noS1
+ * Code Cleanup
+ * Better Static Code Analysis:
+ - Limited number of errors in cppcheck
+ - Important Decrease on high Impact errors in CoverityScan
+ * Better Test Coverage in Continuous Integration:
+ - TM2, CDRX, IF4.5, F1
+ - OAI UE is tested in S1 and noS1 modes with USRP board
+ - Multi-RRU TDD mode
+ - X2 Handover in FDD mode
+
+v1.0.3 -> June 2019: Bug fix for LimeSuite v19.04.0 API
+v1.0.2 -> February 2019: Full OAI support for 3.13.1 UHD
+v1.0.1 -> February 2019: Bug fix for the UE L1 simulator.
v1.0.0 -> January 2019. This version first implements the architectural split described in doc/oai_lte_enb_func_split_arch.png picture.
Only FAPI, nFAPI and IF4.5 interfaces are implemented.
Repository tree structure prepares future integrations of features such as LTE-M, nbIOT or 5G-NR.
@@ -61,6 +80,15 @@ 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
-v1.0.3 -> June 2019: Bug fix for LimeSuite v19.04.0 API
+
+v0.6.1 -> Mostly bugfixes. This is the last version without NFAPI.
+v0.6 -> RRH functionality, UE greatly improved, better TDD support,
+ a lot of bugs fixed. WARNING: oaisim in PHY abstraction mode does not
+ work, you need to use v0.5.2 for that.
+v0.5.2 -> Last version with old code for oaisim (abstraction mode works)
+v0.5.1 -> Merge of bugfix-137-uplink-fixes. It includes stablity fixes for eNB
+v0.5 -> Merge of enhancement-10-harmony-lts. It includes fixes for Ubuntu 16.04 support
+v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the license to OAI Public License V1.0
+v0.3 -> Last stable commit on develop branch before the merge of feature-131-new-license. This is the last commit with GPL License
+v0.2 -> Merge of enhancement-10-harmony to include NGFI RRH + New Interface for RF/BBU
+v0.1 -> Last stable commit on develop branch before enhancement-10-harmony
diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab
index 56624d3230..ed7489aa93 100644
--- a/ci-scripts/Jenkinsfile-gitlab
+++ b/ci-scripts/Jenkinsfile-gitlab
@@ -44,7 +44,7 @@ pipeline {
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-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13"])
+ 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", "Test-IF4p5-TDD-Band38-Multi-RRU" , "Test-Mono-FDD-Band13-X2-HO"])
ansiColor('xterm')
}
@@ -481,6 +481,45 @@ pipeline {
}
}
}
+ stage ("Test X2 Handover - FDD - Band 13 - B210") {
+ steps {
+ script {
+ sh "sleep 60"
+ triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-X2HO-B210', 'Test-Mono-FDD-Band13-X2-HO')
+ }
+ }
+ post {
+ always {
+ script {
+ finalizeSlaveJob('eNB-CI-MONO-FDD-Band13-X2HO-B210')
+ }
+ }
+ failure {
+ script {
+ currentBuild.result = 'FAILURE'
+ }
+ }
+ }
+ }
+ stage ("Test IF4p5 - TDD - Band 38 - B210 - MultiRRU") {
+ steps {
+ script {
+ triggerSlaveJob ('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210', 'Test-IF4p5-TDD-Band38-Multi-RRU')
+ }
+ }
+ post {
+ always {
+ script {
+ finalizeSlaveJob('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210')
+ }
+ }
+ failure {
+ script {
+ currentBuild.result = 'FAILURE'
+ }
+ }
+ }
+ }
stage ("Test IF4p5 - TDD - Band 40 - B210") {
steps {
script {
@@ -504,6 +543,7 @@ pipeline {
stage ("Test MONOLITHIC - FDD - Band 13 - B210") {
steps {
script {
+ sh "sleep 60"
triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-B210', 'Test-Mono-FDD-Band13')
}
}
diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb b/ci-scripts/Jenkinsfile-tmp-multi-enb
new file mode 100644
index 0000000000..c3b825ec06
--- /dev/null
+++ b/ci-scripts/Jenkinsfile-tmp-multi-enb
@@ -0,0 +1,282 @@
+#!/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
+
+// 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
+ }
+ // 1st eNB parameters
+ if (params.eNB_IPAddress == null) {
+ allParametersPresent = false
+ }
+ if (params.eNB_SourceCodePath == null) {
+ allParametersPresent = false
+ }
+ if (params.eNB_Credentials == null) {
+ allParametersPresent = false
+ }
+ // 2nd eNB parameters
+ if (params.eNB1_IPAddress == null) {
+ allParametersPresent = false
+ }
+ if (params.eNB1_SourceCodePath == null) {
+ allParametersPresent = false
+ }
+ if (params.eNB1_Credentials == null) {
+ allParametersPresent = false
+ }
+ // 3rd eNB parameters
+ if (params.eNB2_IPAddress == null) {
+ allParametersPresent = false
+ }
+ if (params.eNB2_SourceCodePath == null) {
+ allParametersPresent = false
+ }
+ if (params.eNB2_Credentials == null) {
+ allParametersPresent = false
+ }
+ // the following 4 parameters should be pushed by the master trigger
+ // if not present, take the job GIT variables (used for developing)
+ if (params.eNB_Repository == null) {
+ eNB_Repository = env.GIT_URL
+ } else {
+ eNB_Repository = params.eNB_Repository
+ }
+ echo "eNB_Repository : ${eNB_Repository}"
+ if (params.eNB_Branch == null) {
+ eNB_Branch = env.GIT_BRANCH
+ } else {
+ eNB_Branch = params.eNB_Branch
+ }
+ echo "eNB_Branch : ${eNB_Branch}"
+ if (params.eNB_CommitID == null) {
+ eNB_CommitID = env.GIT_COMMIT
+ } else {
+ eNB_CommitID = params.eNB_CommitID
+ }
+ echo "eNB_CommitID : ${eNB_CommitID}"
+ if (params.eNB_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.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
+ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'],
+ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
+ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password']
+ ]) {
+ sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}"
+ String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
+ for (xmlFile in myXmlTestSuite) {
+ if (fileExists(xmlFile)) {
+ try {
+ sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}"
+ } catch (Exception e) {
+ currentBuild.result = 'FAILURE'
+ buildStageStatus = false
+ }
+ }
+ }
+ sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
+ }
+ }
+ }
+ }
+ }
+ stage('Log Collection') {
+ parallel {
+ stage('Log Collection (eNB - Build)') {
+ steps {
+ withCredentials([
+ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
+ ]) {
+ echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m'
+ sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
+
+ echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m'
+ sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
+ }
+ script {
+ if(fileExists("build.log.${env.BUILD_ID}.zip")) {
+ archiveArtifacts "build.log.${env.BUILD_ID}.zip"
+ }
+ }
+ }
+ }
+ stage('Log Collection (eNB - Run)') {
+ steps {
+ withCredentials([
+ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
+ ]) {
+ echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
+ sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
+
+ echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m'
+ sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
+ }
+ script {
+ if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
+ archiveArtifacts "enb.log.${env.BUILD_ID}.zip"
+ }
+ if(fileExists("ci-scripts/test_results.html")) {
+ sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html"
+ sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
+ archiveArtifacts "test_results-${JOB_NAME}.html"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ post {
+ always {
+ script {
+ if (params.pipelineZipsConsoleLog != null) {
+ if (params.pipelineZipsConsoleLog) {
+ echo "Archiving Jenkins console log"
+ sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true"
+ sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true"
+ if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) {
+ archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip"
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf
new file mode 100644
index 0000000000..2a7783da08
--- /dev/null
+++ b/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf
@@ -0,0 +1,271 @@
+Active_eNBs = ( "eNB-Eurecom-LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+ ////////// Identification parameters:
+ eNB_ID = 0xe01;
+
+ cell_type = "CELL_MACRO_ENB";
+
+ eNB_name = "eNB-Eurecom-LTEBox";
+
+ // Tracking area code, 0x0000 and 0xfffe are reserved values
+ tracking_area_code = 1;
+
+ plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
+
+ nr_cellid = 98765L;
+ tr_s_preference = "local_mac"
+
+ ////////// 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 = 13;
+ downlink_frequency = 751000000L;
+ uplink_frequency_offset = 31000000;
+ Nid_cell = 1;
+ 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 = 110;
+ 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_groupHoppingEnabled = "ENABLE";
+ pusch_groupAssignment = 0;
+ pusch_sequenceHoppingEnabled = "DISABLE";
+ pusch_nDMRS1 = 1;
+ phich_duration = "NORMAL";
+ phich_resource = "ONESIXTH";
+ srs_enable = "DISABLE";
+ /* srs_BandwidthConfig =;
+ srs_SubframeConfig =;
+ srs_ackNackST =;
+ srs_MaxUpPts =;*/
+
+ pusch_p0_Nominal = -96;
+ pusch_alpha = "AL1";
+ pucch_p0_Nominal = -104;
+ msg3_delta_Preamble = 6;
+ pucch_deltaF_Format1 = "deltaF2";
+ pucch_deltaF_Format1b = "deltaF3";
+ pucch_deltaF_Format2 = "deltaF0";
+ pucch_deltaF_Format2a = "deltaF0";
+ pucch_deltaF_Format2b = "deltaF0";
+
+ rach_numberOfRA_Preambles = 64;
+ rach_preamblesGroupAConfig = "DISABLE";
+ /*
+ rach_sizeOfRA_PreamblesGroupA = ;
+ rach_messageSizeGroupA = ;
+ rach_messagePowerOffsetGroupB = ;
+ */
+ rach_powerRampingStep = 4;
+ rach_preambleInitialReceivedTargetPower = -108;
+ rach_preambleTransMax = 10;
+ rach_raResponseWindowSize = 10;
+ rach_macContentionResolutionTimer = 48;
+ rach_maxHARQ_Msg3Tx = 4;
+
+ pcch_default_PagingCycle = 128;
+ pcch_nB = "oneT";
+ bcch_modificationPeriodCoeff = 2;
+ ue_TimersAndConstants_t300 = 1000;
+ ue_TimersAndConstants_t301 = 1000;
+ ue_TimersAndConstants_t310 = 1000;
+ ue_TimersAndConstants_t311 = 10000;
+ ue_TimersAndConstants_n310 = 20;
+ ue_TimersAndConstants_n311 = 1;
+ ue_TransmissionMode = 1;
+
+ //Parameters for SIB18
+ rxPool_sc_CP_Len = "normal";
+ rxPool_sc_Period = "sf40";
+ rxPool_data_CP_Len = "normal";
+ rxPool_ResourceConfig_prb_Num = 20;
+ rxPool_ResourceConfig_prb_Start = 5;
+ rxPool_ResourceConfig_prb_End = 44;
+ rxPool_ResourceConfig_offsetIndicator_present = "prSmall";
+ rxPool_ResourceConfig_offsetIndicator_choice = 0;
+ rxPool_ResourceConfig_subframeBitmap_present = "prBs40";
+ rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000";
+ rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
+ rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
+/* rxPool_dataHoppingConfig_hoppingParameter = 0;
+ rxPool_dataHoppingConfig_numSubbands = "ns1";
+ rxPool_dataHoppingConfig_rbOffset = 0;
+ rxPool_commTxResourceUC-ReqAllowed = "TRUE";
+*/
+ // Parameters for SIB19
+ discRxPool_cp_Len = "normal"
+ discRxPool_discPeriod = "rf32"
+ discRxPool_numRetx = 1;
+ discRxPool_numRepetition = 2;
+ discRxPool_ResourceConfig_prb_Num = 5;
+ discRxPool_ResourceConfig_prb_Start = 3;
+ discRxPool_ResourceConfig_prb_End = 21;
+ discRxPool_ResourceConfig_offsetIndicator_present = "prSmall";
+ discRxPool_ResourceConfig_offsetIndicator_choice = 0;
+ discRxPool_ResourceConfig_subframeBitmap_present = "prBs40";
+ discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
+ discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
+ discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
+
+ }
+ );
+
+
+ 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";
+ }
+ );
+
+ ///X2
+ enable_x2 = "yes";
+ 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 = "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
+ };
+ }
+);
+
+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
+ att_tx = 0
+ att_rx = 0;
+ bands = [7];
+ max_pdschReferenceSignalPower = -27;
+ max_rxgain = 125;
+ eNB_instances = [0];
+
+ }
+);
+
+NETWORK_CONTROLLER :
+{
+ FLEXRAN_ENABLED = "no";
+ FLEXRAN_INTERFACE_NAME = "eth0";
+ FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR";
+ FLEXRAN_PORT = 2210;
+ FLEXRAN_CACHE = "/mnt/oai_agent_cache";
+ FLEXRAN_AWAIT_RECONF = "no";
+};
+
+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";//PARALLEL_RU_L1_TRX_SPLIT";
+ #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+ worker_config = "WORKER_ENABLE";
+ }
+);
+
+ log_config :
+ {
+ global_log_level ="info";
+ global_log_verbosity ="medium";
+ hw_log_level ="info";
+ hw_log_verbosity ="medium";
+ phy_log_level ="info";
+ phy_log_verbosity ="medium";
+ mac_log_level ="info";
+ mac_log_verbosity ="high";
+ rlc_log_level ="info";
+ rlc_log_verbosity ="medium";
+ pdcp_log_level ="info";
+ pdcp_log_verbosity ="medium";
+ rrc_log_level ="info";
+ rrc_log_verbosity ="medium";
+ };
+
diff --git a/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf
new file mode 100644
index 0000000000..c76a664c15
--- /dev/null
+++ b/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf
@@ -0,0 +1,276 @@
+Active_eNBs = ( "eNB-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-Eurecom-LTEBox";
+
+ // Tracking area code, 0x0000 and 0xfffe are reserved values
+ tracking_area_code = 1;
+
+ plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
+
+ nr_cellid = 123456L;
+ tr_s_preference = "local_mac"
+
+ ////////// 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 = 13;
+ downlink_frequency = 751000000L;
+ uplink_frequency_offset = 31000000;
+ 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 = 110;
+ 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_groupHoppingEnabled = "ENABLE";
+ pusch_groupAssignment = 0;
+ pusch_sequenceHoppingEnabled = "DISABLE";
+ pusch_nDMRS1 = 1;
+ phich_duration = "NORMAL";
+ phich_resource = "ONESIXTH";
+ srs_enable = "DISABLE";
+ /* srs_BandwidthConfig =;
+ srs_SubframeConfig =;
+ srs_ackNackST =;
+ srs_MaxUpPts =;*/
+
+ pusch_p0_Nominal = -96;
+ pusch_alpha = "AL1";
+ pucch_p0_Nominal = -104;
+ msg3_delta_Preamble = 6;
+ pucch_deltaF_Format1 = "deltaF2";
+ pucch_deltaF_Format1b = "deltaF3";
+ pucch_deltaF_Format2 = "deltaF0";
+ pucch_deltaF_Format2a = "deltaF0";
+ pucch_deltaF_Format2b = "deltaF0";
+
+ rach_numberOfRA_Preambles = 64;
+ rach_preamblesGroupAConfig = "DISABLE";
+ /*
+ rach_sizeOfRA_PreamblesGroupA = ;
+ rach_messageSizeGroupA = ;
+ rach_messagePowerOffsetGroupB = ;
+ */
+ rach_powerRampingStep = 4;
+ rach_preambleInitialReceivedTargetPower = -108;
+ rach_preambleTransMax = 10;
+ rach_raResponseWindowSize = 10;
+ rach_macContentionResolutionTimer = 48;
+ rach_maxHARQ_Msg3Tx = 4;
+
+ pcch_default_PagingCycle = 128;
+ pcch_nB = "oneT";
+ bcch_modificationPeriodCoeff = 2;
+ ue_TimersAndConstants_t300 = 1000;
+ ue_TimersAndConstants_t301 = 1000;
+ ue_TimersAndConstants_t310 = 1000;
+ ue_TimersAndConstants_t311 = 10000;
+ ue_TimersAndConstants_n310 = 20;
+ ue_TimersAndConstants_n311 = 1;
+ ue_TransmissionMode = 1;
+
+ //Parameters for SIB18
+ rxPool_sc_CP_Len = "normal";
+ rxPool_sc_Period = "sf40";
+ rxPool_data_CP_Len = "normal";
+ rxPool_ResourceConfig_prb_Num = 20;
+ rxPool_ResourceConfig_prb_Start = 5;
+ rxPool_ResourceConfig_prb_End = 44;
+ rxPool_ResourceConfig_offsetIndicator_present = "prSmall";
+ rxPool_ResourceConfig_offsetIndicator_choice = 0;
+ rxPool_ResourceConfig_subframeBitmap_present = "prBs40";
+ rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000";
+ rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
+ rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
+/* rxPool_dataHoppingConfig_hoppingParameter = 0;
+ rxPool_dataHoppingConfig_numSubbands = "ns1";
+ rxPool_dataHoppingConfig_rbOffset = 0;
+ rxPool_commTxResourceUC-ReqAllowed = "TRUE";
+*/
+ // Parameters for SIB19
+ discRxPool_cp_Len = "normal"
+ discRxPool_discPeriod = "rf32"
+ discRxPool_numRetx = 1;
+ discRxPool_numRepetition = 2;
+ discRxPool_ResourceConfig_prb_Num = 5;
+ discRxPool_ResourceConfig_prb_Start = 3;
+ discRxPool_ResourceConfig_prb_End = 21;
+ discRxPool_ResourceConfig_offsetIndicator_present = "prSmall";
+ discRxPool_ResourceConfig_offsetIndicator_choice = 0;
+ discRxPool_ResourceConfig_subframeBitmap_present = "prBs40";
+ discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff";
+ discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5;
+ discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
+
+ }
+ );
+
+
+ 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";
+ }
+ );
+ ///X2
+ enable_x2 = "yes";
+ t_reloc_prep = 1000; /* unit: millisecond */
+ tx2_reloc_overall = 2000; /* unit: millisecond */
+ target_enb_x2_ip_address = (
+ { ipv4 = "CI_RCC_IP_ADDR";
+ ipv6 = "192:168:30::17";
+ 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
+ };
+ }
+);
+
+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
+ att_tx = 0
+ att_rx = 0;
+ bands = [7];
+ max_pdschReferenceSignalPower = -27;
+ max_rxgain = 125;
+ eNB_instances = [0];
+
+ }
+);
+
+NETWORK_CONTROLLER :
+{
+ FLEXRAN_ENABLED = "no";
+ FLEXRAN_INTERFACE_NAME = "eth0";
+ FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR";
+ FLEXRAN_PORT = 2210;
+ FLEXRAN_CACHE = "/mnt/oai_agent_cache";
+ FLEXRAN_AWAIT_RECONF = "no";
+};
+
+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";//PARALLEL_RU_L1_TRX_SPLIT";
+ #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+ worker_config = "WORKER_ENABLE";
+ }
+);
+
+ log_config :
+ {
+ global_log_level ="info";
+ global_log_verbosity ="medium";
+ hw_log_level ="info";
+ hw_log_verbosity ="medium";
+ phy_log_level ="info";
+ phy_log_verbosity ="medium";
+ mac_log_level ="info";
+ mac_log_verbosity ="high";
+ rlc_log_level ="info";
+ rlc_log_verbosity ="medium";
+ pdcp_log_level ="info";
+ pdcp_log_verbosity ="medium";
+ rrc_log_level ="info";
+ rrc_log_verbosity ="medium";
+ };
+
diff --git a/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf b/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf
new file mode 100644
index 0000000000..b3899fdb6a
--- /dev/null
+++ b/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf
@@ -0,0 +1,242 @@
+Active_eNBs = ( "eNB_Eurecom_LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+ # real_time choice in {hard, rt-preempt, no}
+ real_time = "no";
+
+ ////////// Identification parameters:
+ eNB_ID = 0xe00;
+
+ cell_type = "CELL_MACRO_ENB";
+
+ eNB_name = "eNB_Eurecom_LTEBox";
+
+ // Tracking area code, 0x0000 and 0xfffe are reserved values
+ tracking_area_code = 1;
+ plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } );
+ tr_s_preference = "local_mac"
+
+ ////////// Physical parameters:
+
+ component_carriers = (
+ {
+ node_function = "NGFI_RCC_IF4p5";
+ node_timing = "synch_to_ext_device";
+ node_synch_ref = 0;
+ frame_type = "TDD";
+ tdd_config = 1;
+ tdd_config_s = 0;
+ prefix_type = "NORMAL";
+ eutra_band = 38;
+ downlink_frequency = 2580000000L;
+ uplink_frequency_offset = 0;
+ Nid_cell = 0;
+ N_RB_DL = 50; #25;
+ Nid_cell_mbsfn = 0;
+ nb_antenna_ports = 1;
+ nb_antennas_tx = 1;
+ nb_antennas_rx = 1;
+ tx_gain = 90;
+ rx_gain = 125;
+ pbch_repetition = "FALSE";
+ prach_root = 0;
+ prach_config_index = 0;
+ prach_high_speed = "DISABLE";
+ prach_zero_correlation = 1;
+ prach_freq_offset = 2;
+ pucch_delta_shift = 1;
+ pucch_nRB_CQI = 0;
+ pucch_nCS_AN = 0;
+ pucch_n1_AN = 32;
+ pdsch_referenceSignalPower = -27;
+ pdsch_p_b = 0;
+ pusch_n_SB = 1;
+ pusch_enable64QAM = "DISABLE";
+ pusch_hoppingMode = "interSubFrame";
+ pusch_hoppingOffset = 0;
+ pusch_groupHoppingEnabled = "ENABLE";
+ pusch_groupAssignment = 0;
+ pusch_sequenceHoppingEnabled = "DISABLE";
+ pusch_nDMRS1 = 1;
+ phich_duration = "NORMAL";
+ phich_resource = "ONESIXTH";
+ srs_enable = "DISABLE";
+ /* srs_BandwidthConfig =;
+ srs_SubframeConfig =;
+ srs_ackNackST =;
+ srs_MaxUpPts =;*/
+
+ pusch_p0_Nominal = -104; #-96;
+ pusch_alpha = "AL1";
+ pucch_p0_Nominal = -96; #-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;
+ }
+ );
+
+
+ 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 = "enp129s0f0";
+ ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
+ ENB_INTERFACE_NAME_FOR_S1U = "enp129s0f0";
+ ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; #"127.0.0.4/24";
+ ENB_PORT_FOR_S1U = 2152; # Spec 2152\
+
+ ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
+ ENB_PORT_FOR_X2C = 36422; # Spec 36422
+
+ };
+ }
+);
+
+MACRLCs = (
+ {
+ num_cc = 1;
+ tr_s_preference = "local_L1";
+ tr_n_preference = "local_RRC";
+ }
+);
+
+L1s = (
+ {
+ num_cc = 1;
+ tr_n_preference = "local_mac";
+ }
+);
+
+RUs = (
+ {
+ local_if_name = "enp129s0f0";
+ local_address = "CI_ENB_IP_ADDR";
+ remote_address = "CI_RRU1_IP_ADDR";
+ local_portc = 50002;
+ remote_portc = 50002;
+ local_portd = 50003;
+ remote_portd = 50003;
+ local_rf = "no"
+ tr_preference = "udp_if4p5"
+ nb_tx = 1
+ nb_rx = 1
+ att_tx = 20
+ att_rx = 20;
+ eNB_instances = [0];
+ is_slave = "no";
+ ota_sync_enabled = "yes";
+ },
+ {
+ local_if_name = "enp129s0f0";
+ local_address = "CI_ENB_IP_ADDR";
+ remote_address = "CI_RRU2_IP_ADDR";
+ local_portc = 50010;
+ remote_portc = 50010;
+ local_portd = 50011;
+ remote_portd = 50011;
+ local_rf = "no"
+ tr_preference = "udp_if4p5"
+ nb_tx = 1
+ nb_rx = 1
+ att_tx = 20
+ att_rx = 20;
+ eNB_instances = [0];
+ is_slave = "yes";
+ ota_sync_enabled = "yes";
+ }
+);
+
+THREAD_STRUCT = (
+ {
+ #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
+ parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
+ #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
+ worker_config = "WORKER_ENABLE";
+ }
+);
+
+log_config = {
+ global_log_level ="info";
+ global_log_verbosity ="medium";
+ hw_log_level ="info";
+ hw_log_verbosity ="medium";
+ phy_log_level ="info";
+ phy_log_verbosity ="medium";
+ mac_log_level ="info";
+ mac_log_verbosity ="high";
+ rlc_log_level ="info";
+ rlc_log_verbosity ="medium";
+ pdcp_log_level ="info";
+ pdcp_log_verbosity ="medium";
+ rrc_log_level ="info";
+ rrc_log_verbosity ="medium";
+};
diff --git a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf
index 81fc7eedce..28bfd91560 100644
--- a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf
+++ b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf
@@ -218,7 +218,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_SINGLE_THREAD";
+ parallel_config = "PARALLEL_RU_L1_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
diff --git a/ci-scripts/conf_files/rru.band38.tm1.master.conf b/ci-scripts/conf_files/rru.band38.tm1.master.conf
new file mode 100644
index 0000000000..101ce83892
--- /dev/null
+++ b/ci-scripts/conf_files/rru.band38.tm1.master.conf
@@ -0,0 +1,47 @@
+RUs = (
+ {
+ local_if_name = "enp1s0";
+ remote_address = "CI_RCC_IP_ADDR";
+ local_address = "CI_ENB_IP_ADDR";
+ local_portc = 50002;
+ remote_portc = 50002;
+ local_portd = 50003;
+ remote_portd = 50003;
+ local_rf = "yes"
+ tr_preference = "udp_if4p5";
+ nb_tx = 1;
+ nb_rx = 1;
+ max_pdschReferenceSignalPower = -12;
+ max_rxgain = 100;
+ bands = [38];
+ is_slave = "no";
+ ota_sync_enabled = "yes";
+ }
+);
+
+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";
+ }
+);
+
+log_config = {
+ global_log_level ="info";
+ global_log_verbosity ="medium";
+ hw_log_level ="info";
+ hw_log_verbosity ="medium";
+ phy_log_level ="info";
+ phy_log_verbosity ="medium";
+ mac_log_level ="info";
+ mac_log_verbosity ="high";
+ rlc_log_level ="info";
+ rlc_log_verbosity ="medium";
+ pdcp_log_level ="info";
+ pdcp_log_verbosity ="medium";
+ rrc_log_level ="info";
+ rrc_log_verbosity ="medium";
+};
+
diff --git a/ci-scripts/conf_files/rru.band38.tm1.slave.conf b/ci-scripts/conf_files/rru.band38.tm1.slave.conf
new file mode 100644
index 0000000000..d5efe6bd61
--- /dev/null
+++ b/ci-scripts/conf_files/rru.band38.tm1.slave.conf
@@ -0,0 +1,47 @@
+RUs = (
+ {
+ local_if_name = "enp1s0";
+ remote_address = "CI_RCC_IP_ADDR";
+ local_address = "CI_ENB_IP_ADDR";
+ local_portc = 50010;
+ remote_portc = 50010;
+ local_portd = 50011;
+ remote_portd = 50011;
+ local_rf = "yes"
+ tr_preference = "udp_if4p5";
+ nb_tx = 1;
+ nb_rx = 1;
+ max_pdschReferenceSignalPower = -12;
+ max_rxgain = 100;
+ bands = [38];
+ is_slave = "yes";
+ ota_sync_enabled = "yes";
+ }
+);
+
+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";
+ }
+);
+
+log_config = {
+ global_log_level ="info";
+ global_log_verbosity ="medium";
+ hw_log_level ="info";
+ hw_log_verbosity ="medium";
+ phy_log_level ="info";
+ phy_log_verbosity ="medium";
+ mac_log_level ="info";
+ mac_log_verbosity ="high";
+ rlc_log_level ="info";
+ rlc_log_verbosity ="medium";
+ pdcp_log_level ="info";
+ pdcp_log_verbosity ="medium";
+ rrc_log_level ="info";
+ rrc_log_verbosity ="medium";
+};
+
diff --git a/ci-scripts/doGitLabMerge.sh b/ci-scripts/doGitLabMerge.sh
index dd93ff41b7..c4aa9157de 100755
--- a/ci-scripts/doGitLabMerge.sh
+++ b/ci-scripts/doGitLabMerge.sh
@@ -125,7 +125,16 @@ fi
git config user.email "jenkins@openairinterface.org"
git config user.name "OAI Jenkins"
-git checkout -f $SOURCE_COMMIT_ID
+git checkout -f $SOURCE_COMMIT_ID > checkout.txt 2>&1
+STATUS=`egrep -c "fatal: reference is not a tree" checkout.txt`
+rm -f checkout.txt
+if [ $STATUS -ne 0 ]
+then
+ echo "fatal: reference is not a tree --> $SOURCE_COMMIT_ID"
+ STATUS=-1
+ exit $STATUS
+fi
+
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/main.py b/ci-scripts/main.py
index 23e8921a64..8a0b10d257 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -43,6 +43,7 @@ ENB_PROCESS_SEG_FAULT = -11
ENB_PROCESS_ASSERTION = -12
ENB_PROCESS_REALTIME_ISSUE = -13
ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14
+ENB_PROCESS_SLAVE_RRU_NOT_SYNCED = -15
HSS_PROCESS_FAILED = -2
HSS_PROCESS_OK = +2
MME_PROCESS_FAILED = -3
@@ -57,6 +58,17 @@ OAI_UE_PROCESS_FAILED = -23
OAI_UE_PROCESS_NO_TUNNEL_INTERFACE = -24
OAI_UE_PROCESS_OK = +6
+UE_STATUS_DETACHED = 0
+UE_STATUS_DETACHING = 1
+UE_STATUS_ATTACHING = 2
+UE_STATUS_ATTACHED = 3
+
+X2_HO_REQ_STATE__IDLE = 0
+X2_HO_REQ_STATE__TARGET_RECEIVES_REQ = 1
+X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE = 2
+X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ = 3
+X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK = 10
+
#-----------------------------------------------------------
# Import
#-----------------------------------------------------------
@@ -81,18 +93,27 @@ logging.basicConfig(
#-----------------------------------------------------------
class SSHConnection():
def __init__(self):
+ self.prematureExit = False
+ self.ranRepository = ''
+ self.ranBranch = ''
+ self.ranAllowMerge = False
+ self.ranCommitID = ''
+ self.ranTargetBranch = ''
self.eNBIPAddress = ''
- self.eNBRepository = ''
- self.eNBBranch = ''
- self.eNB_AllowMerge = False
- self.eNBCommitID = ''
- self.eNBTargetBranch = ''
self.eNBUserName = ''
self.eNBPassword = ''
self.eNBSourceCodePath = ''
self.EPCIPAddress = ''
self.EPCUserName = ''
self.EPCPassword = ''
+ self.eNB1IPAddress = ''
+ self.eNB1UserName = ''
+ self.eNB1Password = ''
+ self.eNB1SourceCodePath = ''
+ self.eNB2IPAddress = ''
+ self.eNB2UserName = ''
+ self.eNB2Password = ''
+ self.eNB2SourceCodePath = ''
self.EPCSourceCodePath = ''
self.EPCType = ''
self.EPC_PcapFileName = ''
@@ -104,12 +125,13 @@ class SSHConnection():
self.nbTestXMLfiles = 0
self.desc = ''
self.Build_eNB_args = ''
+ self.backgroundBuild = False
+ self.backgroundBuildTestId = ['', '', '']
self.Initialize_eNB_args = ''
- self.eNBLogFile = ''
self.eNB_instance = ''
- self.eNBOptions = ''
- self.rruOptions = ''
- self.rruLogFile = ''
+ self.eNB_serverId = ''
+ self.eNBLogFiles = ['', '', '']
+ self.eNBOptions = ['', '', '']
self.ping_args = ''
self.ping_packetloss_threshold = ''
self.iperf_args = ''
@@ -117,6 +139,7 @@ class SSHConnection():
self.iperf_profile = ''
self.nbMaxUEtoAttach = -1
self.UEDevices = []
+ self.UEDevicesStatus = []
self.CatMDevices = []
self.UEIPAddresses = []
self.htmlFile = ''
@@ -127,9 +150,14 @@ class SSHConnection():
self.htmlUEFailureMsg = ''
self.picocom_closure = False
self.idle_sleep_time = 0
+ self.x2_ho_options = 'network'
+ self.x2NbENBs = 0
+ self.x2ENBBsIds = []
+ self.x2ENBConnectedUEs = []
self.htmlTabRefs = []
self.htmlTabNames = []
self.htmlTabIcons = []
+ self.repeatCounts = []
self.finalStatus = False
self.OsVersion = ''
self.KernelVersion = ''
@@ -312,45 +340,168 @@ class SSHConnection():
sys.exit('SCP failed')
def BuildeNB(self):
- if self.eNBIPAddress == '' or self.eNBRepository == '' or self.eNBBranch == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.eNBSourceCodePath == '':
+ if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
Usage()
sys.exit('Insufficient Parameter')
- self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
- self.command('mkdir -p ' + self.eNBSourceCodePath, '\$', 5)
- self.command('cd ' + self.eNBSourceCodePath, '\$', 5)
- self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.eNBRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600)
+ if self.eNB_serverId == '0':
+ lIpAddr = self.eNBIPAddress
+ lUserName = self.eNBUserName
+ lPassWord = self.eNBPassword
+ lSourcePath = self.eNBSourceCodePath
+ elif self.eNB_serverId == '1':
+ lIpAddr = self.eNB1IPAddress
+ lUserName = self.eNB1UserName
+ lPassWord = self.eNB1Password
+ lSourcePath = self.eNB1SourceCodePath
+ elif self.eNB_serverId == '2':
+ lIpAddr = self.eNB2IPAddress
+ lUserName = self.eNB2UserName
+ lPassWord = self.eNB2Password
+ lSourcePath = self.eNB2SourceCodePath
+ if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
+ Usage()
+ sys.exit('Insufficient Parameter')
+ self.open(lIpAddr, lUserName, lPassWord)
+ self.command('mkdir -p ' + lSourcePath, '\$', 5)
+ self.command('cd ' + lSourcePath, '\$', 5)
+ self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600)
# Raphael: 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.eNBPassword + ' | sudo -S git clean -x -d -ff', '\$', 30)
+ # Checking the BUILD INFO file
+ if not self.backgroundBuild:
+ self.command('ls *.txt', '\$', 5)
+ result = re.search('LAST_BUILD_INFO', str(self.ssh.before))
+ if result is not None:
+ mismatch = False
+ self.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2)
+ result = re.search(self.ranCommitID, str(self.ssh.before))
+ if result is None:
+ mismatch = True
+ self.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2)
+ if (self.ranAllowMerge):
+ result = re.search('YES', str(self.ssh.before))
+ if result is None:
+ mismatch = True
+ self.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2)
+ if self.ranTargetBranch == '':
+ result = re.search('develop', str(self.ssh.before))
+ else:
+ result = re.search(self.ranTargetBranch, str(self.ssh.before))
+ if result is None:
+ mismatch = True
+ else:
+ result = re.search('NO', str(self.ssh.before))
+ if result is None:
+ mismatch = True
+ if not mismatch:
+ self.close()
+ self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK)
+ return
+
+ self.command('echo ' + lPassWord + ' | 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 self.ranCommitID != '':
+ self.command('git checkout -f ' + self.ranCommitID, '\$', 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'):
+ if (self.ranAllowMerge):
+ if self.ranTargetBranch == '':
+ if (self.ranBranch != 'develop') and (self.ranBranch != '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)
+ logging.debug('Merging with the target branch: ' + self.ranTargetBranch)
+ self.command('git merge --ff origin/' + self.ranTargetBranch + ' -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_eNB_args + ' 2>&1 | stdbuf -o0 tee compile_oai_enb.log', 'Bypassing the Tests|build have failed', 600)
+ if self.backgroundBuild:
+ self.command('echo "./build_oai ' + self.Build_eNB_args + '" > ./my-lte-softmodem-build.sh', '\$', 5)
+ self.command('chmod 775 ./my-lte-softmodem-build.sh', '\$', 5)
+ self.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=build_enb_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ./my-lte-softmodem-build.sh', '\$', 5)
+ self.close()
+ self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK)
+ self.backgroundBuildTestId[int(self.eNB_instance)] = self.testCase_id
+ return
+ 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', 1500)
+ self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.testCase_id)
+
+ def WaitBuildeNBisFinished(self):
+ if self.eNB_serverId == '0':
+ lIpAddr = self.eNBIPAddress
+ lUserName = self.eNBUserName
+ lPassWord = self.eNBPassword
+ lSourcePath = self.eNBSourceCodePath
+ elif self.eNB_serverId == '1':
+ lIpAddr = self.eNB1IPAddress
+ lUserName = self.eNB1UserName
+ lPassWord = self.eNB1Password
+ lSourcePath = self.eNB1SourceCodePath
+ elif self.eNB_serverId == '2':
+ lIpAddr = self.eNB2IPAddress
+ lUserName = self.eNB2UserName
+ lPassWord = self.eNB2Password
+ lSourcePath = self.eNB2SourceCodePath
+ if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
+ Usage()
+ sys.exit('Insufficient Parameter')
+ self.open(lIpAddr, lUserName, lPassWord)
+ count = 40
+ buildOAIprocess = True
+ while (count > 0) and buildOAIprocess:
+ self.command('ps aux | grep --color=never build_ | grep -v grep', '\$', 3)
+ result = re.search('build_oai', str(self.ssh.before))
+ if result is None:
+ buildOAIprocess = False
+ else:
+ count -= 1
+ time.sleep(30)
+ self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.backgroundBuildTestId[int(self.eNB_instance)])
+
+ def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId):
+ self.command('cd ' + lSourcePath + '/cmake_targets', '\$', 3)
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)
- self.close()
+ else:
+ # Generating a BUILD INFO file
+ self.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2)
+ self.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+ if (self.ranAllowMerge):
+ self.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+ if self.ranTargetBranch == '':
+ self.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+ else:
+ self.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+ else:
+ self.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2)
+ self.command('mkdir -p build_log_' + testcaseId, '\$', 5)
+ self.command('mv log/* ' + 'build_log_' + testcaseId, '\$', 5)
+ self.command('mv compile_oai_enb.log ' + 'build_log_' + testcaseId, '\$', 5)
+ if self.eNB_serverId != '0':
+ self.command('cd cmake_targets', '\$', 5)
+ self.command('if [ -e tmp_build' + testcaseId + '.zip ]; then rm -f tmp_build' + testcaseId + '.zip; fi', '\$', 5)
+ self.command('zip -r -qq tmp_build' + testcaseId + '.zip build_log_' + testcaseId, '\$', 5)
+ self.close()
+ if (os.path.isfile('./tmp_build' + testcaseId + '.zip')):
+ os.remove('./tmp_build' + testcaseId + '.zip')
+ self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/tmp_build' + testcaseId + '.zip', '.')
+ if (os.path.isfile('./tmp_build' + testcaseId + '.zip')):
+ self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './tmp_build' + testcaseId + '.zip', self.eNBSourceCodePath + '/cmake_targets/.')
+ os.remove('./tmp_build' + testcaseId + '.zip')
+ self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
+ self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5)
+ self.command('unzip -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5)
+ self.command('rm -f tmp_build' + testcaseId + '.zip', '\$', 5)
+ self.close()
+ else:
+ self.close()
+
if buildStatus:
self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK)
else:
@@ -360,29 +511,29 @@ class SSHConnection():
sys.exit(1)
def BuildOAIUE(self):
- if self.UEIPAddress == '' or self.eNBRepository == '' or self.eNBBranch == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
+ if self.UEIPAddress == '' or self.ranRepository == '' or self.ranBranch == '' 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)
+ self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.ranRepository + ' .; 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 self.ranCommitID != '':
+ self.command('git checkout -f ' + self.ranCommitID, '\$', 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'):
+ if (self.ranAllowMerge):
+ if self.ranTargetBranch == '':
+ if (self.ranBranch != 'develop') and (self.ranBranch != '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)
+ logging.debug('Merging with the target branch: ' + self.ranTargetBranch)
+ self.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
self.command('source oaienv', '\$', 5)
self.command('cd cmake_targets', '\$', 5)
self.command('mkdir -p log', '\$', 5)
@@ -498,7 +649,22 @@ class SSHConnection():
self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
def InitializeeNB(self):
- if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.eNBSourceCodePath == '':
+ if self.eNB_serverId == '0':
+ lIpAddr = self.eNBIPAddress
+ lUserName = self.eNBUserName
+ lPassWord = self.eNBPassword
+ lSourcePath = self.eNBSourceCodePath
+ elif self.eNB_serverId == '1':
+ lIpAddr = self.eNB1IPAddress
+ lUserName = self.eNB1UserName
+ lPassWord = self.eNB1Password
+ lSourcePath = self.eNB1SourceCodePath
+ elif self.eNB_serverId == '2':
+ lIpAddr = self.eNB2IPAddress
+ lUserName = self.eNB2UserName
+ lPassWord = self.eNB2Password
+ lSourcePath = self.eNB2SourceCodePath
+ if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
Usage()
sys.exit('Insufficient Parameter')
check_eNB = False
@@ -519,10 +685,10 @@ class SSHConnection():
logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m')
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.command('echo $USER; nohup sudo tshark -f "host ' + lIpAddr +'" -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)
+ self.open(lIpAddr, lUserName, lPassWord)
+ self.command('cd ' + lSourcePath, '\$', 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 = ''
@@ -535,31 +701,34 @@ class SSHConnection():
logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m')
self.command('cd common/utils/T/tracer', '\$', 5)
self.command('make', '\$', 10)
- self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', self.eNBUserName, 5)
- self.command('cd ' + self.eNBSourceCodePath, '\$', 5)
+ self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', lUserName, 5)
+ self.command('cd ' + lSourcePath, '\$', 5)
full_config_file = full_config_file[:extIdx + 5]
config_path, config_file = os.path.split(full_config_file)
else:
sys.exit('Insufficient Parameter')
ci_full_config_file = config_path + '/ci-' + config_file
rruCheck = False
- result = re.search('rru|du.band', str(config_file))
+ result = re.search('^rru|^rcc|^du.band', 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.band', str(config_file))
+ result = re.search('^rru|^enb|^du.band', str(config_file))
if result is not None:
- self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 10)
+ self.command('echo ' + lPassWord + ' | 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)
+ self.command('echo ' + lPassWord + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10)
# Reloading FGPA bin firmware
- self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 15)
+ self.command('echo ' + lPassWord + ' | 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);
- self.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
+ self.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2);
+ self.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
+ self.command('sed -i -e \'s/CI_RRU1_IP_ADDR/' + self.eNB1IPAddress + '/\' ' + ci_full_config_file, '\$', 2);
+ self.command('sed -i -e \'s/CI_RRU2_IP_ADDR/' + self.eNB2IPAddress + '/\' ' + ci_full_config_file, '\$', 2);
if self.flexranCtrlInstalled and self.flexranCtrlStarted:
self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "yes";/\' ' + ci_full_config_file, '\$', 2);
else:
@@ -567,18 +736,13 @@ 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('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + lSourcePath + '/' + 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)
- result = re.search('rcc|enb|cu.band', str(config_file))
- if result is not None:
- self.eNBLogFile = 'enb_' + self.testCase_id + '.log'
- if extra_options != '':
- self.eNBOptions = extra_options
- result = re.search('rru|du.band', str(config_file))
- if result is not None:
- self.rruLogFile = 'enb_' + self.testCase_id + '.log'
+ self.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
+ self.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
+ self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log'
+ if extra_options != '':
+ self.eNBOptions[int(self.eNB_instance)] = extra_options
time.sleep(6)
doLoop = True
loopCounter = 10
@@ -593,7 +757,6 @@ class SSHConnection():
doLoop = False
logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m')
self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', ALL_PROCESSES_OK)
- self.CreateHtmlTabFooter(False)
# In case of T tracer recording, we need to kill tshark on EPC side
result = re.search('T_stdout', str(self.Initialize_eNB_args))
if result is not None:
@@ -608,8 +771,9 @@ class SSHConnection():
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)
+ self.copyout(lIpAddr, lUserName, lPassWord, self.EPC_PcapFileName, lSourcePath + '/cmake_targets/.')
+ self.prematureExit = True
+ return
else:
self.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting"', '\$', 4)
if rruCheck:
@@ -620,8 +784,6 @@ class SSHConnection():
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)
@@ -640,7 +802,10 @@ class SSHConnection():
# self.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60)
# a dedicated script has to be installed inside the UE
# airplane mode on means call /data/local/tmp/off
- self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
+ if device_id == '84B7N16418004022':
+ self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+ else:
+ self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
#airplane mode off means call /data/local/tmp/on
logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m')
self.close()
@@ -788,8 +953,6 @@ class SSHConnection():
self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE')
logging.error('\033[91mInitialize OAI UE Failed! \033[0m')
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
def checkDevTTYisUnlocked(self):
self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
@@ -940,8 +1103,8 @@ class SSHConnection():
pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE)
if (pStatus < 0):
self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
+ self.prematureExit = True
+ return
try:
statusQueue = SimpleQueue()
lock = Lock()
@@ -1023,15 +1186,16 @@ class SSHConnection():
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:
self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
- self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
+ if device_id == '84B7N16418004022':
+ self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60)
+ else:
+ self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
time.sleep(2)
max_count = 45
count = max_count
@@ -1058,9 +1222,15 @@ class SSHConnection():
count = count - 1
if count == 15 or count == 30:
logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m')
- self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
+ if device_id == '84B7N16418004022':
+ self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+ else:
+ self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
time.sleep(0.5)
- self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
+ if device_id == '84B7N16418004022':
+ self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60)
+ else:
+ self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
time.sleep(0.5)
logging.debug('\u001B[1mWait UE (' + device_id + ') a second until mDataConnectionState=2 (' + str(max_count-count) + ' times)\u001B[0m')
time.sleep(1)
@@ -1085,14 +1255,14 @@ class SSHConnection():
if (pStatus < 0):
self.CreateHtmlTestRow('N/A', 'KO', pStatus)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
+ return
multi_jobs = []
status_queue = SimpleQueue()
lock = Lock()
nb_ue_to_connect = 0
for device_id in self.UEDevices:
if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach):
+ self.UEDevicesStatus[nb_ue_to_connect] = UE_STATUS_ATTACHING
p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,))
p.daemon = True
p.start()
@@ -1103,9 +1273,8 @@ class SSHConnection():
if (status_queue.empty()):
self.CreateHtmlTestRow('N/A', 'KO', ALL_PROCESSES_OK)
- self.CreateHtmlTabFooter(False)
self.AutoTerminateUEandeNB()
- sys.exit(1)
+ return
else:
attach_status = True
html_queue = SimpleQueue()
@@ -1121,6 +1290,11 @@ class SSHConnection():
html_cell = '
UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds'
html_queue.put(html_cell)
if (attach_status):
+ cnt = 0
+ while cnt < len(self.UEDevices):
+ if self.UEDevicesStatus[cnt] == UE_STATUS_ATTACHING:
+ self.UEDevicesStatus[cnt] = UE_STATUS_ATTACHED
+ cnt += 1
self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
result = re.search('T_stdout', str(self.Initialize_eNB_args))
if result is not None:
@@ -1129,13 +1303,14 @@ class SSHConnection():
else:
self.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
def DetachUE_common(self, device_id):
try:
self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
- self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
+ if device_id == '84B7N16418004022':
+ self.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+ else:
+ self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m')
self.close()
except:
@@ -1151,14 +1326,16 @@ class SSHConnection():
if (pStatus < 0):
self.CreateHtmlTestRow('N/A', 'KO', pStatus)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
+ return
multi_jobs = []
+ cnt = 0
for device_id in self.UEDevices:
+ self.UEDevicesStatus[cnt] = UE_STATUS_DETACHING
p = Process(target = self.DetachUE_common, args = (device_id,))
p.daemon = True
p.start()
multi_jobs.append(p)
+ cnt += 1
for job in multi_jobs:
job.join()
self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
@@ -1166,6 +1343,10 @@ class SSHConnection():
if result is not None:
logging.debug('Waiting 5 seconds to fill up record file')
time.sleep(5)
+ cnt = 0
+ while cnt < len(self.UEDevices):
+ self.UEDevicesStatus[cnt] = UE_STATUS_DETACHED
+ cnt += 1
def RebootUE_common(self, device_id):
try:
@@ -1286,6 +1467,11 @@ class SSHConnection():
if len(self.UEDevices) == 0:
logging.debug('\u001B[1;37;41m UE Not Found! \u001B[0m')
sys.exit(1)
+ if len(self.UEDevicesStatus) == 0:
+ cnt = 0
+ while cnt < len(self.UEDevices):
+ self.UEDevicesStatus.append(UE_STATUS_DETACHED)
+ cnt += 1
self.close()
def GetAllCatMDevices(self, terminate_ue_flag):
@@ -1392,8 +1578,6 @@ class SSHConnection():
if (status_queue.empty()):
self.CreateHtmlTestRow(htmlOptions, 'KO', ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
else:
check_status = True
html_queue = SimpleQueue()
@@ -1410,8 +1594,6 @@ class SSHConnection():
else:
self.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
def GetAllUEIPAddresses(self):
if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '':
@@ -1436,7 +1618,11 @@ class SSHConnection():
self.close()
return ue_ip_status
self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
+ idx = 0
for device_id in self.UEDevices:
+ if self.UEDevicesStatus[idx] != UE_STATUS_ATTACHED:
+ idx += 1
+ continue
count = 0
while count < 4:
self.command('stdbuf -o0 adb -s ' + device_id + ' shell ip addr show | grep rmnet', '\$', 15)
@@ -1458,6 +1644,7 @@ class SSHConnection():
ue_ip_status -= 1
continue
self.UEIPAddresses.append(UE_IPAddress)
+ idx += 1
self.close()
return ue_ip_status
@@ -1552,8 +1739,7 @@ class SSHConnection():
if (pStatus < 0):
self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
+ return
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 == '':
@@ -1656,14 +1842,12 @@ class SSHConnection():
if (pStatus < 0):
self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
+ return
ueIpStatus = self.GetAllUEIPAddresses()
if (ueIpStatus < 0):
self.CreateHtmlTestRow(self.ping_args, 'KO', UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
+ return
multi_jobs = []
i = 0
lock = Lock()
@@ -1681,8 +1865,6 @@ class SSHConnection():
if (status_queue.empty()):
self.CreateHtmlTestRow(self.ping_args, 'KO', ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
else:
ping_status = True
html_queue = SimpleQueue()
@@ -1700,8 +1882,6 @@ class SSHConnection():
else:
self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
def Iperf_ComputeTime(self):
result = re.search('-t (?P\d+)', str(self.iperf_args))
@@ -2179,8 +2359,6 @@ class SSHConnection():
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')
@@ -2270,8 +2448,6 @@ class SSHConnection():
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))
@@ -2290,14 +2466,12 @@ class SSHConnection():
if (pStatus < 0):
self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
+ return
ueIpStatus = self.GetAllUEIPAddresses()
if (ueIpStatus < 0):
self.CreateHtmlTestRow(self.iperf_args, 'KO', UE_IP_ADDRESS_ISSUE)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
+ return
multi_jobs = []
i = 0
ue_num = len(self.UEIPAddresses)
@@ -2316,8 +2490,6 @@ class SSHConnection():
if (status_queue.empty()):
self.CreateHtmlTestRow(self.iperf_args, 'KO', ALL_PROCESSES_OK)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
else:
iperf_status = True
iperf_noperf = False
@@ -2340,8 +2512,6 @@ class SSHConnection():
else:
self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue)
self.AutoTerminateUEandeNB()
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
def CheckProcessExist(self, check_eNB, check_OAI_UE):
multi_jobs = []
@@ -2386,13 +2556,13 @@ class SSHConnection():
if (status < 0):
result = status
if result == ENB_PROCESS_FAILED:
- fileCheck = re.search('enb_', str(self.eNBLogFile))
+ fileCheck = re.search('enb_', str(self.eNBLogFiles[0]))
if fileCheck is not None:
- self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.')
- logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFile)
+ self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFiles[0], '.')
+ logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFiles[0])
if logStatus < 0:
result = logStatus
- self.eNBLogFile = ''
+ self.eNBLogFiles[0] = ''
if self.flexranCtrlInstalled and self.flexranCtrlStarted:
self.TerminateFlexranCtrl()
return result
@@ -2530,17 +2700,49 @@ class SSHConnection():
cdrxActivationMessageCount = 0
dropNotEnoughRBs = 0
self.htmleNBFailureMsg = ''
+ isRRU = False
+ isSlave = False
+ slaveReceivesFrameResyncCmd = False
+ X2HO_state = X2_HO_REQ_STATE__IDLE
+ X2HO_inNbProcedures = 0
+ X2HO_outNbProcedures = 0
for line in enb_log_file.readlines():
- if self.rruOptions != '':
- res1 = re.search('max_rxgain (?P[0-9]+)', self.rruOptions)
+ if X2HO_state == X2_HO_REQ_STATE__IDLE:
+ result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line))
+ if result is not None:
+ X2HO_state = X2_HO_REQ_STATE__TARGET_RECEIVES_REQ
+ result = re.search('source eNB receives the X2 HO ACK X2AP_HANDOVER_REQ_ACK', str(line))
+ if result is not None:
+ X2HO_state = X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK
+ if X2HO_state == X2_HO_REQ_STATE__TARGET_RECEIVES_REQ:
+ result = re.search('Received LTE_RRCConnectionReconfigurationComplete from UE', str(line))
+ if result is not None:
+ X2HO_state = X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE
+ if X2HO_state == X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE:
+ result = re.search('issue rrc_eNB_send_PATH_SWITCH_REQ', str(line))
+ if result is not None:
+ X2HO_state = X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ
+ if X2HO_state == X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ:
+ result = re.search('received path switch ack S1AP_PATH_SWITCH_REQ_ACK', str(line))
+ if result is not None:
+ X2HO_state = X2_HO_REQ_STATE__IDLE
+ X2HO_inNbProcedures += 1
+ if X2HO_state == X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK:
+ result = re.search('source eNB receives the X2 UE CONTEXT RELEASE X2AP_UE_CONTEXT_RELEASE', str(line))
+ if result is not None:
+ X2HO_state = X2_HO_REQ_STATE__IDLE
+ X2HO_outNbProcedures += 1
+
+ if self.eNBOptions[int(self.eNB_instance)] != '':
+ res1 = re.search('max_rxgain (?P[0-9]+)', self.eNBOptions[int(self.eNB_instance)])
res2 = re.search('max_rxgain (?P[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 += ' Command line option(s) correctly applied ' + self.rruOptions + '\n\n'
+ self.htmleNBFailureMsg += ' Command line option(s) correctly applied ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n'
else:
- self.htmleNBFailureMsg += ' Command line option(s) NOT applied ' + self.rruOptions + '\n\n'
+ self.htmleNBFailureMsg += ' Command line option(s) NOT applied ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n'
result = re.search('Exiting OAI softmodem', str(line))
if result is not None:
exitSignalReceived = True
@@ -2562,6 +2764,17 @@ class SSHConnection():
if foundAssertion and (msgLine < 3):
msgLine += 1
msgAssertion += str(line)
+ result = re.search('Setting function for RU', str(line))
+ if result is not None:
+ isRRU = True
+ if isRRU:
+ result = re.search('RU 0 is_slave=yes', str(line))
+ if result is not None:
+ isSlave = True
+ if isSlave:
+ result = re.search('Received RRU_frame_resynch command', str(line))
+ if result is not None:
+ slaveReceivesFrameResyncCmd = True
result = re.search('LTE_RRCConnectionSetupComplete from UE', str(line))
if result is not None:
rrcSetupComplete += 1
@@ -2647,14 +2860,41 @@ 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)'
+ if X2HO_inNbProcedures > 0:
+ rrcMsg = 'eNB completed ' + str(X2HO_inNbProcedures) + ' X2 Handover Connection procedure(s)'
logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
self.htmleNBFailureMsg += rrcMsg + '\n'
+ if X2HO_outNbProcedures > 0:
+ rrcMsg = 'eNB completed ' + str(X2HO_outNbProcedures) + ' X2 Handover Release procedure(s)'
+ logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
+ self.htmleNBFailureMsg += rrcMsg + '\n'
+ if self.eNBOptions[int(self.eNB_instance)] != '':
+ res1 = re.search('drx_Config_present prSetup', self.eNBOptions[int(self.eNB_instance)])
+ if res1 is not None:
+ 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'
+ else:
+ rrcMsg = 'eNB did NOT ACTIVATE the CDRX Configuration'
+ logging.debug('\u001B[1;37;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')
self.htmleNBFailureMsg += rachMsg + '\n'
+ if isRRU:
+ if isSlave:
+ if slaveReceivesFrameResyncCmd:
+ rruMsg = 'Slave RRU received the RRU_frame_resynch command from RAU'
+ logging.debug('\u001B[1;30;43m ' + rruMsg + ' \u001B[0m')
+ self.htmleNBFailureMsg += rruMsg + '\n'
+ else:
+ rruMsg = 'Slave RRU DID NOT receive the RRU_frame_resynch command from RAU'
+ logging.debug('\u001B[1;37;41m ' + rruMsg + ' \u001B[0m')
+ self.htmleNBFailureMsg += rruMsg + '\n'
+ self.prematureExit = True
+ return ENB_PROCESS_SLAVE_RRU_NOT_SYNCED
if foundSegFault:
logging.debug('\u001B[1;37;41m eNB ended with a Segmentation Fault! \u001B[0m')
return ENB_PROCESS_SEG_FAULT
@@ -2842,18 +3082,36 @@ class SSHConnection():
return 0
def TerminateeNB(self):
- self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
- self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5)
+ if self.eNB_serverId == '0':
+ lIpAddr = self.eNBIPAddress
+ lUserName = self.eNBUserName
+ lPassWord = self.eNBPassword
+ lSourcePath = self.eNBSourceCodePath
+ elif self.eNB_serverId == '1':
+ lIpAddr = self.eNB1IPAddress
+ lUserName = self.eNB1UserName
+ lPassWord = self.eNB1Password
+ lSourcePath = self.eNB1SourceCodePath
+ elif self.eNB_serverId == '2':
+ lIpAddr = self.eNB2IPAddress
+ lUserName = self.eNB2UserName
+ lPassWord = self.eNB2Password
+ lSourcePath = self.eNB2SourceCodePath
+ if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
+ Usage()
+ sys.exit('Insufficient Parameter')
+ self.open(lIpAddr, lUserName, lPassWord)
+ self.command('cd ' + lSourcePath + '/cmake_targets', '\$', 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 daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5)
- self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5)
+ self.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5)
+ self.command('echo ' + lPassWord + ' | 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)
+ self.command('echo ' + lPassWord + ' | 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()
@@ -2867,50 +3125,46 @@ class SSHConnection():
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.copyout(lIpAddr, lUserName, lPassWord, self.EPC_PcapFileName, lSourcePath + '/cmake_targets/.')
self.close()
logging.debug('\u001B[1m Replaying RAW record file\u001B[0m')
- self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
- self.command('cd ' + self.eNBSourceCodePath + '/common/utils/T/tracer/', '\$', 5)
- raw_record_file = self.eNBLogFile.replace('.log', '_record.raw')
- replay_log_file = self.eNBLogFile.replace('.log', '_replay.log')
- extracted_txt_file = self.eNBLogFile.replace('.log', '_extracted_messages.txt')
- extracted_log_file = self.eNBLogFile.replace('.log', '_extracted_messages.log')
- self.command('./extract_config -i ' + self.eNBSourceCodePath + '/cmake_targets/' + raw_record_file + ' > ' + self.eNBSourceCodePath + '/cmake_targets/' + extracted_txt_file, '\$', 5)
- self.command('echo $USER; nohup ./replay -i ' + self.eNBSourceCodePath + '/cmake_targets/' + raw_record_file + ' > ' + self.eNBSourceCodePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', self.eNBUserName, 5)
- self.command('./textlog -d ' + self.eNBSourceCodePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + self.eNBSourceCodePath + '/cmake_targets/' + extracted_log_file, '\$', 5)
+ self.open(lIpAddr, lUserName, lPassWord)
+ self.command('cd ' + lSourcePath + '/common/utils/T/tracer/', '\$', 5)
+ enbLogFile = self.eNBLogFiles[int(self.eNB_instance)]
+ raw_record_file = enbLogFile.replace('.log', '_record.raw')
+ replay_log_file = enbLogFile.replace('.log', '_replay.log')
+ extracted_txt_file = enbLogFile.replace('.log', '_extracted_messages.txt')
+ extracted_log_file = enbLogFile.replace('.log', '_extracted_messages.log')
+ self.command('./extract_config -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + extracted_txt_file, '\$', 5)
+ self.command('echo $USER; nohup ./replay -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', lUserName, 5)
+ self.command('./textlog -d ' + lSourcePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + lSourcePath + '/cmake_targets/' + extracted_log_file, '\$', 5)
self.close()
- self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + extracted_log_file, '.')
+ self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + extracted_log_file, '.')
logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m')
logStatus = self.AnalyzeLogFile_eNB(extracted_log_file)
self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
- self.eNBLogFile = ''
+ self.eNBLogFiles[int(self.eNB_instance)] = ''
else:
- result = re.search('enb_', str(self.eNBLogFile))
analyzeFile = False
- if result is not None:
+ if self.eNBLogFiles[int(self.eNB_instance)] != '':
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 = ''
+ fileToAnalyze = self.eNBLogFiles[int(self.eNB_instance)]
+ self.eNBLogFiles[int(self.eNB_instance)] = ''
if analyzeFile:
- copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + fileToAnalyze, '.')
+ copyin_res = self.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/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)
return
+ if self.eNB_serverId != '0':
+ self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/')
logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m ' + fileToAnalyze)
logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze)
if (logStatus < 0):
self.CreateHtmlTestRow('N/A', 'KO', logStatus)
- self.CreateHtmlTabFooter(False)
- sys.exit(1)
+ self.preamtureExit = True
+ return
else:
self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
else:
@@ -3049,8 +3303,6 @@ class SSHConnection():
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 = '' + ueAction + ' Completed\n' + self.htmlUEFailureMsg
@@ -3076,11 +3328,122 @@ class SSHConnection():
self.ShowTestID()
self.eNB_instance = '0'
self.TerminateeNB()
+ self.prematureExit = True
def IdleSleep(self):
time.sleep(self.idle_sleep_time)
self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK)
+ def X2_Status(self, idx, fileName):
+ cmd = "curl --silent http://" + self.EPCIPAddress + ":9999/stats | jq '.' > " + fileName
+ message = cmd + '\n'
+ logging.debug(cmd)
+ subprocess.run(cmd, shell=True)
+ if idx == 0:
+ cmd = "jq '.mac_stats | length' " + fileName
+ strNbEnbs = subprocess.check_output(cmd, shell=True, universal_newlines=True)
+ self.x2NbENBs = int(strNbEnbs.strip())
+ cnt = 0
+ while cnt < self.x2NbENBs:
+ cmd = "jq '.mac_stats[" + str(cnt) + "].bs_id' " + fileName
+ bs_id = subprocess.check_output(cmd, shell=True, universal_newlines=True)
+ self.x2ENBBsIds[idx].append(bs_id.strip())
+ cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats | length' " + fileName
+ stNbUEs = subprocess.check_output(cmd, shell=True, universal_newlines=True)
+ nbUEs = int(stNbUEs.strip())
+ ueIdx = 0
+ self.x2ENBConnectedUEs[idx].append([])
+ while ueIdx < nbUEs:
+ cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats[" + str(ueIdx) + "].rnti' " + fileName
+ rnti = subprocess.check_output(cmd, shell=True, universal_newlines=True)
+ self.x2ENBConnectedUEs[idx][cnt].append(rnti.strip())
+ ueIdx += 1
+ cnt += 1
+
+ msg = "FlexRan Controller is connected to " + str(self.x2NbENBs) + " eNB(s)"
+ logging.debug(msg)
+ message += msg + '\n'
+ cnt = 0
+ while cnt < self.x2NbENBs:
+ msg = " -- eNB: " + str(self.x2ENBBsIds[idx][cnt]) + " is connected to " + str(len(self.x2ENBConnectedUEs[idx][cnt])) + " UE(s)"
+ logging.debug(msg)
+ message += msg + '\n'
+ ueIdx = 0
+ while ueIdx < len(self.x2ENBConnectedUEs[idx][cnt]):
+ msg = " -- UE rnti: " + str(self.x2ENBConnectedUEs[idx][cnt][ueIdx])
+ logging.debug(msg)
+ message += msg + '\n'
+ ueIdx += 1
+ cnt += 1
+ return message
+
+ def Perform_X2_Handover(self):
+ html_queue = SimpleQueue()
+ fullMessage = ''
+ msg = 'Doing X2 Handover w/ option ' + self.x2_ho_options
+ logging.debug(msg)
+ fullMessage += msg + '\n'
+ if self.x2_ho_options == 'network':
+ if self.flexranCtrlInstalled and self.flexranCtrlStarted:
+ self.x2ENBBsIds = []
+ self.x2ENBConnectedUEs = []
+ self.x2ENBBsIds.append([])
+ self.x2ENBBsIds.append([])
+ self.x2ENBConnectedUEs.append([])
+ self.x2ENBConnectedUEs.append([])
+ fullMessage += self.X2_Status(0, self.testCase_id + '_pre_ho.json')
+
+ msg = "Activating the X2 Net control on each eNB"
+ logging.debug(msg)
+ fullMessage += msg + '\n'
+ eNB_cnt = self.x2NbENBs
+ cnt = 0
+ while cnt < eNB_cnt:
+ cmd = "curl -XPOST http://" + self.EPCIPAddress + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1"
+ logging.debug(cmd)
+ fullMessage += cmd + '\n'
+ subprocess.run(cmd, shell=True)
+ cnt += 1
+ # Waiting for the activation to be active
+ time.sleep(10)
+ msg = "Switching UE(s) from eNB to eNB"
+ logging.debug(msg)
+ fullMessage += msg + '\n'
+ cnt = 0
+ while cnt < eNB_cnt:
+ ueIdx = 0
+ while ueIdx < len(self.x2ENBConnectedUEs[0][cnt]):
+ cmd = "curl -XPOST http://" + self.EPCIPAddress + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1])
+ logging.debug(cmd)
+ fullMessage += cmd + '\n'
+ subprocess.run(cmd, shell=True)
+ ueIdx += 1
+ cnt += 1
+ time.sleep(10)
+ # check
+ logging.debug("Checking the Status after X2 Handover")
+ fullMessage += self.X2_Status(1, self.testCase_id + '_post_ho.json')
+ cnt = 0
+ x2Status = True
+ while cnt < eNB_cnt:
+ if len(self.x2ENBConnectedUEs[0][cnt]) == len(self.x2ENBConnectedUEs[1][cnt]):
+ x2Status = False
+ cnt += 1
+ if x2Status:
+ msg = "X2 Handover was successful"
+ logging.debug(msg)
+ fullMessage += msg + ''
+ html_queue.put(fullMessage)
+ self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
+ else:
+ msg = "X2 Handover FAILED"
+ logging.error(msg)
+ fullMessage += msg + ''
+ html_queue.put(fullMessage)
+ self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue)
+ else:
+ self.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', ALL_PROCESSES_OK)
+
def LogCollectBuild(self):
if (self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != ''):
IPAddress = self.eNBIPAddress
@@ -3099,7 +3462,6 @@ class SSHConnection():
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 ' + Password + ' | sudo -S rm -rf build_log_*', '\$', 5)
self.close()
def LogCollecteNB(self):
@@ -3276,46 +3638,46 @@ class SSHConnection():
self.htmlFile.write(' \n')
self.htmlFile.write(' \n')
self.htmlFile.write(' | GIT Repository | \n')
- self.htmlFile.write(' ' + self.eNBRepository + ' | \n')
+ self.htmlFile.write(' ' + self.ranRepository + ' | \n')
self.htmlFile.write('
\n')
self.htmlFile.write(' \n')
self.htmlFile.write(' | Job Trigger | \n')
- if (self.eNB_AllowMerge):
+ if (self.ranAllowMerge):
self.htmlFile.write(' Merge-Request | \n')
else:
self.htmlFile.write(' Push to Branch | \n')
self.htmlFile.write('
\n')
self.htmlFile.write(' \n')
- if (self.eNB_AllowMerge):
+ if (self.ranAllowMerge):
self.htmlFile.write(' | Source Branch | \n')
else:
self.htmlFile.write(' Branch | \n')
- self.htmlFile.write(' ' + self.eNBBranch + ' | \n')
+ self.htmlFile.write(' ' + self.ranBranch + ' | \n')
self.htmlFile.write('
\n')
self.htmlFile.write(' \n')
- if (self.eNB_AllowMerge):
+ if (self.ranAllowMerge):
self.htmlFile.write(' | Source Commit ID | \n')
else:
self.htmlFile.write(' Commit ID | \n')
- self.htmlFile.write(' ' + self.eNBCommitID + ' | \n')
+ self.htmlFile.write(' ' + self.ranCommitID + ' | \n')
self.htmlFile.write('
\n')
- if self.eNB_AllowMerge != '':
- commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.eNBCommitID, shell=True, universal_newlines=True)
+ if self.ranAllowMerge != '':
+ commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.ranCommitID, shell=True, universal_newlines=True)
commit_message = commit_message.strip()
self.htmlFile.write(' \n')
- if (self.eNB_AllowMerge):
+ if (self.ranAllowMerge):
self.htmlFile.write(' | Source Commit Message | \n')
else:
self.htmlFile.write(' Commit Message | \n')
self.htmlFile.write(' ' + commit_message + ' | \n')
self.htmlFile.write('
\n')
- if (self.eNB_AllowMerge):
+ if (self.ranAllowMerge):
self.htmlFile.write(' \n')
self.htmlFile.write(' | Target Branch | \n')
- if (self.eNBTargetBranch == ''):
+ if (self.ranTargetBranch == ''):
self.htmlFile.write(' develop | \n')
else:
- self.htmlFile.write(' ' + self.eNBTargetBranch + ' | \n')
+ self.htmlFile.write(' ' + self.ranTargetBranch + ' | \n')
self.htmlFile.write('
\n')
self.htmlFile.write(' \n')
@@ -3337,6 +3699,7 @@ class SSHConnection():
pillMsg = ' '
+ pillMsg += '__STATE_' + self.htmlTabNames[count] + '__'
pillMsg += self.htmlTabNames[count]
pillMsg += ' <\/span>/' test_results.html"
+ subprocess.run(cmd, shell=True)
self.htmlFooterCreated = False
def CreateHtmlFooter(self, passStatus):
@@ -3468,6 +3839,8 @@ class SSHConnection():
self.htmlFile.write(' KO - ' + machine + ' process faced Real Time issue(s) | \n')
elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE) or (processesStatus == OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE):
self.htmlFile.write(' OK? | \n')
+ elif (processesStatus == ENB_PROCESS_SLAVE_RRU_NOT_SYNCED):
+ self.htmlFile.write(' KO - ' + machine + ' Slave RRU could not synch | \n')
elif (processesStatus == OAI_UE_PROCESS_COULD_NOT_SYNC):
self.htmlFile.write(' KO - UE could not sync | \n')
elif (processesStatus == HSS_PROCESS_FAILED):
@@ -3563,12 +3936,12 @@ def Usage():
print(' InitiateHtml, FinalizeHtml')
print(' TerminateeNB, TerminateUE, TerminateHSS, TerminateMME, TerminateSPGW')
print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf')
+ print(' --eNBRepository=[eNB\'s Repository URL] or --ranRepository=[OAI RAN Repository URL]')
+ print(' --eNBBranch=[eNB\'s Branch Name] or --ranBranch=[OAI RAN Repository Branch')
+ print(' --eNBCommitID=[eNB\'s Commit Number] or --ranCommitID=[OAI RAN Repository Commit SHA-1')
+ print(' --eNB_AllowMerge=[eNB\'s Allow Merge Request (with target branch)] or --ranAllowMerge=true/false')
+ print(' --eNBTargetBranch=[eNB\'s Target Branch in case of a Merge Request] or --ranTargetBranch=[Target Branch]')
print(' --eNBIPAddress=[eNB\'s IP Address]')
- print(' --eNBRepository=[eNB\'s Repository URL]')
- print(' --eNBBranch=[eNB\'s Branch Name]')
- print(' --eNBCommitID=[eNB\'s Commit Number]')
- print(' --eNB_AllowMerge=[eNB\'s Allow Merge Request (with target branch)]')
- print(' --eNBTargetBranch=[eNB\'s Target Branch in case of a Merge Request]')
print(' --eNBUserName=[eNB\'s Login User Name]')
print(' --eNBPassword=[eNB\'s Login Password]')
print(' --eNBSourceCodePath=[eNB\'s Source Code Path]')
@@ -3584,7 +3957,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 != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' 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':
+ if action != 'Build_eNB' and action != 'WaitEndBuild_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 != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' 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' and action != 'Perform_X2_Handover':
logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action)
return False
return True
@@ -3592,17 +3965,46 @@ def CheckClassValidity(action,id):
def GetParametersFromXML(action):
if action == 'Build_eNB':
SSH.Build_eNB_args = test.findtext('Build_eNB_args')
+ SSH.eNB_instance = test.findtext('eNB_instance')
+ if (SSH.eNB_instance is None):
+ SSH.eNB_instance = '0'
+ SSH.eNB_serverId = test.findtext('eNB_serverId')
+ if (SSH.eNB_serverId is None):
+ SSH.eNB_serverId = '0'
+ xmlBgBuildField = test.findtext('backgroundBuild')
+ if (xmlBgBuildField is None):
+ SSH.backgroundBuild = False
+ else:
+ if re.match('true', xmlBgBuildField, re.IGNORECASE):
+ SSH.backgroundBuild = True
+ else:
+ SSH.backgroundBuild = False
+
+ if action == 'WaitEndBuild_eNB':
+ SSH.Build_eNB_args = test.findtext('Build_eNB_args')
+ SSH.eNB_instance = test.findtext('eNB_instance')
+ if (SSH.eNB_instance is None):
+ SSH.eNB_instance = '0'
+ SSH.eNB_serverId = test.findtext('eNB_serverId')
+ if (SSH.eNB_serverId is None):
+ SSH.eNB_serverId = '0'
if action == 'Initialize_eNB':
SSH.Initialize_eNB_args = test.findtext('Initialize_eNB_args')
SSH.eNB_instance = test.findtext('eNB_instance')
if (SSH.eNB_instance is None):
SSH.eNB_instance = '0'
+ SSH.eNB_serverId = test.findtext('eNB_serverId')
+ if (SSH.eNB_serverId is None):
+ SSH.eNB_serverId = '0'
if action == 'Terminate_eNB':
SSH.eNB_instance = test.findtext('eNB_instance')
if (SSH.eNB_instance is None):
SSH.eNB_instance = '0'
+ SSH.eNB_serverId = test.findtext('eNB_serverId')
+ if (SSH.eNB_serverId is None):
+ SSH.eNB_serverId = '0'
if action == 'Attach_UE':
nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
@@ -3654,6 +4056,18 @@ def GetParametersFromXML(action):
else:
SSH.idle_sleep_time = int(string_field)
+ if action == 'Perform_X2_Handover':
+ string_field = test.findtext('x2_ho_options')
+ if (string_field is None):
+ SSH.x2_ho_options = 'network'
+ else:
+ if string_field != 'network':
+ logging.error('ERROR: test-case has wrong option ' + string_field)
+ SSH.x2_ho_options = 'network'
+ else:
+ SSH.x2_ho_options = string_field
+
+
#check if given test is in list
#it is in list if one of the strings in 'list' is at the beginning of 'test'
def test_in_list(test, list):
@@ -3684,35 +4098,78 @@ while len(argvs) > 1:
elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE)
mode = matchReg.group(1)
- elif re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBIPAddress = matchReg.group(1)
- elif re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBRepository = matchReg.group(1)
- elif re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
+ elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE)
+ else:
+ matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE)
+ SSH.ranRepository = matchReg.group(1)
+ elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE)
+ else:
+ matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE)
doMerge = matchReg.group(1)
if ((doMerge == 'true') or (doMerge == 'True')):
- SSH.eNB_AllowMerge = True
- elif re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBBranch = matchReg.group(1)
- elif re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
- SSH.eNBCommitID = matchReg.group(1)
- elif re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
- SSH.eNBTargetBranch = matchReg.group(1)
- elif re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBUserName = matchReg.group(1)
- elif re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBPassword = matchReg.group(1)
- elif re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
- matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
- SSH.eNBSourceCodePath = matchReg.group(1)
+ SSH.ranAllowMerge = True
+ elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE)
+ else:
+ matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE)
+ SSH.ranBranch = matchReg.group(1)
+ elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE)
+ else:
+ matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE)
+ SSH.ranCommitID = matchReg.group(1)
+ elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE)
+ else:
+ matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE)
+ SSH.ranTargetBranch = matchReg.group(1)
+ elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNBIPAddress = matchReg.group(1)
+ elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB1IPAddress = matchReg.group(1)
+ elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB2IPAddress = matchReg.group(1)
+ elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNBUserName = matchReg.group(1)
+ elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB1UserName = matchReg.group(1)
+ elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB2UserName = matchReg.group(1)
+ elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNBPassword = matchReg.group(1)
+ elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB1Password = matchReg.group(1)
+ elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB2Password = matchReg.group(1)
+ elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+ if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNBSourceCodePath = matchReg.group(1)
+ elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB1SourceCodePath = matchReg.group(1)
+ elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
+ matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
+ SSH.eNB2SourceCodePath = matchReg.group(1)
elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE)
SSH.EPCIPAddress = matchReg.group(1)
@@ -3772,6 +4229,9 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE):
if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '':
Usage()
sys.exit('Insufficient Parameter')
+ SSH.eNB_serverId = '0'
+ SSH.eNB_instance = '0'
+ SSH.eNBSourceCodePath = '/tmp/'
SSH.TerminateeNB()
elif re.match('^TerminateUE$', mode, re.IGNORECASE):
if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''):
@@ -3864,15 +4324,15 @@ elif re.match('^FinalizeHtml$', mode, re.IGNORECASE):
SSH.CreateHtmlFooter(SSH.finalStatus)
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 == '':
+ if SSH.eNBIPAddress == '' or SSH.ranRepository == '' or SSH.ranBranch == '' 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 != ''):
+ if (SSH.EPCIPAddress != '') and (SSH.EPCIPAddress != 'none'):
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 == '':
+ if SSH.UEIPAddress == '' or SSH.ranRepository == '' or SSH.ranBranch == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '':
Usage()
sys.exit('UE: Insufficient Parameter')
@@ -3890,6 +4350,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
requested_tests=xmlRoot.findtext('TestCaseRequestedList',default='')
if (SSH.nbTestXMLfiles == 1):
SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0'))
+ SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0'))
+ repeatCount = xmlRoot.findtext('repeatCount',default='1')
+ SSH.repeatCounts.append(int(repeatCount))
all_tests=xmlRoot.findall('testCase')
exclusion_tests=exclusion_tests.split()
@@ -3915,7 +4378,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
else:
logging.debug('ERROR: requested test is invalidly formatted: ' + test)
sys.exit(1)
- SSH.CheckFlexranCtrlInstallation()
+ if (SSH.EPCIPAddress != '') and (SSH.EPCIPAddress != 'none'):
+ SSH.CheckFlexranCtrlInstallation()
#get the list of tests to be done
todo_tests=[]
@@ -3930,86 +4394,104 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
SSH.CreateHtmlTabHeader()
- for test_case_id in todo_tests:
- for test in all_tests:
- id = test.get('id')
- if test_case_id != id:
- continue
- SSH.testCase_id = id
- SSH.desc = test.findtext('desc')
- action = test.findtext('class')
- if (CheckClassValidity(action, id) == False):
- continue
- 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' or action == 'DataDisable_UE' or action == 'DataEnable_UE' or action == 'CheckStatusUE':
- if (SSH.ADBIPAddress != 'none'):
- terminate_ue_flag = False
- SSH.GetAllUEDevices(terminate_ue_flag)
- if action == 'Build_eNB':
- SSH.BuildeNB()
- elif action == 'Initialize_eNB':
- SSH.InitializeeNB()
- elif action == 'Terminate_eNB':
- SSH.TerminateeNB()
- elif action == 'Initialize_UE':
- SSH.InitializeUE()
- elif action == 'Terminate_UE':
- SSH.TerminateUE()
- elif action == 'Attach_UE':
- SSH.AttachUE()
- elif action == 'Detach_UE':
- SSH.DetachUE()
- elif action == 'DataDisable_UE':
- SSH.DataDisableUE()
- elif action == 'DataEnable_UE':
- SSH.DataEnableUE()
- elif action == 'CheckStatusUE':
- SSH.CheckStatusUE()
- 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':
- SSH.TerminateCatM()
- elif action == 'Attach_CatM_module':
- SSH.AttachCatM()
- elif action == 'Detach_CatM_module':
- SSH.TerminateCatM()
- elif action == 'Ping_CatM_module':
- SSH.PingCatM()
- elif action == 'Ping':
- SSH.Ping()
- elif action == 'Iperf':
- SSH.Iperf()
- elif action == 'Reboot_UE':
- SSH.RebootUE()
- elif action == 'Initialize_HSS':
- SSH.InitializeHSS()
- elif action == 'Terminate_HSS':
- SSH.TerminateHSS()
- elif action == 'Initialize_MME':
- SSH.InitializeMME()
- elif action == 'Terminate_MME':
- SSH.TerminateMME()
- elif action == 'Initialize_SPGW':
- SSH.InitializeSPGW()
- elif action == 'Terminate_SPGW':
- SSH.TerminateSPGW()
- elif action == 'Initialize_FlexranCtrl':
- SSH.InitializeFlexranCtrl()
- elif action == 'Terminate_FlexranCtrl':
- SSH.TerminateFlexranCtrl()
- elif action == 'IdleSleep':
- SSH.IdleSleep()
- else:
- sys.exit('Invalid action')
-
- SSH.CreateHtmlTabFooter(True)
+ cnt = 0
+ SSH.prematureExit = True
+ while cnt < SSH.repeatCounts[0] and SSH.prematureExit:
+ SSH.prematureExit = False
+ for test_case_id in todo_tests:
+ for test in all_tests:
+ id = test.get('id')
+ if test_case_id != id:
+ continue
+ SSH.testCase_id = id
+ SSH.desc = test.findtext('desc')
+ action = test.findtext('class')
+ if (CheckClassValidity(action, id) == False):
+ continue
+ 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' or action == 'DataDisable_UE' or action == 'DataEnable_UE' or action == 'CheckStatusUE':
+ if (SSH.ADBIPAddress != 'none'):
+ terminate_ue_flag = False
+ SSH.GetAllUEDevices(terminate_ue_flag)
+ if action == 'Build_eNB':
+ SSH.BuildeNB()
+ elif action == 'WaitEndBuild_eNB':
+ SSH.WaitBuildeNBisFinished()
+ elif action == 'Initialize_eNB':
+ SSH.InitializeeNB()
+ elif action == 'Terminate_eNB':
+ SSH.TerminateeNB()
+ elif action == 'Initialize_UE':
+ SSH.InitializeUE()
+ elif action == 'Terminate_UE':
+ SSH.TerminateUE()
+ elif action == 'Attach_UE':
+ SSH.AttachUE()
+ elif action == 'Detach_UE':
+ SSH.DetachUE()
+ elif action == 'DataDisable_UE':
+ SSH.DataDisableUE()
+ elif action == 'DataEnable_UE':
+ SSH.DataEnableUE()
+ elif action == 'CheckStatusUE':
+ SSH.CheckStatusUE()
+ 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':
+ SSH.TerminateCatM()
+ elif action == 'Attach_CatM_module':
+ SSH.AttachCatM()
+ elif action == 'Detach_CatM_module':
+ SSH.TerminateCatM()
+ elif action == 'Ping_CatM_module':
+ SSH.PingCatM()
+ elif action == 'Ping':
+ SSH.Ping()
+ elif action == 'Iperf':
+ SSH.Iperf()
+ elif action == 'Reboot_UE':
+ SSH.RebootUE()
+ elif action == 'Initialize_HSS':
+ SSH.InitializeHSS()
+ elif action == 'Terminate_HSS':
+ SSH.TerminateHSS()
+ elif action == 'Initialize_MME':
+ SSH.InitializeMME()
+ elif action == 'Terminate_MME':
+ SSH.TerminateMME()
+ elif action == 'Initialize_SPGW':
+ SSH.InitializeSPGW()
+ elif action == 'Terminate_SPGW':
+ SSH.TerminateSPGW()
+ elif action == 'Initialize_FlexranCtrl':
+ SSH.InitializeFlexranCtrl()
+ elif action == 'Terminate_FlexranCtrl':
+ SSH.TerminateFlexranCtrl()
+ elif action == 'IdleSleep':
+ SSH.IdleSleep()
+ elif action == 'Perform_X2_Handover':
+ SSH.Perform_X2_Handover()
+ else:
+ sys.exit('Invalid action')
+ if SSH.prematureExit:
+ break
+ if SSH.prematureExit:
+ break
+ cnt += 1
+ if cnt == SSH.repeatCounts[0] and SSH.prematureExit:
+ logging.debug('Testsuite failed ' + str(cnt) + ' time(s)')
+ SSH.CreateHtmlTabFooter(False)
+ sys.exit('Failed Scenario')
+ else:
+ logging.info('Testsuite passed after ' + str(cnt) + ' time(s)')
+ SSH.CreateHtmlTabFooter(True)
else:
Usage()
sys.exit('Invalid mode')
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 06b56458d0..f2df1f7be0 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -1843,7 +1843,7 @@ function run_test_on_vm {
fi
fi
- if [ $S1_NOS1_CFG -eq 0 ]
+ if [ $S1_NOS1_CFG -eq 2 ]
then
get_enb_noS1_ip_addr $ENB_VM_CMDS $ENB_VM_IP_ADDR
echo "############################################################"
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
index 29c9a29c2d..a2e74c6de9 100644
--- 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
@@ -24,6 +24,7 @@
test-05-tm1-nos1-tunnel
Test-05MHz-TM1-noS1-tunnel
tasks
+ 2
030201 090109
030101 000001 090101 000002 040501 040502 000001 040601 040602 040641 040642 000001 090109 030201
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
index 2e6b9a0dc6..9f7546cab3 100644
--- 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
@@ -24,6 +24,7 @@
test-05-tm1-tunnel
Test-05MHz-TM1-tunnel
tasks
+ 2
030201 090109
030102 000001 090102 000002 040503 000001 040603 040604 040643 040644 000001 090109 030201
diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml
index a3f88307ec..9c98ba4a8e 100644
--- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml
@@ -25,6 +25,7 @@
test-05-tm2
Test-05MHz-TM2
tasks
+ 2
030201
040101
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 fd6aabcbbc..1ee223d1c7 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
@@ -34,7 +34,7 @@
Initialize_eNB
Initialize eNB (FDD/Band7/10MHz)
- -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
+ -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf --eNBs.[0].component_carriers.[0].drx_Config_present prRelease
diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1_cdrx.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1_cdrx.xml
new file mode 100644
index 0000000000..f62c31dd5a
--- /dev/null
+++ b/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1_cdrx.xml
@@ -0,0 +1,90 @@
+
+
+ test-10-cdrx-tm1
+ Test-10MHz-CDRX-TM1
+ tasks
+ 4
+
+ 030201
+ 040101
+ 030112 040302 040512 040612 040650 040401 040201 030201
+
+
+
+
+ Initialize_eNB
+ Initialize eNB (FDD/Band7/10MHz) with CDRX
+ -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf --eNBs.[0].component_carriers.[0].drx_Config_present prSetup
+
+
+
+ Terminate_eNB
+ Terminate eNB
+
+
+
+ Initialize_UE
+ Initialize UE
+
+
+
+ Terminate_UE
+ Terminate UE
+
+
+
+ Attach_UE
+ Attach UE
+ 1
+
+
+
+ Detach_UE
+ Detach UE
+
+
+
+ Ping
+ ping (10MHz - 20 sec)
+ -c 20
+ 5
+
+
+
+ Iperf
+ iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile)
+ -u -b 30M -t 30 -i 1
+ 50
+ balanced
+
+
+
+ Iperf
+ iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile)
+ -u -b 20M -t 30 -i 1 -R
+ 50
+ balanced
+
+
+
diff --git a/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml b/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml
index 4dadbbdcba..c2a48037ba 100644
--- a/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml
+++ b/ci-scripts/xml_files/f1_usrp210_band7_test_05mhz.xml
@@ -22,8 +22,9 @@
-->
test-f1-05
- Test-F1-CU/DU-05MHz
+ Test-F1-CU-DU-05MHz
tasks
+ 2
030201
040101
diff --git a/ci-scripts/xml_files/f1_usrp210_band7_test_10mhz.xml b/ci-scripts/xml_files/f1_usrp210_band7_test_10mhz.xml
index 115f3c648a..8d028df433 100644
--- a/ci-scripts/xml_files/f1_usrp210_band7_test_10mhz.xml
+++ b/ci-scripts/xml_files/f1_usrp210_band7_test_10mhz.xml
@@ -22,8 +22,9 @@
-->
test-f1-10
- Test-F1-CU/DU-10MHz
+ Test-F1-CU-DU-10MHz
tasks
+ 4
030201
040101
diff --git a/ci-scripts/xml_files/f1_usrp210_band7_test_20mhz.xml b/ci-scripts/xml_files/f1_usrp210_band7_test_20mhz.xml
index 790afe2a71..061b87294b 100644
--- a/ci-scripts/xml_files/f1_usrp210_band7_test_20mhz.xml
+++ b/ci-scripts/xml_files/f1_usrp210_band7_test_20mhz.xml
@@ -22,8 +22,9 @@
-->
test-f1-20
- Test-F1-CU/DU-20MHz
+ Test-F1-CU-DU-20MHz
tasks
+ 4
030201
040101
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 17ede3f830..15d641efeb 100644
--- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml
+++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml
@@ -24,6 +24,7 @@
test-20
Test-20MHz
tasks
+ 2
030201
040101
diff --git a/ci-scripts/xml_files/multi_rru_band38_build.xml b/ci-scripts/xml_files/multi_rru_band38_build.xml
new file mode 100644
index 0000000000..614ef394f3
--- /dev/null
+++ b/ci-scripts/xml_files/multi_rru_band38_build.xml
@@ -0,0 +1,84 @@
+
+
+ build-tab
+ Build
+ wrench
+
+ 010101 010102 010103
+ 000101 000102 000103
+
+
+
+
+ Build_eNB
+ Build RCC
+ -w USRP -c --eNB
+ 0
+ 0
+ True
+
+
+
+ WaitEndBuild_eNB
+ Wait for end of Build RCC
+ -w USRP -c --eNB
+ 0
+ 0
+
+
+
+ Build_eNB
+ Build Master RRU
+ -w USRP -c --eNB
+ 1
+ 1
+ True
+
+
+
+ WaitEndBuild_eNB
+ Wait for end of Build Master RRU
+ -w USRP -c --eNB
+ 1
+ 1
+
+
+
+ Build_eNB
+ Build Slave RRU
+ -w USRP -c --eNB
+ 2
+ 2
+ True
+
+
+
+ WaitEndBuild_eNB
+ Wait for end of Build Slave RRU
+ -w USRP -c --eNB
+ 2
+ 2
+
+
+
diff --git a/ci-scripts/xml_files/multi_rru_band38_full_termination.xml b/ci-scripts/xml_files/multi_rru_band38_full_termination.xml
new file mode 100644
index 0000000000..d63c73aec5
--- /dev/null
+++ b/ci-scripts/xml_files/multi_rru_band38_full_termination.xml
@@ -0,0 +1,53 @@
+
+
+ test-full-termintation
+ Test-RCC-RRUs-Termination
+ off
+
+ 030211 030212 030213
+
+
+
+
+ Terminate_eNB
+ Terminate RCC
+ 0
+ 0
+
+
+
+ Terminate_eNB
+ Terminate Master RRU
+ 1
+ 1
+
+
+
+ Terminate_eNB
+ Terminate Slave RRU
+ 2
+ 2
+
+
+
diff --git a/ci-scripts/xml_files/multi_rru_band38_test_10mhz_tm1.xml b/ci-scripts/xml_files/multi_rru_band38_test_10mhz_tm1.xml
new file mode 100644
index 0000000000..7658f8a0e5
--- /dev/null
+++ b/ci-scripts/xml_files/multi_rru_band38_test_10mhz_tm1.xml
@@ -0,0 +1,87 @@
+
+
+ test-multi-rru-10
+ Test-Multi-RRU-10MHz
+ tasks
+ 4
+
+ 030211 030212 030213
+ 030111 030112 030113
+ 000001
+ 030211 030212 030213
+
+
+
+
+ IdleSleep
+ Sleep
+ 60
+
+
+
+ Initialize_eNB
+ Initialize RCC (TDD/Band38/10MHz)
+ -O ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf --noS1
+ 0
+ 0
+
+
+
+ Initialize_eNB
+ Initialize Master RRU (TDD/Band38/10MHz)
+ -O ci-scripts/conf_files/rru.band38.tm1.master.conf --noS1
+ 1
+ 1
+
+
+
+ Initialize_eNB
+ Initialize Slave RRU (TDD/Band38/10MHz)
+ -O ci-scripts/conf_files/rru.band38.tm1.slave.conf --noS1
+ 2
+ 2
+
+
+
+ Terminate_eNB
+ Terminate RCC
+ 0
+ 0
+
+
+
+ Terminate_eNB
+ Terminate Master RRU
+ 1
+ 1
+
+
+
+ Terminate_eNB
+ Terminate Slave RRU
+ 2
+ 2
+
+
+
diff --git a/ci-scripts/xml_files/ue_band20_test_10mhz_orange.xml b/ci-scripts/xml_files/ue_band20_test_10mhz_orange.xml
index 19d08d5119..d3e36f603e 100644
--- a/ci-scripts/xml_files/ue_band20_test_10mhz_orange.xml
+++ b/ci-scripts/xml_files/ue_band20_test_10mhz_orange.xml
@@ -24,6 +24,7 @@
test-10mhz-orange
Test-10Mhz-Orange
tasks
+ 4
090109
090110 000001 090109
diff --git a/ci-scripts/xml_files/ue_band20_test_10mhz_sfr.xml b/ci-scripts/xml_files/ue_band20_test_10mhz_sfr.xml
index 50912d3458..3f6441e06e 100644
--- a/ci-scripts/xml_files/ue_band20_test_10mhz_sfr.xml
+++ b/ci-scripts/xml_files/ue_band20_test_10mhz_sfr.xml
@@ -24,6 +24,7 @@
test-10mHz-sfr
Test-10MHz-SFR
tasks
+ 4
090109
090111 000001 090109
diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml
new file mode 100644
index 0000000000..0d2a122537
--- /dev/null
+++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_build.xml
@@ -0,0 +1,66 @@
+
+
+ build-tab
+ Build
+ wrench
+
+ 010101
+ 010102
+ 050101 060101 070101
+
+
+
+
+
+ Build_eNB
+ Build Master eNB (USRP)
+ -w USRP -c --eNB
+ 0
+ 0
+
+
+
+ Build_eNB
+ Build Slave eNB (USRP)
+ -w USRP -c --eNB
+ 1
+ 1
+
+
+
+ Initialize_HSS
+ Initialize HSS
+
+
+
+ Initialize_MME
+ Initialize MME
+
+
+
+ Initialize_SPGW
+ Initialize SPGW
+
+
+
diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_epc_closure.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_epc_closure.xml
new file mode 100644
index 0000000000..07fb6951f8
--- /dev/null
+++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_epc_closure.xml
@@ -0,0 +1,47 @@
+
+
+ epc-closure
+ EPC-Closure
+ log-out
+
+ 050201 060201 070201
+
+
+
+
+ Terminate_HSS
+ Terminate HSS
+
+
+
+ Terminate_MME
+ Terminate MME
+
+
+
+ Terminate_SPGW
+ Terminate SPGW
+
+
+
diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml
new file mode 100644
index 0000000000..91280462b7
--- /dev/null
+++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_full_terminate.xml
@@ -0,0 +1,46 @@
+
+
+ test-x2-ho-full-end
+ Test-X2-HO-Full-Terminate
+ tasks
+
+ 030201 030202
+
+
+
+
+ Terminate_eNB
+ Terminate Master eNB
+ 0
+ 0
+
+
+
+ Terminate_eNB
+ Terminate Slave eNB
+ 1
+ 1
+
+
+
diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml
new file mode 100644
index 0000000000..c43be75a87
--- /dev/null
+++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml
@@ -0,0 +1,191 @@
+
+
+ test-x2-ho-05-tm1
+ Test-X2-HO-FDD-05MHz-TM1
+ tasks
+ 2
+
+ 030201 030202
+ 040101
+ 050102
+ 030101 000002 030102 040301 040501 050401 000002 040502 050402 000002 040503 040401 040201 030201 030202
+ 050202
+
+
+
+
+ IdleSleep
+ Waiting for 60 seconds
+ 60
+
+
+
+ IdleSleep
+ Waiting for 10 seconds
+ 10
+
+
+
+ Initialize_FlexranCtrl
+ Starting Flexran Controller
+
+
+
+ Terminate_FlexranCtrl
+ Stopping Flexran Controller
+
+
+
+ Initialize_eNB
+ Initialize Master eNB (FDD/Band7/5MHz)
+ -O ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf
+ 0
+ 0
+
+
+
+ Initialize_eNB
+ Initialize Slave eNB (FDD/Band7/5MHz)
+ -O ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf
+ 1
+ 1
+
+
+
+ Terminate_eNB
+ Terminate Master eNB
+ 0
+ 0
+
+
+
+ Terminate_eNB
+ Terminate Slave eNB
+ 1
+ 1
+
+
+
+ Initialize_UE
+ Initialize UE
+
+
+
+ Terminate_UE
+ Terminate UE
+
+
+
+ Attach_UE
+ Attach UE
+
+
+
+ Detach_UE
+ Detach UE
+
+
+
+ Ping
+ ping (5MHz - 20 sec)
+ -c 20
+ 5
+
+
+
+ Ping
+ ping (5MHz - 20 sec)
+ -c 20
+ 5
+
+
+
+ Ping
+ ping (5MHz - 20 sec)
+ -c 20
+ 5
+
+
+
+ Iperf
+ iperf (5MHz - DL/8Mbps/UDP)(30 sec)
+ -u -b 8M -t 30 -i 1
+ 50
+ single-ue
+
+
+
+ Iperf
+ iperf (5MHz - DL/8Mbps/UDP)(30 sec)
+ -u -b 8M -t 30 -i 1
+ 50
+ single-ue
+
+
+
+ Iperf
+ iperf (5MHz - DL/8Mbps/UDP)(30 sec)
+ -u -b 8M -t 30 -i 1
+ 50
+ single-ue
+
+
+
+ Iperf
+ iperf (5MHz - UL/5Mbps/UDP)(30 sec)
+ -u -b 5M -t 30 -i 1 -R
+ 50
+ single-ue
+
+
+
+ Iperf
+ iperf (5MHz - UL/5Mbps/UDP)(30 sec)
+ -u -b 5M -t 30 -i 1 -R
+ 50
+ single-ue
+
+
+
+ Iperf
+ iperf (5MHz - UL/5Mbps/UDP)(30 sec)
+ -u -b 5M -t 30 -i 1 -R
+ 50
+ single-ue
+
+
+
+ Perform_X2_Handover
+ Doing a Flexran-Controlled X2 Handover
+ network
+
+
+
+ Perform_X2_Handover
+ Doing a Flexran-Controlled X2 Handover
+ network
+
+
+
diff --git a/cmake_targets/build_ue b/cmake_targets/build_ue
deleted file mode 100755
index 9d9ca839d1..0000000000
--- a/cmake_targets/build_ue
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-#sudo ./build_oai -c -C -I --install-optional-packages --install-system-files --UE -w USRP -V
-#sudo ./build_oai -c -C -I --install-optional-packages --UE -w USRP -V
-#sudo ./build_oai -c -C --UE -w USRP -V
-sudo ./build_oai -c -C --UE -w USRP
-#sudo ./build_oai -c -C --UE -w USRP --build-eclipse
diff --git a/cmake_targets/lte_noS1_build_oai/CMakeLists.template b/cmake_targets/lte_noS1_build_oai/CMakeLists.template
deleted file mode 100644
index 95216b139e..0000000000
--- a/cmake_targets/lte_noS1_build_oai/CMakeLists.template
+++ /dev/null
@@ -1,10 +0,0 @@
-set(ENABLE_ITTI True)
-set(ENABLE_USE_MME False)
-set(PDCP_USE_NETLINK True)
-set(LINK_ENB_PDCP_TO_IP_DRIVER True)
-set(LINK_ENB_PDCP_TO_GTPV1U False)
-set(PDCP_USE_NETLINK_QUEUES False)
-set(LINUX True)
-set(SECU False)
-set(NAS_UE False)
-
diff --git a/cmake_targets/oaisim_build_oai/CMakeLists.template b/cmake_targets/oaisim_build_oai/CMakeLists.template
deleted file mode 100644
index cffbddc93c..0000000000
--- a/cmake_targets/oaisim_build_oai/CMakeLists.template
+++ /dev/null
@@ -1,59 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-set ( CMAKE_BUILD_TYPE "RelWithDebInfo" )
-set ( DEBUG_OMG False )
-set ( DISABLE_XER_PRINT False )
-set ( DRIVER2013 True )
-set ( ENABLE_ITTI True )
-set ( ENABLE_NAS_UE_LOGGING True )
-set ( ENABLE_NEW_MULTICAST True )
-set ( ENABLE_RAL False )
-set ( ENABLE_STANDALONE_EPC False)
-set ( ENABLE_USE_CPU_EXECUTION_TIME True )
-set ( ENABLE_USE_MME True )
-set ( ENABLE_USE_RAW_SOCKET_FOR_SGI True)
-set ( ENABLE_VCD_FIFO False )
-set ( ENB_MODE True )
-set ( EXMIMO_IOT True )
-set ( JUMBO_FRAME True )
-set ( LARGE_SCALE False )
-set ( LINK_ENB_PDCP_TO_GTPV1U True)
-set ( LINUX_LIST False )
-set ( LINUX True )
-set ( LOCALIZATION False )
-set ( LOG_NO_THREAD True )
-set ( DEADLINE_SCHEDULER False )
-set ( MAC_CONTEXT 1 )
-set ( MAX_NUM_CCs 1 )
-set ( MESSAGE_CHART_GENERATOR False)
-set ( MSG_PRINT False )
-set ( MU_RECEIVER False )
-set ( NAS_ADDRESS_FIX False )
-set ( NAS_BUILT_IN_UE True)
-set ( NAS_MME False )
-set ( NAS_UE True )
-set ( NB_ANTENNAS_RX "2" )
-set ( NB_ANTENNAS_TX "2" )
-set ( NO_RRM True )
-set ( OAISIM True )
-set ( OAI_NW_DRIVER_TYPE_ETHERNET False )
-set ( OAI_NW_DRIVER_USE_NETLINK True )
-set ( OPENAIR2 True )
-set ( OPENAIR_LTE True )
-set ( PACKAGE_NAME "oaisim" )
-set ( PDCP_USE_NETLINK True )
-set ( PDCP_MSG_PRINT False )
-set ( PHY_CONTEXT False )
-set ( PHY_EMUL False )
-set ( PHYSIM True )
-set ( RF_BOARD "False" )
-set ( RLC_STOP_ON_LOST_PDU False )
-set ( RRC_ASN1_VERSION "Rel10" )
-set ( RRC_DEFAULT_RAB_IS_AM True)
-set ( RRC_MSG_PRINT False )
-set ( SECU False )
-set ( SMBV False )
-set ( TEST_OMG False )
-set ( USE_3GPP_ADDR_AS_LINK_ADDR False )
-set ( USE_MME "R10" )
-set ( XER_PRINT False )
diff --git a/cmake_targets/oaisim_mme_build_oai/CMakeLists.template b/cmake_targets/oaisim_mme_build_oai/CMakeLists.template
deleted file mode 100644
index eac29006da..0000000000
--- a/cmake_targets/oaisim_mme_build_oai/CMakeLists.template
+++ /dev/null
@@ -1,61 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-set ( CMAKE_BUILD_TYPE "RelWithDebInfo" )
-set ( DEBUG_OMG False )
-set ( DISABLE_XER_PRINT False )
-set ( DRIVER2013 False )
-set ( ENABLE_ITTI True )
-set ( ENABLE_NAS_UE_LOGGING False )
-set ( ENABLE_NEW_MULTICAST False )
-set ( ENABLE_RAL False )
-set ( ENABLE_STANDALONE_EPC False )
-set ( ENABLE_USE_CPU_EXECUTION_TIME False )
-set ( ENABLE_USE_MME False )
-set ( ENABLE_USE_RAW_SOCKET_FOR_SGI True)
-set ( ENABLE_VCD_FIFO False )
-set ( ENB_MODE False )
-set ( EPC_BUILD True )
-set ( EXMIMO_IOT False )
-set ( JUMBO_FRAME False )
-set ( LARGE_SCALE False )
-set ( LINK_ENB_PDCP_TO_GTPV1U True)
-set ( LINUX_LIST False )
-set ( LINUX False )
-set ( LOCALIZATION False )
-set ( LOG_NO_THREAD False )
-set ( DEADLINE_SCHEDULER False )
-set ( MAC_CONTEXT 1 )
-set ( MAX_NUM_CCs 1 )
-set ( MSG_PRINT False )
-set ( MU_RECEIVER False )
-set ( NAS_ADDRESS_FIX False )
-set ( NAS_BUILT_IN_EPC True )
-set ( NAS_MME True )
-set ( NAS_NETLINK False )
-set ( NAS_UE False )
-set ( NB_ANTENNAS_RX "2" )
-set ( NB_ANTENNAS_TX "2" )
-set ( NO_RRM False )
-set ( OAISIM False )
-set ( OAI_NW_DRIVER_TYPE_ETHERNET False )
-set ( OAI_NW_DRIVER_USE_NETLINK False )
-set ( OPENAIR2 False )
-set ( OPENAIR_LTE False )
-set ( PACKAGE_NAME "EPC" )
-set ( PDCP_MSG_PRINT False )
-set ( PHY_CONTEXT False )
-set ( PHY_EMUL False )
-set ( PHYSIM False )
-set ( RF_BOARD "False" )
-set ( RRC_ASN1_VERSION "Rel10" )
-set ( RLC_STOP_ON_LOST_PDU False )
-set ( RRC_MSG_PRINT False )
-set ( SECU False )
-set ( SMBV False )
-set ( TEST_OMG False )
-set ( UPDATE_RELEASE_9 True)
-set ( UPDATE_RELEASE_10 True)
-set ( USE_3GPP_ADDR_AS_LINK_ADDR False )
-set ( USE_MME "R10" )
-set ( XER_PRINT False )
-set ( XFORMS False )
diff --git a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template b/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template
deleted file mode 100644
index 343e928090..0000000000
--- a/cmake_targets/oaisim_noS1_build_oai/CMakeLists.template
+++ /dev/null
@@ -1,62 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-set ( DEBUG_OMG False )
-set ( DISABLE_XER_PRINT False )
-set ( DRIVER2013 True )
-set ( ENABLE_ITTI True )
-set ( ENABLE_NAS_UE_LOGGING False )
-set ( ENABLE_NEW_MULTICAST True )
-set ( ENABLE_RAL False )
-set ( ENABLE_STANDALONE_EPC False)
-set ( ENABLE_USE_CPU_EXECUTION_TIME True )
-set ( ENABLE_USE_MME False )
-set ( ENABLE_USE_RAW_SOCKET_FOR_SGI False)
-set ( ENABLE_VCD_FIFO False )
-set ( ENB_MODE True )
-set ( EXMIMO_IOT True )
-set ( JUMBO_FRAME True )
-set ( LARGE_SCALE False )
-set ( LINK_ENB_PDCP_TO_GTPV1U False)
-set ( LINUX_LIST False )
-set ( LINUX True )
-set ( LOCALIZATION False )
-set ( LOG_NO_THREAD 1 )
-set ( DEADLINE_SCHEDULER False )
-set ( MAC_CONTEXT 1 )
-set ( MAX_NUM_CCs 1 )
-set ( MESSAGE_CHART_GENERATOR False )
-set ( MESSAGE_CHART_GENERATOR_RLC_MAC False )
-set ( MESSAGE_CHART_GENERATOR_PHY False )
-set ( MSG_PRINT False )
-set ( MU_RECEIVER False )
-set ( NAS_ADDRESS_FIX False )
-set ( NAS_BUILT_IN_UE False)
-set ( NAS_MME False )
-set ( NAS_UE False )
-set ( NB_ANTENNAS_RX "2" )
-set ( NB_ANTENNAS_TX "2" )
-set ( NO_RRM True )
-set ( OAISIM True )
-set ( OAI_NW_DRIVER_TYPE_ETHERNET False )
-set ( OAI_NW_DRIVER_USE_NETLINK True )
-set ( OPENAIR2 True )
-set ( OPENAIR_LTE True )
-set ( PACKAGE_NAME "oaisim" )
-set ( PDCP_USE_NETLINK True )
-set ( PDCP_MSG_PRINT False )
-set ( PHY_CONTEXT False )
-set ( PHY_EMUL False )
-set ( PHYSIM True )
-set ( RF_BOARD "False" )
-set ( RRC_ASN1_VERSION "Rel10" )
-set ( RLC_STOP_ON_LOST_PDU False )
-set ( RRC_MSG_PRINT False )
-set ( SECU False )
-set ( SMBV False )
-set ( TEST_OMG False )
-set ( USE_3GPP_ADDR_AS_LINK_ADDR False )
-set ( USE_MME "R10" )
-set ( XER_PRINT False )
-set ( DEBUG_PHY False )
-set ( DEBUG_PHY_PROC False)
-set ( DEBUG_DLSCH False)
diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c
index 87150650db..857a83deab 100644
--- a/common/utils/LOG/log.c
+++ b/common/utils/LOG/log.c
@@ -45,7 +45,19 @@
#include "common/config/config_userapi.h"
// main log variables
-
+log_mem_cnt_t log_mem_d[2];
+int log_mem_flag=0;
+int log_mem_multi=1;
+volatile int log_mem_side=0;
+pthread_mutex_t log_mem_lock;
+pthread_cond_t log_mem_notify;
+pthread_t log_mem_thread;
+int log_mem_file_cnt=0;
+volatile int log_mem_write_flag=0;
+volatile int log_mem_write_side=0;
+char __log_mem_filename[1024]={0};
+char * log_mem_filename = &__log_mem_filename[0];
+char logmem_filename[1024] = {0};
mapping log_level_names[] = {
@@ -456,15 +468,23 @@ 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);
+ if (log_mem_flag == 1) {
+ log_output_memory(file,func,line,comp,level, format,args);
+ } else {
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];
+ if (log_mem_flag == 1) {
+ log_output_memory(file,func,line,comp,level, format,args);
+ } else {
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, ... ) {
@@ -646,6 +666,265 @@ void logClean (void) {
}
}
+extern int oai_exit;
+void flush_mem_to_file(void)
+{
+ int fp;
+ char f_name[1024];
+ struct timespec slp_tm;
+ slp_tm.tv_sec = 0;
+ slp_tm.tv_nsec = 10000;
+
+ pthread_setname_np( pthread_self(), "flush_mem_to_file");
+
+ while (!oai_exit) {
+ pthread_mutex_lock(&log_mem_lock);
+ log_mem_write_flag=0;
+ pthread_cond_wait(&log_mem_notify, &log_mem_lock);
+ log_mem_write_flag=1;
+ pthread_mutex_unlock(&log_mem_lock);
+ // write!
+ if(log_mem_d[log_mem_write_side].enable_flag==0){
+ if(log_mem_file_cnt>5){
+ log_mem_file_cnt=5;
+ printf("log over write!!!\n");
+ }
+ snprintf(f_name,1024, "%s_%d.log",log_mem_filename,log_mem_file_cnt);
+ fp=open(f_name, O_WRONLY | O_CREAT, 0666);
+ int ret = write(fp, log_mem_d[log_mem_write_side].buf_p, log_mem_d[log_mem_write_side].buf_index);
+ if ( ret < 0) {
+ fprintf(stderr,"{LOG} %s %d Couldn't write in %s \n",__FILE__,__LINE__,f_name);
+ exit(EXIT_FAILURE);
+ }
+ close(fp);
+ log_mem_file_cnt++;
+ log_mem_d[log_mem_write_side].buf_index=0;
+ log_mem_d[log_mem_write_side].enable_flag=1;
+ }else{
+ printf("If you'd like to write log, you should set enable flag to 0!!!\n");
+ nanosleep(&slp_tm,NULL);
+ }
+ }
+}
+
+char logmem_log_level[NUM_LOG_LEVEL]={'E','W','I','D','T'};
+
+void log_output_memory(const char *file, const 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];
+
+ //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD, VCD_FUNCTION_IN);
+
+ // make sure that for log trace the extra info is only printed once, reset when the level changes
+ if (level == OAILOG_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 & 0x001) || (c->flag & 0x001) ) {
+ 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 & 0x004) || (c->flag & 0x004) ) {
+ 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 ( (level >= OAILOG_ERR) && (level <= OAILOG_TRACE) ) {
+ len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%c]",
+ logmem_log_level[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;
+
+ struct timeval gettime;
+ gettimeofday(&gettime,NULL);
+ len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "[%ld.%06ld]", gettime.tv_sec, gettime.tv_usec);
+ if (len > MAX_LOG_TOTAL) len = MAX_LOG_TOTAL;
+*/
+ if ( (g_log->flag & FLAG_NOCOLOR) || (c->flag & FLAG_NOCOLOR) ) {
+ len += snprintf(&log_buffer[len], MAX_LOG_TOTAL - len, "%s",
+ log_level_highlight_end[level]);
+ 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;
+ }
+
+ //va_end(args);
+
+ // OAI printf compatibility
+ if(log_mem_flag==1){
+ if(log_mem_d[log_mem_side].enable_flag==1){
+ int temp_index;
+ temp_index=log_mem_d[log_mem_side].buf_index;
+ if(temp_index+len+1 < LOG_MEM_SIZE){
+ log_mem_d[log_mem_side].buf_index+=len;
+ memcpy(&log_mem_d[log_mem_side].buf_p[temp_index],log_buffer,len);
+ }else{
+ log_mem_d[log_mem_side].enable_flag=0;
+ if(log_mem_d[1-log_mem_side].enable_flag==1){
+ temp_index=log_mem_d[1-log_mem_side].buf_index;
+ if(temp_index+len+1 < LOG_MEM_SIZE){
+ log_mem_d[1-log_mem_side].buf_index+=len;
+ log_mem_side=1-log_mem_side;
+ memcpy(&log_mem_d[log_mem_side].buf_p[temp_index],log_buffer,len);
+ /* write down !*/
+ if (pthread_mutex_lock(&log_mem_lock) != 0) {
+ return;
+ }
+ if(log_mem_write_flag==0){
+ log_mem_write_side=1-log_mem_side;
+ if(pthread_cond_signal(&log_mem_notify) != 0) {
+ }
+ }
+ if(pthread_mutex_unlock(&log_mem_lock) != 0) {
+ return;
+ }
+ }else{
+ log_mem_d[1-log_mem_side].enable_flag=0;
+ }
+ }
+ }
+ }
+ }else{
+ fwrite(log_buffer, len, 1, stdout);
+ }
+}
+
+int logInit_log_mem (void)
+{
+ if(log_mem_flag==1){
+ if(log_mem_multi==1){
+ printf("log-mem multi!!!\n");
+ log_mem_d[0].buf_p = malloc(LOG_MEM_SIZE);
+ log_mem_d[0].buf_index=0;
+ log_mem_d[0].enable_flag=1;
+ log_mem_d[1].buf_p = malloc(LOG_MEM_SIZE);
+ log_mem_d[1].buf_index=0;
+ log_mem_d[1].enable_flag=1;
+ log_mem_side=0;
+ if ((pthread_mutex_init (&log_mem_lock, NULL) != 0)
+ || (pthread_cond_init (&log_mem_notify, NULL) != 0)) {
+ log_mem_d[1].enable_flag=0;
+ return -1;
+ }
+ pthread_create(&log_mem_thread, NULL, (void *(*)(void *))flush_mem_to_file, (void*)NULL);
+ }else{
+ printf("log-mem single!!!\n");
+ log_mem_d[0].buf_p = malloc(LOG_MEM_SIZE);
+ log_mem_d[0].buf_index=0;
+ log_mem_d[0].enable_flag=1;
+ log_mem_d[1].enable_flag=0;
+ log_mem_side=0;
+ }
+ }else{
+ log_mem_d[0].buf_p=NULL;
+ log_mem_d[1].buf_p=NULL;
+ log_mem_d[0].enable_flag=0;
+ log_mem_d[1].enable_flag=0;
+ }
+
+ printf("log init done\n");
+
+ return 0;
+}
+
+void close_log_mem(void){
+ int fp;
+ char f_name[1024];
+
+ if(log_mem_flag==1){
+ log_mem_d[0].enable_flag=0;
+ log_mem_d[1].enable_flag=0;
+ usleep(10); // wait for log writing
+ while(log_mem_write_flag==1){
+ usleep(100);
+ }
+ if(log_mem_multi==1){
+ snprintf(f_name,1024, "%s_%d.log",log_mem_filename,log_mem_file_cnt);
+ fp=open(f_name, O_WRONLY | O_CREAT, 0666);
+ int ret = write(fp, log_mem_d[0].buf_p, log_mem_d[0].buf_index);
+ if ( ret < 0) {
+ fprintf(stderr,"{LOG} %s %d Couldn't write in %s \n",__FILE__,__LINE__,f_name);
+ exit(EXIT_FAILURE);
+ }
+ close(fp);
+ free(log_mem_d[0].buf_p);
+
+ snprintf(f_name,1024, "%s_%d.log",log_mem_filename,log_mem_file_cnt);
+ fp=open(f_name, O_WRONLY | O_CREAT, 0666);
+ ret = write(fp, log_mem_d[1].buf_p, log_mem_d[1].buf_index);
+ if ( ret < 0) {
+ fprintf(stderr,"{LOG} %s %d Couldn't write in %s \n",__FILE__,__LINE__,f_name);
+ exit(EXIT_FAILURE);
+ }
+ close(fp);
+ free(log_mem_d[1].buf_p);
+ }else{
+ fp=open(log_mem_filename, O_WRONLY | O_CREAT, 0666);
+ int ret = write(fp, log_mem_d[0].buf_p, log_mem_d[0].buf_index);
+ if ( ret < 0) {
+ fprintf(stderr,"{LOG} %s %d Couldn't write in %s \n",__FILE__,__LINE__,log_mem_filename);
+ exit(EXIT_FAILURE);
+ }
+ close(fp);
+ free(log_mem_d[0].buf_p);
+ }
+ }
+ }
#ifdef LOG_TEST
diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h
index 1c413d580e..be7db5470e 100644
--- a/common/utils/LOG/log.h
+++ b/common/utils/LOG/log.h
@@ -118,6 +118,8 @@ extern "C" {
#define FLAG_NOCOLOR 0x0001 /*!< \brief use colors in log messages, depending on level */
#define FLAG_THREAD 0x0008 /*!< \brief display thread name in log messages */
#define FLAG_LEVEL 0x0010 /*!< \brief display log level in log messages */
+#define FLAG_FUNCT 0x0020
+#define FLAG_FILE_LINE 0x0040
#define FLAG_TIME 0x0100
#define FLAG_INITIALIZED 0x8000
@@ -307,6 +309,19 @@ int is_newline( char *str, int size);
int register_log_component(char *name, char *fext, int compidx);
+#define LOG_MEM_SIZE 100*1024*1024
+#define LOG_MEM_FILE "./logmem.log"
+void flush_mem_to_file(void);
+void log_output_memory(const char *file, const char *func, int line, int comp, int level, const char* format,va_list args);
+int logInit_log_mem(void);
+void close_log_mem(void);
+
+typedef struct {
+ char* buf_p;
+ int buf_index;
+ int enable_flag;
+} log_mem_cnt_t;
+
/* @}*/
/*!\fn int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, char format);
diff --git a/common/utils/LOG/log_extern.h b/common/utils/LOG/log_extern.h
index 3c93d517ca..f6205889dc 100644
--- a/common/utils/LOG/log_extern.h
+++ b/common/utils/LOG/log_extern.h
@@ -27,4 +27,6 @@ extern log_t *g_log;
extern mapping log_level_names[];
extern mapping log_options[];
extern mapping log_maskmap[];
-
+extern int log_mem_flag;
+extern char * log_mem_filename;
+extern char logmem_filename[1024];
diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c
index 8720efd8c0..c391a99786 100644
--- a/common/utils/T/tracer/macpdu2wireshark.c
+++ b/common/utils/T/tracer/macpdu2wireshark.c
@@ -52,6 +52,7 @@ typedef struct {
int max_mib;
int max_sib;
int live;
+ int no_bind;
/* runtime vars */
int cur_mib;
int cur_sib;
@@ -264,9 +265,11 @@ void *receiver(void *_d) {
abort();
}
- if (bind(s, (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)) == -1) {
- perror("bind");
- abort();
+ if (d->no_bind == 0) {
+ if (bind(s, (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)) == -1) {
+ perror("bind");
+ abort();
+ }
}
while (1) {
@@ -290,6 +293,7 @@ void usage(void) {
" -live run live\n"
" -live-ip tracee's IP address (default %s)\n"
" -live-port tracee's port (default %d)\n"
+ " -no-bind don't bind to IP address (for remote logging)\n"
"-i and -live are mutually exclusive options. One of them must be provided\n"
"but not both.\n",
DEFAULT_IP,
@@ -318,78 +322,18 @@ 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], "-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; }
+ if (!strcmp(v[i], "-no-bind")) { d.no_bind = 1; continue; }
usage();
}
diff --git a/common/utils/itti_analyzer/filters.xml b/common/utils/itti_analyzer/filters.xml
index e4a0e627d5..7305a2294c 100644
--- a/common/utils/itti_analyzer/filters.xml
+++ b/common/utils/itti_analyzer/filters.xml
@@ -91,6 +91,8 @@
+
+
@@ -114,6 +116,8 @@
+
+
diff --git a/common/utils/itti_analyzer/filters_ue_enb.xml b/common/utils/itti_analyzer/filters_ue_enb.xml
index 38ed00ceae..77859d20b6 100644
--- a/common/utils/itti_analyzer/filters_ue_enb.xml
+++ b/common/utils/itti_analyzer/filters_ue_enb.xml
@@ -130,6 +130,8 @@
+
+
@@ -153,6 +155,8 @@
+
+
diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h
index 159265c6a8..956d90072d 100644
--- a/common/utils/ocp_itti/intertask_interface.h
+++ b/common/utils/ocp_itti/intertask_interface.h
@@ -283,6 +283,8 @@ typedef struct {
TASK_DEF(TASK_RLC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_PDCP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
+ TASK_DEF(TASK_DATA_FORWARDING, TASK_PRIORITY_MED, 200, NULL, NULL) \
+ TASK_DEF(TASK_END_MARKER, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL)\
TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200, NULL, NULL) \
diff --git a/common/utils/system.c b/common/utils/system.c
index dcec681e2d..31c1035129 100644
--- a/common/utils/system.c
+++ b/common/utils/system.c
@@ -28,13 +28,23 @@
* separate process solves this problem.
*/
+#define _GNU_SOURCE
#include "system.h"
#include
#include
#include
#include
#include
-
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#define MAX_COMMAND 4096
static int command_pipe_read;
@@ -50,37 +60,37 @@ static int module_initialized = 0;
/* util functions */
/********************************************************************/
-static void lock_system(void)
-{
+static void lock_system(void) {
if (pthread_mutex_lock(&lock) != 0) {
printf("pthread_mutex_lock fails\n");
abort();
}
}
-static void unlock_system(void)
-{
+static void unlock_system(void) {
if (pthread_mutex_unlock(&lock) != 0) {
printf("pthread_mutex_unlock fails\n");
abort();
}
}
-static void write_pipe(int p, char *b, int size)
-{
+static void write_pipe(int p, char *b, int size) {
while (size) {
int ret = write(p, b, size);
+
if (ret <= 0) exit(0);
+
b += ret;
size -= ret;
}
}
-static void read_pipe(int p, char *b, int size)
-{
+static void read_pipe(int p, char *b, int size) {
while (size) {
int ret = read(p, b, size);
+
if (ret <= 0) exit(0);
+
b += ret;
size -= ret;
}
@@ -95,14 +105,13 @@ static void read_pipe(int p, char *b, int size)
* when the main process exits, because then a "read" on the pipe
* will return 0, in which case "read_pipe" exits.
*/
-static void background_system_process(void)
-{
+static void background_system_process(void) {
int len;
int ret;
char command[MAX_COMMAND+1];
while (1) {
- read_pipe(command_pipe_read, (char*)&len, sizeof(int));
+ read_pipe(command_pipe_read, (char *)&len, sizeof(int));
read_pipe(command_pipe_read, command, len);
ret = system(command);
write_pipe(result_pipe_write, (char *)&ret, sizeof(int));
@@ -114,8 +123,7 @@ static void background_system_process(void)
/* return -1 on error, 0 on success */
/********************************************************************/
-int background_system(char *command)
-{
+int background_system(char *command) {
int res;
int len;
@@ -125,18 +133,22 @@ int background_system(char *command)
}
len = strlen(command)+1;
+
if (len > MAX_COMMAND) {
printf("FATAL: command too long. Increase MAX_COMMAND (%d).\n", MAX_COMMAND);
printf("command was: '%s'\n", command);
abort();
}
+
/* only one command can run at a time, so let's lock/unlock */
lock_system();
- write_pipe(command_pipe_write, (char*)&len, sizeof(int));
+ write_pipe(command_pipe_write, (char *)&len, sizeof(int));
write_pipe(command_pipe_write, command, len);
- read_pipe(result_pipe_read, (char*)&res, sizeof(int));
+ read_pipe(result_pipe_read, (char *)&res, sizeof(int));
unlock_system();
+
if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) return -1;
+
return 0;
}
@@ -146,17 +158,16 @@ int background_system(char *command)
/* to be called very early by the main processing */
/********************************************************************/
-void start_background_system(void)
-{
+void start_background_system(void) {
int p[2];
pid_t son;
-
module_initialized = 1;
if (pipe(p) == -1) {
perror("pipe");
exit(1);
}
+
command_pipe_read = p[0];
command_pipe_write = p[1];
@@ -164,10 +175,11 @@ void start_background_system(void)
perror("pipe");
exit(1);
}
+
result_pipe_read = p[0];
result_pipe_write = p[1];
-
son = fork();
+
if (son == -1) {
perror("fork");
exit(1);
@@ -181,6 +193,56 @@ void start_background_system(void)
close(result_pipe_read);
close(command_pipe_write);
-
background_system_process();
}
+
+
+void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority){
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+ pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
+ struct sched_param sparam={0};
+ sparam.sched_priority = priority;
+ pthread_attr_setschedparam(&attr, &sparam);
+
+ pthread_create(t, &attr, func, param);
+
+ pthread_setname_np(*t, name);
+ if (affinity != -1 ) {
+ cpu_set_t cpuset;
+ CPU_ZERO(&cpuset);
+ CPU_SET(affinity, &cpuset);
+ AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
+ }
+
+ pthread_attr_destroy(&attr);
+}
+
+// Block CPU C-states deep sleep
+void configure_linux(void) {
+ int ret;
+ static int latency_target_fd=-1;
+ uint32_t latency_target_value=10; // in microseconds
+ if (latency_target_fd == -1) {
+ if ( (latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR)) != -1 ) {
+ ret = write(latency_target_fd, &latency_target_value, sizeof(latency_target_value));
+ if (ret == 0) {
+ printf("# error setting cpu_dma_latency to %d!: %s\n", latency_target_value, strerror(errno));
+ close(latency_target_fd);
+ latency_target_fd=-1;
+ return;
+ }
+ }
+ }
+ if (latency_target_fd != -1)
+ LOG_I(HW,"# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
+ else
+ LOG_E(HW,"Can't set /dev/cpu_dma_latency to %dus\n", latency_target_value);
+
+ // Set CPU frequency to it's maximum
+ if ( 0 != system("for d in /sys/devices/system/cpu/cpu[0-9]*; do cat $d/cpufreq/cpuinfo_max_freq > $d/cpufreq/scaling_min_freq; done"))
+ LOG_W(HW,"Can't set cpu frequency\n");
+
+}
diff --git a/common/utils/system.h b/common/utils/system.h
index 658c17adc1..a89a6c5b17 100644
--- a/common/utils/system.h
+++ b/common/utils/system.h
@@ -21,6 +21,12 @@
#ifndef _SYSTEM_H_OAI_
#define _SYSTEM_H_OAI_
+#include
+#include
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/****************************************************
* send a command to the background process
@@ -36,4 +42,23 @@ int background_system(char *command);
void start_background_system(void);
+void set_latency_target(void);
+void configure_linux(void);
+
+void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority);
+#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO)
+#define OAI_PRIORITY_RT sched_get_priority_max(SCHED_FIFO)-10
+#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_FIFO)
+
+void thread_top_init(char *thread_name,
+ int affinity,
+ uint64_t runtime,
+ uint64_t deadline,
+ uint64_t period);
+
+#ifdef __cplusplus
+}
+#endif
+
+
#endif /* _SYSTEM_H_OAI_ */
diff --git a/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h
index 2f479d8ee6..160111f15e 100644
--- a/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h
+++ b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h
@@ -81,8 +81,8 @@
{"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},\
+ {"snr", &(macuestatptr->snr),TELNET_VARTYPE_INT32,0},\
+ {"target_snr ", &(macuestatptr->target_snr),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},\
diff --git a/doc/BASIC_SIM.md b/doc/BASIC_SIM.md
new file mode 100644
index 0000000000..ab4c3489d9
--- /dev/null
+++ b/doc/BASIC_SIM.md
@@ -0,0 +1,191 @@
+
+
+
+
+
+
+
+ |
+
+ Running OAI Basic Simulator
+ |
+
+
+
+This page is valid on the following branches:
+
+- `master` starting from tag `v1.1.0`
+- `develop` starting from tag `2019.w11`
+
+# 1. Building the basic-simulator.
+
+After the build simplification, the basic simulator is available directly from the standard build.
+
+```bash
+$ source oaienv
+$ cd cmake_targets
+$ ./build_oai --eNB --UE
+```
+
+Both eNB (lte-softmodem) and UE (lte-uesoftmodem) are present on `cmake_targets/lte_build_oai/build` folder.
+
+More details are available on the [build page](BUILD.md).
+
+# 2. Running the basic simulator.
+
+The basic 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 and having debug sessions without any HW radio equipment.
+
+The main limitations are:
+
+- A single OAI UE will connect to the OAI eNB
+- No channel noise
+
+## 2.1. Starting eNB
+
+The basic simulator is able to run with a connected EPC or without any (the so-called "noS1" mode).
+
+Example 1: running in FDD mode with EPC.
+
+```bash
+$ source oaienv
+$ cd cmake_targets/lte_build_oai/build
+$ ENODEB=1 sudo -E ./lte-softmodem -O $OPENAIR_HOME/ci-scripts/conf_files/lte-fdd-basic-sim.conf --basicsim
+```
+
+Edit previously the `ci-scripts/conf_files/lte-fdd-basic-sim.conf` file to modify:
+
+- `N_RB_DL` field to change the Bandwidth (25, 50, 100)
+- `CI_MME_IP_ADDR` with the EPC IP address
+- `CI_ENB_IP_ADDR` with the container (physical server, virtual machine, ...) on which you are executing the eNB soft-modem
+
+Example 2: running in TDD mode without any EPC.
+
+```bash
+$ source oaienv
+$ cd cmake_targets/lte_build_oai/build
+$ ENODEB=1 sudo -E ./lte-softmodem -O $OPENAIR_HOME/ci-scripts/conf_files/lte-tdd-basic-sim.conf --basicsim --noS1
+```
+
+## 2.2. Starting UE
+
+Before starting the UE, you may need to edit the SIM parameters to adapt to your eNB configuration and HSS database.
+
+The file to use for conf2uedate is `openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf`
+
+You need to set the correct OPC, USIM_API_K, MSIN (this is the end par of the IMSI), HPLMN (the front part of IMSI) to match values from HSS.
+
+```bash
+$ source oaienv
+# Edit openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
+$ cd cmake_targets/lte_build_oai/build
+$ ../../nas_sim_tools/build/conf2uedata -c $OPENAIR_HOME/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o .
+$ sudo -E ./lte-uesoftmodem -C 2625000000 -r 25 --ue-rxgain 140 --basicsim [--noS1]
+```
+
+The `-r 25` is to use if in the conf file of the eNB you use N_RB_DL=25. Use 50 if you have N_RB_DL=50 and 100 if you have N_RB_DL=100.
+
+The `-C 2625000000` is the downlink frequency. Use the same value as `downlink_frequency` in the eNB configuration file.
+
+The `--noS1` is mandatory if you started the eNB in that mode.
+
+# 3. Testing the data plane
+
+# 3.1. In S1 mode
+
+First we need to retrieve the IP address allocated to the OAI UE.
+
+On the server that runs the UE:
+
+```bash
+$ ifconfig oaitun_ue1
+oaitun_ue1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+ inet addr:192.172.0.2 P-t-P:192.172.0.2 Mask:255.255.255.0
+...
+```
+
+`192.172.0.2` is the IP address that has been allocated by the SPGW in the EPC.
+
+On the server that runs the EPC:
+
+```bash
+$ ping -c 20 192.172.0.2
+ --- 192.172.0.2 ping statistics ---
+ 20 packets transmitted, 20 received, 0% packet loss, time 19020ms
+ rtt min/avg/max/mdev = 13.241/18.999/24.208/2.840 ms
+```
+
+You can ping the EPC from the UE:
+
+```bash
+$ ping -I oaitun_ue1 -c 20 192.172.0.1
+ --- 192.172.0.1 ping statistics ---
+...
+ 20 packets transmitted, 20 received, 0% packet loss, time 19019ms
+ rtt min/avg/max/mdev = 13.015/18.674/23.738/2.917 ms
+```
+
+For DL iperf testing:
+
+On the server that runs the UE.
+
+```bash
+$ iperf -B 192.172.0.2 -u -s -i 1 -fm -p 5001
+```
+
+On the server that runs the EPC.
+
+```bash
+$ iperf -c 192.172.0.2 -u -t 30 -b 10M -i 1 -fm -B 192.172.0.1 -p 5001
+```
+
+For UL iperf testing:
+
+On the server that runs the EPC.
+
+```bash
+$ iperf -B 192.172.0.1 -u -s -i 1 -fm -p 5001
+```
+
+On the server that runs the UE.
+
+```bash
+$ iperf -c 192.172.0.1 -u -t 30 -b 2M -i 1 -fm -B 192.172.0.2 -p 5001
+```
+
+# 3.2. In noS1 mode
+
+The IP addresses are fixed. But we can still retrieve them programmatically.
+
+For the UE it is quite the same:
+
+```bash
+$ ifconfig oaitun_ue1
+oaitun_ue1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+ inet addr:10.0.1.2 P-t-P:10.0.1.2 Mask:255.255.255.0
+...
+```
+
+For the eNB:
+
+```bash
+$ ifconfig oaitun_enb1
+oaitun_enb1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+ inet addr:10.0.1.1 P-t-P:10.0.1.1 Mask:255.255.255.0
+...
+```
+
+Pinging like this:
+
+```bash
+$ ping -I oaitun_ue1 -c 20 10.0.1.1
+$ ping -I oaitun_enb1 -c 20 10.0.1.2
+```
+
+And the same for iperf:
+
+```bash
+$ iperf -B 10.0.1.2 -u -s -i 1 -fm
+$ iperf -c 10.0.1.2 -u -b 1.00M -t 30 -i 1 -fm -B 10.0.1.1
+```
diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md
index 49c3c93dd6..9c9e72862b 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -33,10 +33,12 @@ The Physical layer implements **3GPP 36.211**, **36.212**, **36.213** and provid
- Max number of antennas: 2
- CQI/PMI reporting: aperiodic, feedback mode 3 - 0 and 3 - 1
- PRACH preamble format 0
-- All downlink (DL) channels are supported: PSS, SSS, PBCH, PCFICH, PHICH, PDCCH, PDSCH, PMCH
-- All uplink (UL) channels are supported: PRACH, PUSCH, PUCCH (format 1/1a/1b), SRS, DRS
+- Downlink (DL) channels are supported: PSS, SSS, PBCH, PCFICH, PHICH, PDCCH, PDSCH, PMCH, MPDCCH
+- Uplink (UL) channels are supported: PRACH, PUSCH, PUCCH (format 1/1a/1b), SRS, DRS
- HARQ support (UL and DL)
- Highly optimized base band processing (including turbo decoder)
+- Multi-RRU support: over the air synchro b/ multi RRU in TDD mode
+- Support for CE-modeA for LTE-M. Limited support for repeatition, single-LTE-M connection, legacy-LTE UE attach is disabled.
### Performances ###
@@ -136,6 +138,7 @@ The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following
- UE Context Release
- X2 timers (t_reloc_prep, tx2_reloc_overall)
- Handover Cancel
+ - X2-U interface implemented
## eNB Advanced Features ##
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index 314c2cc78b..bb89407f70 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -14,6 +14,10 @@
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.
+# Basic Simulator
+
+See the [dedicated page](BASIC_SIM.md).
+
# 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.
diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c
index c835f38e11..f07fb1ad23 100644
--- a/nfapi/oai_integration/nfapi_pnf.c
+++ b/nfapi/oai_integration/nfapi_pnf.c
@@ -83,7 +83,7 @@ nfapi_tx_request_pdu_t *tx_request_pdu[1023][10][10]; // [frame][subframe][max_n
uint8_t tx_pdus[32][8][4096];
-
+nfapi_ue_release_request_body_t release_rntis;
uint16_t phy_antenna_capability_values[] = { 1, 2, 4, 8, 16 };
nfapi_pnf_param_response_t g_pnf_param_resp;
@@ -197,19 +197,19 @@ static pthread_t pnf_start_pthread;
int nfapitooai_level(int nfapi_level) {
switch(nfapi_level) {
case NFAPI_TRACE_ERROR:
- return LOG_ERR;
+ return OAILOG_ERR;
case NFAPI_TRACE_WARN:
- return LOG_WARNING;
+ return OAILOG_WARNING;
case NFAPI_TRACE_NOTE:
- return LOG_INFO;
+ return OAILOG_INFO;
case NFAPI_TRACE_INFO:
- return LOG_DEBUG;
+ return OAILOG_DEBUG;
}
- return LOG_ERR;
+ return OAILOG_ERR;
}
void pnf_nfapi_trace(nfapi_trace_level_t nfapi_level, const char *message, ...) {
@@ -540,7 +540,6 @@ int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap
}
if(req->nfapi_config.earfcn.tl.tag == NFAPI_NFAPI_EARFCN_TAG) {
- fp->eutra_band = 0;
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++;
@@ -896,6 +895,15 @@ int pnf_phy_lbt_dl_config_req(nfapi_pnf_p7_config_t *config, nfapi_lbt_dl_config
return 0;
}
+int pnf_phy_ue_release_req(nfapi_pnf_p7_config_t* config, nfapi_ue_release_request_t* req) {
+ if (req->ue_release_request_body.number_of_TLVs==0)
+ return -1;
+
+ release_rntis.number_of_TLVs = req->ue_release_request_body.number_of_TLVs;
+ memcpy(&release_rntis.ue_release_request_TLVs_list, req->ue_release_request_body.ue_release_request_TLVs_list, sizeof(nfapi_ue_release_request_TLVs_t)*req->ue_release_request_body.number_of_TLVs);
+ return 0;
+}
+
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;
@@ -1024,7 +1032,7 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi
p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req;
p7_config->tx_req = &pnf_phy_tx_req;
p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req;
-
+ p7_config->ue_release_req = &pnf_phy_ue_release_req;
if (NFAPI_MODE==NFAPI_UE_STUB_PNF) {
p7_config->dl_config_req = &memcpy_dl_config_req;
p7_config->ul_config_req = &memcpy_ul_config_req;
@@ -1367,7 +1375,7 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr,
printf("%s() PNF\n\n\n\n\n\n", __FUNCTION__);
if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) {
- nfapi_setmode(NFAPI_PNF); // PNF!
+ nfapi_setmode(NFAPI_MODE_PNF); // PNF!
}
nfapi_pnf_config_t *config = nfapi_pnf_config_create();
diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
index 2752df3435..6b68a29658 100644
--- a/nfapi/oai_integration/nfapi_vnf.c
+++ b/nfapi/oai_integration/nfapi_vnf.c
@@ -42,6 +42,7 @@
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
+extern UL_RCC_IND_t UL_RCC_INFO;
typedef struct {
uint8_t enabled;
@@ -424,6 +425,40 @@ int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indicatio
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);
+ if(NFAPI_MODE == NFAPI_MODE_VNF){
+ int8_t index = -1;
+ for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
+ if((UL_RCC_INFO.rach_ind[i].header.message_id == 0) && (index == -1)){
+ index = i;
+ break;
+ }
+ }
+ if(index == -1){
+ LOG_E(MAC,"phy_rach_indication : num of rach reach max \n");
+ return 0;
+ }
+ UL_RCC_INFO.rach_ind[index] = *ind;
+
+ if (ind->rach_indication_body.number_of_preambles > 0)
+ UL_RCC_INFO.rach_ind[index].rach_indication_body.preamble_list = malloc(sizeof(nfapi_preamble_pdu_t)*ind->rach_indication_body.number_of_preambles );
+
+ for (int i=0; irach_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
+ );
+ }
+ if(ind->rach_indication_body.preamble_list[i].preamble_rel13.tl.tag == NFAPI_PREAMBLE_REL13_TAG) {
+ printf("RACH PREAMBLE REL13 present\n");
+ }
+
+ UL_RCC_INFO.rach_ind[index].rach_indication_body.preamble_list[i] = ind->rach_indication_body.preamble_list[i];
+ }
+ }else{
eNB->UL_INFO.rach_ind = *ind;
eNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = eNB->preamble_list;
@@ -443,7 +478,7 @@ 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);
// vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data);
//mac_rach_ind(p7_vnf->mac, ind);
@@ -454,13 +489,33 @@ int phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indicatio
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);
+ if(NFAPI_MODE == NFAPI_MODE_VNF){
+ int8_t index = -1;
+ for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
+ if((UL_RCC_INFO.harq_ind[i].header.message_id == 0) && (index == -1)){
+ index = i;
+ break;
+ }
+ }
+ if(index == -1){
+ LOG_E(MAC,"phy_harq_indication : num of harq reach max \n");
+ return 0;
+ }
+ UL_RCC_INFO.harq_ind[index] = *ind;
+
+ if (ind->harq_indication_body.number_of_harqs > 0)
+ UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list = malloc(sizeof(nfapi_harq_indication_pdu_t)*ind->harq_indication_body.number_of_harqs );
+ for (int i=0; iharq_indication_body.number_of_harqs; i++) {
+ memcpy(&UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list[i], &ind->harq_indication_body.harq_pdu_list[i], sizeof(nfapi_harq_indication_pdu_t));
+ }
+ }else{
eNB->UL_INFO.harq_ind = *ind;
eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list;
for (int i=0; iharq_indication_body.number_of_harqs; i++) {
memcpy(&eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i], &ind->harq_indication_body.harq_pdu_list[i], sizeof(eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i]));
}
-
+ }
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);
@@ -470,6 +525,37 @@ int phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indicatio
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);
+ if(NFAPI_MODE == NFAPI_MODE_VNF){
+ int8_t index = -1;
+ for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
+ if((UL_RCC_INFO.crc_ind[i].header.message_id == 0) && (index == -1)){
+ index = i;
+ }
+ if(UL_RCC_INFO.rx_ind[i].sfn_sf == ind->sfn_sf){
+ index = i;
+ break;
+ }
+ }
+ if(index == -1){
+ LOG_E(MAC,"phy_crc_indication : num of crc reach max \n");
+ return 0;
+ }
+ UL_RCC_INFO.crc_ind[index] = *ind;
+
+ if (ind->crc_indication_body.number_of_crcs > 0)
+ UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list = malloc(sizeof(nfapi_crc_indication_pdu_t)*ind->crc_indication_body.number_of_crcs );
+
+ for (int i=0; icrc_indication_body.number_of_crcs; i++) {
+ memcpy(&UL_RCC_INFO.crc_ind[index].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, UL_RCC_INFO.crc_ind[index].crc_indication_body.number_of_crcs,
+ i,
+ ind->crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti,
+ UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti);
+ }
+ }else{
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;
@@ -489,7 +575,7 @@ int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_
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);
@@ -504,6 +590,52 @@ int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t
}
pthread_mutex_lock(&eNB->UL_INFO_mutex);
+ if(NFAPI_MODE == NFAPI_MODE_VNF){
+ int8_t index = -1;
+ for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
+ if((UL_RCC_INFO.rx_ind[i].header.message_id == 0) && (index == -1)){
+ index = i;
+ }
+ if(UL_RCC_INFO.crc_ind[i].sfn_sf == ind->sfn_sf){
+ index = i;
+ break;
+ }
+ }
+ if(index == -1){
+ LOG_E(MAC,"phy_rx_indication : num of rx reach max \n");
+ return 0;
+ }
+ UL_RCC_INFO.rx_ind[index] = *ind;
+
+ if (ind->rx_indication_body.number_of_pdus > 0)
+ UL_RCC_INFO.rx_ind[index].rx_indication_body.rx_pdu_list = malloc(sizeof(nfapi_rx_indication_pdu_t)*ind->rx_indication_body.number_of_pdus );
+
+ for (int i=0; irx_indication_body.number_of_pdus; i++) {
+ nfapi_rx_indication_pdu_t *dest_pdu = &UL_RCC_INFO.rx_ind[index].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
+ if(dest_pdu->rx_indication_rel8.length > 0){
+ dest_pdu->data = malloc(dest_pdu->rx_indication_rel8.length);
+ memcpy(dest_pdu->data, src_pdu->data, dest_pdu->rx_indication_rel8.length);
+ }else{
+ dest_pdu->data = NULL;
+ }
+
+ 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
+ );
+ }
+ }else{
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;
@@ -528,7 +660,7 @@ int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t
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);
@@ -544,6 +676,32 @@ int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t
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);
+ if(NFAPI_MODE == NFAPI_MODE_VNF){
+ int8_t index = -1;
+ for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
+ if((UL_RCC_INFO.sr_ind[i].header.message_id == 0) && (index == -1)){
+ index = i;
+ break;
+ }
+ }
+ if(index == -1){
+ LOG_E(MAC,"phy_sr_indication : num of sr reach max \n");
+ return 0;
+ }
+ UL_RCC_INFO.sr_ind[index] = *ind;
+ LOG_D(MAC,"%s() UL_INFO[%d].sr_ind.sr_indication_body.number_of_srs:%d\n", __FUNCTION__, index, eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs);
+ if (ind->sr_indication_body.number_of_srs > 0)
+ UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list = malloc(sizeof(nfapi_sr_indication_pdu_t)*ind->sr_indication_body.number_of_srs );
+
+ for (int i=0; isr_indication_body.number_of_srs; i++) {
+ nfapi_sr_indication_pdu_t *dest_pdu = &UL_RCC_INFO.sr_ind[index].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 %d][rnti:%x cqi:%d channel:%d]\n", index, 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));
+ }
+ }else{
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;
@@ -556,7 +714,7 @@ int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t
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);
@@ -569,7 +727,48 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_
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;
+ if(NFAPI_MODE == NFAPI_MODE_VNF){
+ int8_t index = -1;
+ for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){
+ if((UL_RCC_INFO.cqi_ind[i].header.message_id == 0) && (index == -1)){
+ index = i;
+ break;
+ }
+ }
+ if(index == -1){
+ LOG_E(MAC,"phy_cqi_indication : num of cqi reach max \n");
+ return 0;
+ }
+ UL_RCC_INFO.cqi_ind[index] = *ind;
+ if (ind->cqi_indication_body.number_of_cqis > 0){
+ UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list = malloc(sizeof(nfapi_cqi_indication_pdu_t)*ind->cqi_indication_body.number_of_cqis );
+ UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list = malloc(sizeof(nfapi_cqi_indication_raw_pdu_t)*ind->cqi_indication_body.number_of_cqis );
+ }
+ for (int i=0; icqi_indication_body.number_of_cqis; i++) {
+ nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_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(&UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list[i],
+ src_pdu, sizeof(nfapi_cqi_indication_pdu_t));
+
+ memcpy(&UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list[i],
+ &ind->cqi_indication_body.cqi_raw_pdu_list[i], sizeof(nfapi_cqi_indication_raw_pdu_t));
+ }
+ }else{
+ nfapi_cqi_indication_t *dest_ind = &eNB->UL_INFO.cqi_ind;
+ *dest_ind = *ind;
+ dest_ind->cqi_indication_body.cqi_pdu_list = ind->cqi_indication_body.cqi_pdu_list;
+ dest_ind->cqi_indication_body.cqi_raw_pdu_list = ind->cqi_indication_body.cqi_raw_pdu_list;
+ for(int i=0; icqi_indication_body.number_of_cqis; i++) {
+ nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_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_ind->cqi_indication_body.cqi_pdu_list[i],
+ src_pdu, sizeof(nfapi_cqi_indication_pdu_t));
+ memcpy(&dest_ind->cqi_indication_body.cqi_raw_pdu_list[i],
+ &ind->cqi_indication_body.cqi_raw_pdu_list[i], sizeof(nfapi_cqi_indication_raw_pdu_t));
+ }
+ }
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
return 1;
}
@@ -947,6 +1146,7 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
config->deallocate_p4_p5_vendor_ext = &vnf_deallocate_p4_p5_vendor_ext;
config->codec_config.allocate = &vnf_allocate;
config->codec_config.deallocate = &vnf_deallocate;
+ memset(&UL_RCC_INFO,0,sizeof(UL_RCC_IND_t));
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
pthread_create(&vnf_start_pthread, NULL, (void *)&vnf_start_thread, config);
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__);
@@ -1021,3 +1221,21 @@ int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) {
return retval;
}
+
+int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req){
+ if(release_req->ue_release_request_body.number_of_TLVs <= 0)
+ return 0;
+ nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
+
+ release_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
+ release_req->header.message_id = NFAPI_UE_RELEASE_REQUEST;
+ release_req->ue_release_request_body.tl.tag = NFAPI_UE_RELEASE_BODY_TAG;
+
+ int retval = nfapi_vnf_p7_ue_release_req(p7_config, release_req);
+ if (retval!=0) {
+ LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
+ } else {
+ release_req->ue_release_request_body.number_of_TLVs = 0;
+ }
+ return retval;
+}
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
index 6a70e1f10a..a1a0b6e724 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
@@ -146,6 +146,8 @@ typedef enum {
NFAPI_LBT_DL_INDICATION,
NFAPI_NB_HARQ_INDICATION,
NFAPI_NRACH_INDICATION,
+ NFAPI_UE_RELEASE_REQUEST,
+ NFAPI_UE_RELEASE_RESPONSE,
NFAPI_PNF_PARAM_REQUEST = 0x0100,
NFAPI_PNF_PARAM_RESPONSE,
@@ -2392,6 +2394,19 @@ typedef struct {
} nfapi_tx_request_body_t;
#define NFAPI_TX_REQUEST_BODY_TAG 0x2022
+#define NFAPI_RELEASE_MAX_RNTI 256
+typedef struct {
+ uint32_t handle;
+ uint16_t rnti;
+} nfapi_ue_release_request_TLVs_t;
+
+typedef struct {
+ nfapi_tl_t tl;
+ uint16_t number_of_TLVs;
+ nfapi_ue_release_request_TLVs_t ue_release_request_TLVs_list[NFAPI_RELEASE_MAX_RNTI];
+} nfapi_ue_release_request_body_t;
+#define NFAPI_UE_RELEASE_BODY_TAG 0x2068
+
// P7 Message Structures
typedef struct {
nfapi_p7_message_header_t header;
@@ -3418,6 +3433,19 @@ typedef struct {
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_error_indication_t;
+typedef struct {
+ nfapi_p7_message_header_t header;
+ uint16_t sfn_sf;
+ nfapi_ue_release_request_body_t ue_release_request_body;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_ue_release_request_t;
+
+typedef struct {
+ nfapi_p7_message_header_t header;
+ uint32_t error_code;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_ue_release_response_t;
+
//
// P4 Messages
//
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
old mode 100644
new mode 100755
index 2daf1450c8..be9205d035
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
@@ -81,13 +81,19 @@ void* nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t* config)
if(size == 0)
return 0;
+ void* buffer_p = NULL;
if(config && config->allocate)
{
- return (config->allocate)(size);
+ buffer_p = (config->allocate)(size);
+ if(buffer_p != NULL){
+ memset(buffer_p,0,size);
+ }
+ return buffer_p;
}
else
{
- return calloc(1, size);
+ buffer_p = calloc(1, size);
+ return buffer_p;
}
}
@@ -1577,7 +1583,43 @@ static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
return x && y && z;
}
-
+
+static uint8_t pack_release_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_ue_release_request_body_t* value = (nfapi_ue_release_request_body_t*)tlv;
+ if(push16(value->number_of_TLVs, ppWritePackedMsg, end) == 0){
+ return 0;
+ }
+
+ uint8_t j;
+ uint16_t num = value->number_of_TLVs;
+ for(j = 0; j < num; ++j){
+ if(push16(value->ue_release_request_TLVs_list[j].rnti, ppWritePackedMsg, end) == 0){
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+ nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg;
+ int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end);
+ int y = pack_tlv(NFAPI_UE_RELEASE_BODY_TAG, &pNfapiMsg->ue_release_request_body, ppWritePackedMsg, end, &pack_release_request_body_value);
+ int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+ return x && y && z;
+}
+
+static uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+
+ nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg;
+
+ int x = push32(pNfapiMsg->error_code, ppWritePackedMsg, end);
+ int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+ return x && z;
+}
+
static uint8_t pack_rx_ue_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv;
@@ -2665,7 +2707,15 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__);
result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config);
break;
-
+
+ case NFAPI_UE_RELEASE_REQUEST:
+ result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_UE_RELEASE_RESPONSE:
+ result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
case NFAPI_HARQ_INDICATION:
result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
break;
@@ -4479,7 +4529,55 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
return 1;
}
-
+
+static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+{
+ uint8_t proceed = 1;
+ nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg;
+
+ if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0)
+ return 0;
+
+ while (((uint8_t*)(*ppReadPackedMsg) < end) && proceed)
+ {
+ nfapi_tl_t generic_tl;
+ if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
+ return 0;
+
+ switch(generic_tl.tag)
+ {
+ case NFAPI_UE_RELEASE_BODY_TAG:
+ {
+ pNfapiMsg->ue_release_request_body.tl = generic_tl;
+ if( pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.number_of_TLVs, end) == 0)
+ return 0;
+
+ if(pNfapiMsg->ue_release_request_body.number_of_TLVs > NFAPI_RELEASE_MAX_RNTI)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of relese rnti's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->ue_release_request_body.number_of_TLVs, NFAPI_RELEASE_MAX_RNTI);
+ return 0;
+ } else {
+ uint8_t j;
+ uint16_t num = pNfapiMsg->ue_release_request_body.number_of_TLVs;
+ for(j = 0; j < num; ++j){
+ if(pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.ue_release_request_TLVs_list[j].rnti, end) == 0){
+ return 0;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_ue_release_request FIXME : Invalid type %d \n", generic_tl.tag );
+ }
+ break;
+ };
+ }
+
+ return 1;
+}
+
static uint8_t unpack_harq_indication_tdd_harq_data_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
{
nfapi_harq_indication_tdd_harq_data_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_bundling_t*)tlv;
@@ -5727,7 +5825,18 @@ static uint8_t unpack_nrach_indication_rel13_value(void *tlv, uint8_t **ppReadPa
pull8(ppReadPackedMsg, &value->nrach_ce_level, end));
}
-
+static uint8_t unpack_ue_release_resp(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+{
+ nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg;
+ if(pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) == 0){
+ return 0;
+ }
+ else{
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "ue_release_response:error_code = %d\n", pNfapiMsg->error_code);
+ }
+ return 1;
+}
+
static uint8_t unpack_nrach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv;
@@ -5940,7 +6049,17 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen
if (unpackedBufLen >= sizeof(nfapi_timing_info_t))
retLen = sizeof(nfapi_timing_info_t);
break;
-
+
+ case NFAPI_UE_RELEASE_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t))
+ retLen = sizeof(nfapi_ue_release_request_t);
+ break;
+
+ case NFAPI_UE_RELEASE_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t))
+ retLen = sizeof(nfapi_ue_release_response_t);
+ break;
+
default:
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId);
break;
@@ -6060,7 +6179,14 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
else
return -1;
break;
-
+
+ case NFAPI_UE_RELEASE_REQUEST:
+ if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
+ result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
case NFAPI_HARQ_INDICATION:
if (check_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen))
result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config);
@@ -6158,7 +6284,14 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
else
return -1;
break;
-
+
+ case NFAPI_UE_RELEASE_RESPONSE:
+ if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
+ result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
default:
if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
index b25caf2876..8d17416a41 100644
--- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
+++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
@@ -546,7 +546,7 @@ typedef struct
nfapi_hi_dci0_request_t* hi_dci0_req;
nfapi_tx_request_t* tx_req;
nfapi_lbt_dl_config_request_t* lbt_dl_config_req;
-
+ nfapi_ue_release_request_t* ue_release_req;
} nfapi_pnf_p7_subframe_buffer_t;
typedef struct nfapi_pnf_p7_config nfapi_pnf_p7_config_t;
@@ -652,6 +652,17 @@ typedef struct nfapi_pnf_p7_config
* \return not currently used
*/
int (*lbt_dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req);
+
+ /*! A callback for the UE_RELEASE_REQ.request
+ * \param config A poiner to the PNF P7 config
+ * \param req A pointer to the release rnti request message structure
+ * \return not currently used
+ *
+ * The release request contains pointers to the release rnti to be sent. In the case that the FAPI interface
+ * will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0
+ * and then use the p7 codec config free function to release the rnti when appropriate.
+ */
+ int (*ue_release_req)(nfapi_pnf_p7_config_t* config, nfapi_ue_release_request_t* req);
/*! A callback for vendor extension messages
* \param config A poiner to the PNF P7 config
@@ -796,6 +807,7 @@ int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication
*/
int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg);
+int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_response_t* resp);
#if defined(__cplusplus)
}
#endif
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
index 81abed81a9..9446730375 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
@@ -36,7 +36,7 @@ extern uint16_t sf_ahead;
void add_sf(uint16_t *frameP, uint16_t *subframeP, int offset)
{
- *frameP = *frameP + ((*subframeP + offset) / 10);
+ *frameP = (*frameP + ((*subframeP + offset) / 10))%1024;
*subframeP = ((*subframeP + offset) % 10);
}
@@ -241,6 +241,16 @@ void deallocate_nfapi_lbt_dl_config_request(nfapi_lbt_dl_config_request_t* req,
pnf_p7_free(pnf_p7, req);
}
+nfapi_ue_release_request_t* allocate_nfapi_ue_release_request(pnf_p7_t* pnf_p7)
+{
+ return pnf_p7_malloc(pnf_p7, sizeof(nfapi_ue_release_request_t));
+}
+
+void deallocate_nfapi_ue_release_request(nfapi_ue_release_request_t* req, pnf_p7_t* pnf_p7)
+{
+ pnf_p7_free(pnf_p7, req);
+}
+
pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len)
{
pnf_p7_rx_message_t* msg = 0;
@@ -720,6 +730,21 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
}
}
+ if(tx_subframe_buffer->ue_release_req != 0)
+ {
+ if(pnf_p7->_public.ue_release_req)
+ (pnf_p7->_public.ue_release_req)(&(pnf_p7->_public), tx_subframe_buffer->ue_release_req);
+ }
+ else
+ {
+ //send dummy
+ if(pnf_p7->_public.ue_release_req && pnf_p7->_public.dummy_subframe.ue_release_req)
+ {
+ pnf_p7->_public.dummy_subframe.ue_release_req->sfn_sf = sfn_sf_tx;
+ (pnf_p7->_public.ue_release_req)(&(pnf_p7->_public), pnf_p7->_public.dummy_subframe.ue_release_req);
+ }
+ }
+
if(tx_subframe_buffer->dl_config_req != 0)
{
deallocate_nfapi_dl_config_request(tx_subframe_buffer->dl_config_req, pnf_p7);
@@ -735,6 +760,10 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
deallocate_nfapi_hi_dci0_request(tx_subframe_buffer->hi_dci0_req, pnf_p7);
tx_subframe_buffer->hi_dci0_req = 0;
}
+ if(tx_subframe_buffer->ue_release_req != 0){
+ deallocate_nfapi_ue_release_request(tx_subframe_buffer->ue_release_req, pnf_p7);
+ tx_subframe_buffer->ue_release_req = 0;
+ }
}
else
{
@@ -799,7 +828,7 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
}
} // sfn_sf match
- if (subframe_buffer->dl_config_req == 0 && subframe_buffer->tx_req == 0 && subframe_buffer->ul_config_req == 0 && subframe_buffer->lbt_dl_config_req == 0)
+ if (subframe_buffer->dl_config_req == 0 && subframe_buffer->tx_req == 0 && subframe_buffer->ul_config_req == 0 && subframe_buffer->lbt_dl_config_req == 0 && subframe_buffer->ue_release_req == 0)
{
memset(&(pnf_p7->subframe_buffer[buffer_index]), 0, sizeof(nfapi_pnf_p7_subframe_buffer_t));
pnf_p7->subframe_buffer[buffer_index].sfn_sf = -1;
@@ -1310,6 +1339,80 @@ void pnf_handle_p7_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pn
}
+void pnf_handle_ue_release_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
+{
+ nfapi_ue_release_request_t* req = allocate_nfapi_ue_release_request(pnf_p7);
+ if(req == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to alloced nfapi_ue_release_request structure\n");
+ return;
+ }
+
+ int unpack_result = nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_ue_release_request_t), &pnf_p7->_public.codec_config);
+ if(unpack_result == 0)
+ {
+ if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "failed to lock mutex\n");
+ return;
+ }
+
+ if(is_p7_request_in_window(req->sfn_sf, "ue_release_request", pnf_p7))
+ {
+ uint32_t sfn_sf_dec = NFAPI_SFNSF2DEC(req->sfn_sf);
+ uint8_t buffer_index = sfn_sf_dec % pnf_p7->_public.subframe_buffer_size;
+
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UE_RELEASE_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_sf_dec, buffer_index);
+
+ if (0 && NFAPI_SFNSF2DEC(req->sfn_sf)%100==0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() UE_RELEASE_REQ.req sfn_sf:%d rntis:%d - UE_RELEASE_REQ is within window\n",
+ __FUNCTION__,
+ NFAPI_SFNSF2DEC(req->sfn_sf),
+ req->ue_release_request_body.number_of_TLVs);
+
+ if(pnf_p7->subframe_buffer[buffer_index].ue_release_req != 0)
+ {
+ deallocate_nfapi_ue_release_request(pnf_p7->subframe_buffer[buffer_index].ue_release_req, pnf_p7);
+ }
+
+ pnf_p7->subframe_buffer[buffer_index].sfn_sf = req->sfn_sf;
+ pnf_p7->subframe_buffer[buffer_index].ue_release_req = req;
+
+ pnf_p7->stats.tx_ontime++;
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() UE_RELEASE_REQUEST Request is outside of window REQ:SFN_SF:%d CURR:SFN_SF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), NFAPI_SFNSF2DEC(pnf_p7->sfn_sf));
+
+ deallocate_nfapi_ue_release_request(req, pnf_p7);
+ if(pnf_p7->_public.timing_info_mode_aperiodic)
+ {
+ pnf_p7->timing_info_aperiodic_send = 1;
+ }
+
+ pnf_p7->stats.tx_late++;
+ }
+ nfapi_ue_release_response_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_UE_RELEASE_RESPONSE;
+ resp.header.phy_id = req->header.phy_id;
+ resp.error_code = NFAPI_MSG_OK;
+ nfapi_pnf_ue_release_resp(&(pnf_p7->_public), &resp);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "do ue_release_response\n");
+
+ if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "failed to unlock mutex\n");
+ return;
+ }
+ }
+ else
+ {
+ deallocate_nfapi_ue_release_request(req, pnf_p7);
+ }
+}
uint32_t calculate_t2(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_time_hr)
{
@@ -1445,7 +1548,11 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7,
case NFAPI_LBT_DL_CONFIG_REQUEST:
pnf_handle_lbt_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7);
break;
-
+
+ case NFAPI_UE_RELEASE_REQUEST:
+ pnf_handle_ue_release_request(pRecvMsg, recvMsgLen, pnf_p7);
+ break;
+
default:
{
if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
@@ -1536,7 +1643,7 @@ void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, ui
NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate PNF_P7 reassemby buffer len:%d\n", length);
return;
}
-
+ memset(pnf_p7->reassemby_buffer, 0, length);
pnf_p7->reassemby_buffer_size = length;
}
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
index 74de5e5d78..24e73ae9b3 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
@@ -223,3 +223,15 @@ int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_messag
return pnf_p7_pack_and_send_p7_message(_this, msg, 0);
}
+int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_response_t* resp)
+{
+ if (config == NULL || resp == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ return -1;
+ }
+
+ pnf_p7_t* _this = (pnf_p7_t*)(config);
+
+ return pnf_p7_pack_and_send_p7_message(_this, &(resp->header), sizeof(nfapi_ue_release_response_t));
+}
diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
index 462901391a..ed8f6ba968 100644
--- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
+++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
@@ -988,6 +988,15 @@ int nfapi_vnf_p7_lbt_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_lbt_dl_c
*/
int nfapi_vnf_p7_vendor_extension(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* msg);
+/*! Send the RELEASE_RNTI.request
+ * \param config A pointer to the vnf p7 configuration
+ * \param req A data structure for the decoded RELEASE_RNTI.request.
+ * \return A status value. 0 equal success, -1 indicates failure
+ *
+ * The caller is responsiable for memory management of any pointers set in the req, which
+ * may be released after this function call has returned or at a later pointer
+ */
+int nfapi_vnf_p7_ue_release_req(nfapi_vnf_p7_config_t* config, nfapi_ue_release_request_t* req);
#if defined(__cplusplus)
}
#endif
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
index 4b7acabec3..985a6f830a 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
@@ -822,6 +822,28 @@ void vnf_handle_nrach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p
}
}
+void vnf_handle_ue_release_resp(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
+{
+
+ // ensure it's valid
+ if (pRecvMsg == NULL || vnf_p7 == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ nfapi_ue_release_response_t resp;
+
+ if(nfapi_p7_message_unpack(pRecvMsg, recvMsgLen, &resp, sizeof(resp), &vnf_p7->_public.codec_config) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Failed to unpack message\n", __FUNCTION__);
+ }
+
+
+ vnf_p7_codec_free(vnf_p7, resp.vendor_extension);
+ }
+}
+
void vnf_handle_p7_vendor_extension(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7, uint16_t message_id)
{
if (pRecvMsg == NULL || vnf_p7 == NULL)
@@ -1334,6 +1356,10 @@ void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
vnf_handle_nrach_indication(pRecvMsg, recvMsgLen, vnf_p7);
break;
+ case NFAPI_UE_RELEASE_RESPONSE:
+ vnf_handle_ue_release_resp(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
default:
{
if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
@@ -1430,7 +1456,7 @@ void vnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate VNF_P7 reassemby buffer len:%d\n", length);
return;
}
-
+ memset(phy->reassembly_buffer, 0, length);
phy->reassembly_buffer_size = length;
}
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
index 4a85f7e4b3..0444dca71d 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
@@ -523,6 +523,14 @@ int nfapi_vnf_p7_vendor_extension(nfapi_vnf_p7_config_t* config, nfapi_p7_messag
return vnf_p7_pack_and_send_p7_msg(vnf_p7, header);
}
+int nfapi_vnf_p7_ue_release_req(nfapi_vnf_p7_config_t* config, nfapi_ue_release_request_t* req)
+{
+ if(config == 0 || req == 0)
+ return -1;
+
+ vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
+ return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
+}
int nfapi_vnf_p7_release_msg(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* header)
{
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index fad4311714..61a58c1b19 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -34,6 +34,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "assertions.h"
#include
+#include "nfapi/oai_integration/vendor_ext.h"
extern uint32_t from_earfcn(int eutra_bandP,uint32_t dl_earfcn);
extern int32_t get_uldl_offset(int eutra_bandP);
@@ -408,6 +409,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
+ if (NFAPI_MODE!=NFAPI_MODE_VNF){
common_vars->rxdata = (int32_t **)NULL;
common_vars->txdataF = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t*));
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*));
@@ -511,6 +513,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++)
eNB->UE_stats_ptr[UE_id] = &eNB->UE_stats[UE_id];
+ }
eNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index b4b253a297..1913afab2d 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -291,24 +291,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
y[0] = &yseq0[0];
y[1] = &yseq1[0];
- 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 , here we set 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, here we set elements as 2 */
+ memset(e, 2, DCI_BITS_MAX);
e_ptr = e;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,1);
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.h b/openair1/PHY/LTE_TRANSPORT/dci.h
index c5654aa742..cd76f20919 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci.h
+++ b/openair1/PHY/LTE_TRANSPORT/dci.h
@@ -38,7 +38,7 @@
#define CCEBITS 72
#define CCEPERSYMBOL 33 // This is for 1200 RE
#define CCEPERSYMBOL0 22 // This is for 1200 RE
-#define DCI_BITS_MAX ((2*CCEPERSYMBOL+CCEPERSYMBOL0)*CCEBITS)
+#define DCI_BITS_MAX ((2*CCEPERSYMBOL+CCEPERSYMBOL0)*CCEBITS + 64)
//#define Mquad (Msymb/4)
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index b44a04eb74..327b0cf57c 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -384,9 +384,8 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
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);
+ if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) {
+ LOG_E(PHY,"dlsch_encoding_2threads illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
return(-1);
}
@@ -569,7 +568,12 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
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;
+ uint8_t harq_pid = dlsch->harq_ids[frame%2][subframe];
+ if(harq_pid >= dlsch->Mdlharq) {
+ LOG_E(PHY,"dlsch_encoding_all illegal harq_pid %d\n", harq_pid);
+ return(-1);
+ }
+ B = dlsch->harq_processes[harq_pid]->B;
LOG_D(PHY,"B %d, harq_pid %d\n",B,dlsch->harq_ids[frame%2][subframe]);
@@ -676,9 +680,8 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
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);
+ if((harq_pid < 0) || (harq_pid >= dlsch->Mdlharq)) {
+ LOG_E(PHY,"dlsch_encoding illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
return(-1);
}
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
index e8b56f3bdf..8a3649cf87 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
@@ -2257,8 +2257,8 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
if ((dlsch0 != NULL) && (dlsch1 != NULL)){
harq_pid = dlsch0->harq_ids[frame%2][subframe_offset];
- if(harq_pid >= dlsch0->Mdlharq) {
- LOG_E(PHY,"illegal harq_pid %d\n", harq_pid);
+ if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
+ LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
return(-1);
}
dlsch0_harq = dlsch0->harq_processes[harq_pid];
@@ -2278,8 +2278,8 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
}else if ((dlsch0 != NULL) && (dlsch1 == NULL)){
harq_pid = dlsch0->harq_ids[frame%2][subframe_offset];
- if(harq_pid >= dlsch0->Mdlharq) {
- LOG_E(PHY,"illegal harq_pid %d\n", harq_pid);
+ if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
+ LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
return(-1);
}
dlsch0_harq = dlsch0->harq_processes[harq_pid];
@@ -2299,8 +2299,8 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
}else if ((dlsch0 == NULL) && (dlsch1 != NULL)){
harq_pid = dlsch1->harq_ids[frame%2][subframe_offset];
- if(harq_pid >= dlsch1->Mdlharq) {
- LOG_E(PHY,"illegal harq_pid %d\n", harq_pid);
+ if((harq_pid < 0) || (harq_pid >= dlsch1->Mdlharq)) {
+ LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
return(-1);
}
dlsch1_harq = dlsch1->harq_processes[harq_pid];
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index 676d753ab5..72be96c95b 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -1063,7 +1063,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
#endif
}
- for (l2=0,l=(nsymb>>1); l<(nsymb-1); l++,l2++) {
+ for (l2=0,l=(nsymb>>1); l < nsymb; l++,l2++) {
stat_re += (((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15))/nsymb;
stat_im += (((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15))/nsymb;
off+=2;
@@ -1092,7 +1092,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
// stat_max *= nsymb; // normalize to energy per symbol
// stat_max /= (frame_parms->N_RB_UL*12); //
- stat_max /= (nsymb*12);
+ stat_max /= 12;
#ifdef DEBUG_PUCCH_RX
printf("[eNB] PUCCH: stat %d, stat_max %d, phase_max %d\n", stat,stat_max,phase_max);
@@ -1181,7 +1181,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
stat_ref_re=0;
stat_ref_im=0;
- for (l2=0,l=(nsymb>>1); l<(nsymb-1); l++,l2++) {
+ for (l2=0,l=(nsymb>>1); l< nsymb; l++,l2++) {
if ((l2<2) || ((l2>(nsymb>>1) - 3)) ) { // data symbols
stat_re += ((rxcomp[aa][off]*(int32_t)cfo[l2<<1])>>15) - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l2<<1)])>>15);
stat_im += ((rxcomp[aa][off]*(int32_t)cfo[1+(l2<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l2<<1)])>>15);
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
index 6c1f674788..9e8685732f 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
@@ -329,6 +329,8 @@ typedef struct {
uint8_t subframe;
/// corresponding UE RNTI
uint16_t rnti;
+ /// UE ID from Layer2
+ uint16_t ue_id;
/// Type (SR, HARQ, CQI, HARQ_SR, HARQ_CQI, SR_CQI, HARQ_SR_CQI)
UCI_type_t type;
/// SRS active flag
diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
index 88c652133b..c301c8510f 100644
--- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
@@ -41,7 +41,7 @@ int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_
uint16_t i;
int16_t first_free_index=-1;
AssertFatal(eNB!=NULL,"eNB is null\n");
- for (i=0; iuci_vars[i].active >0) &&
(eNB->uci_vars[i].rnti==rnti) &&
(eNB->uci_vars[i].frame==frame) &&
diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h
index f7123d6b43..6036928a90 100644
--- a/openair1/PHY/defs_eNB.h
+++ b/openair1/PHY/defs_eNB.h
@@ -339,6 +339,8 @@ typedef struct RU_t_s{
int north_out_cnt;
/// flag to indicate the RU is a slave to another source
int is_slave;
+ /// flag to indicate if the RU has to perform OTA sync
+ int ota_sync_enable;
/// flag to indicate that the RU should generate the DMRS sequence in slot 2 (subframe 1) for OTA synchronization and calibration
int generate_dmrs_sync;
/// flag to indicate if the RU has a control channel
@@ -1049,7 +1051,7 @@ typedef struct PHY_VARS_eNB_s {
LTE_eNB_PRACH prach_vars_br;
#endif
LTE_eNB_COMMON common_vars;
- LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX];
+ LTE_eNB_UCI uci_vars[NUMBER_OF_UCI_VARS_MAX];
LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
LTE_eNB_PBCH pbch;
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h
index ea7d2e5033..272ca0a9ff 100644
--- a/openair1/PHY/phy_vars.h
+++ b/openair1/PHY/phy_vars.h
@@ -45,6 +45,7 @@ int16_t *primary_synch2_time;
#ifndef OCP_FRAMEWORK
PHY_VARS_UE ***PHY_vars_UE_g;
RAN_CONTEXT_t RC;
+UL_RCC_IND_t UL_RCC_INFO;
//PHY_VARS_eNB ***PHY_vars_eNB_g;
//PHY_VARS_RN **PHY_vars_RN_g;
diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c
index b311149532..5f8b4ec3db 100644
--- a/openair1/SCHED/fapi_l1.c
+++ b/openair1/SCHED/fapi_l1.c
@@ -42,7 +42,7 @@ 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);
-
+int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req);
void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,
int frame, int subframe,
L1_rxtx_proc_t *proc,
@@ -186,21 +186,11 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
#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]
- );
+ if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
+ LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
+ return;
+ }
+
dlsch0_harq = dlsch0->harq_processes[harq_pid];
dlsch1_harq = dlsch1->harq_processes[harq_pid];
AssertFatal(dlsch0_harq!=NULL,"dlsch_harq is null\n");
@@ -588,6 +578,7 @@ void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,
uci->frame = frame;
uci->subframe = subframe;
uci->rnti = ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti;
+ uci->ue_id = find_dlsch(ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
uci->type = SR;
uci->pucch_fmt = pucch_format1;
uci->num_antenna_ports = 1;
@@ -615,6 +606,7 @@ void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_
uci->frame = frame;
uci->subframe = subframe;
uci->rnti = ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti;
+ uci->ue_id = find_dlsch(ul_config_pdu->uci_sr_harq_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
uci->type = HARQ_SR;
uci->num_antenna_ports = 1;
uci->num_pucch_resources = 1;
@@ -638,6 +630,7 @@ void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu
uci->frame = frame;
uci->subframe = subframe;
uci->rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti;
+ uci->ue_id = find_dlsch(ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE);
uci->type = HARQ;
uci->srs_active = srs_active;
uci->num_antenna_ports = ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel11.num_ant_ports;
@@ -809,7 +802,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
// clear DCI allocation maps for new subframe
-
+ if (NFAPI_MODE!=NFAPI_MODE_VNF)
for (i=0; iulsch[i]) {
ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid];
@@ -825,7 +818,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
//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);
+ if (NFAPI_MODE!=NFAPI_MODE_VNF)
+ 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;
@@ -840,7 +834,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
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,
+ if (NFAPI_MODE!=NFAPI_MODE_VNF)
+ 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;
@@ -872,7 +867,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
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);
+ if (NFAPI_MODE!=NFAPI_MODE_VNF)
+ 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,
@@ -913,7 +909,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
#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);
+ if (NFAPI_MODE!=NFAPI_MODE_VNF)
+ handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu);
eNB->mpdcch_vars[subframe&1].num_dci++;
break;
#endif
@@ -921,16 +918,24 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
}
if ((NFAPI_MODE!=NFAPI_MONOLITHIC) && do_oai && !dont_send) {
- oai_nfapi_tx_req(Sched_INFO->TX_req);
+ if(Sched_INFO->TX_req->tx_request_body.number_of_pdus > 0){
+ Sched_INFO->TX_req->sfn_sf = frame << 4 | subframe;
+ oai_nfapi_tx_req(Sched_INFO->TX_req);
+ }
+ Sched_INFO->DL_req->sfn_sf = frame << 4 | subframe;
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
+ Sched_INFO->UE_release_req->sfn_sf = frame << 4 | subframe;
+ oai_nfapi_ue_release_req(Sched_INFO->UE_release_req);
}
if ((NFAPI_MODE!=NFAPI_MONOLITHIC) && number_hi_dci0_pdu!=0) {
+ HI_DCI0_req->sfn_sf = frame << 4 | subframe;
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;
}
+if (NFAPI_MODE!=NFAPI_MODE_VNF)
for (i=0; ihi_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);
@@ -955,6 +960,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
if (NFAPI_MODE!=NFAPI_MONOLITHIC) {
if (number_ul_pdu>0) {
//LOG_D(PHY, "UL_CONFIG to send to PNF\n");
+ UL_req->sfn_sf = frame << 4 | subframe;
oai_nfapi_ul_config_req(UL_req);
UL_req->ul_config_request_body.number_of_pdus=0;
number_ul_pdu=0;
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 28dd38b65a..f5a724e39c 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -47,8 +47,7 @@
#include "intertask_interface.h"
-
-
+nfapi_ue_release_request_body_t release_rntis;
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;
@@ -230,13 +229,11 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
-void pdsch_procedures(PHY_VARS_eNB *eNB,
+bool dlsch_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) {
+ LTE_eNB_UE_stats *ue_stats) {
int frame=proc->frame_tx;
int subframe=proc->subframe_tx;
LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
@@ -265,27 +262,6 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
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);
-
if (ue_stats) ue_stats->dlsch_sliding_cnt++;
if (dlsch_harq->round == 0) {
@@ -300,15 +276,17 @@ 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);
+ 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);
// 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;
+ return false;
}
start_meas(&eNB->dlsch_encoding_stats);
@@ -330,44 +308,57 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
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);
- 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,
- dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL);
- stop_meas(&eNB->dlsch_modulation_stats);
- }
-
#ifdef PHY_TX_THREAD
- dlsch->active[subframe] = 0;
+ dlsch->active[subframe] = 0;
#else
- dlsch->active = 0;
+ dlsch->active = 0;
#endif
- dlsch_harq->round++;
- LOG_D(PHY,"Generating DLSCH/PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
+ dlsch_harq->round++;
+ LOG_D(PHY,"Generated DLSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
+ return true;
+ }
+ return false;
+}
+
+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) {
+ 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;
+ // 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);
+ 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,
+ dlsch->ue_type==0 ? dlsch1 : (LTE_eNB_DLSCH_t *)NULL);
+ stop_meas(&eNB->dlsch_modulation_stats);
+
+ LOG_D(PHY,"Generated PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
}
@@ -467,6 +458,11 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
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_pdcch_symbols == 0){
+ LOG_E(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);
+ return;
+ }
+
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);
@@ -514,9 +510,9 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
) {
// get harq_pid
harq_pid = dlsch0->harq_ids[frame%2][subframe];
- AssertFatal(harq_pid>=0,"harq_pid is negative\n");
+ //AssertFatal(harq_pid>=0,"harq_pid is negative\n");
- if (harq_pid>=8) {
+ if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
if (dlsch0->ue_type==0)
@@ -531,14 +527,18 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
dlsch0->harq_ids[frame%2][6],
dlsch0->harq_ids[frame%2][7]);
} else {
- // generate pdsch
- pdsch_procedures(eNB,
+ if (dlsch_procedures(eNB,
proc,
harq_pid,
dlsch0,
- dlsch1,
- &eNB->UE_stats[(uint32_t)UE_id],
- 0);
+ &eNB->UE_stats[(uint32_t)UE_id])) {
+ // if we generate dlsch, we must generate pdsch
+ pdsch_procedures(eNB,
+ proc,
+ harq_pid,
+ dlsch0,
+ dlsch1);
+ }
}
} else if ((dlsch0)&&(dlsch0->rnti>0)&&
#ifdef PHY_TX_THREAD
@@ -601,7 +601,7 @@ void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,u
// 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]);
+ int SNRtimes10 = dB_fixed_times10(stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
@@ -634,7 +634,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
LTE_eNB_UCI *uci = NULL;
LTE_DL_FRAME_PARMS *fp = &(eNB->frame_parms);
- for (int i = 0; i < NUMBER_OF_UE_MAX; i++) {
+ for (int i = 0; i < NUMBER_OF_UCI_VARS_MAX; i++) {
uci = &(eNB->uci_vars[i]);
if ((uci->active == 1) && (uci->frame == frame) && (uci->subframe == subframe)) {
@@ -682,7 +682,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
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->ue_id,
uci->n_pucch_1_0_sr[0],
0, // n2_pucch
uci->srs_active, // shortened format
@@ -724,7 +724,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
SR_payload);
metric[0] = rx_pucch(eNB,
uci->pucch_fmt,
- i,
+ uci->ue_id,
uci->n_pucch_1[0][0],
0, //n2_pucch
uci->srs_active, // shortened format
@@ -748,7 +748,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
SR_payload = 1;
metric[0]=rx_pucch(eNB,
uci->pucch_fmt,
- i,
+ uci->ue_id,
uci->n_pucch_1_0_sr[0],
0, //n2_pucch
uci->srs_active, // shortened format
@@ -778,7 +778,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
#if 1
metric[0] = rx_pucch(eNB,
uci->pucch_fmt,
- i,
+ uci->ue_id,
uci->n_pucch_1[0][0],
0, //n2_pucch
uci->srs_active, // shortened format
@@ -798,7 +798,7 @@ uci_procedures(PHY_VARS_eNB *eNB,
SR_payload = 1;
metric[0] = rx_pucch(eNB,
pucch_format1b,
- i,
+ uci->ue_id,
uci->n_pucch_1_0_sr[0],
0, //n2_pucch
uci->srs_active, // shortened format
@@ -1136,11 +1136,11 @@ uci_procedures(PHY_VARS_eNB *eNB,
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);
+ if (eNB->first_sr[uci->ue_id] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4
+ eNB->first_sr[uci->ue_id] = 0;
+ eNB->dlsch[uci->ue_id][0]->harq_processes[0]->round = 0;
+ eNB->dlsch[uci->ue_id][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[uci->ue_id]->rnti, frame, subframe);
}
}
}
@@ -1463,7 +1463,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) {
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]);
+ int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
if (SNRtimes10 < -640)
pdu->rx_indication_rel8.ul_cqi = 0;
@@ -1516,8 +1516,10 @@ static void do_release_harq(PHY_VARS_eNB *eNB,
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);
-
+ if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
+ LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
+ return;
+ }
dlsch0_harq = dlsch0->harq_processes[harq_pid];
dlsch1_harq = dlsch1->harq_processes[harq_pid];
@@ -1566,37 +1568,39 @@ static void do_release_harq(PHY_VARS_eNB *eNB,
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];
+ if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
+ LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
+ return;
+ }
+ dlsch0_harq = dlsch0->harq_processes[harq_pid];
+ dlsch1_harq = dlsch1->harq_processes[harq_pid];
- AssertFatal(dlsch0_harq != NULL, "Dlsch0_harq is null\n");
+ 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 (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 ((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
@@ -1635,7 +1639,7 @@ int getM(PHY_VARS_eNB *eNB,int frame,int subframe) {
harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx];
- if (harq_pid>=0 && harq_pid<10) {
+ if (harq_pid>=0 && harq_pidMdlharq) {
dlsch0_harq = dlsch0->harq_processes[harq_pid];
dlsch1_harq = dlsch1->harq_processes[harq_pid];
AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
@@ -1651,8 +1655,9 @@ int getM(PHY_VARS_eNB *eNB,int frame,int subframe) {
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];
+ nfapi_cqi_indication_pdu_t *pdu = &eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_pdu_list[eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis];
+ nfapi_cqi_indication_raw_pdu_t *raw_pdu = &eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_raw_pdu_list[eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis];
+ pdu->instance_length = 0;
pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
pdu->rx_ue_information.rnti = rnti;
@@ -1678,9 +1683,11 @@ void fill_ulsch_cqi_indication (PHY_VARS_eNB *eNB, uint16_t frame, uint8_t subfr
pdu->cqi_indication_rel9.number_of_cc_reported = 1;
pdu->ul_cqi_information.channel = 1; // PUSCH
+ pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
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);
+ eNB->UL_INFO.cqi_ind.cqi_indication_body.tl.tag = NFAPI_CQI_INDICATION_BODY_TAG;
+ eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis++;
+ LOG_D(PHY,"eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis:%d\n", eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis);
pthread_mutex_unlock(&eNB->UL_INFO_mutex);
}
@@ -1769,7 +1776,7 @@ void fill_uci_harq_indication (PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, i
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]);
+ int SNRtimes10 = dB_fixed_times10(uci->stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0];
if (SNRtimes10 < -100)
LOG_I (PHY, "uci->stat %d \n", uci->stat);
@@ -1997,3 +2004,44 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 );
}
+
+void release_rnti_of_phy(module_id_t mod_id){
+ int i,j;
+ int CC_id;
+ rnti_t rnti;
+ PHY_VARS_eNB *eNB_PHY = NULL;
+ LTE_eNB_ULSCH_t *ulsch = NULL;
+ LTE_eNB_DLSCH_t *dlsch = NULL;
+ for(i = 0; i< release_rntis.number_of_TLVs;i++){
+ for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+ eNB_PHY = RC.eNB[mod_id][CC_id];
+ rnti = release_rntis.ue_release_request_TLVs_list[i].rnti;
+ for (j=0; julsch[j];
+ if((ulsch != NULL) && (ulsch->rnti == rnti)){
+ LOG_I(PHY, "clean_eNb_ulsch ulsch[%d] UE %x\n", j, rnti);
+ clean_eNb_ulsch(ulsch);
+ }
+
+ dlsch = eNB_PHY->dlsch[j][0];
+ if((dlsch != NULL) && (dlsch->rnti == rnti)){
+ LOG_I(PHY, "clean_eNb_dlsch dlsch[%d] UE %x \n", j, rnti);
+ clean_eNb_dlsch(dlsch);
+ }
+ }
+ ulsch = eNB_PHY->ulsch[j];
+ if((ulsch != NULL) && (ulsch->rnti == rnti)){
+ LOG_I(PHY, "clean_eNb_ulsch ulsch[%d] UE %x\n", j, rnti);
+ clean_eNb_ulsch(ulsch);
+ }
+ for(j=0; juci_vars[j].rnti == rnti){
+ LOG_I(PHY, "clean eNb uci_vars[%d] UE %x \n",j, rnti);
+ memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
+ }
+
+ }
+ }
+ }
+ memset(&release_rntis, 0, sizeof(nfapi_ue_release_request_body_t));
+}
diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c
index 928b272edd..1f1a36b238 100644
--- a/openair1/SCHED/ru_procedures.c
+++ b/openair1/SCHED/ru_procedures.c
@@ -100,7 +100,7 @@ void feptx0(RU_t *ru,int slot) {
*/
int num_symb = 7;
- if (subframe_select(fp,subframe) == SF_S) num_symb=fp->dl_symbols_in_S_subframe;
+ if (subframe_select(fp,subframe) == SF_S) num_symb=fp->dl_symbols_in_S_subframe+1;
if (ru->generate_dmrs_sync == 1 && slot == 0 && subframe == 1 && aa==0) {
//int32_t dmrs[ru->frame_parms.ofdm_symbol_size*14] __attribute__((aligned(32)));
diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h
index dccfbf7c38..7fcabdc5dd 100644
--- a/openair1/SCHED/sched_eNB.h
+++ b/openair1/SCHED/sched_eNB.h
@@ -219,6 +219,7 @@ int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subf
void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset);
+void release_rnti_of_phy(module_id_t mod_id);
/*@}*/
diff --git a/openair1/SIMULATION/LTE_PHY/dummy_functions.c b/openair1/SIMULATION/LTE_PHY/dummy_functions.c
index 7f5fa1fb75..d3c6381d72 100644
--- a/openair1/SIMULATION/LTE_PHY/dummy_functions.c
+++ b/openair1/SIMULATION/LTE_PHY/dummy_functions.c
@@ -91,5 +91,5 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);}
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); }
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); }
-
+int oai_nfapi_ue_release_req(nfapi_ue_release_request_t *release_req){ return(0); }
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index df6781cea2..a90d199526 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -618,8 +618,8 @@ int main(int argc, char **argv) {
eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list;
eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list;
eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list;
- eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list;
- eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list;
+ eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_pdu_list = eNB->cqi_pdu_list;
+ eNB->UL_INFO.cqi_ind.cqi_indication_body.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 **));
diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c
index 8341c574da..f056d51b5d 100644
--- a/openair1/SIMULATION/TOOLS/random_channel.c
+++ b/openair1/SIMULATION/TOOLS/random_channel.c
@@ -1204,6 +1204,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
return(chan_desc);
}
+void free_channel_desc_scm(channel_desc_t * ch) {
+ // Must be made cleanly, a lot of leaks...
+ free(ch);
+}
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
diff --git a/openair2/COMMON/gtpv1_u_messages_def.h b/openair2/COMMON/gtpv1_u_messages_def.h
index 27723eec15..1948f1596a 100644
--- a/openair2/COMMON/gtpv1_u_messages_def.h
+++ b/openair2/COMMON/gtpv1_u_messages_def.h
@@ -25,4 +25,8 @@ MESSAGE_DEF(GTPV1U_ENB_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_del
MESSAGE_DEF(GTPV1U_ENB_DELETE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, gtpv1u_enb_delete_tunnel_resp_t, Gtpv1uDeleteTunnelResp)
MESSAGE_DEF(GTPV1U_ENB_TUNNEL_DATA_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_tunnel_data_ind_t, Gtpv1uTunnelDataInd)
MESSAGE_DEF(GTPV1U_ENB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_tunnel_data_req_t, Gtpv1uTunnelDataReq)
+MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_data_forwarding_req_t,Gtpv1uDataForwardingReq)
+MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_data_forwarding_ind_t,Gtpv1uDataForwardingInd)
+MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_req_t, Gtpv1uEndMarkerReq)
+MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd)
MESSAGE_DEF(GTPV1U_ENB_S1_REQ, MESSAGE_PRIORITY_MED, Gtpv1uS1Req, gtpv1uS1Req)
diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h
index c398b55e3e..4f81c22fb0 100644
--- a/openair2/COMMON/gtpv1_u_messages_types.h
+++ b/openair2/COMMON/gtpv1_u_messages_types.h
@@ -33,10 +33,33 @@
#define GTPV1U_ENB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDeleteTunnelResp
#define GTPV1U_ENB_TUNNEL_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uTunnelDataInd
#define GTPV1U_ENB_TUNNEL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uTunnelDataReq
+#define GTPV1U_ENB_DATA_FORWARDING_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDataForwardingReq
+#define GTPV1U_ENB_DATA_FORWARDING_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uDataForwardingInd
+#define GTPV1U_ENB_END_MARKER_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerReq
+#define GTPV1U_ENB_END_MARKER_IND(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uEndMarkerInd
+
#define GTPV1U_ENB_S1_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uS1Req
#define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF
+typedef struct gtpv1u_enb_create_x2u_tunnel_req_s {
+ rnti_t rnti;
+ int num_tunnels;
+ teid_t tenb_X2u_teid[GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
+ ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
+ transport_layer_addr_t enb_addr[GTPV1U_MAX_BEARERS_PER_UE];
+} gtpv1u_enb_create_x2u_tunnel_req_t;
+
+typedef struct gtpv1u_enb_create_x2u_tunnel_resp_s {
+ uint8_t status; ///< Status of S1U endpoint creation (Failed = 0xFF or Success = 0x0)
+ rnti_t rnti;
+ int num_tunnels;
+ teid_t enb_X2u_teid[GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier
+ ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE];
+ transport_layer_addr_t enb_addr;
+} gtpv1u_enb_create_x2u_tunnel_resp_t;
+
+
typedef struct gtpv1u_enb_create_tunnel_req_s {
rnti_t rnti;
int num_tunnels;
@@ -99,6 +122,50 @@ typedef struct gtpv1u_enb_tunnel_data_req_s {
rb_id_t rab_id;
} gtpv1u_enb_tunnel_data_req_t;
+typedef struct gtpv1u_enb_data_forwarding_req_s {
+ uint8_t *buffer;
+ uint32_t length;
+ uint32_t offset; ///< start of message offset in buffer
+ rnti_t rnti;
+ rb_id_t rab_id;
+} gtpv1u_enb_data_forwarding_req_t;
+
+typedef struct gtpv1u_enb_data_forwarding_ind_s {
+ uint32_t frame;
+ uint8_t enb_flag;
+ uint32_t rb_id;
+ uint32_t muip;
+ uint32_t confirmp;
+ uint32_t sdu_size;
+ uint8_t *sdu_p;
+ uint8_t mode;
+ uint16_t rnti;
+ uint8_t module_id;
+ uint8_t eNB_index;
+} gtpv1u_enb_data_forwarding_ind_t;
+
+typedef struct gtpv1u_enb_end_marker_req_s {
+ uint8_t *buffer;
+ uint32_t length;
+ uint32_t offset; ///< start of message offset in buffer
+ rnti_t rnti;
+ rb_id_t rab_id;
+} gtpv1u_enb_end_marker_req_t;
+
+typedef struct gtpv1u_enb_end_marker_ind_s {
+ uint32_t frame;
+ uint8_t enb_flag;
+ uint32_t rb_id;
+ uint32_t muip;
+ uint32_t confirmp;
+ uint32_t sdu_size;
+ uint8_t *sdu_p;
+ uint8_t mode;
+ uint16_t rnti;
+ uint8_t module_id;
+ uint8_t eNB_index;
+} gtpv1u_enb_end_marker_ind_t;
+
typedef struct {
in_addr_t enb_ip_address_for_S1u_S12_S4_up;
tcp_udp_port_t enb_port_for_S1u_S12_S4_up;
diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h
index d284f4d0b9..5f2a95f576 100644
--- a/openair2/COMMON/x2ap_messages_types.h
+++ b/openair2/COMMON/x2ap_messages_types.h
@@ -107,6 +107,8 @@ typedef struct x2ap_register_enb_req_s {
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
+ uint32_t subframeAssignment[MAX_NUM_CCs];
+ uint32_t specialSubframe[MAX_NUM_CCs];
int num_cc;
/* To be considered for TDD */
@@ -205,7 +207,7 @@ typedef struct x2ap_handover_req_s {
x2ap_lastvisitedcell_info_t lastvisitedcell_info;
- uint8_t rrc_buffer[1024 /* arbitrary, big enough */];
+ uint8_t rrc_buffer[8192 /* arbitrary, big enough */];
int rrc_buffer_size;
int target_assoc_id;
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 290b1c8cdf..a957e11bcd 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -160,7 +160,7 @@ void RCconfig_L1(void) {
LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_inst=1 this is because phy_init_RU() uses that to index and not RC.num_eNB - why the 2 similar variables?\n", __FUNCTION__);
LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_CC[0]=%d for init_eNB_afterRU()\n", __FUNCTION__, RC.nb_CC[0]);
LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_macrlc_inst:%d because used by mac_top_init_eNB()\n", __FUNCTION__, RC.nb_macrlc_inst);
- //mac_top_init_eNB();
+ mac_top_init_eNB();
configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd,
RC.eNB[j][0]->eth_params_n .remote_portd);
} else { // other midhaul
@@ -2509,6 +2509,8 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
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;
+ X2AP_REGISTER_ENB_REQ (msg_p).subframeAssignment[J] = ccparams_lte.tdd_config;
+ X2AP_REGISTER_ENB_REQ (msg_p).specialSubframe[J] = ccparams_lte.tdd_config_s;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index 63aeee09e4..2caba47e2b 100644
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -104,6 +104,7 @@ typedef enum {
#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 CONFIG_STRING_RU_OTA_SYNC_ENABLE "ota_sync_enabled"
#define RU_LOCAL_IF_NAME_IDX 0
#define RU_LOCAL_ADDRESS_IDX 1
@@ -128,6 +129,7 @@ typedef enum {
#define RU_SDR_CLK_SRC 20
#define RU_SF_EXTENSION_IDX 21
#define RU_END_OF_BURST_DELAY_IDX 22
+#define RU_OTA_SYNC_ENABLE_IDX 23
@@ -153,12 +155,13 @@ typedef enum {
{CONFIG_STRING_RU_ENB_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \
{CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
-{CONFIG_STRING_RU_IS_SLAVE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
+{CONFIG_STRING_RU_IS_SLAVE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 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_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}, \
+{CONFIG_STRING_RU_OTA_SYNC_ENABLE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
}
/*---------------------------------------------------------------------------------------------------------------------------------------*/
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index cc6751ddb1..ec2497d6ad 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -113,22 +113,22 @@ static const eutra_bandentry_t eutra_bandtable[] = {
{30, 23050, 23250, 23500, 23600, 97700},
{31, 45250, 34900, 46250, 35900, 98700},
{32, 0, 0, 14520, 14960, 99200},
- {33, 19000, 19200, 19000, 19200, 36000},
- {34, 20100, 20250, 20100, 20250, 36200},
- {35, 18500, 19100, 18500, 19100, 36350},
- {36, 19300, 19900, 19300, 19900, 36950},
- {37, 19100, 19300, 19100, 19300, 37550},
- {38, 25700, 26200, 25700, 26300, 37750},
- {39, 18800, 19200, 18800, 19200, 38250},
- {40, 23000, 24000, 23000, 24000, 38650},
- {41, 24960, 26900, 24960, 26900, 39650},
- {42, 34000, 36000, 34000, 36000, 41590},
- {43, 36000, 38000, 36000, 38000, 43590},
- {44, 7030, 8030, 7030, 8030, 45590},
- {45, 14470, 14670, 14470, 14670, 46590},
- {46, 51500, 59250, 51500, 59250, 46790},
- {65, 19200, 20100, 21100, 22000, 65536},
- {66, 17100, 18000, 21100, 22000, 66436},
+ {33, 19000, 19200, 19000, 19200, 360000},
+ {34, 20100, 20250, 20100, 20250, 362000},
+ {35, 18500, 19100, 18500, 19100, 363500},
+ {36, 19300, 19900, 19300, 19900, 369500},
+ {37, 19100, 19300, 19100, 19300, 375500},
+ {38, 25700, 26200, 25700, 26300, 377500},
+ {39, 18800, 19200, 18800, 19200, 382500},
+ {40, 23000, 24000, 23000, 24000, 386500},
+ {41, 24960, 26900, 24960, 26900, 396500},
+ {42, 34000, 36000, 34000, 36000, 415900},
+ {43, 36000, 38000, 36000, 38000, 435900},
+ {44, 7030, 8030, 7030, 8030, 455900},
+ {45, 14470, 14670, 14470, 14670, 465900},
+ {46, 51500, 59250, 51500, 59250, 467900},
+ {65, 19200, 20100, 21100, 22000, 655360},
+ {66, 17100, 18000, 21100, 22000, 664360},
{67, 0, 0, 7380, 7580, 67336},
{68, 6980, 7280, 7530, 7830, 67536}
};
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index 4e781e5b3f..45b46aae54 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -600,10 +600,10 @@ 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
- int32_t normalized_rx_power;
- /// target rx power
- int32_t target_rx_power;
+ /// snr
+ int32_t snr;
+ /// target snr
+ int32_t target_snr;
/// num rx pdu
uint32_t num_pdu_rx[NB_RB_MAX];
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index c6200dc74d..3a809c4327 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -126,9 +126,11 @@ void schedule_SRS(module_id_t module_idP,
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) {
+ LOG_E(MAC,"physicalConfigDedicated is null for UE %d\n",UE_id);
+ printf("physicalConfigDedicated is null for UE %d\n",UE_id);
+ return;
+ }
/* CDRX condition on Active Time and SRS type-0 report (36.321 5.7) */
UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
@@ -462,6 +464,7 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
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;
+ DL_req[CC_id].sfn_sf = frameP<<4 | subframeP;
LOG_D(MAC,
"UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",
UE_id, rnti,
@@ -506,6 +509,13 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1;
}
} // ul_failure_timer>0
+
+ UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++;
+ if((U_PLANE_INACTIVITY_VALUE != 0) && (UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE * 10))){
+ LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti);
+ mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti);
+ UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
+ }// time > 60s
}
void
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index f7b11511fc..9a908313ba 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -868,8 +868,10 @@ generate_Msg4(module_id_t module_idP,
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.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 = ra->rnti;
+ ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.tl.tag = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL13_TAG;
ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (ra->rach_resource_type < 3) ? 1 : 2;
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];
@@ -957,9 +959,12 @@ generate_Msg4(module_id_t module_idP,
1, // tpc, none
getRIV(N_RB_DL, first_rb, 4), // resource_block_coding
ra->msg4_mcs, // mcs
- 1, // ndi
+ 1 - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid],
0, // rv
0); // vrb_flag
+
+ UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid] = 1 - UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid];
+
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,
@@ -1049,7 +1054,7 @@ generate_Msg4(module_id_t module_idP,
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,
+ rrc_sdu_length+offset,
mac->pdu_index[CC_idP],
mac->UE_list.
DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]);
@@ -1194,7 +1199,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
1, // tpc, none
getRIV(N_RB_DL, first_rb, 4), // resource_block_coding
ra->msg4_mcs, // mcs
- 1, // ndi
+ UE_list->UE_template[CC_idP][UE_id].oldNDI[ra->harq_pid],
round & 3, // rv
0); // vrb_flag
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
index fb80c9e1d6..d523fb4e17 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
@@ -1158,6 +1158,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for S_RNTI\n", frameP, subframeP);
dl_req->number_dci++;
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));
@@ -1188,6 +1189,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
dl_req->number_pdu++;
+ dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
// Rel10 fields
dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL10_TAG;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index ddbda5b2a0..134089dbf4 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -488,7 +488,7 @@ schedule_ue_spec(module_id_t 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 snr, target_snr;
int tpc = 1;
UE_sched_ctrl_t *ue_sched_ctrl;
int mcs;
@@ -717,9 +717,12 @@ schedule_ue_spec(module_id_t module_idP,
eNB_UE_stats->harq_pid = harq_pid;
eNB_UE_stats->harq_round = round_DL;
+ if (eNB_UE_stats->rrc_status < RRC_RECONFIGURED) {
+ ue_sched_ctrl->uplane_inactivity_timer = 0;
+ }
+
if (eNB_UE_stats->rrc_status < RRC_CONNECTED) {
- LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n",
- UE_id);
+ LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", UE_id);
continue;
}
@@ -733,7 +736,7 @@ schedule_ue_spec(module_id_t module_idP,
eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE);
*/
if (NFAPI_MODE != NFAPI_MONOLITHIC) {
- eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctrl->dl_cqi[CC_id]];
+ eNB_UE_stats->dlsch_mcs1 = 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);
@@ -1006,9 +1009,11 @@ schedule_ue_spec(module_id_t module_idP,
, 0
#endif
);
- pthread_mutex_lock(&rrc_release_freelist);
if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) {
+ while(pthread_mutex_trylock(&rrc_release_freelist)){
+ /* spin... */
+ }
uint16_t release_total = 0;
for (release_num = 0, release_ctrl = &rrc_release_info.RRC_release_ctrl[0];
@@ -1055,9 +1060,9 @@ schedule_ue_spec(module_id_t module_idP,
if(release_total >= rrc_release_info.num_UEs)
break;
}
+ pthread_mutex_unlock(&rrc_release_freelist);
}
- pthread_mutex_unlock(&rrc_release_freelist);
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)) {
@@ -1477,11 +1482,11 @@ schedule_ue_spec(module_id_t module_idP,
}
// do PUCCH power control
- // this is the normalized RX power
+ // this is the snr
// 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_ctrl->pucch1_snr[CC_id]) - 640) / 10) + 30;
- target_rx_power= (eNB->puCch10xSnr / 10) + 30;
+ // converting to dBm
+ snr = (5 * ue_sched_ctrl->pucch1_snr[CC_id] - 640) / 10;
+ target_snr = eNB->puCch10xSnr / 10;
// 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->pucch_tpc_tx_frame * 10 + ue_template->pucch_tpc_tx_subframe;
@@ -1493,22 +1498,22 @@ schedule_ue_spec(module_id_t module_idP,
ue_template->pucch_tpc_tx_frame = frameP;
ue_template->pucch_tpc_tx_subframe = subframeP;
- if (normalized_rx_power > (target_rx_power + 4)) {
+ if (snr > target_snr + 4) {
tpc = 0; //-1
- } else if (normalized_rx_power < (target_rx_power - 4)) {
+ } else if (snr < target_snr - 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",
+ LOG_D(MAC, "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, snr/target snr %d/%d\n",
module_idP,
frameP,
subframeP,
harq_pid,
tpc,
- normalized_rx_power,
- target_rx_power);
+ snr,
+ target_snr);
} // Po_PUCCH has been updated
else {
tpc = 1; //0
@@ -1889,8 +1894,8 @@ schedule_ue_spec_br(module_id_t module_idP,
int round_DL = 0;
int ta_update = 0;
int32_t tpc = 1;
- int32_t normalized_rx_power = 0;
- int32_t target_rx_power = 0;
+ int32_t snr = 0;
+ int32_t target_snr = 0;
uint16_t TBS = 0;
uint16_t j = 0;
uint16_t sdu_lengths[NB_RB_MAX];
@@ -2368,10 +2373,10 @@ schedule_ue_spec_br(module_id_t module_idP,
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 is the snr */
+ /* unit is not dBm, it's special from nfapi, convert to dBm */
+ snr = (5 * ue_sched_ctl->pucch1_snr[CC_id] - 640) / 10;
+ target_snr = mac->puCch10xSnr / 10;
/* 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;
@@ -2384,22 +2389,22 @@ schedule_ue_spec_br(module_id_t module_idP,
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)) {
+ if (snr > target_snr + 4) {
tpc = 0; //-1
- } else if (normalized_rx_power<(target_rx_power - 4)) {
+ } else if (snr < target_snr - 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",
+ LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, snr/target snr %d/%d\n",
module_idP,
frameP,
subframeP,
harq_pid,
tpc,
- normalized_rx_power,
- target_rx_power);
+ snr,
+ target_snr);
} else { // Po_PUCCH has been updated
tpc = 1; // 0
}
@@ -3084,11 +3089,9 @@ schedule_PCH(module_id_t module_idP,
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.new_data_indicator_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.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;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
index 697c738b80..c071c1f505 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
@@ -585,6 +585,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id,
// uint16_t r1=0;
uint8_t CC_id;
UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
+ int N_RB_DL;
UE_sched_ctrl_t *ue_sched_ctl;
// int rrc_status = RRC_IDLE;
COMMON_channels_t *cc;
@@ -600,6 +601,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id,
#endif
memset(rballoc_sub[0],0,(MAX_NUM_CCs)*(N_RBG_MAX)*sizeof(unsigned char));
memset(min_rb_unit,0,sizeof(min_rb_unit));
+ memset(MIMO_mode_indicator[0], 0, MAX_NUM_CCs*N_RBG_MAX*sizeof(unsigned char));
for (CC_id=0; CC_id 0) // If this CC is allocated for MBSFN skip it here
@@ -640,7 +642,18 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id,
average_rbs_per_user[CC_id] = 0;
cc = &RC.mac[Mod_id]->common_channels[CC_id];
// Get total available RBS count and total UE count
- temp_total_rbs_count = RC.mac[Mod_id]->eNB_stats[CC_id].available_prbs;
+ N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
+ temp_total_rbs_count = 0;
+ for(uint8_t rbg_i = 0;rbg_i < N_RBG[CC_id];rbg_i++ ){
+ if(rballoc_sub[CC_id][rbg_i] == 0){
+ if((rbg_i == N_RBG[CC_id] -1) &&
+ ((N_RB_DL == 25) || (N_RB_DL == 50))){
+ temp_total_rbs_count += (min_rb_unit[CC_id] -1);
+ }else{
+ temp_total_rbs_count += min_rb_unit[CC_id];
+ }
+ }
+ }
temp_total_ue_count = dlsch_ue_select[CC_id].ue_num;
for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) {
@@ -825,7 +838,7 @@ schedule_ue_spec_fairRR(module_id_t 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 snr, target_snr;
int32_t tpc = 1;
static int32_t tpc_accumulated = 0;
UE_sched_ctrl_t *ue_sched_ctl;
@@ -1001,6 +1014,10 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
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_RECONFIGURED) {
+ UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
+ }
+
if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status <
RRC_CONNECTED)
continue;
@@ -1013,7 +1030,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE);
*/
if (NFAPI_MODE != NFAPI_MONOLITHIC) {
- eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]];
+ eNB_UE_stats->dlsch_mcs1 = 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]];
}
@@ -1287,9 +1304,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
,0, 0
#endif
);
- pthread_mutex_lock(&rrc_release_freelist);
- if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) {
+ if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)){
+ while(pthread_mutex_trylock(&rrc_release_freelist)) {
+ /* spin... */
+ }
uint16_t release_total = 0;
for(uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
@@ -1326,9 +1345,9 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
if(release_total >= rrc_release_info.num_UEs)
break;
}
+ pthread_mutex_unlock(&rrc_release_freelist);
}
- 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++) {
@@ -1720,11 +1739,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
}
// do PUCCH power control
- // this is the normalized RX power
+ // this is the snr
eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
/* Unit is not dBm, it's special from nfapi */
- normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30;//(+eNB->measurements.n0_power_dB[0])
- target_rx_power= eNB->puCch10xSnr/10 + 30;//(+eNB->measurements.n0_power_dB[0])
+ snr = (5 * ue_sched_ctl->pucch1_snr[CC_id] - 640) / 10;
+ target_snr = eNB->puCch10xSnr / 10;
// 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;
@@ -1736,19 +1755,19 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
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)) {
+ if (snr > target_snr + 4) {
tpc = 0; //-1
tpc_accumulated--;
- } else if (normalized_rx_power<(target_rx_power-4)) {
+ } else if (snr < target_snr - 4) {
tpc = 2; //+1
tpc_accumulated++;
} else {
tpc = 1; //0
}
- LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
+ LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n",
module_idP,frameP, subframeP,harq_pid,tpc,
- tpc_accumulated,normalized_rx_power,target_rx_power);
+ tpc_accumulated,snr,target_snr);
} // Po_PUCCH has been updated
else {
tpc = 1; //0
@@ -1763,6 +1782,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
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);
+ 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
@@ -1972,7 +1992,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
uint8_t cc_id_flag[MAX_NUM_CCs];
uint8_t harq_pid = 0,round = 0;
UE_list_t *UE_list= &eNB->UE_list;
- uint8_t aggregation = 2;
+ uint8_t aggregation;
int format_flag;
nfapi_hi_dci0_request_body_t *HI_DCI0_req;
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
@@ -2031,7 +2051,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
if ( round > 0 ) {
hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
format_flag = 2;
-
+ aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0);
if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
cc_id_flag[CC_id] = 1;
continue;
@@ -2110,7 +2130,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
format_flag = 2;
rnti = UE_RNTI(module_idP,first_ue_id[CC_id][temp]);
-
+ aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[first_ue_id[CC_id][temp]].dl_cqi[CC_id],format0);
if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
cc_id_flag[CC_id] = 1;
break;
@@ -2182,7 +2202,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
((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)) ) {
hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
format_flag = 2;
-
+ aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0);
if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
cc_id_flag[CC_id] = 1;
continue;
@@ -2235,7 +2255,7 @@ void ulsch_scheduler_pre_ue_select_fairRR(
hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
format_flag = 2;
rnti = UE_RNTI(module_idP,ul_inactivity_id[CC_id][temp]);
-
+ aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[ul_inactivity_id[CC_id][temp]].dl_cqi[CC_id],format0);
if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
cc_id_flag[CC_id] = 1;
continue;
@@ -2402,8 +2422,8 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id])) &&
((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) {
rb_table_index++;
- tbs = get_TBS_UL(mcs,rb_table[rb_table_index])<<3;
- tx_power= estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0);
+ tbs = get_TBS_UL(mcs,rb_table[rb_table_index]);
+ tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0);
}
if ( rb_table[rb_table_index]<3 ) {
@@ -2434,12 +2454,20 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs;
}
} else {
- // assigne RBS( 3 RBs)
- first_rb[CC_id] = first_rb[CC_id] + 3;
- UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3;
- UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2;
- UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
- }
+ if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED){
+ // assigne RBS( 6 RBs)
+ first_rb[CC_id] = first_rb[CC_id] + 6;
+ UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 6;
+ UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 5;
+ UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
+ }else{
+ // assigne RBS( 3 RBs)
+ first_rb[CC_id] = first_rb[CC_id] + 3;
+ UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3;
+ UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2;
+ UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
+ }
+ }
} else if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE ) {
// assigne RBS( 3 RBs)
first_rb[CC_id] = first_rb[CC_id] + 3;
@@ -2609,7 +2637,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
unsigned char sched_subframeP,
ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]) {
int16_t UE_id;
- uint8_t aggregation = 2;
+ uint8_t aggregation;
uint16_t first_rb[MAX_NUM_CCs];
uint8_t ULSCH_first_end;
rnti_t rnti = -1;
@@ -2618,8 +2646,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
uint8_t status = 0;
uint8_t rb_table_index = -1;
uint32_t cqi_req,cshift,ndi,tpc;
- int32_t normalized_rx_power;
- int32_t target_rx_power=-90;
+ int32_t snr;
+ int32_t target_snr=0;
static int32_t tpc_accumulated=0;
int CC_id,ulsch_ue_num;
int N_RB_UL;
@@ -2738,6 +2766,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
harq_pid = subframe2harqpid(cc,sched_frame,sched_subframeP);
rnti = UE_RNTI(CC_id,UE_id);
+ aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0);
LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n",
module_idP,frameP,subframeP,harq_pid,UE_id,rnti,CC_id, aggregation,N_RB_UL);
int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes;
@@ -2757,12 +2786,12 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
if (cc->tdd_Config) {
switch (cc->tdd_Config->subframeAssignment) {
case 1:
- if( subframeP == 1 || subframeP == 6 ) cqi_req=0;
+ if( sched_subframeP == 1 || sched_subframeP == 6 ) cqi_req=0;
break;
case 3:
- if( subframeP == 1 ) cqi_req=0;
+ if( sched_subframeP == 1 ) cqi_req=0;
break;
@@ -2782,8 +2811,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
//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 = (5*UE_sched_ctrl->pusch_snr[CC_id]-640)/10+30; //(+eNB->measurements.n0_power_dB[0])
- target_rx_power= eNB->puSch10xSnr/10 + 30; //(+eNB->measurements.n0_power_dB[0])
+ snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10;
+ target_snr = eNB->puSch10xSnr / 10;
// 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;
@@ -2793,10 +2822,10 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
UE_template->pusch_tpc_tx_frame=frameP;
UE_template->pusch_tpc_tx_subframe=subframeP;
- if (normalized_rx_power>(target_rx_power+4)) {
+ if (snr > target_snr + 4) {
tpc = 0; //-1
tpc_accumulated--;
- } else if (normalized_rx_power<(target_rx_power-4)) {
+ } else if (snr < target_snr - 4) {
tpc = 2; //+1
tpc_accumulated++;
} else {
@@ -2807,9 +2836,9 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
}
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",
+ LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n",
module_idP,frameP,subframeP,harq_pid,tpc,
- tpc_accumulated,normalized_rx_power,target_rx_power);
+ tpc_accumulated,snr,target_snr);
}
// new transmission
@@ -2822,8 +2851,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
UE_sched_ctrl->cqi_req_timer);
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].snr = snr;
+ UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul;
UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
@@ -2872,6 +2901,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
memset((void *)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu);
+ 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.dci_format = NFAPI_UL_DCI_FORMAT_0;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti;
@@ -2998,8 +3028,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
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(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));
- 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].snr = snr;
+ UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
uint8_t mcs_rv = 0;
if(rvidx_tab[round&3]==1) {
@@ -3029,6 +3059,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP,
memset((void *)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu);
+ 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.dci_format = NFAPI_UL_DCI_FORMAT_0;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
index 4f74ab0d09..18f35d4fe3 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
@@ -199,8 +199,8 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
uint8_t mcs = 20;
uint8_t harq_pid = 0;
uint32_t cqi_req = 0,cshift,ndi,tpc = 1;
- int32_t normalized_rx_power;
- int32_t target_rx_power= 178;
+ int32_t snr;
+ int32_t target_snr = 10; /* TODO: target_rx_power was 178, what to put? is it meaningful? */
int CC_id = 0;
int nb_rb = 24;
int N_RB_UL;
@@ -258,15 +258,15 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
//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 = (5*UE_sched_ctrl->pusch_snr[CC_id]-640)/10+30;
+ // this is the snr and this should be constant (regardless of mcs)
+ snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10;
// new transmission
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].snr = snr;
+ UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = mcs;
UE_template->mcs_UL[harq_pid] = mcs;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = mcs;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 856045166f..63f838f652 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -2193,8 +2193,8 @@ add_new_ue(module_id_t mod_idP,
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] = 0;
+ UE_list->UE_template[cc_idP][UE_id].oldNDI_UL[j] = 0;
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;
}
@@ -2319,9 +2319,10 @@ rrc_mac_remove_ue(module_id_t mod_idP,
rntiP);
}
- pthread_mutex_lock(&rrc_release_freelist);
-
- if (rrc_release_info.num_UEs > 0) {
+ if(rrc_release_info.num_UEs > 0){
+ while(pthread_mutex_trylock(&rrc_release_freelist)) {
+ /* spin... */
+ }
uint16_t release_total = 0;
for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
@@ -2341,6 +2342,7 @@ rrc_mac_remove_ue(module_id_t mod_idP,
break;
}
}
+ pthread_mutex_unlock(&rrc_release_freelist);
}
pthread_mutex_unlock(&rrc_release_freelist);
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index dd228c4250..be1f838aaa 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -460,7 +460,7 @@ rx_sdu(const module_id_t enb_mod_idP,
if (RA_id != -1) {
RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]);
- mac_rrc_data_ind(enb_mod_idP,
+ int8_t ret = mac_rrc_data_ind(enb_mod_idP,
CC_idP,
frameP, subframeP,
UE_id,
@@ -474,6 +474,7 @@ rx_sdu(const module_id_t enb_mod_idP,
#endif
);
/* Received a new rnti */
+ if (ret == 0) {
ra->state = MSGCRNTI;
LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Received rnti(Msg4)\n",
enb_mod_idP,
@@ -502,6 +503,9 @@ rx_sdu(const module_id_t enb_mod_idP,
}
UE_template_ptr->ul_SR = 1;
UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1;
+ } else {
+ cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
+ }
// break;
}
}
@@ -797,6 +801,10 @@ rx_sdu(const module_id_t enb_mod_idP,
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); //(unsigned int*)crc_status);
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];
+
+ if (mac_eNB_get_rrc_status(enb_mod_idP, current_rnti) < RRC_RECONFIGURED) {
+ UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
+ }
}
break;
@@ -1329,8 +1337,8 @@ schedule_ulsch_rnti(module_id_t module_idP,
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 snr = 0;
+ int32_t target_snr = 0;
int32_t framex10psubframe = 0;
static int32_t tpc_accumulated = 0;
int sched_frame = 0;
@@ -1555,13 +1563,12 @@ schedule_ulsch_rnti(module_id_t module_idP,
/* 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)
+ * Compute the expected ULSCH RX snr (for the stats)
+ * This is the normalized RX snr 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;
+ snr = (5 * UE_sched_ctrl_ptr->pusch_snr[CC_id] - 640) / 10;
+ target_snr = mac->puSch10xSnr / 10;
/*
* This assumes accumulated tpc
@@ -1575,10 +1582,10 @@ schedule_ulsch_rnti(module_id_t module_idP,
UE_template_ptr->pusch_tpc_tx_frame = frameP;
UE_template_ptr->pusch_tpc_tx_subframe = subframeP;
- if (normalized_rx_power > (target_rx_power + 4)) {
+ if (snr > target_snr + 4) {
tpc = 0; // -1
tpc_accumulated--;
- } else if (normalized_rx_power < (target_rx_power - 4)) {
+ } else if (snr < target_snr - 4) {
tpc = 2; // +1
tpc_accumulated++;
} else {
@@ -1589,21 +1596,21 @@ schedule_ulsch_rnti(module_id_t module_idP,
}
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",
+ LOG_D(MAC, "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n",
module_idP,
frameP,
subframeP,
harq_pid,
tpc,
tpc_accumulated,
- normalized_rx_power,
- target_rx_power);
+ snr,
+ target_snr);
}
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_list->eNB_UE_stats[CC_id][UE_id].snr = snr;
+ UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
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];
@@ -1941,8 +1948,8 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
uint8_t status = 0;
uint32_t cshift = 0;
uint32_t ndi = 0;
- int32_t normalized_rx_power = 0;
- int32_t target_rx_power = -90;
+ int32_t snr = 0;
+ int32_t target_snr = 0;
int n = 0;
int CC_id = 0;
int N_RB_UL = 0;
@@ -2050,10 +2057,10 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
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;
+ /* Power control: compute the expected ULSCH RX snr (for the stats) */
+ /* This is the normalized snr and this should be constant (regardless of mcs) */
+ snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10;
+ target_snr = eNB->puSch10xSnr / 10; /* TODO: target_rx_power was 178, what to put? */
/* 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;
@@ -2063,10 +2070,10 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
UE_template->pusch_tpc_tx_frame = frameP;
UE_template->pusch_tpc_tx_subframe = subframeP;
- if (normalized_rx_power > (target_rx_power + 4)) {
+ if (snr > target_snr + 4) {
tpc = 0; //-1
UE_sched_ctrl->tpc_accumulated[CC_id]--;
- } else if (normalized_rx_power < (target_rx_power - 4)) {
+ } else if (snr < target_snr - 4) {
tpc = 2; //+1
UE_sched_ctrl->tpc_accumulated[CC_id]++;
} else {
@@ -2077,15 +2084,15 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
}
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",
+ LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n",
module_idP,
frameP,
subframeP,
harq_pid,
tpc,
UE_sched_ctrl->tpc_accumulated[CC_id],
- normalized_rx_power,
- target_rx_power);
+ snr,
+ target_snr);
}
/* New transmission */
@@ -2094,8 +2101,8 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
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].snr = snr;
+ UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
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;
diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index 276f1e4e6f..1760355f61 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -169,7 +169,7 @@
#define MAX_NUM_SLICES 10
-#define U_PLANE_INACTIVITY_VALUE 6000
+#define U_PLANE_INACTIVITY_VALUE 0 /* defined 10ms order (zero means infinity) */
/*
* eNB part
@@ -754,10 +754,10 @@ 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
- int32_t normalized_rx_power;
- /// target rx power
- int32_t target_rx_power;
+ /// snr
+ int32_t snr;
+ /// target snr
+ int32_t target_snr;
/// num rx pdu
uint32_t num_pdu_rx[NB_RB_MAX];
@@ -1438,6 +1438,8 @@ typedef struct eNB_MAC_INST_s {
tx_request_pdu[NFAPI_CC_MAX][MAX_NUM_TX_REQUEST_PDU];
/// NFAPI DL PDU structure
nfapi_tx_request_t TX_req[NFAPI_CC_MAX];
+ /// NFAPI UE_release_req structure
+ nfapi_ue_release_request_t UE_release_req;
/// UL handle
uint32_t ul_handle;
UE_list_t UE_list;
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c
index 2f001bdcfd..4d34338ea9 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c
@@ -806,6 +806,7 @@ mem_block_t * rlc_am_get_pdu_to_retransmit(
rlc_sn_t sn = rlc_pP->vt_a;
rlc_sn_t sn_end = rlc_pP->vt_s;
mem_block_t* pdu_p = NULL;
+ mem_block_t* mb_p = NULL;
rlc_am_tx_data_pdu_management_t* tx_data_pdu_management;
//Assertion(eNB)_PRAN_DesignDocument_annex No.769
if((rlc_pP->retrans_num_pdus <= 0) || (rlc_pP->vt_a == rlc_pP->vt_s))
@@ -884,6 +885,18 @@ mem_block_t * rlc_am_get_pdu_to_retransmit(
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
tx_data_pdu_management->retx_count_next,
sn);
+ mb_p = rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE].mem_block;
+ if(mb_p != NULL){
+ free_mem_block(mb_p, __func__);
+ tx_data_pdu_management->mem_block = NULL;
+ tx_data_pdu_management->flags.retransmit = 0;
+ tx_data_pdu_management->flags.ack = 1;
+ tx_data_pdu_management->flags.transmitted = 0;
+ rlc_pP->retrans_num_bytes_to_retransmit -= tx_data_pdu_management->retx_payload_size;
+ tx_data_pdu_management->retx_payload_size = 0;
+ tx_data_pdu_management->num_holes = 0;
+ rlc_pP->retrans_num_pdus --;
+ }
}
}
else if (rlc_pP->nb_bytes_requested_by_mac >= 5)
@@ -938,6 +951,18 @@ mem_block_t * rlc_am_get_pdu_to_retransmit(
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
tx_data_pdu_management->retx_count_next,
sn);
+ mb_p = rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE].mem_block;
+ if(mb_p != NULL){
+ free_mem_block(mb_p, __func__);
+ tx_data_pdu_management->mem_block = NULL;
+ tx_data_pdu_management->flags.retransmit = 0;
+ tx_data_pdu_management->flags.ack = 1;
+ tx_data_pdu_management->flags.transmitted = 0;
+ rlc_pP->retrans_num_bytes_to_retransmit -= tx_data_pdu_management->retx_payload_size;
+ tx_data_pdu_management->retx_payload_size = 0;
+ tx_data_pdu_management->num_holes = 0;
+ rlc_pP->retrans_num_pdus --;
+ }
}
}
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c
index 9d69882923..4a06553901 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c
@@ -938,7 +938,7 @@ rlc_am_rx_check_all_byte_segments(
rlc_am_pdu_info_t *pdu_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info;
mem_block_t *cursor_p = NULL;
mem_block_t *first_cursor_p = NULL;
- rlc_sn_t sn = pdu_info_p->sn;
+ rlc_usn_t sn = pdu_info_p->sn;
sdu_size_t next_waited_so;
sdu_size_t last_end_so;
@@ -969,6 +969,9 @@ rlc_am_rx_check_all_byte_segments(
// the so field of the first PDU should be 0
//cursor_p = list.head;
//we start from the first stored PDU segment of this SN
+ if(cursor_p->data == NULL){
+ return;
+ }
pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
// if the first segment does not have SO = 0 then no need to continue
@@ -985,6 +988,9 @@ rlc_am_rx_check_all_byte_segments(
while (cursor_p->next != NULL) {
//msg("rlc_am_rx_check_all_byte_segments(%d) @4\n",sn);
cursor_p = cursor_p->next;
+ if(cursor_p->data == NULL){
+ return;
+ }
pdu_info_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
if (pdu_info_p->sn == sn) {
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c
index 40bab6ff0b..dbe55c483d 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c
@@ -358,8 +358,6 @@ void rlc_am_segment_10 (
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
pdu_remaining_size);
//msg ("[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] pdu_mem_p %p pdu_p %p pdu_p->data %p data %p data_sdu_p %p pdu_remaining_size %d\n", rlc_pP->module_id, rlc_pP->rb_id, ctxt_pP->frame, pdu_mem_p, pdu_p, pdu_p->data, data, data_sdu_p,pdu_remaining_size);
- rlc_am_mui.rrc_mui[rlc_am_mui.rrc_mui_num] = sdu_mngt_p->mui;
- rlc_am_mui.rrc_mui_num++;
memcpy(data, data_sdu_p, pdu_remaining_size);
pdu_mngt_p->payload_size += pdu_remaining_size;
@@ -397,8 +395,6 @@ void rlc_am_segment_10 (
continue_fill_pdu_with_sdu = 0;
pdu_remaining_size = 0;
} else if ((sdu_mngt_p->sdu_remaining_size + (li_length_in_bytes ^ 3)) < pdu_remaining_size ) {
- rlc_am_mui.rrc_mui[rlc_am_mui.rrc_mui_num] = sdu_mngt_p->mui;
- rlc_am_mui.rrc_mui_num++;
if (fill_num_li == (RLC_AM_MAX_SDU_IN_PDU - 1)) {
LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] [SIZE %d] REACHING RLC_AM_MAX_SDU_IN_PDU LIs -> STOP SEGMENTATION FOR THIS PDU SDU\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
@@ -416,6 +412,8 @@ void rlc_am_segment_10 (
// reduce the size of the PDU
continue_fill_pdu_with_sdu = 0;
fi_last_byte_pdu_is_last_byte_sdu = 1;
+ rlc_am_mui.rrc_mui[rlc_am_mui.rrc_mui_num] = sdu_mngt_p->mui;
+ rlc_am_mui.rrc_mui_num++;
} else {
LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] Filling PDU with %d all remaining bytes of SDU\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c
index 2251344c47..32c4d9788c 100644
--- a/openair2/LAYER2/openair2_proc.c
+++ b/openair2/LAYER2/openair2_proc.c
@@ -176,13 +176,13 @@ int dump_eNB_l2_stats(char *buffer, int length) {
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",
+ len += sprintf(&buffer[len],"[MAC] UE %d (ULSCH), Status %s, Failute timer %d, RNTI %x : snr (%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].snr,
+ UE_list->eNB_UE_stats[CC_id][UE_id].target_snr,
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,
diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c
index ad49a16cec..2cc43189c6 100644
--- a/openair2/PHY_INTERFACE/IF_Module.c
+++ b/openair2/PHY_INTERFACE/IF_Module.c
@@ -17,10 +17,34 @@ extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind);
extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
extern uint16_t sf_ahead;
+extern UL_RCC_IND_t UL_RCC_INFO;
+
uint16_t frame_cnt=0;
void handle_rach(UL_IND_t *UL_info) {
int i;
+ if(NFAPI_MODE == NFAPI_MODE_VNF){
+ for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){
+ if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles>0) {
+ AssertFatal(UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n");
+ 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_RCC_INFO.rach_ind[j].sfn_sf));
+ initiate_ra_proc(UL_info->module_id,
+ UL_info->CC_id,
+ NFAPI_SFNSF2SFN(UL_RCC_INFO.rach_ind[j].sfn_sf),
+ NFAPI_SFNSF2SF(UL_RCC_INFO.rach_ind[j].sfn_sf),
+ UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.preamble,
+ UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.timing_advance,
+ UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.rnti
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+ ,0
+#endif
+ );
+ free(UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list);
+ UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles = 0;
+ UL_RCC_INFO.rach_ind[j].header.message_id = 0;
+ }
+ }
+ }else{
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;
@@ -37,6 +61,7 @@ void handle_rach(UL_IND_t *UL_info) {
#endif
);
}
+ }
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
@@ -72,6 +97,22 @@ void handle_sr(UL_IND_t *UL_info) {
if (UL_info->sr_ind.sr_indication_body.number_of_srs>0) {
oai_nfapi_sr_indication(&UL_info->sr_ind);
}
+ } else if(NFAPI_MODE == NFAPI_MODE_VNF){
+ for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){
+ if(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs > 0){
+ for (i=0;imodule_id,
+ UL_info->CC_id,
+ NFAPI_SFNSF2SFN(UL_RCC_INFO.sr_ind[j].sfn_sf),
+ NFAPI_SFNSF2SF(UL_RCC_INFO.sr_ind[j].sfn_sf),
+ UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list[i].rx_ue_information.rnti,
+ UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list[i].ul_cqi_information.ul_cqi);
+ }
+ free(UL_RCC_INFO.sr_ind[j].sr_indication_body.sr_pdu_list);
+ UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs=0;
+ UL_RCC_INFO.sr_ind[j].header.message_id = 0;
+ }
+ }
} else {
for (i=0; isr_ind.sr_indication_body.number_of_srs; i++)
SR_indication(UL_info->module_id,
@@ -89,27 +130,46 @@ void handle_cqi(UL_IND_t *UL_info) {
int i;
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;
+ if (UL_info->cqi_ind.cqi_indication_body.number_of_cqis>0) {
+ LOG_D(PHY,"UL_info->cqi_ind.number_of_cqis:%d\n", UL_info->cqi_ind.cqi_indication_body.number_of_cqis);
+ UL_info->cqi_ind.header.message_id = NFAPI_RX_CQI_INDICATION;
+ UL_info->cqi_ind.sfn_sf = UL_info->frame<<4 | UL_info->subframe;
+
+ oai_nfapi_cqi_indication(&UL_info->cqi_ind);
+ UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0;
+ }
+ } else if (NFAPI_MODE == NFAPI_MODE_VNF) {
+ for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){
+ if(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis > 0){
+ for (i=0;imodule_id,
+ UL_info->CC_id,
+ NFAPI_SFNSF2SFN(UL_RCC_INFO.cqi_ind[j].sfn_sf),
+ NFAPI_SFNSF2SF(UL_RCC_INFO.cqi_ind[j].sfn_sf),
+ UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_pdu_list[i].rx_ue_information.rnti,
+ &UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_pdu_list[i].cqi_indication_rel9,
+ UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_raw_pdu_list[i].pdu,
+ &UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_pdu_list[i].ul_cqi_information);
+ }
+
+ free(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_pdu_list);
+ free(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.cqi_raw_pdu_list);
+ UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis=0;
+ UL_RCC_INFO.cqi_ind[j].header.message_id = 0;
+ }
}
} else {
- for (i=0; icqi_ind.number_of_cqis; i++)
+ for (i=0;icqi_ind.cqi_indication_body.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);
+ NFAPI_SFNSF2SFN(UL_info->cqi_ind.sfn_sf),
+ NFAPI_SFNSF2SF(UL_info->cqi_ind.sfn_sf),
+ UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].rx_ue_information.rnti,
+ &UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].cqi_indication_rel9,
+ UL_info->cqi_ind.cqi_indication_body.cqi_raw_pdu_list[i].pdu,
+ &UL_info->cqi_ind.cqi_indication_body.cqi_pdu_list[i].ul_cqi_information);
- UL_info->cqi_ind.number_of_cqis=0;
+ UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0;
}
}
@@ -123,7 +183,22 @@ void handle_harq(UL_IND_t *UL_info) {
}
UL_info->harq_ind.harq_indication_body.number_of_harqs = 0;
+ }else if(NFAPI_MODE == NFAPI_MODE_VNF){
+ for(uint8_t j = 0;j < NUM_NFPAI_SUBFRAME;j++){
+ if(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs > 0){
+ for (int i=0;imodule_id,
+ UL_info->CC_id,
+ NFAPI_SFNSF2SFN(UL_RCC_INFO.harq_ind[j].sfn_sf),
+ NFAPI_SFNSF2SF(UL_RCC_INFO.harq_ind[j].sfn_sf),
+ &UL_RCC_INFO.harq_ind[j].harq_indication_body.harq_pdu_list[i]);
+ }
+ free(UL_RCC_INFO.harq_ind[j].harq_indication_body.harq_pdu_list);
+ UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs=0;
+ UL_RCC_INFO.harq_ind[j].header.message_id = 0;
+ }
+ }
} else {
for (int i=0; i < UL_info->harq_ind.harq_indication_body.number_of_harqs; i++)
harq_indication(UL_info->module_id,
@@ -151,6 +226,56 @@ void handle_ulsch(UL_IND_t *UL_info) {
oai_nfapi_rx_ind(&UL_info->rx_ind);
UL_info->rx_ind.rx_indication_body.number_of_pdus = 0;
}
+ } else if(NFAPI_MODE == NFAPI_MODE_VNF){
+ for(uint8_t k = 0;k < NUM_NFPAI_SUBFRAME;k++){
+ if((UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus>0) && (UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs>0)){
+ for (i=0;icrc_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_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti, i,UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti);
+ if (UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].rx_ue_information.rnti == UL_RCC_INFO.rx_ind[k].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_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list[j].crc_indication_rel8.crc_flag);
+ if (UL_RCC_INFO.crc_ind[k].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_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->frame,
+ NFAPI_SFNSF2SF(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->subframe,
+ UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti,
+ (uint8_t *)NULL,
+ UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length,
+ UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance,
+ UL_RCC_INFO.rx_ind[k].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_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->frame,
+ NFAPI_SFNSF2SF(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->subframe,
+ UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti,
+ UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data,
+ UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length,
+ UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance,
+ UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi);
+ }
+ if(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data != NULL){
+ free(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data);
+ }
+ 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;jcrc_ind.crc_indication_body.number_of_crcs;j++)
+ } // for (i=0;irx_ind.number_of_pdus;i++)
+ free(UL_RCC_INFO.crc_ind[k].crc_indication_body.crc_pdu_list);
+ free(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list);
+ UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs = 0;
+ UL_RCC_INFO.crc_ind[k].header.message_id =0;
+ UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus = 0;
+ UL_RCC_INFO.rx_ind[k].header.message_id = 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) {
for (i=0; irx_ind.rx_indication_body.number_of_pdus; i++) {
@@ -574,11 +699,11 @@ void UL_indication(UL_IND_t *UL_info) {
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);
+ 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.cqi_indication_body.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
@@ -604,6 +729,7 @@ void UL_indication(UL_IND_t *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);
@@ -634,6 +760,9 @@ void UL_indication(UL_IND_t *UL_info) {
sched_info->UL_req = NULL;
sched_info->TX_req = &mac->TX_req[CC_id];
+ pthread_mutex_lock(&lock_ue_freelist);
+ sched_info->UE_release_req = &mac->UE_release_req;
+ pthread_mutex_unlock(&lock_ue_freelist);
#ifdef DUMP_FAPI
dump_dl(sched_info);
#endif
diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h
index b6ede7d598..c42ba992c9 100644
--- a/openair2/PHY_INTERFACE/IF_Module.h
+++ b/openair2/PHY_INTERFACE/IF_Module.h
@@ -71,7 +71,7 @@ typedef struct{
nfapi_sr_indication_t sr_ind;
/// CQI indication list
- nfapi_cqi_indication_body_t cqi_ind;
+ nfapi_cqi_indication_t cqi_ind;
/// RACH indication list
nfapi_rach_indication_t rach_ind;
@@ -90,7 +90,27 @@ typedef struct{
} UL_IND_t;
// Downlink subframe P7
+#define NUM_NFPAI_SUBFRAME 5
+typedef struct{
+ /// harq indication list
+ nfapi_harq_indication_t harq_ind[NUM_NFPAI_SUBFRAME];
+ /// crc indication list
+ nfapi_crc_indication_t crc_ind[NUM_NFPAI_SUBFRAME];
+
+ /// SR indication list
+ nfapi_sr_indication_t sr_ind[NUM_NFPAI_SUBFRAME];
+
+ /// CQI indication list
+ nfapi_cqi_indication_t cqi_ind[NUM_NFPAI_SUBFRAME];
+
+ /// RACH indication list
+ nfapi_rach_indication_t rach_ind[NUM_NFPAI_SUBFRAME];
+
+ /// RX indication
+ nfapi_rx_indication_t rx_ind[NUM_NFPAI_SUBFRAME];
+
+} UL_RCC_IND_t;
typedef struct{
/// Module ID
@@ -109,6 +129,8 @@ typedef struct{
nfapi_hi_dci0_request_t *HI_DCI0_req;
/// Pointers to DL SDUs
nfapi_tx_request_t *TX_req;
+ /// Pointers to ue_release
+ nfapi_ue_release_request_t *UE_release_req;
}Sched_Rsp_t;
typedef struct {
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 8d625fbdc5..930387c742 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -236,8 +236,8 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subfram
// change for mutiple UE's simulation.
//pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_lock(&fill_ul_mutex.cqi_mutex);
- nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_pdu_list[UL_INFO->cqi_ind.number_of_cqis];
- nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_raw_pdu_list[UL_INFO->cqi_ind.number_of_cqis];
+ nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis];
+ nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis];
pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG;
pdu->rx_ue_information.rnti = rnti;
@@ -263,7 +263,7 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subfram
- UL_INFO->cqi_ind.number_of_cqis++;
+ UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis++;
// change for mutiple UE's simulation.
//pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex);
pthread_mutex_unlock(&fill_ul_mutex.cqi_mutex);
diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c
index 6478641438..219c905c42 100644
--- a/openair2/RRC/LTE/L2_interface.c
+++ b/openair2/RRC/LTE/L2_interface.c
@@ -309,10 +309,13 @@ mac_rrc_data_ind(
ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id],rntiP);
if(ue_context_p) {
- rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,
- ue_context_p,
- 0);
- ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+ if (ue_context_p->ue_context.Status != RRC_RECONFIGURED) {
+ LOG_E(RRC,"[eNB %d] Received C-RNTI ,but UE %x status(%d) not RRC_RECONFIGURED\n",module_idP,rntiP,ue_context_p->ue_context.Status);
+ return (-1);
+ } else {
+ rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,ue_context_p,0);
+ ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+ }
}
}
@@ -362,8 +365,7 @@ void mac_eNB_rrc_ul_failure(const module_id_t 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);
+ //rrc_mac_remove_ue(Mod_instP,rntiP);
}
void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP,
diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
index ecb21dae6c..9303fb79f1 100644
--- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
@@ -4072,6 +4072,7 @@ do_RRCConnectionReestablishment(
LTE_DL_CCCH_Message_t dl_ccch_msg;
LTE_RRCConnectionReestablishment_t *rrcConnectionReestablishment = NULL;
int i = 0;
+ ue_context_pP->ue_context.reestablishment_xid = Transaction_id;
LTE_SRB_ToAddModList_t **SRB_configList2 = NULL;
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id];
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index ef0598a40a..21f6429c7c 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -348,11 +348,24 @@ typedef enum HO_STATE_e {
HO_COMPLETE, // initiated by the target eNB
HO_REQUEST,
HO_ACK,
+ HO_FORWARDING,
HO_CONFIGURED,
+ HO_END_MARKER,
+ HO_FORWARDING_COMPLETE,
HO_RELEASE,
HO_CANCEL
} HO_STATE_t;
+typedef enum DATA_FORWARDING_STATE_e {
+ FORWARDING_EMPTY=0,
+ FORWARDING_NO_EMPTY
+} DATA_FORWARDING_STATE_t;
+
+typedef enum DATA_ENDMARK_STATE_e {
+ ENDMARK_EMPTY=0,
+ ENDMARK_NO_EMPTY
+} DATA_ENDMARK_STATE_t;
+
typedef enum SL_TRIGGER_e {
SL_RECEIVE_COMMUNICATION=0,
SL_TRANSMIT_RELAY_ONE_TO_ONE,
@@ -477,6 +490,9 @@ typedef struct HANDOVER_INFO_s {
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 */
+ uint32_t x2u_teid;
+ DATA_FORWARDING_STATE_t forwarding_state;
+ DATA_ENDMARK_STATE_t endmark_state;
} HANDOVER_INFO;
typedef struct PER_EVENT_s {
@@ -693,6 +709,12 @@ typedef struct eNB_RRC_UE_s {
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];
+ /* Total number of e_rab already setup in the list */
+ uint8_t nb_x2u_e_rabs;
+ // LG: For GTPV1 TUNNELS(X2U)
+ uint32_t enb_gtp_x2u_teid[S1AP_MAX_E_RAB];
+ transport_layer_addr_t enb_gtp_x2u_addrs[S1AP_MAX_E_RAB];
+ rb_id_t enb_gtp_x2u_ebi[S1AP_MAX_E_RAB];
uint32_t ul_failure_timer;
uint32_t ue_release_timer;
uint32_t ue_release_timer_thres;
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 4543ff3050..d93510ac5d 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -116,6 +116,10 @@ extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eN
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);
+pthread_mutex_t rrc_release_freelist;
+RRC_release_list_t rrc_release_info;
+pthread_mutex_t lock_ue_freelist;
+
void
openair_rrc_on(
const protocol_ctxt_t *const ctxt_pP
@@ -1110,6 +1114,8 @@ void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag) {
free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti;
free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag;
free_list->num_UEs++;
+ eNB_MAC->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = rnti;
+ eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs++;
free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1);
pthread_mutex_unlock(&lock_ue_freelist);
}
@@ -1154,28 +1160,32 @@ void release_UE_in_freeList(module_id_t mod_id) {
for (i=0; iulsch[i];
-
if((ulsch != NULL) && (ulsch->rnti == rnti)) {
void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti);
clean_eNb_ulsch(ulsch);
}
- if(eNB_PHY->uci_vars[i].rnti == rnti) {
- LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti);
- memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
- }
- }
-
- for (i=0; idlsch[i][0];
-
if((dlsch != NULL) && (dlsch->rnti == rnti)) {
void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti);
clean_eNb_dlsch(dlsch);
}
}
+ ulsch = eNB_PHY->ulsch[i];
+ if((ulsch != NULL) && (ulsch->rnti == rnti)) {
+ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
+ LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti);
+ clean_eNb_ulsch(ulsch);
+ }
+
+ for (i=0; iuci_vars[i].rnti == rnti) {
+ LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti);
+ memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
+ }
+ }
if (flexran_agent_get_rrc_xface(mod_id)) {
flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change(
@@ -1237,6 +1247,34 @@ void release_UE_in_freeList(module_id_t mod_id) {
}
}
+int rrc_eNB_previous_SRB2(rrc_eNB_ue_context_t* ue_context_pP)
+{
+ struct LTE_SRB_ToAddMod *SRB2_config = NULL;
+ uint8_t i;
+ LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList;
+ LTE_SRB_ToAddModList_t** SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[ue_context_pP->ue_context.reestablishment_xid];
+ if (*SRB_configList2 != NULL) {
+ if((*SRB_configList2)->list.count!=0){
+ LOG_D(RRC, "rrc_eNB_previous_SRB2 SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p",
+ SRB_configList2, (*SRB_configList2)->list.count, (*SRB_configList2)->list.array[0]);
+ }
+ for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
+ if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ){
+ SRB2_config = (*SRB_configList2)->list.array[i];
+ break;
+ }
+ }
+ }else{
+ LOG_E(RRC, "rrc_eNB_previous_SRB2 SRB_configList2 NULL\n");
+ }
+
+ if (SRB2_config != NULL) {
+ ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
+ }else{
+ LOG_E(RRC, "rrc_eNB_previous_SRB2 SRB2_config NULL\n");
+ }
+ return 0;
+}
//-----------------------------------------------------------------------------
/*
* Process the rrc connection setup complete message from UE (SRB1 Active)
@@ -1552,10 +1590,6 @@ rrc_eNB_generate_RRCConnectionReestablishment(
rnti);
}
- /* 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_RRCConnectionReestablishmentReject is triggered */
- ue_context_pP->ue_context.ue_reestablishment_timer_thres = 1000;
}
//-----------------------------------------------------------------------------
@@ -1602,6 +1636,8 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
LTE_C_RNTI_t *cba_RNTI = NULL;
int measurements_enabled;
uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);
+ int ret = 0;
+
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
ue_context_pP->ue_context.reestablishment_xid = next_xid;
@@ -1707,10 +1743,36 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
create_tunnel_req.rnti = ctxt_pP->rnti; // warning put zero above
create_tunnel_req.num_tunnels = j;
- gtpv1u_update_s1u_tunnel(
+
+ ret = gtpv1u_update_s1u_tunnel(
ctxt_pP->instance,
&create_tunnel_req,
reestablish_rnti);
+ if ( ret != 0 ) {
+ LOG_E(RRC,"gtpv1u_update_s1u_tunnel failed,start to release UE %x\n",reestablish_rnti);
+ // update s1u tunnel failed,reset rnti?
+ if (eNB_ue_s1ap_id > 0) {
+ h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&rrc_ue_s1ap_ids_p);
+ if (h_rc == HASH_TABLE_OK ) {
+ rrc_ue_s1ap_ids_p->ue_rnti = reestablish_rnti;
+ }
+ }
+ if (ue_initial_id != 0) {
+ h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&rrc_ue_s1ap_ids_p);
+ if (h_rc == HASH_TABLE_OK ) {
+ rrc_ue_s1ap_ids_p->ue_rnti = reestablish_rnti;
+ }
+ }
+ ue_context_pP->ue_context.ue_release_timer_s1 = 1;
+ ue_context_pP->ue_context.ue_release_timer_thres_s1 = 100;
+ ue_context_pP->ue_context.ue_release_timer = 0;
+ ue_context_pP->ue_context.ue_reestablishment_timer = 0;
+ ue_context_pP->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
+ rrc_eNB_free_UE(ctxt_pP->module_id,ue_context_pP);
+ ue_context_pP->ue_context.ul_failure_timer = 0;
+ put_UE_in_freelist(ctxt_pP->module_id, ctxt_pP->rnti, 0);
+ return;
+ }
} /* EPC_MODE_ENABLED */
/* Update RNTI in ue_context */
@@ -2232,8 +2294,9 @@ rrc_eNB_generate_RRCConnectionRelease(
ue_context_pP->ue_context.rnti,
rrc_eNB_mui,
size);
- pthread_mutex_lock(&rrc_release_freelist);
-
+ while (pthread_mutex_trylock(&rrc_release_freelist)) {
+ /* spin... */
+ }
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_pP->ue_context.ue_release_timer_s1 > 0) {
@@ -4056,8 +4119,40 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt
MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0;
MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1;
MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6;
- MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = (LTE_Q_OffsetRange_t *) CALLOC(1,sizeof(LTE_Q_OffsetRange_t));
- *(MeasObj->measObject.choice.measObjectEUTRA.offsetFreq) = ue_context_pP->ue_context.measurement_info->offsetFreq; // Default is 15 or 0dB
+//<<<<<<< HEAD
+ MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB
+ if (rrc_inst->carrier[0].sib1->tdd_Config!=NULL) {
+ MeasObj->measObject.choice.measObjectEUTRA.ext1 = CALLOC(1, sizeof(struct LTE_MeasObjectEUTRA__ext1));
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measCycleSCell_r10 = NULL;
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10 = CALLOC(1, sizeof(struct LTE_MeasSubframePatternConfigNeigh_r10));
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->present=LTE_MeasSubframePatternConfigNeigh_r10_PR_setup;
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.present=LTE_MeasSubframePattern_r10_PR_subframePatternTDD_r10;
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.present=LTE_MeasSubframePattern_r10__subframePatternTDD_r10_PR_subframeConfig1_5_r10;
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf=CALLOC(3, sizeof(uint8_t));
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.size=3;
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.bits_unused=4;
+ switch (rrc_inst->carrier[0].sib1->tdd_Config->subframeAssignment) {
+ case 1: //subframe 0,4,5,9
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[0]=0x8C;
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[1]=0x63;
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[2]=0x10;
+ break;
+
+ default: //subframe 0 , 5
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[0]=0x84;
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[1]=0x21;
+ MeasObj->measObject.choice.measObjectEUTRA.ext1->measSubframePatternConfigNeigh_r10->choice.setup.measSubframePatternNeigh_r10.choice.subframePatternTDD_r10.choice.subframeConfig1_5_r10.buf[2]=0x00;
+ break;
+ }
+ }
+
+ MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList =
+ (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList));
+ CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList;
+//=======
+// MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = (LTE_Q_OffsetRange_t *) CALLOC(1,sizeof(LTE_Q_OffsetRange_t));
+// *(MeasObj->measObject.choice.measObjectEUTRA.offsetFreq) = ue_context_pP->ue_context.measurement_info->offsetFreq; // Default is 15 or 0dB
+//>>>>>>> origin/OAI_develop
if (RC.rrc[ctxt_pP->module_id]->num_neigh_cells > 0) {
MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList =
@@ -4553,7 +4648,9 @@ rrc_eNB_process_MeasurementReport(
/* 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(
@@ -4610,10 +4707,10 @@ rrc_eNB_generate_HandoverPreparationInformation(
uint8_t *buffer,
int *_size
) {
- memset(buffer, 0, RRC_BUF_SIZE);
+ memset(buffer, 0, 8192);
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);
+ ho_size = do_HandoverPreparation(ho_buf, 8192, ue_context_pP->ue_context.UE_Capability, ue_context_pP->ue_context.UE_Capability_size);
*_size = ho_size;
}
@@ -4681,8 +4778,8 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re
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.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);
@@ -4756,6 +4853,10 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re
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);
}
+ rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(mod_id, ue_context_target_p);
+
+ ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION;
+ ue_context_target_p->ue_context.handover_info->state = HO_ACK;
}
void rrc_eNB_process_handoverCommand(
@@ -4971,7 +5072,8 @@ check_handovers(
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;
+ ue_context_p->ue_context.handover_info->state = HO_FORWARDING;
+
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);
@@ -4984,13 +5086,162 @@ check_handovers(
X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = ue_context_p->ue_context.setup_e_rabs;
for (int i=0; iue_context.setup_e_rabs; i++) {
+ /* set gtpv teid info */
X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id;
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid = ue_context_p->ue_context.enb_gtp_x2u_teid[i];
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr = ue_context_p->ue_context.enb_gtp_x2u_addrs[i];
}
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);
}
}
+
+ if (ue_context_p->ue_context.Status == RRC_RECONFIGURED
+ && ue_context_p->ue_context.handover_info != NULL &&
+ ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_NO_EMPTY ) {
+
+#if defined(ENABLE_ITTI)
+ MessageDef *msg_p;
+ int result;
+ protocol_ctxt_t ctxt;
+
+ do {
+ // Checks if a message has been sent to PDCP sub-task
+ itti_poll_msg (TASK_DATA_FORWARDING, &msg_p);
+
+ if (msg_p != NULL) {
+
+ switch (ITTI_MSG_ID(msg_p)) {
+ case GTPV1U_ENB_DATA_FORWARDING_IND:
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(
+ &ctxt,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).module_id,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).enb_flag,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rnti,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).frame,
+ 0,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).eNB_index);
+ LOG_D(RRC, PROTOCOL_CTXT_FMT"[check_handovers]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),
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode);
+
+ LOG_I(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %d \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id);
+ result = pdcp_data_req (&ctxt,
+ SRB_FLAG_NO,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_size,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_p,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+ , NULL, NULL
+#endif
+ );
+ if (result != TRUE){
+ LOG_E(RRC, "target enb send data forwarding buffer to PDCP request failed!\n");
+ }else{
+ LOG_D(RRC, "target enb send data forwarding buffer to PDCP!\n");
+ }
+
+ // Message buffer has been processed, free it now.
+ result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).sdu_p);
+ AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+ break;
+
+ default:
+ LOG_E(RRC, "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);
+ ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_EMPTY;
+ }
+ if( ue_context_p->ue_context.Status == RRC_RECONFIGURED &&
+ ue_context_p->ue_context.handover_info != NULL &&
+ ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_EMPTY &&
+ ue_context_p->ue_context.handover_info->endmark_state == ENDMARK_NO_EMPTY &&
+ ue_context_p->ue_context.handover_info->state == HO_END_MARKER ){
+
+ MessageDef *msg_p;
+ int result;
+ protocol_ctxt_t ctxt;
+
+ do {
+ // Checks if a message has been sent to PDCP sub-task
+ itti_poll_msg (TASK_END_MARKER, &msg_p);
+
+ if (msg_p != NULL) {
+
+ switch (ITTI_MSG_ID(msg_p)) {
+ case GTPV1U_ENB_END_MARKER_IND:
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(
+ &ctxt,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).module_id,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).enb_flag,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).rnti,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).frame,
+ 0,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).eNB_index);
+ LOG_I(RRC, PROTOCOL_CTXT_FMT"[check_handovers]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),
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp,
+ GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode);
+
+ LOG_D(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %d \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id);
+ result = pdcp_data_req (&ctxt,
+ SRB_FLAG_NO,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).rb_id,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).muip,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).confirmp,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_size,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_p,
+ GTPV1U_ENB_END_MARKER_IND (msg_p).mode
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+ , NULL, NULL
+#endif
+ );
+ if (result != TRUE){
+ LOG_E(RRC, "target enb send spgw buffer to PDCP request failed!\n");
+ }else{
+ LOG_D(RRC, "target enb send spgw buffer to PDCP!\n");
+ }
+
+ // Message buffer has been processed, free it now.
+ result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), GTPV1U_ENB_END_MARKER_IND (msg_p).sdu_p);
+ AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+ break;
+
+ default:
+ LOG_E(RRC, "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);
+
+ ue_context_p->ue_context.handover_info->endmark_state = ENDMARK_EMPTY;
+ ue_context_p->ue_context.handover_info->state = HO_FORWARDING_COMPLETE;
+
+#endif
+ }
}
}
@@ -7002,15 +7253,51 @@ rrc_eNB_decode_ccch(
rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
break;
}
-
+ if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
+ (RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)){
+ LOG_E(RRC,
+ PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the c-rnti UE\n",
+ PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+ RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
+ rrc_eNB_previous_SRB2(ue_context_p);
+ ue_context_p->ue_context.ue_reestablishment_timer = 0;
+ }
+ //previous rnti
+ rnti_t previous_rnti = 0;
+ for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+ if (reestablish_rnti_map[i][1] == c_rnti) {
+ previous_rnti = reestablish_rnti_map[i][0];
+ break;
+ }
+ }
+ if(previous_rnti != 0){
+ UE_id = find_UE_id(ctxt_pP->module_id, previous_rnti);
+ if(UE_id == -1){
+ LOG_E(RRC,
+ PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest without UE_id(MAC) previous rnti %x, let's reject the UE\n",
+ PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),previous_rnti);
+ rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
+ break;
+ }
if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)) {
LOG_E(RRC,
PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the Previous UE\n",
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
- ue_context_p->ue_context.ue_reestablishment_timer = 0;
- }
+ rrc_eNB_previous_SRB2(ue_context_p);
+ ue_context_p->ue_context.ue_reestablishment_timer = 0;
+ }
+ }
+
+ //c-plane not end
+ if((ue_context_p->ue_context.Status != RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1)) {
+ LOG_E(RRC,
+ PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest (UE %x c-plane is not end), let's reject the UE\n",
+ PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti);
+ rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
+ break;
+ }
if(ue_context_p->ue_context.ue_reestablishment_timer > 0) {
LOG_E(RRC,
@@ -7553,6 +7840,9 @@ rrc_eNB_decode_dcch(
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;
+ if(ue_context_p->ue_context.handover_info){
+ ue_context_p->ue_context.handover_info->state = HO_CONFIGURED;
+ }
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);
@@ -7631,6 +7921,7 @@ rrc_eNB_decode_dcch(
}
} 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 {
@@ -7725,7 +8016,7 @@ rrc_eNB_decode_dcch(
}
RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
- ue_context_p->ue_context.ue_reestablishment_timer = 0;
+ ue_context_p->ue_context.reestablishment_xid = -1;
if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.present ==
LTE_RRCConnectionReestablishmentComplete__criticalExtensions_PR_rrcConnectionReestablishmentComplete_r8) {
@@ -8536,7 +8827,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
instance = ITTI_MSG_INSTANCE(msg_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);
+ LOG_D(RRC,"Received message %s\n",msg_name_p);
switch (ITTI_MSG_ID(msg_p)) {
case TERMINATE_MESSAGE:
@@ -8675,6 +8966,9 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
case X2AP_HANDOVER_REQ_ACK: {
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
+ x2ap_handover_req_ack_t *x2ap_handover_req_ack = NULL;
+ hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
+ gtpv1u_ue_data_t *gtpv1u_ue_data_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? */
@@ -8686,7 +8980,44 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
DevAssert(ue_context_p != NULL);
if (ue_context_p->ue_context.handover_info->state != HO_REQUEST) abort();
+
+ hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, ue_context_p->ue_context.rnti, (void**)>pv1u_ue_data_p);
+ /* set target enb gtp teid */
+ if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
+ LOG_E(RRC, "X2AP_HANDOVER_REQ_ACK func(), hashtable_get failed: while getting ue rnti %x in hashtable ue_mapping\n", ue_context_p->ue_context.rnti);
+ } else {
+ uint8_t nb_e_rabs_tobesetup = 0;
+ ebi_t eps_bearer_id = 0;
+ int ip_offset = 0;
+ in_addr_t in_addr;
+ x2ap_handover_req_ack = &X2AP_HANDOVER_REQ_ACK(msg_p);
+ nb_e_rabs_tobesetup = x2ap_handover_req_ack->nb_e_rabs_tobesetup;
+ ue_context_p->ue_context.nb_x2u_e_rabs = nb_e_rabs_tobesetup;
+ for(int i=0; i< nb_e_rabs_tobesetup; i++){
+ ip_offset = 0;
+ eps_bearer_id = x2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
+ ue_context_p->ue_context.enb_gtp_x2u_ebi[i] = eps_bearer_id;
+ ue_context_p->ue_context.enb_gtp_x2u_teid[i] = x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid;
+ gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_teNB = x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid;
+
+ if ((x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 4) ||
+ (x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 20)) {
+ in_addr = *((in_addr_t*)x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer);
+ ip_offset = 4;
+ gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr = in_addr;
+ ue_context_p->ue_context.enb_gtp_x2u_addrs[i] = x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr;
+ }
+ if ((x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 16) ||
+ (x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length == 20)) {
+ memcpy(gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip6_addr.s6_addr,
+ &x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer[ip_offset],
+ 16);
+ }
+
+ }
+ }
+
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;
diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
index ff8f455d6c..d873a825ba 100644
--- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
+++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
@@ -27,14 +27,19 @@
* \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;
@@ -88,6 +93,88 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
}
}
+//------------------------------------------------------------------------------
+boolean_t
+gtpv_data_req(
+ 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,
+ const pdcp_transmission_mode_t modeP,
+ uint32_t task_id
+)
+//------------------------------------------------------------------------------
+{
+ if(sdu_sizeP == 0)
+ {
+ LOG_I(GTPU,"gtpv_data_req sdu_sizeP == 0");
+ return FALSE;
+ }
+ LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %d", ctxt_pP->rnti, sdu_sizeP, rb_idP);
+#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;
+
+ if(task_id == TASK_DATA_FORWARDING){
+
+ LOG_I(GTPU,"gtpv_data_req task_id = TASK_DATA_FORWARDING\n");
+
+ message_buffer = itti_malloc (TASK_GTPV1_U, TASK_DATA_FORWARDING, sdu_sizeP);
+
+ memcpy (message_buffer, buffer_pP, sdu_sizeP);
+
+ message_p = itti_alloc_new_message (TASK_GTPV1_U, GTPV1U_ENB_DATA_FORWARDING_IND);
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame = ctxt_pP->frame;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag = ctxt_pP->enb_flag;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id = rb_idP;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).muip = muiP;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).confirmp = confirmP;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_size = sdu_sizeP;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_p = message_buffer;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).mode = modeP;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).module_id = ctxt_pP->module_id;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rnti = ctxt_pP->rnti;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index;
+
+ itti_send_msg_to_task (TASK_DATA_FORWARDING, 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 if(task_id == TASK_END_MARKER){
+
+ LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n");
+
+ message_buffer = itti_malloc (TASK_GTPV1_U, TASK_END_MARKER, sdu_sizeP);
+
+ memcpy (message_buffer, buffer_pP, sdu_sizeP);
+
+ message_p = itti_alloc_new_message (TASK_GTPV1_U, GTPV1U_ENB_END_MARKER_IND);
+ GTPV1U_ENB_END_MARKER_IND (message_p).frame = ctxt_pP->frame;
+ GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag = ctxt_pP->enb_flag;
+ GTPV1U_ENB_END_MARKER_IND (message_p).rb_id = rb_idP;
+ GTPV1U_ENB_END_MARKER_IND (message_p).muip = muiP;
+ GTPV1U_ENB_END_MARKER_IND (message_p).confirmp = confirmP;
+ GTPV1U_ENB_END_MARKER_IND (message_p).sdu_size = sdu_sizeP;
+ GTPV1U_ENB_END_MARKER_IND (message_p).sdu_p = message_buffer;
+ GTPV1U_ENB_END_MARKER_IND (message_p).mode = modeP;
+ GTPV1U_ENB_END_MARKER_IND (message_p).module_id = ctxt_pP->module_id;
+ GTPV1U_ENB_END_MARKER_IND (message_p).rnti = ctxt_pP->rnti;
+ GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index;
+
+ itti_send_msg_to_task (TASK_END_MARKER, 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.
+ }
+ }
+#endif
+
+ return TRUE;
+
+}
+
+//#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
@@ -112,3 +199,5 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
}
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 23806f6a04..00c7490359 100644
--- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h
+++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h
@@ -53,4 +53,16 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
const rrc_eNB_ue_context_t* const ue_context_pP
);
+boolean_t
+gtpv_data_req(
+ 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,
+ const pdcp_transmission_mode_t modeP,
+ uint32_t task_id
+);
+
#endif /* RRC_ENB_GTPV1U_H_ */
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index dabe5b1524..23284b4b4f 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -257,6 +257,15 @@ rrc_eNB_S1AP_get_ue_ids(
}
if (ue_desc_p != NULL) {
+ struct s1ap_eNB_ue_context_s *s1ap_ue_context_p = NULL;
+ if ((s1ap_ue_context_p = RB_REMOVE(s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head, ue_desc_p)) != NULL) {
+ LOG_E(RRC, "Removed UE context eNB_ue_s1ap_id %u\n", s1ap_ue_context_p->eNB_ue_s1ap_id);
+ s1ap_eNB_free_ue_context(s1ap_ue_context_p);
+ } else {
+ LOG_E(RRC, "Removing UE context eNB_ue_s1ap_id %u: did not find context\n",ue_desc_p->eNB_ue_s1ap_id);
+ }
+ return NULL; //skip the operation below to avoid loop
+ result = rrc_eNB_S1AP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, eNB_ue_s1ap_id);
if (ue_desc_p->ue_initial_id != UE_INITIAL_ID_INVALID) {
result = rrc_eNB_S1AP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, eNB_ue_s1ap_id);
@@ -935,6 +944,8 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
uint8_t inde_list[NB_RB_MAX - 3]= {0};
+ int ret;
+
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
protocol_ctxt_t ctxt;
ue_initial_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).ue_initial_id;
@@ -976,10 +987,23 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above
// create_tunnel_req.num_tunnels = i;
- gtpv1u_create_s1u_tunnel(
+
+ ret = gtpv1u_create_s1u_tunnel(
instance,
&create_tunnel_req,
&create_tunnel_resp);
+ if ( ret != 0 ) {
+ LOG_E(RRC,"rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_s1u_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti);
+ ue_context_p->ue_context.ue_release_timer_s1 = 1;
+ ue_context_p->ue_context.ue_release_timer_thres_s1 = 100;
+ ue_context_p->ue_context.ue_release_timer = 0;
+ ue_context_p->ue_context.ue_reestablishment_timer = 0;
+ ue_context_p->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
+ rrc_eNB_free_UE(ctxt.module_id,ue_context_p);
+ ue_context_p->ue_context.ul_failure_timer = 0;
+ return (0);
+ }
+
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
&ctxt,
&create_tunnel_resp,
@@ -1252,6 +1276,8 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
protocol_ctxt_t ctxt;
uint8_t e_rab_done;
+ int ret = 0;
+
ue_initial_id = S1AP_E_RAB_SETUP_REQ (msg_p).ue_initial_id;
eNB_ue_s1ap_id = S1AP_E_RAB_SETUP_REQ (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);
@@ -1314,10 +1340,22 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above
create_tunnel_req.num_tunnels = e_rab_done;
// NN: not sure if we should create a new tunnel: need to check teid, etc.
- gtpv1u_create_s1u_tunnel(
+ ret = gtpv1u_create_s1u_tunnel(
instance,
&create_tunnel_req,
&create_tunnel_resp);
+ if ( ret != 0 ) {
+ LOG_E(RRC,"rrc_eNB_process_S1AP_E_RAB_SETUP_REQ : gtpv1u_create_s1u_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti);
+ ue_context_p->ue_context.ue_release_timer_s1 = 1;
+ ue_context_p->ue_context.ue_release_timer_thres_s1 = 100;
+ ue_context_p->ue_context.ue_release_timer = 0;
+ ue_context_p->ue_context.ue_reestablishment_timer = 0;
+ ue_context_p->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ
+ rrc_eNB_free_UE(ctxt.module_id,ue_context_p);
+ ue_context_p->ue_context.ul_failure_timer = 0;
+ return (0);
+ }
+
rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
&ctxt,
&create_tunnel_resp,
@@ -2040,6 +2078,69 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
return 0;
}
+int rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(instance_t instance, rrc_eNB_ue_context_t* const ue_context_target_p) {
+ gtpv1u_enb_create_x2u_tunnel_req_t create_tunnel_req;
+ gtpv1u_enb_create_x2u_tunnel_resp_t create_tunnel_resp;
+ uint8_t e_rab_done;
+ uint8_t inde_list[NB_RB_MAX - 3]= {0};
+
+ if (ue_context_target_p == NULL) {
+
+ return (-1);
+ } else {
+
+ /* Save e RAB information for later */
+ {
+ LOG_I(RRC, "[eNB %d] rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ: rnti %u nb_of_e_rabs %d\n",
+ instance, ue_context_target_p->ue_context.rnti, ue_context_target_p->ue_context.nb_of_e_rabs);
+ int i;
+ memset(&create_tunnel_req, 0, sizeof(create_tunnel_req));
+ uint8_t nb_e_rabs_tosetup = ue_context_target_p->ue_context.nb_of_e_rabs;
+ e_rab_done = 0;
+
+ for (i = 0;i < nb_e_rabs_tosetup; i++) {
+
+ if(ue_context_target_p->ue_context.e_rab[i].status >= E_RAB_STATUS_DONE)
+ continue;
+
+ create_tunnel_req.eps_bearer_id[e_rab_done] = ue_context_target_p->ue_context.e_rab[i].param.e_rab_id;
+ LOG_I(RRC,"x2 tunnel setup: local index %d UE id %x, eps id %d \n",
+ i,
+ ue_context_target_p->ue_context.rnti,
+ create_tunnel_req.eps_bearer_id[i] );
+ inde_list[i] = e_rab_done;
+ e_rab_done++;
+ }
+
+ create_tunnel_req.rnti = ue_context_target_p->ue_context.rnti; // warning put zero above
+ create_tunnel_req.num_tunnels = e_rab_done;
+ // NN: not sure if we should create a new tunnel: need to check teid, etc.
+ gtpv1u_create_x2u_tunnel(
+ instance,
+ &create_tunnel_req,
+ &create_tunnel_resp);
+
+ ue_context_target_p->ue_context.nb_x2u_e_rabs = create_tunnel_resp.num_tunnels;
+ for (i = 0; i < create_tunnel_resp.num_tunnels; i++) {
+ ue_context_target_p->ue_context.enb_gtp_x2u_teid[inde_list[i]] = create_tunnel_resp.enb_X2u_teid[i];
+ ue_context_target_p->ue_context.enb_gtp_x2u_addrs[inde_list[i]] = create_tunnel_resp.enb_addr;
+ ue_context_target_p->ue_context.enb_gtp_x2u_ebi[inde_list[i]] = create_tunnel_resp.eps_bearer_id[i];
+
+ LOG_I(RRC, "rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ tunnel (%u, %u) bearer UE context index %u, msg index %u, eps bearer id %u, gtp addr len %d \n",
+ create_tunnel_resp.enb_X2u_teid[i],
+ ue_context_target_p->ue_context.enb_gtp_x2u_teid[inde_list[i]],
+ inde_list[i],
+ i,
+ create_tunnel_resp.eps_bearer_id[i],
+ create_tunnel_resp.enb_addr.length);
+ }
+ }
+
+ 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;
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h
index 5feb55d635..e5ff9c27d6 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.h
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h
@@ -278,6 +278,7 @@ int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t *const ctxt_p
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_X2AP_TUNNEL_SETUP_REQ(instance_t instance, rrc_eNB_ue_context_t* const ue_context_target_p);
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);
diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h
index e7e5e71d80..a8ee7ecabe 100644
--- a/openair2/RRC/LTE/rrc_proto.h
+++ b/openair2/RRC/LTE/rrc_proto.h
@@ -667,9 +667,11 @@ void openair_rrc_top_init_ue(
uint8_t cba_group_active,
uint8_t HO_active
);
-pthread_mutex_t rrc_release_freelist;
-RRC_release_list_t rrc_release_info;
-pthread_mutex_t lock_ue_freelist;
+
+extern pthread_mutex_t rrc_release_freelist;
+extern RRC_release_list_t rrc_release_info;
+extern pthread_mutex_t lock_ue_freelist;
+
void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti);
void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag);
void release_UE_in_freeList(module_id_t mod_id);
diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h
index e1a8b506bc..03d8216b56 100644
--- a/openair2/X2AP/x2ap_eNB_defs.h
+++ b/openair2/X2AP/x2ap_eNB_defs.h
@@ -173,6 +173,8 @@ typedef struct x2ap_eNB_instance_s {
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
+ uint32_t subframeAssignment[MAX_NUM_CCs];
+ uint32_t specialSubframe[MAX_NUM_CCs];
int num_cc;
net_ip_address_t target_enb_x2_ip_address[X2AP_MAX_NB_ENB_IP_ADDRESS];
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c
index 53ec8574fd..38ebd732ac 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.c
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.c
@@ -144,7 +144,92 @@ int x2ap_eNB_generate_x2_setup_request(
}
}
else {
- AssertFatal(0,"X2Setuprequest not supported for TDD!");
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD;
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i];
+ switch (instance_p->subframeAssignment[i]) {
+ case 0:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0;
+ break;
+ case 1:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1;
+ break;
+ case 2:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2;
+ break;
+ case 3:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3;
+ break;
+ case 4:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4;
+ break;
+ case 5:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5;
+ break;
+ case 6:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6;
+ break;
+ default:
+ AssertFatal(0,"Failed: Check value for subframeAssignment");
+ break;
+ }
+ switch (instance_p->specialSubframe[i]) {
+ case 0:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0;
+ break;
+ case 1:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1;
+ break;
+ case 2:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2;
+ break;
+ case 3:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3;
+ break;
+ case 4:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4;
+ break;
+ case 5:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5;
+ break;
+ case 6:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6;
+ break;
+ case 7:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7;
+ break;
+ case 8:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8;
+ break;
+ default:
+ AssertFatal(0,"Failed: Check value for subframeAssignment");
+ break;
+ }
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal;
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal;
+
+ switch (instance_p->N_RB_DL[i]) {
+ case 6:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
+ break;
+ case 15:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
+ break;
+ case 25:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
+ break;
+ case 50:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
+ break;
+ case 75:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
+ break;
+ case 100:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
+ break;
+ default:
+ AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
+ break;
+ }
}
}
ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
@@ -279,7 +364,92 @@ int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eN
}
}
else {
- AssertFatal(0,"X2Setupresponse not supported for TDD!");
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD;
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i];
+ switch (instance_p->subframeAssignment[i]) {
+ case 0:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0;
+ break;
+ case 1:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1;
+ break;
+ case 2:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2;
+ break;
+ case 3:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3;
+ break;
+ case 4:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4;
+ break;
+ case 5:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5;
+ break;
+ case 6:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6;
+ break;
+ default:
+ AssertFatal(0,"Failed: Check value for subframeAssignment");
+ break;
+ }
+ switch (instance_p->specialSubframe[i]) {
+ case 0:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0;
+ break;
+ case 1:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1;
+ break;
+ case 2:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2;
+ break;
+ case 3:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3;
+ break;
+ case 4:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4;
+ break;
+ case 5:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5;
+ break;
+ case 6:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6;
+ break;
+ case 7:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7;
+ break;
+ case 8:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8;
+ break;
+ default:
+ AssertFatal(0,"Failed: Check value for subframeAssignment");
+ break;
+ }
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal;
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal;
+
+ switch (instance_p->N_RB_DL[i]) {
+ case 6:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
+ break;
+ case 15:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
+ break;
+ case 25:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
+ break;
+ case 50:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
+ break;
+ case 75:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
+ break;
+ case 100:
+ servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
+ break;
+ default:
+ AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
+ break;
+ }
}
}
ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
@@ -627,6 +797,27 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p,
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;
+ e_RABs_Admitted_Item->uL_GTP_TunnelEndpoint = NULL;
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint = (X2AP_GTPtunnelEndpoint_t *)calloc(1, sizeof(*e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint));
+
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size = (uint8_t)x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.length;
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.bits_unused = 0;
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf =
+ calloc(1, e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size);
+
+ memcpy (e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf,
+ x2ap_handover_req_ack->e_rabs_tobesetup[i].eNB_addr.buffer,
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size);
+
+ X2AP_DEBUG("X2 handover response target ip addr. length %lu bits_unused %d buf %d.%d.%d.%d\n",
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size,
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.bits_unused,
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[0],
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[1],
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[2],
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf[3]);
+
+ INT32_TO_OCTET_STRING(x2ap_handover_req_ack->e_rabs_tobesetup[i].gtp_teid, &e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->gTP_TEID);
}
ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs);
}
diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c
index 2a44501a33..33fd9c5295 100644
--- a/openair2/X2AP/x2ap_eNB_handler.c
+++ b/openair2/X2AP/x2ap_eNB_handler.c
@@ -730,7 +730,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
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*/)
+ if (c->size > 8192 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s */)
{ printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
memcpy(X2AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size);
@@ -749,6 +749,8 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
{
X2AP_HandoverRequestAcknowledge_t *x2HandoverRequestAck;
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;
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
@@ -816,12 +818,62 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
X2AP_HANDOVER_REQ_ACK(msg).rnti = rnti;
+
+ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck,
+ X2AP_ProtocolIE_ID_id_E_RABs_Admitted_List, true);
+
+ if (ie == NULL ) {
+ X2AP_ERROR("%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
+ return -1;
+ }else{
+ if (ie->value.choice.E_RABs_Admitted_List.list.count > 0) {
+
+ uint8_t nb_e_rabs_tobesetup;
+ nb_e_rabs_tobesetup = ie->value.choice.E_RABs_Admitted_List.list.count;
+ X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = nb_e_rabs_tobesetup;
+
+ for (int i=0; ivalue.choice.E_RABs_Admitted_List.list.array[i];
+ e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item;
+
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id = e_RABs_Admitted_Item->e_RAB_ID ;
+ X2AP_ERROR("x2u tunnel: index %d e_rab_id %d\n", i, X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].e_rab_id);
+
+ if(e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint == NULL){
+ X2AP_DEBUG("%s %d: X2AP_E_RABs_Admitted_Item_t->dL_GTP_TunnelEndpoint is a NULL pointer \n", __FILE__, __LINE__);
+ continue;
+ }
+
+ memcpy(X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer,
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.buf,
+ e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size);
+
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.length = e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->transportLayerAddress.size;
+
+ OCTET_STRING_TO_INT32(&e_RABs_Admitted_Item->dL_GTP_TunnelEndpoint->gTP_TEID,
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid);
+
+
+ X2AP_DEBUG("x2u tunnel: index %d target enb ip %d.%d.%d.%d length %d gtp teid %u\n",
+ i,
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[0],
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[1],
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[2],
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.buffer[3],
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].eNB_addr.length,
+ X2AP_HANDOVER_REQ_ACK(msg).e_rabs_tobesetup[i].gtp_teid);
+ }
+
+ }
+
+ }
+
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*/)
+ 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);
diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c
index fcadb0530e..e56edb8fe6 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB.c
+++ b/openair3/GTPV1-U/gtpv1u_eNB.c
@@ -50,12 +50,18 @@
#include "common/ran_context.h"
#include "gtpv1u_eNB_defs.h"
#include "gtpv1u_eNB_task.h"
+#include "rrc_eNB_GTPV1U.h"
#undef GTP_DUMP_SOCKET
extern unsigned char NB_eNB_INST;
extern RAN_CONTEXT_t RC;
+extern struct rrc_eNB_ue_context_s*
+rrc_eNB_get_ue_context(
+ eNB_RRC_INST* rrc_instance_pP,
+ rnti_t rntiP);
+
#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0
#include
static int gtpv1u_dump_socket_g;
@@ -105,6 +111,27 @@ static void gtpv1u_eNB_write_dump_socket(uint8_t *buffer_pP, uint32_t buffer_len
#endif
+//-----------------------------------------------------------------------------
+static int gtpv1u_eNB_get_msgsource(struct rrc_eNB_ue_context_s *ue_context_p, teid_t teid)
+{
+ int erab_index = 0;
+
+ /* source enb */
+ if(ue_context_p->ue_context.handover_info != NULL && ue_context_p->ue_context.handover_info->state == HO_COMPLETE)
+ {
+ return GTPV1U_MSG_FROM_SPGW;
+ }
+
+ /* target enb */
+ for (erab_index = 0; erab_index < ue_context_p->ue_context.nb_x2u_e_rabs; erab_index++) {
+ if(ue_context_p->ue_context.enb_gtp_x2u_teid[erab_index] == teid){
+ return GTPV1U_MSG_FROM_SOURCE_ENB;
+ }
+ }
+
+ return GTPV1U_MSG_FROM_SPGW;
+}
+
//-----------------------------------------------------------------------------
static int gtpv1u_eNB_send_init_udp(const Gtpv1uS1Req *req) {
// Create and alloc new message
@@ -198,10 +225,16 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
case NW_GTPV1U_ULP_API_RECV_TPDU: {
uint8_t buffer[4096];
uint32_t buffer_len;
+ struct rrc_eNB_ue_context_s *ue_context_p;
+ uint16_t msgType = NW_GTP_GPDU;
+ NwGtpv1uMsgT *pMsg = NULL;
+
/* Nw-gptv1u stack has processed a PDU. we can schedule it to PDCP
* for transmission.
*/
teid = pUlpApi->apiInfo.recvMsgInfo.teid;
+ pMsg = (NwGtpv1uMsgT *) pUlpApi->apiInfo.recvMsgInfo.hMsg;
+ msgType = pMsg->msgType;
if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
buffer, &buffer_len)) {
@@ -243,6 +276,158 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
0,0,
(gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4,
buffer_len);
+
+ ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id], ctxt.rnti);
+ if((ue_context_p != NULL) &&
+ (ue_context_p->ue_context.handover_info != NULL) &&
+ (ue_context_p->ue_context.handover_info->state < HO_FORWARDING_COMPLETE)) {
+
+ if(msgType == NW_GTP_END_MARKER){
+ /* in the source enb, UE in RRC_HO_EXECUTION mode */
+ if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION && ue_context_p->ue_context.handover_info->state == HO_COMPLETE) {
+ /* set handover state */
+ //ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
+
+ MessageDef *msg;
+ // Configure end marker
+ msg = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_END_MARKER_REQ);
+ GTPV1U_ENB_END_MARKER_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + buffer_len);
+ memcpy(>PV1U_ENB_END_MARKER_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], buffer, buffer_len);
+ GTPV1U_ENB_END_MARKER_REQ(msg).length = buffer_len;
+ GTPV1U_ENB_END_MARKER_REQ(msg).rnti = ctxt.rnti;
+ GTPV1U_ENB_END_MARKER_REQ(msg).rab_id = gtpv1u_teid_data_p->eps_bearer_id;
+ GTPV1U_ENB_END_MARKER_REQ(msg).offset = GTPU_HEADER_OVERHEAD_MAX;
+ LOG_I(GTPU, "Send End Marker to GTPV1-U at frame %d and subframe %d \n", ctxt.frame,ctxt.subframe);
+ itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(ctxt.module_id), msg);
+ return NW_GTPV1U_OK;
+ }
+ }
+
+ if (ue_context_p->ue_context.Status == RRC_HO_EXECUTION || ue_context_p->ue_context.Status == RRC_RECONFIGURED) {
+
+ int msgsrc = gtpv1u_eNB_get_msgsource(ue_context_p, teid);
+
+ LOG_D(GTPU,"UE INFO.ueStatus %d, handover state %d, forwarding state %d, from %s. message type %s\n",
+ ue_context_p->ue_context.Status,
+ ue_context_p->ue_context.handover_info->state,
+ ue_context_p->ue_context.handover_info->forwarding_state,
+ msgsrc == GTPV1U_MSG_FROM_SOURCE_ENB?"Source eNB":"EPC",
+ msgsrc != GTPV1U_MSG_FROM_SOURCE_ENB? "UDP DATA" :
+ msgType == NW_GTP_END_MARKER?"END MARKER":"DATA FORWARDING");
+
+ /* target enb */
+ if(msgType == NW_GTP_END_MARKER){
+ LOG_I(GTPU, "target end receive END MARKER\n");
+ ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
+ gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req;
+ memset(&delete_tunnel_req, 0 , sizeof(delete_tunnel_req));
+ delete_tunnel_req.rnti = ctxt.rnti;
+ gtpv1u_delete_x2u_tunnel(ctxt.module_id, &delete_tunnel_req, GTPV1U_TARGET_ENB);
+ return NW_GTPV1U_OK;
+ }
+
+ /* form source eNB message */
+ if(msgsrc == GTPV1U_MSG_FROM_SOURCE_ENB)
+ {
+ LOG_I(GTPU, "Received a message data forwarding length %d\n", buffer_len);
+
+#if defined(LOG_GTPU) && LOG_GTPU > 0
+ LOG_T(GTPU, "forwarding data info:\n", buffer_len);
+
+ for(int i=1;i<=buffer_len; i++){
+ LOG_T(GTPU, "%02x ", buffer[i-1]);
+ if(i%20 == 0)LOG_T(GTPU, "\n");
+ }
+ LOG_T(GTPU, "\n");
+#endif
+
+ result = gtpv_data_req(
+ &ctxt,
+ (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,
+ TASK_DATA_FORWARDING
+ );
+
+ if ( result == FALSE ) {
+ LOG_W(GTPU, "DATA FORWARDING message save failed\n");
+ return NW_GTPV1U_FAILURE;
+ }
+ ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_NO_EMPTY;
+ return NW_GTPV1U_OK;
+ }
+ /* from epc message */
+ else
+ {
+ /* in the source enb, UE in RRC_HO_EXECUTION mode */
+ if (ue_context_p->ue_context.handover_info->state == HO_COMPLETE) {
+ MessageDef *msg;
+ // Configure target
+ msg = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_DATA_FORWARDING_REQ);
+ GTPV1U_ENB_DATA_FORWARDING_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + buffer_len);
+ memcpy(>PV1U_ENB_DATA_FORWARDING_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], buffer, buffer_len);
+ GTPV1U_ENB_DATA_FORWARDING_REQ(msg).length = buffer_len;
+ GTPV1U_ENB_DATA_FORWARDING_REQ(msg).rnti = ctxt.rnti;
+ GTPV1U_ENB_DATA_FORWARDING_REQ(msg).rab_id = gtpv1u_teid_data_p->eps_bearer_id;
+ GTPV1U_ENB_DATA_FORWARDING_REQ(msg).offset = GTPU_HEADER_OVERHEAD_MAX;
+
+#if defined(LOG_GTPU) && LOG_GTPU > 0
+
+ LOG_T(GTPU, "Send data forwarding sdu_buffer to target enb. len %d info\n", buffer);
+ for(int i=1; i<=buffer_len; i++){
+ LOG_T(GTPU, "%02x ", buffer[i-1]);
+ if(i%20 == 0)LOG_T(GTPU, "\n");
+ }
+ LOG_T(GTPU, "\n");
+#endif
+
+ LOG_I(GTPU, "Send data forwarding to GTPV1-U at frame %d and subframe %d \n", ctxt.frame,ctxt.subframe);
+ itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(ctxt.module_id), msg);
+ return NW_GTPV1U_OK;
+ }
+
+ /* target eNB. x2ho forwarding is processing. spgw message save to TASK_END_MARKER */
+ if(ue_context_p->ue_context.handover_info->state != HO_COMPLETE &&
+ ue_context_p->ue_context.handover_info->state != HO_END_MARKER )
+ {
+ LOG_I(GTPU, "x2ho forwarding is processing. Received a spgw message. length %d\n", buffer_len);
+#if defined(LOG_GTPU) && LOG_GTPU > 0
+ LOG_T(GTPU, "spgw data info:\n", buffer_len);
+ for(int i=1;i<=buffer_len; i++){
+ LOG_T(GTPU, "%02x ", buffer[i-1]);
+ if(i%20 == 0)LOG_T(GTPU, "\n");
+ }
+ LOG_T(GTPU, "\n");
+#endif
+
+ result = gtpv_data_req(
+ &ctxt,
+ (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,
+ TASK_END_MARKER
+ );
+
+ if ( result == FALSE ) {
+ LOG_W(GTPU, "DATA FORWARDING message save failed\n");
+ return NW_GTPV1U_FAILURE;
+ }
+
+ ue_context_p->ue_context.handover_info->endmark_state = ENDMARK_NO_EMPTY;
+ return NW_GTPV1U_OK;
+ }
+
+ }
+
+ }
+
+ }
result = pdcp_data_req(
&ctxt,
SRB_FLAG_NO,
@@ -259,7 +444,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
if ( result == FALSE ) {
if (ctxt.configured == FALSE )
- LOG_W(GTPU, "PDCP data request failed, cause: RB is not configured!\n") ;
+ LOG_W(GTPU, "PDCP data request failed, cause: [UE:%x]RB is not configured!\n", ctxt.rnti) ;
else
LOG_W(GTPU, "PDCP data request failed\n");
@@ -550,6 +735,154 @@ gtpv1u_new_data_req(
return 0;
}
+//-----------------------------------------------------------------------------
+int
+gtpv1u_create_x2u_tunnel(
+ const instance_t instanceP,
+ const gtpv1u_enb_create_x2u_tunnel_req_t * const create_tunnel_req_pP,
+ gtpv1u_enb_create_x2u_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;
+ /* Local tunnel end-point identifier */
+ teid_t x2u_teid = 0;
+ gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL;
+ hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
+ int i;
+ ebi_t eps_bearer_id = 0;
+
+ MSC_LOG_RX_MESSAGE(
+ MSC_GTPU_ENB,
+ MSC_RRC_ENB,
+ NULL,0,
+ MSC_AS_TIME_FMT" CREATE_X2U_TUNNEL_REQ RNTI %"PRIx16" inst %u ntuns %u ebid %u enb-x2u 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->tenb_X2u_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;
+
+ for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
+ eps_bearer_id = create_tunnel_req_pP->eps_bearer_id[i];
+ LOG_D(GTPU, "Rx GTPV1U_ENB_CREATE_X2U_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 {
+ x2u_teid = gtpv1u_new_teid();
+ LOG_D(GTPU, "gtpv1u_create_x2u_tunnel() 0x%x %u(dec)\n", x2u_teid, x2u_teid);
+ stack_req.apiInfo.createTunnelEndPointInfo.teid = x2u_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);
+
+ memcpy(&create_tunnel_resp_pP->enb_addr.buffer,
+ &RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up,
+ sizeof (in_addr_t));
+
+ LOG_D(GTPU, "gtpv1u_create_x2u_tunnel() end addr %d.%d.%d.%d\n",
+ create_tunnel_resp_pP->enb_addr.buffer[0],
+ create_tunnel_resp_pP->enb_addr.buffer[1],
+ create_tunnel_resp_pP->enb_addr.buffer[2],
+ create_tunnel_resp_pP->enb_addr.buffer[3]);
+
+ create_tunnel_resp_pP->enb_addr.length = sizeof (in_addr_t);
+ create_tunnel_resp_pP->eps_bearer_id[i] = eps_bearer_id;
+ create_tunnel_resp_pP->num_tunnels += 1;
+
+ //-----------------------
+ // GTPV1U->PDCP mapping
+ //-----------------------
+ create_tunnel_resp_pP->enb_X2u_teid[i] = x2u_teid;
+ hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, x2u_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));
+ gtpv1u_teid_data_p->enb_id = 0; // TO DO
+ gtpv1u_teid_data_p->ue_id = create_tunnel_req_pP->rnti;
+ gtpv1u_teid_data_p->eps_bearer_id = eps_bearer_id;
+ hash_rc = hashtable_insert(RC.gtpv1u_data_g->teid_mapping, x2u_teid, gtpv1u_teid_data_p);
+ AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting teid mapping in GTPV1U hashtable");
+ } else {
+ create_tunnel_resp_pP->enb_X2u_teid[i] = 0;
+ 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,
+ x2u_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);
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+int gtpv1u_delete_x2u_tunnel(
+ const instance_t instanceP,
+ const gtpv1u_enb_delete_tunnel_req_t * const req_pP,
+ int enbflag)
+{
+ gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
+ hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
+ int erab_index = 0;
+ ebi_t eps_bearer_id = 0;
+ struct rrc_eNB_ue_context_s *ue_context_p = NULL;
+
+ ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instanceP], req_pP->rnti);
+ if(ue_context_p != NULL){
+ /* in the source enb */
+ if(enbflag == GTPV1U_SOURCE_ENB){
+ 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 < ue_context_p->ue_context.nb_x2u_e_rabs; erab_index++) {
+ eps_bearer_id = ue_context_p->ue_context.enb_gtp_x2u_ebi[erab_index];
+ LOG_I(GTPU, "gtpv1u_delete_x2u_tunnel user rnti %x teNB X2U teid %u eps bearer id %u\n",
+ req_pP->rnti,
+ gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_teNB,
+ ue_context_p->ue_context.enb_gtp_x2u_ebi[erab_index]);
+
+ gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_teNB = 0;
+ gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr = 0;
+ //gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].tenb_ip6_addr = 0;
+ }
+ ue_context_p->ue_context.nb_x2u_e_rabs = 0;
+ }
+ }
+ /* in the target enb */
+ else{
+ for (erab_index = 0; erab_index < ue_context_p->ue_context.nb_x2u_e_rabs; erab_index++) {
+ //-----------------------
+ // GTPV1U->PDCP mapping
+ //-----------------------
+ hash_rc = hashtable_remove(RC.gtpv1u_data_g->teid_mapping, ue_context_p->ue_context.enb_gtp_x2u_teid[erab_index]);
+ LOG_I(GTPU, "Removed user rnti %x , enb X2U teid %u\n", req_pP->rnti, ue_context_p->ue_context.enb_gtp_x2u_teid[erab_index]);
+
+ if (hash_rc != HASH_TABLE_OK) {
+ LOG_D(GTPU, "Removed user rnti %x , enb X2U teid %u not found\n", req_pP->rnti, ue_context_p->ue_context.enb_gtp_x2u_teid[erab_index]);
+ }
+ }
+ ue_context_p->ue_context.nb_x2u_e_rabs = 0;
+ }
+ }
+ return 0;
+}
+
//-----------------------------------------------------------------------------
int
gtpv1u_create_s1u_tunnel(
@@ -572,6 +905,10 @@ gtpv1u_create_s1u_tunnel(
int ip_offset = 0;
in_addr_t in_addr;
int addrs_length_in_bytes= 0;
+ int loop_counter = 0;
+ int ret = 0;
+
+
MSC_LOG_RX_MESSAGE(
MSC_GTPU_ENB,
MSC_RRC_ENB,
@@ -586,6 +923,7 @@ gtpv1u_create_s1u_tunnel(
for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
ip_offset = 0;
+ loop_counter = 0;
eps_bearer_id = create_tunnel_req_pP->eps_bearer_id[i];
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);
@@ -600,7 +938,13 @@ gtpv1u_create_s1u_tunnel(
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);
+ loop_counter++;
+ } while (rc != NW_GTPV1U_OK && loop_counter < 10);
+ if ( rc != NW_GTPV1U_OK && loop_counter == 10 ) {
+ LOG_E(GTPU,"NwGtpv1uCreateTunnelEndPoint failed 10 times,start next loop\n");
+ ret = -1;
+ continue;
+ }
//-----------------------
// PDCP->GTPV1U mapping
@@ -682,7 +1026,8 @@ gtpv1u_create_s1u_tunnel(
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);
- return 0;
+ //return 0;
+ return ret;
}
int gtpv1u_update_s1u_tunnel(
@@ -713,9 +1058,15 @@ int gtpv1u_update_s1u_tunnel(
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");
+ //AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable");
+ if ( hash_rc != HASH_TABLE_OK ) {
+ LOG_E(GTPU,"Failed to insert ue_mapping(rnti=%x) in GTPV1U hashtable\n",create_tunnel_req_pP->rnti);
+ return -1;
+ } else {
LOG_I(GTPU, "inserting ue_mapping(rnti=%x) in GTPV1U hashtable\n",
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);
@@ -1043,6 +1394,176 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) {
}
break;
+ case GTPV1U_ENB_DATA_FORWARDING_REQ: {
+ gtpv1u_enb_data_forwarding_req_t *data_req_p = NULL;
+ NwGtpv1uUlpApiT stack_req;
+ NwGtpv1uRcT rc = NW_GTPV1U_FAILURE;
+ hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
+ gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
+ teid_t enb_s1u_teid = 0;
+ teid_t tenb_x2u_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_DATA_FORWARDING_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);
+
+ 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);
+ } else {
+ if ((data_req_p->rab_id >= GTPV1U_BEARER_OFFSET) && (data_req_p->rab_id <= max_val_LTE_DRB_Identity)) {
+ enb_s1u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_eNB;
+ tenb_x2u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_teNB; // target enb teid
+ stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU;
+ stack_req.apiInfo.sendtoInfo.teid = tenb_x2u_teid;
+ stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr;// target enb ip
+
+ rc = nwGtpv1uGpduMsgNew(
+ RC.gtpv1u_data_g->gtpv1u_stack,
+ tenb_x2u_teid,
+ NW_FALSE,
+ RC.gtpv1u_data_g->seq_num++,
+ data_req_p->buffer,
+ data_req_p->length,
+ data_req_p->offset,
+ &(stack_req.apiInfo.sendtoInfo.hMsg));
+
+ 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,tenb_x2u_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);
+
+ 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,tenb_x2u_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,
+ tenb_x2u_teid,
+ data_req_p->length);
+
+ }
+
+ rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack,
+ stack_req.apiInfo.sendtoInfo.hMsg);
+
+ if (rc != NW_GTPV1U_OK) {
+ LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc);
+ }
+ }
+ }
+ }
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_OUT);
+ /* Buffer still needed, do not free it */
+ //itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), data_req_p->buffer)
+ }
+ break;
+
+ case GTPV1U_ENB_END_MARKER_REQ:{
+ gtpv1u_enb_end_marker_req_t *data_req_p = NULL;
+ NwGtpv1uUlpApiT stack_req;
+ NwGtpv1uRcT rc = NW_GTPV1U_FAILURE;
+ hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS;
+ gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL;
+ teid_t enb_s1u_teid = 0;
+ teid_t tenb_x2u_teid = 0;
+ NwGtpv1uMsgT *pMsg = NULL;
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_IN);
+ data_req_p = >PV1U_ENB_END_MARKER_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);
+
+ 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);
+ } else {
+ if ((data_req_p->rab_id >= GTPV1U_BEARER_OFFSET) && (data_req_p->rab_id <= max_val_LTE_DRB_Identity)) {
+ enb_s1u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_eNB;
+ tenb_x2u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_teNB; // target enb teid
+ stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU;
+ stack_req.apiInfo.sendtoInfo.teid = tenb_x2u_teid;
+ stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr;// target enb ip
+
+ rc = nwGtpv1uGpduMsgNew(
+ RC.gtpv1u_data_g->gtpv1u_stack,
+ tenb_x2u_teid,
+ NW_FALSE,
+ RC.gtpv1u_data_g->seq_num++,
+ data_req_p->buffer,
+ data_req_p->length,
+ data_req_p->offset,
+ &(stack_req.apiInfo.sendtoInfo.hMsg));
+
+ 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,tenb_x2u_teid,data_req_p->length);
+ (void)enb_s1u_teid; /* avoid gcc warning "set but not used" */
+ } else {
+ pMsg = (NwGtpv1uMsgT *) stack_req.apiInfo.sendtoInfo.hMsg;
+ pMsg->msgType = NW_GTP_END_MARKER;
+ rc = nwGtpv1uProcessUlpReq(RC.gtpv1u_data_g->gtpv1u_stack, &stack_req);
+
+ 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,tenb_x2u_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,
+ tenb_x2u_teid,
+ data_req_p->length);
+
+ }
+
+ rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack,
+ stack_req.apiInfo.sendtoInfo.hMsg);
+
+ if (rc != NW_GTPV1U_OK) {
+ LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc);
+ }
+
+ gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req;
+ memset(&delete_tunnel_req, 0 , sizeof(delete_tunnel_req));
+ delete_tunnel_req.rnti = data_req_p->rnti;
+ gtpv1u_delete_x2u_tunnel(instance, &delete_tunnel_req, GTPV1U_SOURCE_ENB);
+ }
+ }
+ }
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_OUT);
+ }
+ break;
+
case TERMINATE_MESSAGE: {
if (RC.gtpv1u_data_g->ue_mapping != NULL) {
hashtable_destroy (&(RC.gtpv1u_data_g->ue_mapping));
diff --git a/openair3/GTPV1-U/gtpv1u_eNB_defs.h b/openair3/GTPV1-U/gtpv1u_eNB_defs.h
index 978a3c58bc..79d9a1dcdd 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB_defs.h
+++ b/openair3/GTPV1-U/gtpv1u_eNB_defs.h
@@ -40,6 +40,11 @@
#define GTPV1U_MAX_BEARERS_ID (max_val_LTE_DRB_Identity - GTPV1U_BEARER_OFFSET)
+#define GTPV1U_SOURCE_ENB (0)
+#define GTPV1U_TARGET_ENB (1)
+#define GTPV1U_MSG_FROM_SOURCE_ENB (0)
+#define GTPV1U_MSG_FROM_SPGW (1)
+
typedef enum {
BEARER_DOWN = 0,
BEARER_IN_CONFIG,
@@ -65,6 +70,9 @@ typedef struct gtpv1u_bearer_s {
teid_t teid_sgw; ///< Remote TEID
in_addr_t sgw_ip_addr;
struct in6_addr sgw_ip6_addr;
+ teid_t teid_teNB;
+ in_addr_t tenb_ip_addr; ///< target eNB ipv4
+ struct in6_addr tenb_ip6_addr; ///< target eNB ipv6
tcp_udp_port_t port;
//NwGtpv1uStackSessionHandleT stack_session;
bearer_state_t state;
diff --git a/openair3/GTPV1-U/gtpv1u_eNB_task.h b/openair3/GTPV1-U/gtpv1u_eNB_task.h
index 9830ea6169..a6e2625941 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB_task.h
+++ b/openair3/GTPV1-U/gtpv1u_eNB_task.h
@@ -44,6 +44,12 @@ int gtpv1u_eNB_init(void);
void *gtpv1u_eNB_process_itti_msg(void*);
void *gtpv1u_eNB_task(void *args);
+int
+gtpv1u_create_x2u_tunnel(
+ const instance_t instanceP,
+ const gtpv1u_enb_create_x2u_tunnel_req_t * const create_tunnel_req_pP,
+ gtpv1u_enb_create_x2u_tunnel_resp_t * const create_tunnel_resp_pP);
+
int
gtpv1u_create_s1u_tunnel(
const instance_t instanceP,
@@ -55,4 +61,9 @@ 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);
+
+int gtpv1u_delete_x2u_tunnel(
+ const instance_t instanceP,
+ const gtpv1u_enb_delete_tunnel_req_t * const req_pP,
+ int enbflag);
#endif /* GTPV1U_ENB_TASK_H_ */
diff --git a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c
index 3e8da5d015..0c7663921b 100644
--- a/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c
+++ b/openair3/GTPV1-U/nw-gtpv1u/src/NwGtpv1u.c
@@ -378,9 +378,14 @@ NwGtpv1uCreateTunnelEndPoint( NW_IN NwGtpv1uStackT *thiz,
*phStackSession = (NwGtpv1uStackSessionHandleT) pTunnelEndPoint;
pTunnelEndPoint = RB_FIND(NwGtpv1uTunnelEndPointIdentifierMap,
&(thiz->teidMap), pTunnelEndPoint);
- NW_ASSERT(pTunnelEndPoint);
- GTPU_DEBUG("Tunnel end-point 0x%p creation successful for teid 0x%x %u(dec)",
- pTunnelEndPoint, (unsigned int)teid, (unsigned int)teid);
+ //NW_ASSERT(pTunnelEndPoint);
+ if (!pTunnelEndPoint) {
+ GTPU_ERROR("Tunnel end-point cannot be NULL");
+ rc = NW_GTPV1U_FAILURE;
+ } else {
+ GTPU_DEBUG("Tunnel end-point 0x%p creation successful for teid 0x%x %u(dec)",
+ pTunnelEndPoint, (unsigned int)teid, (unsigned int)teid);
+ }
}
} else {
@@ -893,8 +898,14 @@ nwGtpv1uProcessUdpReq( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
break;
case NW_GTP_END_MARKER:
- GTPU_DEBUG("NW_GTP_END_MARKER\n");
- ret = NW_GTPV1U_OK;
+#if defined(LOG_GTPU) && LOG_GTPU > 0
+ for(int i =1; i<= udpDataLen; i++){
+ printf("%02x ", udpData[i-1]);
+ if(i % 20 == 0)printf("\n");
+ }
+#endif
+ GTPU_INFO("NW_GTP_END_MARKER\n");
+ ret = nwGtpv1uProcessGpdu(thiz, udpData, udpDataLen, peerIp);
break;
default:
diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c
index e2396d015f..e773ae6a20 100644
--- a/openair3/S1AP/s1ap_eNB_handlers.c
+++ b/openair3/S1AP/s1ap_eNB_handlers.c
@@ -1518,7 +1518,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
if (stream == 0) {
S1AP_ERROR("[SCTP %d] Received s1 path switch request ack on stream (%d)\n",
assoc_id, stream);
- return -1;
+ //return -1;
}
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
diff --git a/openair3/SCTP/sctp_default_values.h b/openair3/SCTP/sctp_default_values.h
index 5008ea0b72..528ffb5a05 100644
--- a/openair3/SCTP/sctp_default_values.h
+++ b/openair3/SCTP/sctp_default_values.h
@@ -26,6 +26,6 @@
#define SCTP_IN_STREAMS (16)
#define SCTP_MAX_ATTEMPTS (2)
#define SCTP_TIMEOUT (5)
-#define SCTP_RECV_BUFFER_SIZE (1024)
+#define SCTP_RECV_BUFFER_SIZE (8192)
#endif /* SCTP_DEFAULT_VALUES_H_ */
diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c
index e934888178..3cb64254fc 100644
--- a/openair3/SCTP/sctp_eNB_task.c
+++ b/openair3/SCTP/sctp_eNB_task.c
@@ -955,6 +955,11 @@ sctp_eNB_read_from_socket(
return;
}
+ if (!(flags & MSG_EOR)) {
+ SCTP_ERROR("fatal: partial SCTP messages are not handled\n");
+ exit(1);
+ }
+
if (flags & MSG_NOTIFICATION) {
union sctp_notification *snp;
snp = (union sctp_notification *)buffer;
diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c
index 27f754badc..90ee87900d 100644
--- a/openair3/UDP/udp_eNB_task.c
+++ b/openair3/UDP/udp_eNB_task.c
@@ -371,13 +371,13 @@ void *udp_eNB_task(void *args_p)
udp_sd = udp_sock_p->sd;
pthread_mutex_unlock(&udp_socket_list_mutex);
-#if defined(LOG_UDP) && LOG_UDP > 0
+//#if defined(LOG_UDP) && LOG_UDP > 0
LOG_D(UDP_, "[%d] Sending message of size %u to "IPV4_ADDR" and port %u\n",
udp_sd,
udp_data_req_p->buffer_length,
IPV4_ADDR_FORMAT(udp_data_req_p->peer_address),
udp_data_req_p->peer_port);
-#endif
+//#endif
bytes_written = sendto(
udp_sd,
&udp_data_req_p->buffer[udp_data_req_p->buffer_offset],
diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h
index 31a7173630..c9d0027bf2 100644
--- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h
+++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h
@@ -27,7 +27,7 @@
#include
#include "common_lib.h"
-#include "log.h"
+#include "LOG/log.h"
/** @addtogroup _BLADERF_PHY_RF_INTERFACE_
* @{
diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c
index c1685e11ec..010f54a3ba 100644
--- a/targets/ARCH/COMMON/common_lib.c
+++ b/targets/ARCH/COMMON/common_lib.c
@@ -105,7 +105,7 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param
if ( IS_SOFTMODEM_BASICSIM ) {
libname=OAI_BASICSIM_LIBNAME;
shlib_fdesc[0].fname="device_init";
- } else if ( IS_SOFTMODEM_RFSIM ) {
+ } else if ( IS_SOFTMODEM_RFSIM && flag == RAU_LOCAL_RADIO_HEAD) {
libname=OAI_RFSIM_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else if (flag == RAU_LOCAL_RADIO_HEAD) {
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index 2deb0ee895..638f5ed989 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -65,8 +65,8 @@ pthread_mutex_t Sockmutex;
typedef struct buffer_s {
int conn_sock;
- bool alreadyRead;
- uint64_t lastReceivedTS;
+ openair0_timestamp lastReceivedTS;
+ openair0_timestamp lastWroteTS;
bool headerMode;
samplesBlockHeader_t th;
char *transferPtr;
@@ -78,7 +78,7 @@ typedef struct buffer_s {
typedef struct {
int listen_sock, epollfd;
- uint64_t nextTimestamp;
+ openair0_timestamp nextTimestamp;
uint64_t typeStamp;
char *ip;
uint16_t port;
@@ -123,9 +123,9 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
// Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
// the parameter "-s" is declared as SNR, but the input power is not well defined
// −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
- const double rxGain= 132.24 - snr_dB;
+ const double rxGain= 132.24 - snr_dB;
// sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
- // fixme: the last constant is pure trial results to make decent noise
+ // fixme: the last constant is pure trial results to make decent noise
const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
// Fixme: we don't fill the offset length samples at begining ?
// anyway, in today code, channel_offset=0
@@ -154,9 +154,6 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
}
out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
- printf("in: %d, out %d= %f*%f + %f*%f\n",
- input_sig[((TS+i)*nbTx)%CirSize].r, out_ptr->r , rx_tmp.x,
- pathLossLinear, noise_per_sample,gaussdouble(0.0,1.0));
out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
out_ptr++;
}
@@ -175,8 +172,8 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
ptr->conn_sock=sock;
- ptr->alreadyRead=false;
ptr->lastReceivedTS=0;
+ ptr->lastWroteTS=0;
ptr->headerMode=true;
ptr->transferPtr=(char *)&ptr->th;
ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
@@ -379,21 +376,22 @@ sin_addr:
setblocking(sock, notBlocking);
allocCirBuf(t, sock);
- t->buf[sock].alreadyRead=true; // UE will start blocking on read
return 0;
}
-uint64_t lastW=-1;
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
rfsimulator_state_t *t = device->priv;
LOG_D(HW,"sending %d samples at time: %ld\n", nsamps, timestamp);
- for (int i=0; ibuf[i];
- if (ptr->conn_sock >= 0 ) {
+ for (int i=0; ibuf[i];
+
+ if (b->conn_sock >= 0 ) {
+ if ( abs((double)b->lastWroteTS-timestamp) > (double)CirSize)
+ LOG_E(HW,"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS);
samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp};
- fullwrite(ptr->conn_sock,&header, sizeof(header), t);
+ fullwrite(b->conn_sock,&header, sizeof(header), t);
sample_t tmpSamples[nsamps][nbAnt];
for(int a=0; aconn_sock >= 0 )
- fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
+ if (b->conn_sock >= 0 ) {
+ fullwrite(b->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
+ b->lastWroteTS=timestamp+nsamps;
+ }
}
}
- lastW=timestamp;
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) );
// Let's verify we don't have incoming data
// This is mandatory when the opposite side don't transmit
- // This is mandatory when the opposite side don't transmit
flushInput(t, 0);
pthread_mutex_unlock(&Sockmutex);
return nsamps;
@@ -485,7 +483,6 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) ||
(t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol");
b->headerMode=false;
- b->alreadyRead=true;
if ( b->lastReceivedTS != b->th.timestamp) {
int nbAnt= b->th.nbAnt;
@@ -501,8 +498,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
}
b->lastReceivedTS=b->th.timestamp;
- AssertFatal(lastW == -1 || ( abs((double)lastW-b->lastReceivedTS) < (double)CirSize),
- "Tx/Rx shift too large Tx:%lu, Rx:%lu\n", lastW, b->lastReceivedTS);
+ AssertFatal(b->lastWroteTS == 0 || ( abs((double)b->lastWroteTS-b->lastReceivedTS) < (double)CirSize),
+ "Tx/Rx shift too large Tx:%lu, Rx:%lu\n", b->lastWroteTS, b->lastReceivedTS);
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
}
@@ -561,15 +558,33 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
return nsamps;
}
} else {
+
bool have_to_wait;
do {
have_to_wait=false;
for ( int sock=0; sockbuf[sock].circularBuf && t->buf[sock].alreadyRead )
- if ( t->buf[sock].lastReceivedTS == 0 ||
- (t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
+ buffer_t *b=&t->buf[sock];
+ if ( b->circularBuf) {
+ LOG_D(HW,"sock: %d, lastWroteTS: %lu, lastRecvTS: %lu, TS must be avail: %lu\n",
+ sock, b->lastWroteTS,
+ b->lastReceivedTS,
+ t->nextTimestamp+nsamps);
+ if ( b->lastReceivedTS > b->lastWroteTS ) {
+ // The caller momdem (NB, UE, ...) must send Tx in advance, so we fill TX if Rx is in advance
+ // This occurs for example when UE is in sync mode: it doesn't transmit
+ // with USRP, it seems ok: if "tx stream" is off, we may consider it actually cuts the Tx power
+ struct complex16 v={0};
+ void *samplesVoid[b->th.nbAnt];
+ for ( int i=0; i th.nbAnt; i++)
+ samplesVoid[i]=(void*)&v;
+ rfsimulator_write(device, b->lastReceivedTS, samplesVoid, 1, b->th.nbAnt, 0);
+ }
+ }
+
+ if ( b->circularBuf )
+ if ( t->nextTimestamp+nsamps > b->lastReceivedTS ) {
have_to_wait=true;
break;
}
@@ -592,7 +607,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
for (int sock=0; sockbuf[sock];
- if ( ptr->circularBuf && ptr->alreadyRead ) {
+ if ( ptr->circularBuf ) {
bool reGenerateChannel=false;
//fixme: when do we regenerate
diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h
index 644952ca79..b81fd09147 100644
--- a/targets/COMMON/openairinterface5g_limits.h
+++ b/targets/COMMON/openairinterface5g_limits.h
@@ -12,13 +12,16 @@
// This problem will be fixed in the future.
# ifndef UESIM_EXPANSION
# define NUMBER_OF_UE_MAX 16
+# define NUMBER_OF_UCI_VARS_MAX 56
# define NUMBER_OF_CONNECTED_eNB_MAX 3
# else
# define NUMBER_OF_UE_MAX 256
+# define NUMBER_OF_UCI_VARS_MAX 256
# define NUMBER_OF_CONNECTED_eNB_MAX 1
# endif
# else
# define NUMBER_OF_UE_MAX 256
+# define NUMBER_OF_UCI_VARS_MAX 256
# define NUMBER_OF_CONNECTED_eNB_MAX 1
# endif
#else
@@ -32,13 +35,16 @@ and the other are using MAX_MOBILES_PER_ENB in for-loop.
*/
# ifndef UESIM_EXPANSION
# define NUMBER_OF_UE_MAX 16
+# define NUMBER_OF_UCI_VARS_MAX 56
# define NUMBER_OF_CONNECTED_eNB_MAX 3
# else
# define NUMBER_OF_UE_MAX 256
+# define NUMBER_OF_UCI_VARS_MAX 256
# define NUMBER_OF_CONNECTED_eNB_MAX 1
# endif
# else
# define NUMBER_OF_UE_MAX 256
+# define NUMBER_OF_UCI_VARS_MAX 256
# define NUMBER_OF_CONNECTED_eNB_MAX 1
# endif
# if defined(STANDALONE) && STANDALONE==1
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 3105b7c855..1ad25febac 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -189,14 +189,14 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name
eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
- eNB->UL_INFO.cqi_ind.number_of_cqis
+ eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis
) {
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d num_pdcch_symbols:%d\n",
NFAPI_SFNSF2DEC(eNB->UL_INFO.rx_ind.sfn_sf), eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
NFAPI_SFNSF2DEC(eNB->UL_INFO.harq_ind.sfn_sf), eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
NFAPI_SFNSF2DEC(eNB->UL_INFO.crc_ind.sfn_sf), eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
- eNB->UL_INFO.cqi_ind.number_of_cqis,
+ eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis,
proc->frame_rx, proc->subframe_rx,
proc->frame_tx, proc->subframe_tx, eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols);
}
@@ -218,9 +218,11 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name
wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx);
#endif
}
-
- release_UE_in_freeList(eNB->Mod_id);
-
+ if (NFAPI_MODE!=NFAPI_MODE_PNF) {
+ release_UE_in_freeList(eNB->Mod_id);
+ } else {
+ release_rnti_of_phy(eNB->Mod_id);
+ }
// UE-specific RX processing for subframe n
if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) {
phy_procedures_eNB_uespec_RX(eNB, proc);
@@ -429,13 +431,12 @@ static void *L1_thread( void *param ) {
}
LOG_D(PHY,"L1 RX %d.%d done\n",proc->frame_rx,proc->subframe_rx);
-
- if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) phy_procedures_eNB_TX(eNB, proc, 1);
-
-
if (NFAPI_MODE!=NFAPI_MODE_VNF) {
- if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB,proc->frame_rx,proc->subframe_rx,proc->frame_tx,proc->subframe_tx,proc->timestamp_tx);
- else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(eNB,proc,proc->frame_tx,proc->subframe_tx,proc->timestamp_tx);
+ if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB,proc->frame_rx,proc->subframe_rx,proc->frame_tx,proc->subframe_tx,proc->timestamp_tx);
+ else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) {
+ phy_procedures_eNB_TX(eNB, proc, 1);
+ wakeup_txfh(eNB,proc,proc->frame_tx,proc->subframe_tx,proc->timestamp_tx);
+ }
}
if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break;
@@ -635,15 +636,12 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU_PRACH))==0,"mutex_lock return %d\n",ret);
for (i=0; inum_RU; i++) {
- if (ru == eNB->RU_list[i]) {
- LOG_D(PHY,"frame %d, subframe %d: RU %d for eNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,eNB->Mod_id,proc->RU_mask_prach,eNB->num_RU);
-
- if ((proc->RU_mask_prach&(1< 0)
- LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
- eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach);
-
- proc->RU_mask_prach |= (1<RU_list[i] && eNB->RU_list[i]->wait_cnt == 0) {
+ LOG_D(PHY,"frame %d, subframe %d: RU %d for eNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,eNB->Mod_id,proc->RU_mask_prach,eNB->num_RU);
+ proc->RU_mask_prach |= (1<RU_list[i]->state == RU_SYNC || eNB->RU_list[i]->wait_cnt > 0) {
+ proc->RU_mask_prach |= (1<RU_mask_prach != (1<num_RU)-1) { // not all RUs have provided their information so return
@@ -929,7 +927,9 @@ 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!=NFAPI_MODE_VNF) {
+ if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) {
+ pthread_create( &L1_proc->pthread, attr0, L1_thread, proc );
+ } else if ((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==NFAPI_MODE_VNF) { // this is neccesary in VNF or L2 FAPI simulator.
@@ -940,10 +940,12 @@ void init_eNB_proc(int inst) {
pthread_create( &L1_proc_tx->pthread, attr1, L1_thread, L1_proc_tx);
}
- pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB );
+ if (NFAPI_MODE!=NFAPI_MODE_VNF) {
+ pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB );
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
- pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB );
+ 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);
@@ -1104,6 +1106,7 @@ void init_transport(PHY_VARS_eNB *eNB) {
LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
LOG_I(PHY, "Initialise transport\n");
+if (NFAPI_MODE!=NFAPI_MODE_VNF) {
for (i=0; iMod_id,eNB->CC_id,eNB->dlsch_ra);
eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp);
LOG_D(PHY,"eNB %d.%d : MCH %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_MCH);
+}
eNB->rx_total_gain_dB=130;
for(i=0; iUL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list;
eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list;
eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list;
- eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list;
- eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list;
+ eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_pdu_list = eNB->cqi_pdu_list;
+ eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list;
eNB->prach_energy_counter = 0;
}
}
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 8ed220da8e..89abd12499 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -217,6 +217,7 @@ void fh_if4p5_south_in(RU_t *ru,int *frame,int *subframe) {
if (proc->symbol_mask[*subframe]==0) { // this is normal case, if not true then we received a PULTICK before the previous subframe was finished
do {
recv_IF4p5(ru, &f, &sf, &packet_type, &symbol_number);
+ LOG_D(PHY,"fh_if4p5_south_in: RU %d, frame %d, subframe %d, f %d, sf %d\n",ru->idx,*frame,*subframe,f,sf);
if (oai_exit == 1 || ru->cmd== STOP_RU) break;
if (packet_type == IF4p5_PULFFT) proc->symbol_mask[sf] = proc->symbol_mask[sf] | (1<symbol_mask[*subframe]);
- } while(proc->symbol_mask[*subframe] != symbol_mask_full);
+ LOG_D(PHY,"rx_fh_if4p5 for RU %d: subframe %d, sf %d, symbol mask %x\n",ru->idx,*subframe,sf,proc->symbol_mask[sf]);
+ } while(proc->symbol_mask[sf] != symbol_mask_full);
}
else {
f = *frame;
@@ -437,10 +438,13 @@ void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *subframe) {
proc->first_tx = 0;
symbol_mask_full = ((subframe_select(fp,*subframe) == SF_S) ? (1<dl_symbols_in_S_subframe) : (1<symbols_per_tti))-1;
} else {
- AssertFatal(frame_tx == *frame,
+ /* AssertFatal(frame_tx == *frame,
"frame_tx %d is not what we expect %d\n",frame_tx,*frame);
AssertFatal(subframe_tx == *subframe,
"In frame_tx %d : subframe_tx %d is not what we expect %d\n",frame_tx,subframe_tx,*subframe);
+ */
+ *frame = frame_tx;
+ *subframe = subframe_tx;
}
if (packet_type == IF4p5_PDLFFT) {
@@ -1661,7 +1665,7 @@ void *ru_thread( void *param ) {
proc->instance_cnt_asynch_rxtx=0;
pthread_cond_signal(&proc->cond_asynch_rxtx);
AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_asynch_rxtx))==0,"mutex_unlock returns %d\n",ret);
- } else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx);
+ } else LOG_D(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 == 1) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
@@ -1872,7 +1876,8 @@ void *ru_thread_synch(void *arg) {
&avg);
LOG_I(PHY,"RU synch cnt %d: %d, val %llu (%d dB,%d dB)\n",cnt,ru->rx_offset,(unsigned long long)peak_val,dB_fixed64(peak_val),dB_fixed64(avg));
cnt++;
- if (/*ru->rx_offset >= 0*/dB_fixed(peak_val)>=85 && cnt>10) {
+ //if (/*ru->rx_offset >= 0*/dB_fixed(peak_val)>=85 && cnt>10) {
+ if (ru->rx_offset >= 0 && avg>0 && dB_fixed(peak_val/avg)>=15 && cnt>10) {
LOG_I(PHY,"Estimated peak_val %d dB, avg %d => timing offset %llu\n",dB_fixed(peak_val),dB_fixed(avg),(unsigned long long int)ru->rx_offset);
ru->in_synch = 1;
/*
@@ -2628,7 +2633,11 @@ void init_RU(char *rf_config_file, clock_source_t clock_source,clock_source_t ti
// NOTE: multiple CC_id are not handled here yet!
ru->openair0_cfg.clock_source = clock_source;
ru->openair0_cfg.time_source = time_source;
-// ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0;
+ //ru->generate_dmrs_sync = (ru->is_slave == 0) ? 1 : 0;
+ if ((ru->is_slave == 0) && (ru->ota_sync_enable == 1))
+ ru->generate_dmrs_sync = 1;
+ else
+ ru->generate_dmrs_sync = 0;
if (ru->generate_dmrs_sync == 1) {
generate_ul_ref_sigs();
ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms.ofdm_symbol_size*2*sizeof(int16_t));
@@ -2915,10 +2924,15 @@ void RCconfig_RU(void) {
printf("RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr));
if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
else RC.ru[j]->is_slave=0;
+ printf("RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr));
+ if (strcmp(*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr), "yes") == 0) RC.ru[j]->ota_sync_enable=1;
+ else RC.ru[j]->ota_sync_enable=0;
}
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);
for (i=0;inum_bands;i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i];
} //strcmp(local_rf, "yes") == 0
else {
diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c
index dd91f54004..a5fee5397f 100644
--- a/targets/RT/USER/lte-softmodem-common.c
+++ b/targets/RT/USER/lte-softmodem-common.c
@@ -62,6 +62,7 @@ void get_common_options(void) {
uint32_t nonbiot;
uint32_t rfsim;
uint32_t basicsim;
+ char *logmem_filename = NULL;
uint32_t do_forms;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
@@ -83,6 +84,13 @@ void get_common_options(void) {
load_module_shlib("telnetsrv",NULL,0,NULL);
}
+ if (logmem_filename != NULL && strlen(logmem_filename) > 0) {
+ log_mem_filename = &logmem_filename[0];
+ log_mem_flag = 1;
+ printf("Enabling OPT for log save at memory %s\n",log_mem_filename);
+ logInit_log_mem();
+ }
+
if (noS1) {
set_softmodem_optmask(SOFTMODEM_NOS1_BIT);
}
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 119e0c39e4..70b458a7fe 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -261,7 +261,7 @@ void exit_function(const char *file, const char *function, const int line, const
if (s != NULL) {
printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s);
}
-
+ close_log_mem();
oai_exit = 1;
if (RC.ru == NULL)
@@ -524,6 +524,7 @@ int main( int argc, char **argv ) {
int i;
int CC_id = 0;
int ru_id;
+ int node_type = ngran_eNB;
if ( load_configmodule(argc,argv,0) == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
@@ -604,12 +605,13 @@ int main( int argc, char **argv ) {
RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration;
itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
}
+ node_type = RC.rrc[0]->node_type;
} else {
printf("RC.nb_inst = 0, Initializing L1\n");
RCconfig_L1();
}
- if (RC.nb_inst > 0 && NODE_IS_CU(RC.rrc[0]->node_type)) {
+ if (RC.nb_inst > 0 && NODE_IS_CU(node_type)) {
protocol_ctxt_t ctxt;
ctxt.module_id = 0 ;
ctxt.instance = 0;
@@ -621,7 +623,7 @@ int main( int argc, char **argv ) {
}
/* start threads if only L1 or not a CU */
- if (RC.nb_inst == 0 || !NODE_IS_CU(RC.rrc[0]->node_type)) {
+ if (RC.nb_inst == 0 || !NODE_IS_CU(node_type) || NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) {
// 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);
@@ -720,7 +722,7 @@ int main( int argc, char **argv ) {
LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit);
// stop threads
- if (RC.nb_inst == 0 || !NODE_IS_CU(RC.rrc[0]->node_type)) {
+ if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) {
if(IS_SOFTMODEM_DOFORMS)
end_forms();
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index b9a775509d..15154fea0b 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -225,6 +225,7 @@
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
{"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \
+ {"log-mem", NULL, 0, strptr:(char **)&logmem_filename, defstrval:NULL, TYPE_STRING, 0}, \
}
#define CMDLINE_ONLINELOG_IDX 0
#define CMDLINE_GLOGLEVEL_IDX 1
@@ -236,6 +237,7 @@
{ .s2= { config_check_intrange, {0,4}}}, \
{ .s5= {NULL }} , \
{ .s5= {NULL }} , \
+ { .s5= {NULL }} , \
}
/***************************************************************************************************************************************/
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 89b58bd776..42ec7d216d 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -1053,9 +1053,9 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
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;
+ UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = (nfapi_cqi_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t));
+ UL_INFO->cqi_ind.cqi_indication_body.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.cqi_indication_body.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);
@@ -1262,10 +1262,10 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
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;
- free(UL_INFO->cqi_ind.cqi_raw_pdu_list);
- UL_INFO->cqi_ind.cqi_raw_pdu_list = NULL;
+ free(UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list);
+ UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = NULL;
+ free(UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list);
+ UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = NULL;
free(UL_INFO);
UL_INFO = NULL;