diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab
index 19c26aa8e4..1919a7e03b 100644
--- a/ci-scripts/Jenkinsfile-gitlab
+++ b/ci-scripts/Jenkinsfile-gitlab
@@ -329,13 +329,13 @@ pipeline {
stage ("Test physical simulators") {
steps {
script {
- gitlabCommitStatus(name: "Test phy-sim") {
- timeout (time: 20, unit: 'MINUTES') {
- try {
+ timeout (time: 20, unit: 'MINUTES') {
+ try {
+ gitlabCommitStatus(name: "Test phy-sim") {
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
- } catch (Exception e) {
- currentBuild.result = 'FAILURE'
}
+ } catch (Exception e) {
+ currentBuild.result = 'FAILURE'
}
}
}
@@ -360,13 +360,13 @@ pipeline {
stage ("Test basic simulator") {
steps {
script {
- gitlabCommitStatus(name: "Test basic-sim") {
- timeout (time: 30, unit: 'MINUTES') {
- try {
+ timeout (time: 30, unit: 'MINUTES') {
+ try {
+ gitlabCommitStatus(name: "Test basic-sim") {
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
- } catch (Exception e) {
- currentBuild.result = 'FAILURE'
}
+ } catch (Exception e) {
+ currentBuild.result = 'FAILURE'
}
}
}
@@ -375,13 +375,13 @@ pipeline {
stage ("Test L2 simulator") {
steps {
script {
- gitlabCommitStatus(name: "Test L2-sim") {
- timeout (time: 30, unit: 'MINUTES') {
- try {
+ timeout (time: 30, unit: 'MINUTES') {
+ try {
+ gitlabCommitStatus(name: "Test L2-sim") {
sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
- } catch (Exception e) {
- currentBuild.result = 'FAILURE'
}
+ } catch (Exception e) {
+ currentBuild.result = 'FAILURE'
}
}
}
diff --git a/ci-scripts/buildOnRH.sh b/ci-scripts/buildOnRH.sh
index bb57cde165..076f34f8d2 100755
--- a/ci-scripts/buildOnRH.sh
+++ b/ci-scripts/buildOnRH.sh
@@ -180,7 +180,7 @@ echo "Checking build status"
echo "############################################################"
LOG_PATTERN=.Rel14.txt
-NB_PATTERN_FILES=4
+NB_PATTERN_FILES=7
LOG_FILES=`ls $ARCHIVES_LOC/*.txt`
STATUS=0
@@ -204,12 +204,13 @@ then
STATUS=-1
fi
+echo "COMMAND: build_oai -I -w USRP --eNB" > $ARCHIVES_LOC/build_final_status.log
if [ $STATUS -eq 0 ]
then
- echo "BUILD_OK" > $ARCHIVES_LOC/build_final_status.log
+ echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log
echo "STATUS seems OK"
else
- echo "BUILD_KO" > $ARCHIVES_LOC/build_final_status.log
+ echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log
echo "STATUS failed?"
fi
exit $STATUS
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index 5e89384ebb..6fa3ae2f24 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -408,6 +408,11 @@ class SSHConnection():
self.command('echo $USER; nohup sudo tshark -f "host ' + self.eNBIPAddress +'" -i ' + eth_interface + ' -w /tmp/enb_' + self.testCase_id + '_s1log.pcap > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5)
self.close()
self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
+ self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 5)
+ 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 sudo b2xx_fx3_utils --reset-device', '\$', 5)
self.command('cd ' + self.eNBSourceCodePath, '\$', 5)
# Initialize_eNB_args usually start with -O and followed by the location in repository
full_config_file = self.Initialize_eNB_args.replace('-O ','')
diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
index c28f51415e..917b0e7491 100755
--- a/ci-scripts/oai-ci-vm-tool
+++ b/ci-scripts/oai-ci-vm-tool
@@ -69,7 +69,7 @@ VM_MEMORY=2048
VM_CPU=4
ARCHIVES_LOC=enb_usrp
LOG_PATTERN=.Rel14.txt
-NB_PATTERN_FILES=4
+NB_PATTERN_FILES=7
BUILD_OPTIONS="--eNB -w USRP"
KEEP_VM_ALIVE=0
RUN_OPTIONS="none"
@@ -231,7 +231,7 @@ case $key in
VM_NAME=ci-enb-usrp
ARCHIVES_LOC=enb_usrp
LOG_PATTERN=.Rel14.txt
- NB_PATTERN_FILES=4
+ NB_PATTERN_FILES=7
BUILD_OPTIONS="--eNB -w USRP --mu"
NBARGS=$[$NBARGS+256]
shift
@@ -272,7 +272,7 @@ case $key in
VM_NAME=ci-enb-ethernet
ARCHIVES_LOC=enb_eth
LOG_PATTERN=.Rel14.txt
- NB_PATTERN_FILES=6
+ NB_PATTERN_FILES=8
BUILD_OPTIONS="--eNB -t ETHERNET --noS1"
NBARGS=$[$NBARGS+256]
shift
@@ -281,7 +281,7 @@ case $key in
VM_NAME=ci-ue-ethernet
ARCHIVES_LOC=ue_eth
LOG_PATTERN=.Rel14.txt
- NB_PATTERN_FILES=6
+ NB_PATTERN_FILES=8
BUILD_OPTIONS="--UE -t ETHERNET --noS1"
NBARGS=$[$NBARGS+256]
shift
@@ -292,7 +292,7 @@ case $key in
VM_CPU=8
ARCHIVES_LOC=l2_sim
LOG_PATTERN=.Rel14.txt
- NB_PATTERN_FILES=4
+ NB_PATTERN_FILES=6
BUILD_OPTIONS="--eNB -t ETHERNET"
RUN_OPTIONS="complex"
NBARGS=$[$NBARGS+256]
@@ -314,7 +314,7 @@ case $key in
VM_NAME=ci-enb-usrp
ARCHIVES_LOC=enb_usrp
LOG_PATTERN=.Rel14.txt
- NB_PATTERN_FILES=4
+ NB_PATTERN_FILES=7
BUILD_OPTIONS="--eNB -w USRP --mu"
NBARGS=$[$NBARGS+256]
;;
@@ -351,7 +351,7 @@ case $key in
VM_NAME=ci-enb-ethernet
ARCHIVES_LOC=enb_eth
LOG_PATTERN=.Rel14.txt
- NB_PATTERN_FILES=6
+ NB_PATTERN_FILES=8
BUILD_OPTIONS="--eNB -t ETHERNET --noS1"
NBARGS=$[$NBARGS+256]
;;
@@ -359,7 +359,7 @@ case $key in
VM_NAME=ci-ue-ethernet
ARCHIVES_LOC=ue_eth
LOG_PATTERN=.Rel14.txt
- NB_PATTERN_FILES=6
+ NB_PATTERN_FILES=8
BUILD_OPTIONS="--UE -t ETHERNET --noS1"
NBARGS=$[$NBARGS+256]
;;
@@ -369,7 +369,7 @@ case $key in
VM_CPU=8
ARCHIVES_LOC=l2_sim
LOG_PATTERN=.Rel14.txt
- NB_PATTERN_FILES=4
+ NB_PATTERN_FILES=6
BUILD_OPTIONS="--eNB -t ETHERNET"
RUN_OPTIONS="complex"
NBARGS=$[$NBARGS+256]
@@ -510,13 +510,16 @@ else
fi
fi
-# Checking uvt-kvm is installed
-UVT_KVM_PATH=`which uvt-kvm | grep -c uvt-kvm`
-if [ $UVT_KVM_PATH -eq 0 ]
+if [ $REPORT_BUILD_CMD -ne 1 ] && [ $REPORT_TEST_CMD -ne 1 ]
then
- echo "Error: uvt-kvm is not installed"
- top_usage
- exit 1
+ # Checking uvt-kvm is installed
+ UVT_KVM_PATH=`which uvt-kvm | grep -c uvt-kvm`
+ if [ $UVT_KVM_PATH -eq 0 ]
+ then
+ echo "Error: uvt-kvm is not installed"
+ top_usage
+ exit 1
+ fi
fi
if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ]
diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh
index 3e385fb810..b5561eea54 100755
--- a/ci-scripts/reportBuildLocally.sh
+++ b/ci-scripts/reportBuildLocally.sh
@@ -143,13 +143,21 @@ function summary_table_header {
echo "
$1
" >> ./build_results.html
if [ -f $2/build_final_status.log ]
then
+ if [ `grep -c COMMAND $2/build_final_status.log` -eq 1 ]
+ then
+ COMMAND=`grep COMMAND $2/build_final_status.log | sed -e "s#COMMAND: ##"`
+ else
+ COMMAND="Unknown"
+ fi
if [ `grep -c BUILD_OK $2/build_final_status.log` -eq 1 ]
then
echo " " >> ./build_results.html
+ echo " $COMMAND " >> ./build_results.html
echo " BUILD was SUCCESSFUL " >> ./build_results.html
echo "
" >> ./build_results.html
else
echo " " >> ./build_results.html
+ echo " $COMMAND " >> ./build_results.html
echo " BUILD was a FAILURE! " >> ./build_results.html
echo "
" >> ./build_results.html
fi
@@ -220,6 +228,13 @@ function sca_summary_table_header {
NB_WARNINGS=`egrep -c "severity=\"warning\"" $1`
ADDED_ERRORS="0"
ADDED_WARNINGS="0"
+ FINAL_LOG=`echo $1 | sed -e "s#cppcheck\.xml#build_final_status.log#"`
+ if [ `grep -c COMMAND $FINAL_LOG` -eq 1 ]
+ then
+ COMMAND=`grep COMMAND $FINAL_LOG | sed -e "s#COMMAND: ##"`
+ else
+ COMMAND="Unknown"
+ fi
if [ $MR_TRIG -eq 1 ]
then
if [ -d ../../cppcheck_archives ]
@@ -237,12 +252,14 @@ function sca_summary_table_header {
if [ $NB_ERRORS -eq 0 ] && [ $NB_WARNINGS -eq 0 ]
then
echo " " >> ./build_results.html
+ echo " $COMMAND
" >> ./build_results.html
echo " CPPCHECK found NO error and NO warning " >> ./build_results.html
echo "
" >> ./build_results.html
else
if [ $NB_ERRORS -eq 0 ]
then
echo " " >> ./build_results.html
+ echo " $COMMAND
" >> ./build_results.html
if [ $PU_TRIG -eq 1 ]
then
echo " CPPCHECK found NO error and $NB_WARNINGS warnings " >> ./build_results.html
@@ -259,6 +276,7 @@ function sca_summary_table_header {
echo "
" >> ./build_results.html
else
echo " " >> ./build_results.html
+ echo "
$COMMAND
" >> ./build_results.html
if [ $PU_TRIG -eq 1 ]
then
echo "
CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings " >> ./build_results.html
@@ -543,7 +561,8 @@ function report_build {
summary_table_row "LTE SoftModem - Release 14" ./archives/enb_usrp/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_row1.html
summary_table_row "Coding - Release 14" ./archives/enb_usrp/coding.Rel14.txt "Built target coding" ./enb_usrp_row2.html
summary_table_row "OAI USRP device if - Release 14" ./archives/enb_usrp/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html
- summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_row4.html
+ summary_table_row "OAI ETHERNET transport - Release 14" ./archives/enb_usrp/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html
+ summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_row5.html
summary_table_footer
summary_table_header "OAI Build basic simulator option" ./archives/basic_sim
@@ -586,6 +605,8 @@ function report_build {
summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_eth/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_eth_row4.html
summary_table_row "RB Tools - Release 14" ./archives/enb_eth/rb_tool.Rel14.txt "Built target rb_tool" ./enb_eth_row5.html
summary_table_row "NAS Mesh - Release 14" ./archives/enb_eth/nasmesh.Rel14.txt "Built target nasmesh" ./enb_eth_row6.html
+ summary_table_row "RF Simulator - Release 14" ./archives/enb_eth/rfsimulator.Rel14.txt "Built target rfsimulator" ./enb_eth_row7.html
+ summary_table_row "TCP OAI Bridge - Release 14" ./archives/enb_eth/tcp_bridge_oai.Rel14.txt "Built target tcp_bridge_oai" ./enb_eth_row8.html
summary_table_footer
summary_table_header "OAI Build UE -- ETHERNET transport option" ./archives/ue_eth
@@ -595,6 +616,8 @@ function report_build {
summary_table_row "Parameters Lib Config - Release 14" ./archives/ue_eth/params_libconfig.Rel14.txt "Built target params_libconfig" ./ue_eth_row4.html
summary_table_row "RB Tools - Release 14" ./archives/ue_eth/rb_tool.Rel14.txt "Built target rb_tool" ./ue_eth_row5.html
summary_table_row "NAS Mesh - Release 14" ./archives/ue_eth/nasmesh.Rel14.txt "Built target nasmesh" ./ue_eth_row6.html
+ summary_table_row "RF Simulator - Release 14" ./archives/ue_eth/rfsimulator.Rel14.txt "Built target rfsimulator" ./ue_eth_row7.html
+ summary_table_row "TCP OAI Bridge - Release 14" ./archives/ue_eth/tcp_bridge_oai.Rel14.txt "Built target tcp_bridge_oai" ./ue_eth_row8.html
summary_table_footer
if [ -e ./archives/red_hat ]
@@ -605,7 +628,8 @@ function report_build {
summary_table_row "LTE SoftModem - Release 14" ./archives/red_hat/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_rh_row1.html
summary_table_row "Coding - Release 14" ./archives/red_hat/coding.Rel14.txt "Built target coding" ./enb_usrp_rh_row2.html
summary_table_row "OAI USRP device if - Release 14" ./archives/red_hat/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_rh_row3.html
- summary_table_row "Parameters Lib Config - Release 14" ./archives/red_hat/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_rh_row4.html
+ summary_table_row "OAI ETHERNET transport - Release 14" ./archives/red_hat/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./enb_usrp_rh_row4.html
+ summary_table_row "Parameters Lib Config - Release 14" ./archives/red_hat/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_rh_row5.html
summary_table_footer
fi
diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh
index 8608ba20ee..63cd3f831f 100755
--- a/ci-scripts/reportTestLocally.sh
+++ b/ci-scripts/reportTestLocally.sh
@@ -316,7 +316,7 @@ function report_test {
fi
echo " " >> ./test_simulator_results.html
fi
-
+
if [ -f $ARCHIVES_LOC/${TMODE}_${BW}*iperf*dl*client*txt ]
then
IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}*iperf*client*txt`
@@ -377,7 +377,7 @@ function report_test {
fi
PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'`
PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'`
- if [[ $PERF_INT -lt 90 ]]
+ if [[ $PERF_INT -lt 70 ]]
then
echo "
KO | " >> ./test_simulator_results.html
else
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 5b9ba3d093..8d2c5cda06 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -227,6 +227,10 @@ function check_iperf {
local LOC_BASE_LOG=$1
local LOC_REQ_BW=$2
local LOC_REQ_BW_MINUS_ONE=`echo "$LOC_REQ_BW - 1" | bc -l`
+ local LOC_REQ_BW_MINUS_TWO=`echo "$LOC_REQ_BW - 2" | bc -l`
+ local LOC_REQ_BW_MINUS_THREE=`echo "$LOC_REQ_BW - 3" | bc -l`
+ local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl`
+ local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim`
if [ -f ${LOC_BASE_LOG}_client.txt ]
then
local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt`
@@ -235,11 +239,26 @@ function check_iperf {
IPERF_STATUS=-1
else
local EFFECTIVE_BANDWIDTH=`tail -n3 ${LOC_BASE_LOG}_client.txt | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"`
- if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]]
+ if [ $LOC_IS_DL -eq 1 ] && [ $LOC_IS_BASIC_SIM -eq 1 ]
then
- echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH"
+ if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_TWO}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_THREE}.*Mbits.* ]]
+ then
+ echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH"
+ else
+ IPERF_STATUS=-1
+ fi
else
- IPERF_STATUS=-1
+ if [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW}.*Mbits.* ]] || [[ $EFFECTIVE_BANDWIDTH =~ .*${LOC_REQ_BW_MINUS_ONE}.*Mbits.* ]]
+ then
+ if [ $LOC_IS_DL -eq 1 ]
+ then
+ echo "got requested DL bandwidth: $EFFECTIVE_BANDWIDTH"
+ else
+ echo "got requested UL bandwidth: $EFFECTIVE_BANDWIDTH"
+ fi
+ else
+ IPERF_STATUS=-1
+ fi
fi
fi
else
@@ -299,7 +318,7 @@ function install_epc_on_vm {
if [ -d /opt/ltebox-archives/ ]
then
# Checking if all ltebox archives are available to run ltebx epc on a brand new VM
- if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim.zip ]
+ if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim-develop.zip ]
then
echo "############################################################"
echo "Test EPC on VM ($EPC_VM_NAME) will be using ltebox"
@@ -349,7 +368,7 @@ function install_epc_on_vm {
echo "############################################################"
scp -o StrictHostKeyChecking=no /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
scp -o StrictHostKeyChecking=no /opt/ltebox-archives/etc-conf.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
- scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
+ scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim-develop.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
echo "############################################################"
echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)"
@@ -363,8 +382,8 @@ function install_epc_on_vm {
# Installing HSS
echo "echo \"cd /opt\"" >> $LOC_EPC_VM_CMDS
echo "cd /opt" >> $LOC_EPC_VM_CMDS
- echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim.zip\"" >> $LOC_EPC_VM_CMDS
- echo "sudo unzip -qq /home/ubuntu/hss-sim.zip" >> $LOC_EPC_VM_CMDS
+ echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim-develop.zip\"" >> $LOC_EPC_VM_CMDS
+ echo "sudo unzip -qq /home/ubuntu/hss-sim-develop.zip" >> $LOC_EPC_VM_CMDS
echo "echo \"cd /opt/hss_sim0609\"" >> $LOC_EPC_VM_CMDS
echo "cd /opt/hss_sim0609" >> $LOC_EPC_VM_CMDS
@@ -500,16 +519,6 @@ function build_ue_on_separate_folder {
echo "cd tmp-ue" >> $1
echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $1
echo "unzip -qq -DD ../localZip.zip" >> $1
-
- # We may have some adaptation to do
- if [ -f /opt/ltebox-archives/adapt_ue_l2_sim.txt ]
- then
- echo "############################################################"
- echo "Doing some adaptation on UE side"
- echo "############################################################"
- cat /opt/ltebox-archives/adapt_ue_l2_sim.txt >> $1
- fi
-
echo "echo \"source oaienv\"" >> $1
echo "source oaienv" >> $1
echo "cd cmake_targets/" >> $1
@@ -664,7 +673,7 @@ function run_test_on_vm {
if [ "$RUN_OPTIONS" == "none" ]
then
echo "No run on VM testing for this variant currently"
- exit $STATUS
+ return
fi
if [[ $RUN_OPTIONS =~ .*run_exec_autotests.* ]]
@@ -794,15 +803,6 @@ function run_test_on_vm {
# Retrieve EPC real IP address
retrieve_real_epc_ip_addr $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR
- # We may have some adaptation to do
- if [ -f /opt/ltebox-archives/adapt_ue_sim.txt ]
- then
- echo "############################################################"
- echo "Doing some adaptation on UE side"
- echo "############################################################"
- ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < /opt/ltebox-archives/adapt_ue_sim.txt
- fi
-
echo "############################################################"
echo "Starting the eNB in FDD-5MHz mode"
echo "############################################################"
@@ -823,7 +823,8 @@ function run_test_on_vm {
recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
- exit -1
+ STATUS=-1
+ return
fi
get_ue_ip_addr $VM_CMDS $VM_IP_ADDR
@@ -839,10 +840,10 @@ function run_test_on_vm {
echo "Iperf DL"
echo "############################################################"
CURR_IPERF_LOG_BASE=fdd_05MHz_iperf_dl
- iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE
+ iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 10 $CURR_IPERF_LOG_BASE
scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC
- check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15
+ check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 10
echo "############################################################"
echo "Iperf UL"
@@ -882,7 +883,8 @@ function run_test_on_vm {
recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
- exit -1
+ STATUS=-1
+ return
fi
get_ue_ip_addr $VM_CMDS $VM_IP_ADDR
@@ -898,10 +900,10 @@ function run_test_on_vm {
echo "Iperf DL"
echo "############################################################"
CURR_IPERF_LOG_BASE=fdd_10MHz_iperf_dl
- iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE
+ iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 10 $CURR_IPERF_LOG_BASE
scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC
- check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15
+ check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 10
echo "############################################################"
echo "Iperf UL"
@@ -941,7 +943,8 @@ function run_test_on_vm {
recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
- exit -1
+ STATUS=-1
+ return
fi
get_ue_ip_addr $VM_CMDS $VM_IP_ADDR
@@ -957,10 +960,10 @@ function run_test_on_vm {
echo "Iperf DL"
echo "############################################################"
CURR_IPERF_LOG_BASE=fdd_20MHz_iperf_dl
- iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE
+ iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 12 $CURR_IPERF_LOG_BASE
scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC
- check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15
+ check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 12
echo "############################################################"
echo "Terminate enb/ue simulators"
@@ -993,7 +996,8 @@ function run_test_on_vm {
echo "ERROR: compiling flexran controller on vm went wrong"
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
- exit -1
+ STATUS=-1
+ return
fi
FLEXRAN_CTL_VM_NAME=`echo $VM_NAME | sed -e "s#basic-sim#flexran-rtc#"`
FLEXRAN_CTL_VM_CMDS=`echo $VM_CMDS | sed -e "s#cmds#flexran-rtc-cmds#"`
@@ -1003,7 +1007,8 @@ function run_test_on_vm {
echo "ERROR: Flexran Ctl VM is not alive"
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
- exit -1
+ STATUS=-1
+ return
fi
uvt-kvm wait $FLEXRAN_CTL_VM_NAME --insecure
FLEXRAN_CTL_VM_IP_ADDR=`uvt-kvm ip $FLEXRAN_CTL_VM_NAME`
@@ -1038,7 +1043,8 @@ function run_test_on_vm {
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
stop_flexran_ctrl $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
- exit -1
+ STATUS=-1
+ return
fi
query_flexran_ctrl_status $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR 03_enb_ue_connected
get_ue_ip_addr $VM_CMDS $VM_IP_ADDR
@@ -1080,7 +1086,8 @@ function run_test_on_vm {
recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
- exit -1
+ STATUS=-1
+ return
fi
get_ue_ip_addr $VM_CMDS $VM_IP_ADDR
@@ -1117,50 +1124,52 @@ function run_test_on_vm {
CURRENT_ENB_LOG_FILE=tdd_10MHz_enb.log
start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-tdd-basic-sim.conf none
- echo "############################################################"
- echo "Starting the UE in TDD-10MHz mode"
- echo "############################################################"
- CURRENT_UE_LOG_FILE=tdd_10MHz_ue.log
- start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2350
- if [ $UE_SYNC -eq 0 ]
- then
- echo "Problem w/ eNB and UE not syncing"
- terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR
- scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
- scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
- recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
- terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
- echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
- exit -1
- fi
- get_ue_ip_addr $VM_CMDS $VM_IP_ADDR
-
- echo "############################################################"
- echo "Pinging the UE"
- echo "############################################################"
- PING_LOG_FILE=tdd_10MHz_ping_ue.txt
- ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE
- scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
- check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
-
- echo "############################################################"
- echo "Iperf DL"
- echo "############################################################"
- CURR_IPERF_LOG_BASE=tdd_10MHz_iperf_dl
- iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE
- scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC
- scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC
- check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6
-
- echo "############################################################"
- echo "Terminate enb/ue simulators"
- echo "############################################################"
- terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR
- scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
- scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
- recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
- sleep 10
-
+# Disabling TDD-10MHz in order to stop getting false negatives
+# echo "############################################################"
+# echo "Starting the UE in TDD-10MHz mode"
+# echo "############################################################"
+# CURRENT_UE_LOG_FILE=tdd_10MHz_ue.log
+# start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2350
+# if [ $UE_SYNC -eq 0 ]
+# then
+# echo "Problem w/ eNB and UE not syncing"
+# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR
+# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
+# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
+# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
+# terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
+# echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
+# STATUS=-1
+# return
+# fi
+# get_ue_ip_addr $VM_CMDS $VM_IP_ADDR
+#
+# echo "############################################################"
+# echo "Pinging the UE"
+# echo "############################################################"
+# PING_LOG_FILE=tdd_10MHz_ping_ue.txt
+# ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE
+# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
+# check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
+#
+# echo "############################################################"
+# echo "Iperf DL"
+# echo "############################################################"
+# CURR_IPERF_LOG_BASE=tdd_10MHz_iperf_dl
+# iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE
+# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC
+# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC
+# check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6
+#
+# echo "############################################################"
+# echo "Terminate enb/ue simulators"
+# echo "############################################################"
+# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR
+# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
+# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
+# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
+# sleep 10
+#
# Disabling TDD-20MHz in order to stop getting false negatives
# echo "############################################################"
# echo "Starting the eNB in TDD-20MHz mode"
@@ -1182,7 +1191,8 @@ function run_test_on_vm {
# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
# terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
# echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
-# exit -1
+# STATUS=-1
+# return
# fi
# get_ue_ip_addr $VM_CMDS $VM_IP_ADDR
#
@@ -1294,7 +1304,8 @@ function run_test_on_vm {
scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
- exit -1
+ STATUS=-1
+ return
fi
echo "############################################################"
diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh
index 3969e895af..7e4504944f 100755
--- a/ci-scripts/waitBuildOnVM.sh
+++ b/ci-scripts/waitBuildOnVM.sh
@@ -133,7 +133,7 @@ function check_on_vm_build {
rm -f $VM_CMDS
echo "############################################################"
- echo "Checking build status"
+ echo "Checking build status"
echo "############################################################"
if [[ "$VM_NAME" == *"-cppcheck"* ]]
@@ -145,7 +145,7 @@ function check_on_vm_build {
STATUS=0
NB_FOUND_FILES=0
- for FULLFILE in $LOG_FILES
+ for FULLFILE in $LOG_FILES
do
if [[ $FULLFILE == *"$LOG_PATTERN"* ]]
then
@@ -185,10 +185,16 @@ function check_on_vm_build {
fi
fi
+ if [[ "$VM_NAME" == *"-cppcheck"* ]]
+ then
+ echo "COMMAND: cppcheck $BUILD_OPTIONS . 2> cppcheck.xml" > $ARCHIVES_LOC/build_final_status.log
+ else
+ echo "COMMAND: build_oai -I $BUILD_OPTIONS" > $ARCHIVES_LOC/build_final_status.log
+ fi
if [[ $STATUS -eq 0 ]]
then
- echo "BUILD_OK" > $ARCHIVES_LOC/build_final_status.log
+ echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log
else
- echo "BUILD_KO" > $ARCHIVES_LOC/build_final_status.log
+ echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log
fi
}
diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml
index d5a25c7fa7..9cdd7523ad 100644
--- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml
+++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml
@@ -65,7 +65,7 @@
Ping
ping (5MHz - 20 sec)
-c 20
-
25
+
50
@@ -112,7 +112,7 @@
Iperf
iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced)
-u -b 2M -t 30 -i 1 -R
- 50
+ 80
unbalanced
diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml
index 4a40929548..3a877ea3c3 100644
--- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml
+++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml
@@ -37,14 +37,14 @@
-O ci-scripts/conf_files/rru.tdd.band40.conf
0
-
+
Initialize_eNB
Initialize RCC (TDD/Band40/5MHz)
-O ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf
1
-
+
Terminate_eNB
Terminate RCC
@@ -81,7 +81,7 @@
Ping
ping (5MHz - 20 sec)
-c 20
- 25
+ 50
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index b886ef0ff3..63bf4efa50 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -21,7 +21,7 @@
# Author: laurent THOMAS, Lionel GAUTHIER
-cmake_minimum_required (VERSION 2.8)
+cmake_minimum_required (VERSION 3.0)
#############################################
# Base directories, compatible with legacy OAI building
@@ -169,11 +169,12 @@ endif()
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -fPIC ")
# add autotools definitions that were maybe used!
+set(MKVER "'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'")
set(CMAKE_C_FLAGS
- "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'"
+ "${CMAKE_C_FLAGS} -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP -D${MKVER}"
)
set(CMAKE_CXX_FLAGS
- "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D'MAKE_VERSION(a,b,c)=((a)*256+(b)*16+c)'"
+ "${CMAKE_CXX_FLAGS} ${C_FLAGS_PROCESSOR} -std=c++11 -D${MKVER}"
)
@@ -467,6 +468,7 @@ add_library(X2AP_ENB
${X2AP_DIR}/x2ap_eNB_itti_messaging.c
${X2AP_DIR}/x2ap_eNB_management_procedures.c
${X2AP_DIR}/x2ap_eNB_generate_messages.c
+ ${X2AP_DIR}/x2ap_ids.c
)
add_dependencies(X2AP_ENB rrc_flag x2_flag)
@@ -519,7 +521,8 @@ add_library(F1AP
add_list1_option(NB_ANTENNAS_RX "2" "Number of antennas in reception" "1" "2" "4")
add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4")
-add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR")
+add_list2_option(RF_BOARD "EXMIMO" "RF head type" "None" "EXMIMO" "OAI_USRP" "OAI_BLADERF" "CPRIGW" "OAI_LMSSDR" "OAI_SIMU")
+
add_list2_option(TRANSP_PRO "None" "Transport protocol type" "None" "ETHERNET")
#NOKIA config enhancement
@@ -627,6 +630,8 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE
add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} )
set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
+add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c)
+
##########################################################
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
@@ -1392,7 +1397,7 @@ set(L2_SRC
${RLC_DIR}/rlc.c
${RLC_DIR}/rlc_rrc.c
${RLC_DIR}/rlc_mpls.c
- ${RRC_DIR}/rrc_UE.c
+# ${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_eNB.c
${RRC_DIR}/rrc_eNB_S1AP.c
${RRC_DIR}/rrc_eNB_UE_context.c
@@ -2058,6 +2063,8 @@ add_executable(lte-softmodem
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
+ ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
+ ${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 870aeec7c6..887b3ebe2f 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -77,7 +77,7 @@ trap handle_ctrl_c INT
function print_help() {
echo_info "
This program installs OpenAirInterface Software
-You should have ubuntu 14.xx, updated, and the Linux kernel >= 3.14
+You should have ubuntu 16.xx or 18.04 updated
Options
-h
This help
@@ -170,6 +170,9 @@ Options
--basic-simulator
Generates a basic [1 UE + 1 eNB + no channel] simulator.
See targets/ARCH/tcp_bridge/README.tcp_bridge_oai for documentation.
+--rfsimulator
+ Generate virtual RF driver
+ to use it, set the environement variable RFSIMULATOR to \"enb\" in the eNB and to the eNB IP address in the UEs
Usage (first build):
NI/ETTUS B201 + COTS UE : ./build_oai -I --eNB -x --install-system-files -w USRP
Usage (Regular):
@@ -238,25 +241,21 @@ function main() {
echo_info "Setting release to: $REL"
shift 2;;
-w | --hardware)
- HW="$2" #"${i#*=}"
# Use OAI_USRP as the key word USRP is used inside UHD driver
- if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" -a "$HW" != "IRIS" ] ; then
- echo_fatal "Unknown HW type $HW will exit..."
- else
- if [ "$HW" == "USRP" ] ; then
- HW="OAI_USRP"
- fi
- if [ "$HW" == "BLADERF" ] ; then
- HW="OAI_BLADERF"
- fi
- if [ "$HW" == "LMSSDR" ] ; then
- HW="OAI_LMSSDR"
- fi
- if [ "$HW" == "IRIS" ] ; then
- HW="OAI_IRIS"
- fi
+ case "$2" in
+ "EXMIMO")
+ HW="EXMIMO"
+ ;;
+ "USRP" | "BLADERF" | "LMSSDR" | "IRIS" | "SIMU")
+ HW="OAI_"$2
+ ;;
+ "None")
+ HW="None"
+ ;;
+ *)
+ echo_fatal "Unknown HW type $HW: exit..."
+ esac
echo_info "Setting hardware to: $HW"
- fi
shift 2;;
-t | --transport_protocol)
TP="$2" #"${i#*=}"
@@ -378,6 +377,10 @@ function main() {
BASIC_SIMULATOR=1
echo_info "Compiling the basic simulator"
shift 1;;
+ --rfsimulator)
+ RFSIMULATOR=true
+ echo_info "Compiling the RF simulator"
+ shift 1;;
-h | --help)
print_help
exit 1;;
@@ -390,11 +393,6 @@ function main() {
CMAKE_CMD="$CMAKE_CMD .."
echo_info "CMAKE_CMD=$CMAKE_CMD"
- if [ "$eNB" = "1" ] && [ "$UE" = "1" ]; then
- echo_error "Cannot build UE and eNB on one build_oai execution"
- echo_error "use 2 build_oai invocations"
- exit
- fi
#########################################################
# check validity of HW and TP parameters for eNB
#########################################################
@@ -413,33 +411,17 @@ function main() {
fi
echo_info "RF HW set to $HW"
- #Now we set flags to enable deadline scheduler settings
- #By default: USRP: disable,
- #By default: BLADERF: enable,
- #By default: EXMIMO: enable
- if [ "$FORCE_DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then
- if [ "$HW" = "EXMIMO" ] ; then
+ # If the user doesn't specify the Linux scheduler to use, we set a value
+ if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then
+ case "$HW" in
+ "EXMIMO")
DEADLINE_SCHEDULER_FLAG_USER="True"
- elif [ "$HW" = "ETHERNET" ] ; then
+ ;;
+ *)
DEADLINE_SCHEDULER_FLAG_USER="False"
- elif [ "$HW" = "OAI_USRP" ] ; then
- DEADLINE_SCHEDULER_FLAG_USER="False"
- elif [ "$HW" = "OAI_BLADERF" ] ; then
- DEADLINE_SCHEDULER_FLAG_USER="False"
- elif [ "$HW" = "OAI_LMSSDR" ] ; then
- DEADLINE_SCHEDULER_FLAG_USER="False"
- elif [ "$HW" = "OAI_IRIS" ] ; then
- DEADLINE_SCHEDULER_FLAG_USER="False"
- elif [ "$HW" = "None" ] ; then
- DEADLINE_SCHEDULER_FLAG_USER="False"
- else
- echo_error "Unknown HW type $HW. Exiting now..."
- exit
- fi
- else
- DEADLINE_SCHEDULER_FLAG_USER=$FORCE_DEADLINE_SCHEDULER_FLAG_USER
+ ;;
+ esac
fi
-
#Disable CPU Affinity for deadline scheduler
if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "True" ] ; then
CPU_AFFINITY_FLAG_USER="False"
@@ -520,26 +502,19 @@ function main() {
echo_info "3. building the compilation directives ..."
DIR=$OPENAIR_DIR/cmake_targets
- if [ "$NOS1" = "1" ] ; then
- lte_build_dir=lte_noS1_build_oai
- if [ "$eNB" = "1" ] ; then
- lte_exec=lte-softmodem-nos1
- fi
- if [ "$UE" = "1" ] ; then
- lte_exec=lte-uesoftmodem-nos1
+
+ if [ "$T_TRACER" = "False" ] ; then
+ noLOGDirsuffix="_noLOG"
fi
+ if [ "$NOS1" = "1" ] ; then
+ noS1Dir="_noS1"
+ bin_suffix="-nos1"
else
lte_build_dir=lte_build_oai
- if [ "$eNB" = "1" ] ; then
- lte_exec=lte-softmodem
- fi
- if [ "$UE" = "1" ] ; then
- lte_exec=lte-uesoftmodem
- fi
- fi
- if [ "$T_TRACER" = "False" ] ; then
- lte_build_dir=${lte_build_dir}_noLOG
+ bin_suffix=""
fi
+
+ lte_build_dir="lte${noS1Dir}_build_oai${noLOGDirsuffix}"
# configuration module libraries, one currently available, using libconfig
config_libconfig_shlib=params_libconfig
@@ -587,8 +562,8 @@ function main() {
eval $CMAKE_CMD
fi
- if [ "$eNB" = "1" -o "$UE" = "1" ] ; then
- echo_info "Compiling $lte_exec"
+ if [ "$eNB" = "1" ] ; then
+ lte_exec=lte-softmodem${bin_suffix}
compilations \
$lte_build_dir $lte_exec \
$lte_exec $dbin/$lte_exec.$REL
@@ -612,7 +587,29 @@ function main() {
fi
fi
- if [ "$UE" = 1 -a "$NOS1" = "0" ] ; then
+ if [ "$UE" = 1 ] ; then
+ lte_exec=lte-uesoftmodem${bin_suffix}
+ compilations \
+ $lte_build_dir $lte_exec \
+ $lte_exec $dbin/$lte_exec.$REL
+
+ # mandatory shared lib
+ compilations \
+ $lte_build_dir $config_libconfig_shlib \
+ lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
+ compilations \
+ $lte_build_dir coding \
+ libcoding.so $dbin/libcoding.so
+
+ if [ "$NOS1" = "1" ] ; then
+ compilations \
+ $lte_build_dir nasmesh \
+ CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
+ compilations \
+ $lte_build_dir rb_tool \
+ rb_tool $dbin/rb_tool
+ cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
+ else
# ue_ip driver compilation
echo_info "Compiling UE specific part"
compilations \
@@ -652,6 +649,7 @@ function main() {
echo_warning "not generated UE NAS files: binaries not found"
fi
fi
+ fi
if [ "$SIMUS_PHY" = "1" -o "$SIMUS_CORE" = "1" ] ; then
cd $OPENAIR_DIR/cmake_targets/lte-simulators
@@ -716,23 +714,19 @@ function main() {
cp $OPENAIR_DIR/cmake_targets/tools/init_exmimo2 $dbin
fi
-
-
# Telnet server compilation
#####################
if [ "$BUILD_TELNETSRV" = "1" ] ; then
- build_dir=$lte_build_dir
compilations \
- $build_dir telnetsrv \
+ $lte_build_dir telnetsrv \
libtelnetsrv.so $dbin/libtelnetsrv.so
fi
- # Telnet server compilation
+ # msc library compilation
#####################
if [ "$MSC_GEN" = "1" ] ; then
- build_dir=$lte_build_dir
compilations \
- $build_dir msc \
+ $lte_build_dir msc \
libmsc.so $dbin/libmsc.so
fi
@@ -740,8 +734,6 @@ function main() {
#####################################
if [ "$eNB" = "1" -o "$UE" = "1" ] ; then
- build_dir=$lte_build_dir
-
# build RF device libraries
if [ "$HW" != "None" ] ; then
rm -f liboai_device.so
@@ -750,7 +742,7 @@ function main() {
# link liboai_device.so with the selected RF device library
if [ "$HW" == "EXMIMO" ] ; then
compilations \
- $build_dir oai_exmimodevif \
+ $lte_build_dir oai_exmimodevif \
liboai_exmimodevif.so $dbin/liboai_exmimodevif.so.$REL
ln -sf liboai_exmimodevif.so liboai_device.so
@@ -758,7 +750,7 @@ function main() {
echo_info "liboai_device.so is linked to EXMIMO device library"
elif [ "$HW" == "OAI_USRP" ] ; then
compilations \
- $build_dir oai_usrpdevif \
+ $lte_build_dir oai_usrpdevif \
liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL
ln -sf liboai_usrpdevif.so liboai_device.so
@@ -767,7 +759,7 @@ function main() {
elif [ "$HW" == "OAI_BLADERF" ] ; then
if [ -f "/usr/include/libbladeRF.h" ] ; then
compilations \
- $build_dir oai_bladerfdevif \
+ $lte_build_dir oai_bladerfdevif \
liboai_bladerfdevif.so $dbin/liboai_bladerfdevif.so.$REL
fi
@@ -775,18 +767,18 @@ function main() {
ln -sf $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so
echo_info "liboai_device.so is linked to BLADERF device library"
elif [ "$HW" == "OAI_LMSSDR" ] ; then
-# if [ -f "/usr/include/libbladeRF.h" ] ; then
+ # if [ -f "/usr/include/libbladeRF.h" ] ; then
compilations \
- $build_dir oai_lmssdrdevif \
+ $lte_build_dir oai_lmssdrdevif \
liboai_lmssdrdevif.so $dbin/liboai_lmssdrdevif.so.$REL
-# fi
+ # fi
ln -sf liboai_lmssdrdevif.so liboai_device.so
ln -sf $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so
echo_info "liboai_device.so is linked to LMSSDR device library"
elif [ "$HW" == "OAI_IRIS" ] ; then
compilations \
- $build_dir oai_irisdevif \
+ $lte_build_dir oai_irisdevif \
liboai_irisdevif.so $dbin/liboai_irisdevif.so.$REL
ln -s liboai_irisdevif.so liboai_device.so
@@ -797,22 +789,33 @@ function main() {
fi
fi
- # build trasport protocol libraries (currently only ETHERNET is available)
- if [ "$TP" != "None" ] ; then
+ # build simulators devices
+ echo_info "Compiling rfsimulator"
+ compilations \
+ $lte_build_dir rfsimulator \
+ librfsimulator.so $dbin/librfsimulator.so.$REL
+ echo_info "Compiling basicsimulator"
+ compilations \
+ $lte_build_dir tcp_bridge_oai \
+ libtcp_bridge_oai.so $dbin/libtcp_bridge_oai.so.$REL
+ # build transport protocol libraries (currently only ETHERNET is available)
+
rm -f liboai_transpro.so
rm -f $dbin/liboai_transpro.so
-
- if [ "$TP" == "ETHERNET" ] ; then
compilations \
- $build_dir oai_eth_transpro \
+ $lte_build_dir oai_eth_transpro \
liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL
ln -sf liboai_eth_transpro.so liboai_transpro.so
ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
- echo_info "liboai_transpro.so is linked with ETHERNET library"
- fi
+ echo_info "liboai_transpro.so is linked to ETHERNET transport"
fi
-fi
+ if [ "$RFSIMULATOR" == "true" -o "$HW" == "OAI_SIMU" ] ; then
+ echo_info "Compiling rfsimulator"
+ compilations \
+ $lte_build_dir rfsimulator \
+ librfsimulator.so $dbin/librfsimulator.so.$REL
+ fi
# Doxygen Support
#####################
diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c
index 7ea3b70bb4..8720efd8c0 100644
--- a/common/utils/T/tracer/macpdu2wireshark.c
+++ b/common/utils/T/tracer/macpdu2wireshark.c
@@ -289,7 +289,7 @@ void usage(void) {
" -max-sib report at maximum n SIBs\n"
" -live run live\n"
" -live-ip tracee's IP address (default %s)\n"
- " -live-port tracee's port (default %d)\n"
+ " -live-port tracee's port (default %d)\n"
"-i and -live are mutually exclusive options. One of them must be provided\n"
"but not both.\n",
DEFAULT_IP,
diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c
index b6803ead6b..7f8645be02 100644
--- a/common/utils/telnetsrv/telnetsrv.c
+++ b/common/utils/telnetsrv/telnetsrv.c
@@ -77,17 +77,17 @@ paramdef_t telnetoptions[] = {
/* configuration parameters for telnet utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
- {"listenaddr", "", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 },
- {"listenport", "", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 },
- {"priority", "", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 },
- {"loopcount", "", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 },
- {"loopdelay", "", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 },
- {"histfile", "", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 },
- {"histsize", "", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 },
- {"phypbsize", "",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 },
- {"staticmod", "", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))},
- {"shrmod", "", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 }
+ {"listenaddr", "\n", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 },
+ {"listenport", "\n", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 },
+ {"priority", "\n", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 },
+ {"loopcount", "\n", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 },
+ {"loopdelay", "\n", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 },
+ {"histfile", "\n", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 },
+ {"histsize", "\n", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 },
+ {"phypbsize", "\n",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 },
+ {"staticmod", "\n", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))},
+ {"shrmod", "\n", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 }
};
int get_phybsize(void) {
@@ -355,7 +355,7 @@ int setgetvar(int moduleindex,char getorset,char *params) {
char varname[TELNET_CMD_MAXSIZE];
char *varval=NULL;
memset(varname,0,sizeof(varname));
- n = sscanf(params,"%19s %ms",varname,&varval);
+ n = sscanf(params,"%9s %ms",varname,&varval);
for ( i=0 ; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL ; i++) {
if ( strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,varname,strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0) {
@@ -475,7 +475,7 @@ int process_command(char *buf) {
memset(cmdb,0,sizeof(cmdb));
bufbck=strdup(buf);
rt=CMDSTATUS_NOTFOUND;
- j = sscanf(buf,"%9s %9s %2000[^\t\n]",modulename,cmd,cmdb);
+ j = sscanf(buf,"%9s %9s %9[^\t\n]",modulename,cmd,cmdb);
if (telnetparams.telnetdbg > 0)
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb);
diff --git a/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h
new file mode 100644
index 0000000000..2f479d8ee6
--- /dev/null
+++ b/common/utils/telnetsrv/telnetsrv_ltemeasur_def.h
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+/*! \file common/utils/telnetsrv/telnetsrv_ltemeasur_def.h
+ * \brief: definitions of macro used to initialize the telnet_ltemeasurdef_t
+ * \ strucures arrays which are then used by the display functions
+ * \ in telnetsrv_measurements.c.
+ * \author Francois TABURET
+ * \date 2019
+ * \version 0.1
+ * \company NOKIA BellLabs France
+ * \email: francois.taburet@nokia-bell-labs.com
+ * \note
+ * \warning
+ */
+
+
+#define LTEMAC_MEASURE \
+{ \
+ {"total_num_bcch_pdu", &(macstatptr->total_num_bcch_pdu),TELNET_VARTYPE_INT32,0},\
+ {"bcch_buffer", &(macstatptr->bcch_buffer),TELNET_VARTYPE_INT32,0},\
+ {"total_bcch_buffer", &(macstatptr->total_bcch_buffer),TELNET_VARTYPE_INT32,0},\
+ {"bcch_mcs", &(macstatptr->bcch_mcs),TELNET_VARTYPE_INT32,0},\
+ {"total_num_ccch_pdu", &(macstatptr->total_num_ccch_pdu),TELNET_VARTYPE_INT32,0},\
+ {"ccch_buffer", &(macstatptr->ccch_buffer),TELNET_VARTYPE_INT32,0},\
+ {"total_ccch_buffer", &(macstatptr->total_ccch_buffer),TELNET_VARTYPE_INT32,0},\
+ {"ccch_mcs", &(macstatptr->ccch_mcs),TELNET_VARTYPE_INT32,0},\
+ {"total_num_pcch_pdu", &(macstatptr->total_num_pcch_pdu),TELNET_VARTYPE_INT32,0},\
+ {"pcch_buffer", &(macstatptr->pcch_buffer),TELNET_VARTYPE_INT32,0},\
+ {"total_pcch_buffer", &(macstatptr->total_pcch_buffer),TELNET_VARTYPE_INT32,0},\
+ {"pcch_mcs", &(macstatptr->pcch_mcs),TELNET_VARTYPE_INT32,0},\
+ {"num_dlactive_UEs", &(macstatptr->num_dlactive_UEs),TELNET_VARTYPE_INT16,0},\
+ {"available_prbs", &(macstatptr->available_prbs),TELNET_VARTYPE_INT16,0},\
+ {"total_available_prbs", &(macstatptr->total_available_prbs),TELNET_VARTYPE_INT32,0},\
+ {"available_ncces", &(macstatptr->available_ncces),TELNET_VARTYPE_INT16,0},\
+ {"dlsch_bitrate", &(macstatptr->dlsch_bitrate),TELNET_VARTYPE_INT32,0},\
+ {"dlsch_bytes_tx", &(macstatptr->dlsch_bytes_tx),TELNET_VARTYPE_INT32,0},\
+ {"dlsch_pdus_tx", &(macstatptr->dlsch_pdus_tx),TELNET_VARTYPE_INT32,0},\
+ {"total_dlsch_bitrate", &(macstatptr->total_dlsch_bitrate),TELNET_VARTYPE_INT32,0},\
+ {"total_dlsch_bytes_tx", &(macstatptr->total_dlsch_bytes_tx),TELNET_VARTYPE_INT32,0},\
+ {"total_dlsch_pdus_tx", &(macstatptr->total_dlsch_pdus_tx),TELNET_VARTYPE_INT32,0},\
+ {"ulsch_bitrate", &(macstatptr->ulsch_bitrate),TELNET_VARTYPE_INT32,0},\
+ {"ulsch_bytes_rx", &(macstatptr->ulsch_bytes_rx),TELNET_VARTYPE_INT32,0},\
+ {"ulsch_pdus_rx", &(macstatptr->ulsch_pdus_rx),TELNET_VARTYPE_INT32,0},\
+ {"total_ulsch_bitrate", &(macstatptr->total_ulsch_bitrate),TELNET_VARTYPE_INT32,0},\
+ {"total_ulsch_bytes_rx", &(macstatptr->total_ulsch_bytes_rx),TELNET_VARTYPE_INT32,0},\
+ {"total_ulsch_pdus_rx", &(macstatptr->total_ulsch_pdus_rx),TELNET_VARTYPE_INT32,0},\
+ {"sched_decisions", &(macstatptr->sched_decisions),TELNET_VARTYPE_INT32,0},\
+ {"missed_deadlines", &(macstatptr->missed_deadlines),TELNET_VARTYPE_INT32,0},\
+}
+
+#define LTEMAC_UEMEASURE \
+{ \
+ {"dlsch_mcs1", &(macuestatptr->dlsch_mcs1),TELNET_VARTYPE_INT8,0},\
+ {"dlsch_mcs2", &(macuestatptr->dlsch_mcs2),TELNET_VARTYPE_INT8,0},\
+ {"rbs_used", &(macuestatptr->rbs_used),TELNET_VARTYPE_INT32,0},\
+ {"rbs_used_retx", &(macuestatptr->rbs_used_retx),TELNET_VARTYPE_INT16,0},\
+ {"total_rbs_used", &(macuestatptr->total_rbs_used),TELNET_VARTYPE_INT16,0},\
+ {"ncce_used", &(macuestatptr->ncce_used),TELNET_VARTYPE_INT16,0},\
+ {"ncce_used_retx", &(macuestatptr->ncce_used_retx),TELNET_VARTYPE_INT16,0},\
+ {"TBS", &(macuestatptr->TBS),TELNET_VARTYPE_INT32,0},\
+ {"total_pdu_bytes", &(macuestatptr->total_pdu_bytes),TELNET_VARTYPE_INT64,0},\
+ {"total_num_pdus", &(macuestatptr->total_num_pdus),TELNET_VARTYPE_INT32,0},\
+ {"overhead_bytes", &(macuestatptr->overhead_bytes),TELNET_VARTYPE_INT64,0},\
+ {"crnti", &(macuestatptr->crnti),TELNET_VARTYPE_INT16,0},\
+ {"normalized_rx_power", &(macuestatptr->normalized_rx_power),TELNET_VARTYPE_INT32,0},\
+ {"target_rx_power", &(macuestatptr->target_rx_power),TELNET_VARTYPE_INT32,0},\
+ {"ulsch_mcs1", &(macuestatptr->ulsch_mcs1),TELNET_VARTYPE_INT8,0},\
+ {"ulsch_mcs2", &(macuestatptr->ulsch_mcs2),TELNET_VARTYPE_INT8,0},\
+ {"rbs_used_rx", &(macuestatptr->rbs_used_rx),TELNET_VARTYPE_INT32,0},\
+ {"rbs_used_retx_rx", &(macuestatptr->rbs_used_retx_rx),TELNET_VARTYPE_INT32,0},\
+ {"total_rbs_used_rx", &(macuestatptr->total_rbs_used_rx),TELNET_VARTYPE_INT32,0},\
+ {"ulsch_TBS", &(macuestatptr->ulsch_TBS),TELNET_VARTYPE_INT32,0},\
+ {"total_pdu_bytes_rx", &(macuestatptr->total_pdu_bytes_rx),TELNET_VARTYPE_INT64,0},\
+ {"total_num_pdus_rx", &(macuestatptr->total_num_pdus_rx),TELNET_VARTYPE_INT32,0},\
+ {"num_errors_rx", &(macuestatptr->num_errors_rx),TELNET_VARTYPE_INT32,0},\
+}
+
+#define LTE_RLCMEASURE \
+{ \
+ {"rlc_mode", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_pdcp_sdu", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_pdcp_bytes", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_pdcp_sdu_discarded", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_pdcp_bytes_discarded", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_data_pdu", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_data_bytes", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_retransmit_pdu_by_status", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_retransmit_bytes_by_status", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_retransmit_pdu", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_retransmit_bytes", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_control_pdu", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"tx_control_bytes", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_pdcp_sdu", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_pdcp_bytes", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_data_pdus_duplicate", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_data_bytes_duplicate", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_data_pdu", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_data_bytes", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_data_pdu_dropped", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_data_bytes_dropped", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_data_pdu_out_of_window", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_data_bytes_out_of_window", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_control_pdu", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"rx_control_bytes", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"timer_reorder_tout", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"timer_poll_retrans_tout", NULL, TELNET_VARTYPE_UINT, 0},\
+ {"timer_status_prohibit_tout", NULL, TELNET_VARTYPE_UINT, 0},\
+}
diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.c b/common/utils/telnetsrv/telnetsrv_phycmd.c
index 35554a77a6..c60126f1c7 100644
--- a/common/utils/telnetsrv/telnetsrv_phycmd.c
+++ b/common/utils/telnetsrv/telnetsrv_phycmd.c
@@ -29,7 +29,7 @@
* \note
* \warning
*/
-#define _GNU_SOURCE
+#define _GNU_SOURCE
#include
#include
@@ -39,88 +39,104 @@
#define TELNETSRV_PHYCMD_MAIN
#include "telnetsrv_phycmd.h"
char *prnbuff;
-extern int dump_eNB_l2_stats(char *buffer, int length);
+extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length);
-void init_phytelnet(void) {
- prnbuff=malloc(get_phybsize() );
-
- if (prnbuff == NULL) {
- fprintf(stderr,"Error %s on malloc in init_phytelnet()\n",strerror(errno));
- }
+void init_phytelnet(void)
+{
+prnbuff=malloc(get_phybsize() );
+if (prnbuff == NULL)
+ {
+ fprintf(stderr,"Error %s on malloc in init_phytelnet()\n",strerror(errno));
+ }
}
-void display_uestatshead( telnet_printfunc_t prnt) {
- prnt("cc ue rnti Dmcs Umcs tao tau Dbr Dtb \n");
+void display_uestatshead( telnet_printfunc_t prnt)
+{
+prnt("cc ue rnti Dmcs Umcs tao tau Dbr Dtb \n");
}
-void dump_uestats(int debug, telnet_printfunc_t prnt, uint8_t prntflag) {
- int p;
- prnbuff=malloc(20480);
- p=dump_eNB_l2_stats( prnbuff, 20480);
+void dump_uestats(int debug, telnet_printfunc_t prnt, uint8_t prntflag)
+{
- if(prntflag>=1)
- prnt("%s\n",prnbuff);
+int p;
+
+ p=dump_eNB_l2_stats( prnbuff, 0);
+ if(prntflag>=1)
+ prnt("%s\n",prnbuff);
+ if(debug>=1)
+ prnt("%i bytes printed\n",p);
- if(debug>=1)
- prnt("%i bytes printed\n",p);
- free(prnbuff);
}
-void display_uestats(int debug, telnet_printfunc_t prnt, int ue) {
- for (int cc=0; cc<1 ; cc++) {
- }
+void display_uestats(int debug, telnet_printfunc_t prnt, int ue)
+{
+ for (int cc=0; cc<1 ; cc++)
+ {
+
+
+ }
}
-void display_phycounters(char *buf, int debug, telnet_printfunc_t prnt) {
- prnt(" DLSCH kb DLSCH kb/s\n");
- dump_uestats(debug, prnt,0);
+void display_phycounters(char *buf, int debug, telnet_printfunc_t prnt)
+{
+ prnt(" DLSCH kb DLSCH kb/s\n");
+
+ dump_uestats(debug, prnt,0);
+
}
-int dump_phyvars(char *buf, int debug, telnet_printfunc_t prnt) {
- if (debug > 0)
- prnt("phy interface module received %s\n",buf);
+int dump_phyvars(char *buf, int debug, telnet_printfunc_t prnt)
+{
+
+
- if (strcasestr(buf,"phycnt") != NULL) {
- display_phycounters(buf, debug, prnt);
- }
-
- if (strcasestr(buf,"uestat") != NULL) {
- char *cptr=strcasestr(buf+sizeof("uestat"),"UE");
- display_uestatshead(prnt);
-
- if (cptr != NULL) {
- int ueidx = strtol( cptr+sizeof("UE"), NULL, 10);
-
- if (ueidx < NUMBER_OF_UE_MAX && ueidx >= 0) {
- display_uestats(debug, prnt,ueidx);
- }
- } /* if cptr != NULL */
- else {
- for (int ue=0; ue 0)
+ prnt("phy interface module received %s\n",buf);
+ if (strcasestr(buf,"phycnt") != NULL)
+ {
+ display_phycounters(buf, debug, prnt);
+ }
+ if (strcasestr(buf,"uestat") != NULL)
+ {
+ char *cptr=strcasestr(buf+sizeof("uestat"),"UE");
+ display_uestatshead(prnt);
+ if (cptr != NULL)
+ {
+ int ueidx = strtol( cptr+sizeof("UE"), NULL, 10);
+ if (ueidx < NUMBER_OF_UE_MAX && ueidx >= 0)
+ {
+ display_uestats(debug, prnt,ueidx);
+ }
+ } /* if cptr != NULL */
+ else
+ {
+ for (int ue=0; ue]", dump_phyvars},
+ {"disp","[phycnt,uedump,uestat UE]", dump_phyvars},
- {"","",NULL},
+ {"","",NULL},
};
/*-------------------------------------------------------------------------------------*/
-void add_phy_cmds(void) {
- init_phytelnet();
- add_telnetcmd("phy", phy_vardef, phy_cmdarray);
+void add_phy_cmds(void)
+{
+
+ init_phytelnet();
+ add_telnetcmd("phy", phy_vardef, phy_cmdarray);
}
diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c
index 3b423bd465..9dd512091d 100644
--- a/common/utils/telnetsrv/telnetsrv_proccmd.c
+++ b/common/utils/telnetsrv/telnetsrv_proccmd.c
@@ -183,7 +183,7 @@ struct dirent *entry;
{
if(entry->d_name[0] == '.')
continue;
- snprintf(aname, sizeof(aname), "/proc/%d/task/%s/stat", getpid(),entry->d_name);
+ snprintf(aname, sizeof(aname), "/proc/%d/task/%.*s/stat", getpid(),(int)(sizeof(aname)-24),entry->d_name);
read_statfile(aname,debug,prnt);
} /* while entry != NULL */
closedir(proc_dir);
diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c
index dd8c2e54db..1be5f6d520 100644
--- a/openair1/PHY/INIT/lte_param_init.c
+++ b/openair1/PHY/INIT/lte_param_init.c
@@ -33,31 +33,29 @@
#include "phy_init.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
-
+#include "targets/RT/USER/lte-softmodem.h"
extern PHY_VARS_eNB *eNB;
extern PHY_VARS_UE *UE;
extern RU_t *ru;
-extern void phy_init_RU(RU_t*);
+extern void phy_init_RU(RU_t *);
void lte_param_init(PHY_VARS_eNB **eNBp,
- PHY_VARS_UE **UEp,
- RU_t **rup,
- unsigned char N_tx_port_eNB,
+ PHY_VARS_UE **UEp,
+ RU_t **rup,
+ unsigned char N_tx_port_eNB,
unsigned char N_tx_phy,
- unsigned char N_rx_ru,
+ unsigned char N_rx_ru,
unsigned char N_rx_ue,
- unsigned char transmission_mode,
- uint8_t extended_prefix_flag,
- frame_t frame_type,
- uint16_t Nid_cell,
- uint8_t tdd_config,
- uint8_t N_RB_DL,
- uint8_t pa,
- uint8_t threequarter_fs,
+ unsigned char transmission_mode,
+ uint8_t extended_prefix_flag,
+ frame_t frame_type,
+ uint16_t Nid_cell,
+ uint8_t tdd_config,
+ uint8_t N_RB_DL,
+ uint8_t pa,
+ uint8_t threequarter_fs,
uint8_t osf,
- uint32_t perfect_ce)
-{
-
+ uint32_t perfect_ce) {
LTE_DL_FRAME_PARMS *frame_parms;
int i;
PHY_VARS_eNB *eNB;
@@ -71,23 +69,16 @@ void lte_param_init(PHY_VARS_eNB **eNBp,
UE = *UEp;
ru = *rup;
printf("eNB %p, UE %p, ru %p\n",eNB,UE,ru);
-
-
-
- memset((void*)eNB,0,sizeof(PHY_VARS_eNB));
- memset((void*)UE,0,sizeof(PHY_VARS_UE));
- memset((void*)ru,0,sizeof(RU_t));
-
+ memset((void *)eNB,0,sizeof(PHY_VARS_eNB));
+ memset((void *)UE,0,sizeof(PHY_VARS_UE));
+ memset((void *)ru,0,sizeof(RU_t));
ru->eNB_list[0] = eNB;
eNB->RU_list[0] = ru;
ru->num_eNB=1;
-
srand(0);
randominit(0);
set_taus_seed(0);
-
frame_parms = &(eNB->frame_parms);
-
frame_parms->N_RB_DL = N_RB_DL; //50 for 10MHz and 25 for 5 MHz
frame_parms->N_RB_UL = N_RB_DL;
frame_parms->threequarter_fs = threequarter_fs;
@@ -106,13 +97,9 @@ void lte_param_init(PHY_VARS_eNB **eNBp,
// frame_parms->Bsrs = 0;
// frame_parms->kTC = 0;44
// frame_parms->n_RRC = 0;
-
init_frame_parms(frame_parms,osf);
-
//copy_lte_parms_to_phy_framing(frame_parms, &(PHY_config->PHY_framing));
-
// phy_init_top(frame_parms); //allocation
-
UE->is_secondary_ue = 0;
UE->frame_parms = *frame_parms;
UE->frame_parms.nb_antennas_rx=N_rx_ue;
@@ -121,14 +108,10 @@ void lte_param_init(PHY_VARS_eNB **eNBp,
ru->nb_tx = N_tx_phy;
ru->nb_rx = N_rx_ru;
ru->if_south = LOCAL_RF;
-
eNB->configured=1;
-
eNB->transmission_mode[0] = transmission_mode;
UE->transmission_mode[0] = transmission_mode;
-
dump_frame_parms(frame_parms);
-
UE->measurements.n_adj_cells=0;
UE->measurements.adj_cell_id[0] = Nid_cell+1;
UE->measurements.adj_cell_id[1] = Nid_cell+2;
@@ -144,7 +127,6 @@ void lte_param_init(PHY_VARS_eNB **eNBp,
phy_init_RU(ru);
generate_pcfich_reg_mapping(&UE->frame_parms);
generate_phich_reg_mapping(&UE->frame_parms);
-
// DL power control init
//if (transmission_mode == 1) {
UE->pdsch_config_dedicated->p_a = pa;
@@ -166,17 +148,13 @@ void lte_param_init(PHY_VARS_eNB **eNBp,
if (eNB->frame_parms.N_RB_DL == 100) ru->N_TA_offset = 624;
else if (eNB->frame_parms.N_RB_DL == 50) ru->N_TA_offset = 624/2;
else if (eNB->frame_parms.N_RB_DL == 25) ru->N_TA_offset = 624/4;
- }
- else ru->N_TA_offset=0;
+ } else ru->N_TA_offset=0;
-#if BASIC_SIMULATOR
- /* this is required for the basic simulator in TDD mode
- * TODO: find a proper cleaner solution
- */
- UE->N_TA_offset = 0;
-#endif
+ if (IS_SOFTMODEM_BASICSIM)
+ /* this is required for the basic simulator in TDD mode
+ * TODO: find a proper cleaner solution
+ */
+ UE->N_TA_offset = 0;
printf("Done lte_param_init\n");
-
-
}
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index 6b5863edc9..edd063a090 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -45,7 +45,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "PHY/LTE_TRANSPORT/transport_extern.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
-
+#include "targets/RT/USER/lte-softmodem.h"
//#define DEBUG_DCI_ENCODING 1
//#define DEBUG_DCI_DECODING 1
//#define DEBUG_PHY
@@ -64,35 +64,26 @@ void dci_encoding(uint8_t *a,
uint8_t A,
uint16_t E,
uint8_t *e,
- uint16_t rnti)
-{
-
-
+ uint16_t rnti) {
uint8_t D = (A + 16);
uint32_t RCC;
uint8_t d[3*(MAX_DCI_SIZE_BITS + 16) + 96];
uint8_t w[3*3*(MAX_DCI_SIZE_BITS+16)];
-
#ifdef DEBUG_DCI_ENCODING
int32_t i;
#endif
// encode dci
-
#ifdef DEBUG_DCI_ENCODING
printf("Doing DCI encoding for %d bits, e %p, rnti %x, E %d\n",A,e,rnti,E);
#endif
-
memset((void *)d,LTE_NULL,96);
-
ccodelte_encode(A,2,a,d+96,rnti);
-
#ifdef DEBUG_DCI_ENCODING
for (i=0; i<16+A; i++)
printf("%d : (%d,%d,%d)\n",i,*(d+96+(3*i)),*(d+97+(3*i)),*(d+98+(3*i)));
#endif
-
#ifdef DEBUG_DCI_ENCODING
printf("Doing DCI interleaving for %d coded bits, e %p\n",D*3,e);
#endif
@@ -100,27 +91,24 @@ void dci_encoding(uint8_t *a,
//#ifdef DEBUG_DCI_ENCODING
if (E>1000) printf("Doing DCI rate matching for %d channel bits, RCC %d, e %p\n",E,RCC,e);
+
//#endif
lte_rate_matching_cc(RCC,E,w,e);
-
-
-
}
uint8_t *generate_dci0(uint8_t *dci,
uint8_t *e,
uint8_t DCI_LENGTH,
- uint16_t coded_bits,
- uint16_t rnti)
-{
-
+ uint16_t coded_bits,
+ uint16_t rnti) {
uint8_t dci_flip[8];
+#ifdef DEBUG_DCI_ENCODING
- #ifdef DEBUG_DCI_ENCODING
- for (int i=0;i<1+((DCI_LENGTH+16)/8);i++)
+ for (int i=0; i<1+((DCI_LENGTH+16)/8); i++)
printf("i %d : %x\n",i,dci[i]);
- #endif
+
+#endif
if (DCI_LENGTH<=32) {
dci_flip[0] = dci[3];
@@ -129,8 +117,7 @@ uint8_t *generate_dci0(uint8_t *dci,
dci_flip[3] = dci[0];
#ifdef DEBUG_DCI_ENCODING
printf("DCI => %x,%x,%x,%x\n",
- dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3]);
-
+ dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3]);
#endif
} else {
dci_flip[0] = dci[7];
@@ -143,13 +130,12 @@ uint8_t *generate_dci0(uint8_t *dci,
dci_flip[7] = dci[0];
#ifdef DEBUG_DCI_ENCODING
printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
- dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3],
- dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]);
+ dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3],
+ dci_flip[4],dci_flip[5],dci_flip[6],dci_flip[7]);
#endif
}
dci_encoding(dci_flip,DCI_LENGTH,coded_bits,e,rnti);
-
return(e+coded_bits);
}
@@ -160,9 +146,7 @@ uint8_t *generate_dci0(uint8_t *dci,
-void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi)
-{
-
+void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **wbar,uint8_t n_symbols_pdcch,uint8_t mi) {
int32_t *wptr,*wptr2,*zptr;
uint32_t Mquad = get_nquad(n_symbols_pdcch,frame_parms,mi);
uint32_t RCC = (Mquad>>5), ND;
@@ -180,7 +164,6 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w
Kpi = (RCC<<5);
ND = Kpi - Mquad;
-
k=0;
for (col=0; col<32; col++) {
@@ -191,12 +174,9 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w
if (index>=ND) {
for (a=0; anb_antenna_ports_eNB; a++) {
//printf("a %d k %d\n",a,k);
-
wptr = &wtemp[a][k<<2];
zptr = &z[a][(index-ND)<<2];
-
//printf("wptr=%p, zptr=%p\n",wptr,zptr);
-
wptr[0] = zptr[0];
wptr[1] = zptr[1];
wptr[2] = zptr[2];
@@ -212,9 +192,7 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w
// permutation
for (i=0; inb_antenna_ports_eNB; a++) {
-
//wptr = &wtemp[a][i<<2];
//wptr2 = &wbar[a][((i+frame_parms->Nid_cell)%Mquad)<<2];
wptr = &wtemp[a][((i+frame_parms->Nid_cell)%Mquad)<<2];
@@ -230,17 +208,13 @@ void pdcch_interleaving(LTE_DL_FRAME_PARMS *frame_parms,int32_t **z, int32_t **w
void pdcch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t subframe,
uint8_t *e,
- uint32_t length)
-{
+ uint32_t length) {
int i;
uint8_t reset;
uint32_t x1, x2, s=0;
-
//LOG_D(PHY, "%s(fp, subframe:%d, e, length:%d)\n", __FUNCTION__, subframe, length);
-
reset = 1;
// x1 is set in lte_gold_generic
-
x2 = (subframe<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2
for (i=0; inushift%3;
-
int Msymb2;
int split_flag=0;
switch (frame_parms->N_RB_DL) {
- case 100:
- Msymb2 = Msymb;
- break;
+ case 100:
+ Msymb2 = Msymb;
+ break;
- case 75:
- Msymb2 = 3*Msymb/4;
- break;
+ case 75:
+ Msymb2 = 3*Msymb/4;
+ break;
- case 50:
- Msymb2 = Msymb>>1;
- break;
+ case 50:
+ Msymb2 = Msymb>>1;
+ break;
- case 25:
- Msymb2 = Msymb>>2;
- break;
+ case 25:
+ Msymb2 = Msymb>>2;
+ break;
- case 15:
- Msymb2 = Msymb*15/100;
- break;
+ case 15:
+ Msymb2 = Msymb*15/100;
+ break;
- case 6:
- Msymb2 = Msymb*6/100;
- break;
+ case 6:
+ Msymb2 = Msymb*6/100;
+ break;
- default:
- Msymb2 = Msymb>>2;
- break;
+ default:
+ Msymb2 = Msymb>>2;
+ break;
}
-
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PCFICH,1);
generate_pcfich(num_pdcch_symbols,
amp,
@@ -328,42 +295,37 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
y[0] = &yseq0[0];
y[1] = &yseq1[0];
-#if BASIC_SIMULATOR
- /* this should be the normal case
- * but it has to be validated for all the various cases
- * so let's just do it for the basic simulator
- */
- memset(e, 2, DCI_BITS_MAX);
-#else
-#if 1
- // reset all bits to , 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);
+ // here we interpret NIL as a random QPSK sequence. That makes power estimation easier.
+ for (i=0; i=1; L>>=1) {
for (i=0; i=0) {
e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
@@ -375,14 +337,13 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
}
}
}
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,0);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DCI0,0);
// Scrambling
#ifdef DEBUG_DCI_ENCODING
printf("pdcch scrambling\n");
#endif
//LOG_D(PHY, "num_pdcch_symbols:%d mi:%d nquad:%d\n", num_pdcch_symbols, mi, get_nquad(num_pdcch_symbols, frame_parms, mi));
-
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING,1);
pdcch_scrambling(frame_parms,
subframe,
@@ -390,11 +351,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
8*get_nquad(num_pdcch_symbols, frame_parms, mi));
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_SCRAMBLING,0);
//72*get_nCCE(num_pdcch_symbols,frame_parms,mi));
-
-
-
-
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,1);
+
// Now do modulation
if (frame_parms->nb_antenna_ports_eNB==1)
gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15)>>15);
@@ -402,7 +360,6 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
gain_lin_QPSK = amp/2;
e_ptr = e;
-
#ifdef DEBUG_DCI_ENCODING
printf(" PDCCH Modulation, Msymb %d, Msymb2 %d,gain_lin_QPSK %d\n",Msymb,Msymb2,gain_lin_QPSK);
#endif
@@ -410,91 +367,73 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
//LOG_D(PHY,"%s() Msymb2:%d\n", __FUNCTION__, Msymb2);
if (frame_parms->nb_antenna_ports_eNB==1) { //SISO
-
-
for (i=0; i>2);
#endif
// first antenna position n -> x0
- ((int16_t*)&y[0][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+ ((int16_t *)&y[0][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
e_ptr++;
- ((int16_t*)&y[0][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+ ((int16_t *)&y[0][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
e_ptr++;
-
// second antenna position n -> -x1*
- ((int16_t*)&y[1][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK;
+ ((int16_t *)&y[1][i])[0] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? gain_lin_QPSK : -gain_lin_QPSK;
e_ptr++;
- ((int16_t*)&y[1][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
+ ((int16_t *)&y[1][i])[1] = (*e_ptr==2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
e_ptr++;
-
// fill in the rest of the ALAMOUTI precoding
- ((int16_t*)&y[0][i+1])[0] = -((int16_t*)&y[1][i])[0];
- ((int16_t*)&y[0][i+1])[1] = ((int16_t*)&y[1][i])[1];
- ((int16_t*)&y[1][i+1])[0] = ((int16_t*)&y[0][i])[0];
- ((int16_t*)&y[1][i+1])[1] = -((int16_t*)&y[0][i])[1];
-
+ ((int16_t *)&y[0][i+1])[0] = -((int16_t *)&y[1][i])[0];
+ ((int16_t *)&y[0][i+1])[1] = ((int16_t *)&y[1][i])[1];
+ ((int16_t *)&y[1][i+1])[0] = ((int16_t *)&y[0][i])[0];
+ ((int16_t *)&y[1][i+1])[1] = -((int16_t *)&y[0][i])[1];
}
}
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_MODULATION,0);
-
-
#ifdef DEBUG_DCI_ENCODING
printf(" PDCCH Interleaving\n");
#endif
-
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING,1);
// printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]);
// This is the interleaving procedure defined in 36-211, first part of Section 6.8.5
pdcch_interleaving(frame_parms,&y[0],&wbar[0],num_pdcch_symbols,mi);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_INTERLEAVING,0);
-
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,1);
mprime=0;
nsymb = (frame_parms->Ncp==0) ? 14:12;
re_offset = frame_parms->first_carrier_offset;
-
// This is the REG allocation algorithm from 36-211, second part of Section 6.8.5
// printf("DCI (SF %d) : txdataF %p (0 %p)\n",subframe,&txdataF[0][512*14*subframe],&txdataF[0][0]);
#ifdef DEBUG_DCI_ENCODING
printf("kprime loop - N_RB_DL:%d lprime:num_pdcch_symbols:%d Ncp:%d pcfich:%02x,%02x,%02x,%02x ofdm_symbol_size:%d first_carrier_offset:%d nb_antenna_ports_eNB:%d\n",
- frame_parms->N_RB_DL, num_pdcch_symbols,frame_parms->Ncp,
- frame_parms->pcfich_reg[0],
- frame_parms->pcfich_reg[1],
- frame_parms->pcfich_reg[2],
- frame_parms->pcfich_reg[3],
- frame_parms->ofdm_symbol_size,
- frame_parms->first_carrier_offset,
- frame_parms->nb_antenna_ports_eNB
- );
+ frame_parms->N_RB_DL, num_pdcch_symbols,frame_parms->Ncp,
+ frame_parms->pcfich_reg[0],
+ frame_parms->pcfich_reg[1],
+ frame_parms->pcfich_reg[2],
+ frame_parms->pcfich_reg[3],
+ frame_parms->ofdm_symbol_size,
+ frame_parms->first_carrier_offset,
+ frame_parms->nb_antenna_ports_eNB
+ );
#endif
+
for (kprime=0; kprimeN_RB_DL*12; kprime++) {
for (lprime=0; lprimeofdm_symbol_size*(lprime+(subframe*nsymb));
-
-
-
tti_offset = symbol_offset + re_offset;
-
(re_offset==(frame_parms->ofdm_symbol_size-2)) ? (split_flag=1) : (split_flag=0);
// printf("kprime %d, lprime %d => REG %d (symbol %d)\n",kprime,lprime,(lprime==0)?(kprime/6) : (kprime>>2),symbol_offset);
@@ -505,16 +444,13 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
#endif
} else {
// Copy REG to TX buffer
-
if ((lprime == 0)||
((lprime==1)&&(frame_parms->nb_antenna_ports_eNB == 4))) {
// first symbol, or second symbol+4 TX antennas skip pilots
-
kprime_mod12 = kprime%12;
if ((kprime_mod12 == 0) || (kprime_mod12 == 6)) {
// kprime represents REG
-
for (i=0; i<6; i++) {
if ((i!=(nushiftmod3))&&(i!=(nushiftmod3+3))) {
txdataF[0][tti_offset+i] = wbar[0][mprime];
@@ -523,9 +459,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
txdataF[1][tti_offset+i] = wbar[1][mprime];
#ifdef DEBUG_DCI_ENCODING
- printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+ printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime]));
#endif
-
mprime++;
}
}
@@ -543,7 +478,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
txdataF[1][tti_offset+i] = wbar[1][mprime];
#ifdef DEBUG_DCI_ENCODING
- LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+ LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime]));
#endif
mprime++;
}
@@ -554,7 +489,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
txdataF[1][tti_offset+0] = wbar[1][mprime];
#ifdef DEBUG_DCI_ENCODING
- printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+ printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime]));
#endif
mprime++;
txdataF[0][tti_offset+1] = wbar[0][mprime];
@@ -563,7 +498,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
txdataF[1][tti_offset+1] = wbar[1][mprime];
#ifdef DEBUG_DCI_ENCODING
- printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+ printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short *)&wbar[0][mprime],*(1+(short *)&wbar[0][mprime]));
#endif
mprime++;
txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[0][mprime];
@@ -572,8 +507,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[1][mprime];
#ifdef DEBUG_DCI_ENCODING
- printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short*)&wbar[0][mprime],
- *(1+(short*)&wbar[0][mprime]));
+ printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short *)&wbar[0][mprime],
+ *(1+(short *)&wbar[0][mprime]));
#endif
mprime++;
txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[0][mprime];
@@ -582,11 +517,10 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[1][mprime];
#ifdef DEBUG_DCI_ENCODING
- printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short*)&wbar[0][mprime],
- *(1+(short*)&wbar[0][mprime]));
+ printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short *)&wbar[0][mprime],
+ *(1+(short *)&wbar[0][mprime]));
#endif
mprime++;
-
}
}
}
@@ -594,7 +528,6 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
if (mprime>=Msymb2)
return(num_pdcch_symbols);
} // check_phich_reg
-
} //lprime loop
re_offset++;
@@ -602,8 +535,8 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
if (re_offset == (frame_parms->ofdm_symbol_size))
re_offset = 1;
} // kprime loop
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,0);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX,0);
return(num_pdcch_symbols);
}
diff --git a/openair1/PHY/LTE_TRANSPORT/pss.c b/openair1/PHY/LTE_TRANSPORT/pss.c
index 33bd5cc7e8..9ebd841430 100644
--- a/openair1/PHY/LTE_TRANSPORT/pss.c
+++ b/openair1/PHY/LTE_TRANSPORT/pss.c
@@ -38,72 +38,65 @@
//#include "defs.h"
#include "PHY/defs_eNB.h"
#include "PHY/phy_extern.h"
+#include "targets/RT/USER/lte-softmodem.h"
int generate_pss(int32_t **txdataF,
short amp,
LTE_DL_FRAME_PARMS *frame_parms,
unsigned short symbol,
- unsigned short slot_offset)
-{
-
+ unsigned short slot_offset) {
unsigned int Nsymb;
unsigned short k,m,aa,a;
uint8_t Nid2;
short *primary_sync;
-
-
Nid2 = frame_parms->Nid_cell % 3;
switch (Nid2) {
- case 0:
- primary_sync = primary_synch0;
- break;
+ case 0:
+ primary_sync = primary_synch0;
+ break;
- case 1:
- primary_sync = primary_synch1;
- break;
+ case 1:
+ primary_sync = primary_synch1;
+ break;
- case 2:
- primary_sync = primary_synch2;
- break;
+ case 2:
+ primary_sync = primary_synch2;
+ break;
- default:
- LOG_E(PHY,"[PSS] eNb_id has to be 0,1,2\n");
- return(-1);
+ default:
+ LOG_E(PHY,"[PSS] eNb_id has to be 0,1,2\n");
+ return(-1);
}
a = (frame_parms->nb_antenna_ports_eNB == 1) ? amp: (amp*ONE_OVER_SQRT2_Q15)>>15;
//printf("[PSS] amp=%d, a=%d\n",amp,a);
-#if BASIC_SIMULATOR
- /* a hack to remove at some point (the UE doesn't synch with 100 RBs) */
- a = (frame_parms->nb_antenna_ports_eNB == 1) ? 4*amp: (amp*ONE_OVER_SQRT2_Q15)>>15;
-#endif
+ if (IS_SOFTMODEM_BASICSIM)
+ /* a hack to remove at some point (the UE doesn't synch with 100 RBs) */
+ a = (frame_parms->nb_antenna_ports_eNB == 1) ? 4*amp: (amp*ONE_OVER_SQRT2_Q15)>>15;
Nsymb = (frame_parms->Ncp==NORMAL)?14:12;
for (aa=0; aanb_antenna_ports_eNB; aa++) {
// aa = 0;
-
// The PSS occupies the inner 6 RBs, which start at
k = frame_parms->ofdm_symbol_size-3*12+5;
//printf("[PSS] k = %d\n",k);
for (m=5; m<67; m++) {
- ((short*)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size +
- symbol*frame_parms->ofdm_symbol_size + k)] =
- (a * primary_sync[2*m]) >> 15;
- ((short*)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size +
- symbol*frame_parms->ofdm_symbol_size + k) + 1] =
- (a * primary_sync[2*m+1]) >> 15;
-
+ ((short *)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size +
+ symbol*frame_parms->ofdm_symbol_size + k)] =
+ (a * primary_sync[2*m]) >> 15;
+ ((short *)txdataF[aa])[2*(slot_offset*Nsymb/2*frame_parms->ofdm_symbol_size +
+ symbol*frame_parms->ofdm_symbol_size + k) + 1] =
+ (a * primary_sync[2*m+1]) >> 15;
k+=1;
if (k >= frame_parms->ofdm_symbol_size) {
k++; //skip DC
k-=frame_parms->ofdm_symbol_size;
}
-
}
}
diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c
index 358a561c21..5a5f9852b1 100644
--- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c
+++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c
@@ -63,7 +63,6 @@ struct msghdr nas_msg_rx;
#define GRAAL_NETLINK_ID 31
-
static int tun_alloc(char *dev) {
struct ifreq ifr;
int fd, err;
@@ -93,12 +92,12 @@ static int tun_alloc(char *dev) {
return fd;
}
-int netlink_init_tun(void) {
+int netlink_init_tun(char *ifprefix) {
int ret;
char ifname[64];
for (int i = 0; i < NUMBER_OF_UE_MAX; i++) {
- sprintf(ifname, "oaitun_ue%d",i+1);
+ sprintf(ifname, "oaitun_%.3s%d",ifprefix,i+1);
nas_sock_fd[i] = tun_alloc(ifname);
if (nas_sock_fd[i] == -1) {
diff --git a/openair1/SIMULATION/ETH_TRANSPORT/proto.h b/openair1/SIMULATION/ETH_TRANSPORT/proto.h
index 6d54bfb24c..d84322da31 100644
--- a/openair1/SIMULATION/ETH_TRANSPORT/proto.h
+++ b/openair1/SIMULATION/ETH_TRANSPORT/proto.h
@@ -62,6 +62,6 @@ int multicast_link_read_data_from_sock(uint8_t eNB_flag);
void clear_eNB_transport_info(uint8_t);
void clear_UE_transport_info(uint8_t);
int netlink_init(void);
-int netlink_init_tun(void);
+int netlink_init_tun(char *ifsuffix);
#endif /* EMU_PROTO_H_ */
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index 74613f8fb1..c7916b8dfc 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -783,12 +783,14 @@ int main(int argc, char **argv) {
case 'u':
dual_stream_UE=1;
- if (UE != NULL)
- UE->use_ia_receiver = 1;
+
+ if (UE != NULL)
+ UE->use_ia_receiver = 1;
else {
printf("UE is NULL\n");
exit(-1);
- }
+ }
+
if ((n_tx_port!=2) || (transmission_mode!=5)) {
printf("IA receiver only supported for TM5!");
exit(-1);
@@ -951,8 +953,8 @@ int main(int argc, char **argv) {
fl_set_object_label(form_ue->button_0, "IA Receiver ON");
fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN);
} else {
- printf("UE is NULL\n");
- exit(-1);
+ printf("UE is NULL\n");
+ exit(-1);
}
}
}
@@ -2139,5 +2141,7 @@ int main(int argc, char **argv) {
else
return(0);
}
-
-
+/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
+uint64_t get_softmodem_optmask(void) {
+ return 0;
+}
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index e38d6ad3cd..3e9623dc2f 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -1211,9 +1211,7 @@ int main(int argc, char **argv) {
}
dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round);
-
round=5;
-
}
if (n_frames==1) printf("round %d errors %u/%u\n",round,errs[round],trials);
@@ -1509,5 +1507,7 @@ int main(int argc, char **argv) {
return(0);
}
-
-
+/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
+uint64_t get_softmodem_optmask(void) {
+ return 0;
+}
diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h
index 08ea93f427..4000545966 100644
--- a/openair2/COMMON/rrc_messages_def.h
+++ b/openair2/COMMON/rrc_messages_def.h
@@ -72,3 +72,6 @@ MESSAGE_DEF(NAS_CONN_ESTABLI_CNF, MESSAGE_PRIORITY_MED, NasConnEstab
MESSAGE_DEF(NAS_CONN_RELEASE_IND, MESSAGE_PRIORITY_MED, NasConnReleaseInd, nas_conn_release_ind)
MESSAGE_DEF(NAS_UPLINK_DATA_CNF, MESSAGE_PRIORITY_MED, NasUlDataCnf, nas_ul_data_cnf)
MESSAGE_DEF(NAS_DOWNLINK_DATA_IND, MESSAGE_PRIORITY_MED, NasDlDataInd, nas_dl_data_ind)
+
+// eNB: realtime -> RRC messages
+MESSAGE_DEF(RRC_SUBFRAME_PROCESS, MESSAGE_PRIORITY_MED, RrcSubframeProcess, rrc_subframe_process)
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 2e6d7a9d0b..9d6100c8b2 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -82,6 +82,8 @@
#define NAS_UPLINK_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_cnf
#define NAS_DOWNLINK_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_ind
+#define RRC_SUBFRAME_PROCESS(mSGpTR) (mSGpTR)->ittiMsg.rrc_subframe_process
+
//-------------------------------------------------------------------------------------------//
typedef struct RrcStateInd_s {
Rrc_State_t state;
@@ -400,4 +402,10 @@ typedef nas_release_ind_t NasConnReleaseInd;
typedef ul_info_transfer_cnf_t NasUlDataCnf;
typedef dl_info_transfer_ind_t NasDlDataInd;
+// eNB: realtime -> RRC messages
+typedef struct rrc_subframe_process_s {
+ protocol_ctxt_t ctxt;
+ int CC_id;
+} RrcSubframeProcess;
+
#endif /* RRC_MESSAGES_TYPES_H_ */
diff --git a/openair2/COMMON/x2ap_messages_def.h b/openair2/COMMON/x2ap_messages_def.h
index d5555c1839..65fa9c801d 100644
--- a/openair2/COMMON/x2ap_messages_def.h
+++ b/openair2/COMMON/x2ap_messages_def.h
@@ -40,3 +40,6 @@ MESSAGE_DEF(X2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, x2ap_der
/* handover messages X2AP <-> RRC */
MESSAGE_DEF(X2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, x2ap_handover_req_t , x2ap_handover_req)
MESSAGE_DEF(X2AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_handover_req_ack_t , x2ap_handover_req_ack)
+
+/* handover messages X2AP <-> S1AP */
+MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, x2ap_ue_context_release_t , x2ap_ue_context_release)
diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h
index 7cdd0ff0ff..38429b712e 100644
--- a/openair2/COMMON/x2ap_messages_types.h
+++ b/openair2/COMMON/x2ap_messages_types.h
@@ -33,11 +33,21 @@
#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack
#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf
#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind
+#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release
#define X2AP_MAX_NB_ENB_IP_ADDRESS 2
// eNB application layer -> X2AP messages
+
+/* X2AP UE CONTEXT RELEASE */
+typedef struct x2ap_ue_context_release_s {
+ /* used for X2AP->RRC in source and RRC->X2AP in target */
+ int rnti;
+
+ int source_assoc_id;
+} x2ap_ue_context_release_t;
+
typedef struct x2ap_register_enb_req_s {
/* Unique eNB_id to identify the eNB within EPC.
* For macro eNB ids this field should be 20 bits long.
@@ -128,12 +138,12 @@ typedef struct x2ap_lastvisitedcell_info_s {
uint64_t time_UE_StayedInCell;
}x2ap_lastvisitedcell_info_t;
-//used for src
typedef struct x2ap_handover_req_s {
- int source_rnti; /* TODO: to be fixed/remove */
- int source_x2id; /* TODO: to be fixed/remove */
+ /* used for RRC->X2AP in source eNB */
+ int rnti;
- int old_eNB_ue_x2ap_id;
+ /* used for X2AP->RRC in target eNB */
+ int x2_id;
LTE_PhysCellId_t target_physCellId;
@@ -167,15 +177,17 @@ typedef struct x2ap_handover_req_s {
uint8_t rrc_buffer[1024 /* arbitrary, big enough */];
int rrc_buffer_size;
- /* TODO: this parameter has to be removed */
- int target_mod_id;
+ int target_assoc_id;
} x2ap_handover_req_t;
typedef struct x2ap_handover_req_ack_s {
- int source_rnti; /* TODO: to be fixed/remove */
- int source_x2id; /* TODO: to be fixed/remove */
- /* TODO: this parameter has to be removed */
- int target_mod_id;
+ /* used for RRC->X2AP in target and X2AP->RRC in source */
+ int rnti;
+
+ /* used for RRC->X2AP in target */
+ int x2_id_target;
+
+ int source_assoc_id;
uint8_t nb_e_rabs_tobesetup;
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index ed0e13c0c7..c84a9554de 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -2188,7 +2188,9 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) {
if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
+ X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 0;
} else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
+ X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 0;
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv6 = 1;
} else if (strcmp(*(X2ParamList.paramarray[l][ENB_X2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
X2AP_REGISTER_ENB_REQ (msg_p).target_enb_x2_ip_address[l].ipv4 = 1;
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index fbe810f536..73d73c3556 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -865,7 +865,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
rntiP, -1
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,
- -1
+ 0
#endif
)) == -1)
{
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index 7d9d9b478a..79b4a02865 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -52,7 +52,7 @@
#include "targets/COMMON/openairinterface5g_limits.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#include "UTIL/OSA/osa_defs.h"
-
+#include "openair2/RRC/NAS/nas_config.h"
# include "intertask_interface.h"
@@ -556,7 +556,6 @@ pdcp_data_ind(
uint32_t rx_hfn_for_count;
int pdcp_sn_for_count;
int security_ok;
-
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_IN);
LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)sdu_buffer_pP->data,sdu_buffer_sizeP,
"[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP);
@@ -683,6 +682,7 @@ pdcp_data_ind(
}
#if 0
+
/* Removed by Cedric */
if (pdcp_is_rx_seq_number_valid(sequence_number, pdcp_p, srb_flagP) == TRUE) {
LOG_T(PDCP, "Incoming PDU has a sequence number (%d) in accordance with RX window\n", sequence_number);
@@ -704,6 +704,7 @@ pdcp_data_ind(
free_mem_block(sdu_buffer_pP, __func__);
return FALSE;
}
+
#endif
// SRB1/2: control-plane data
@@ -814,26 +815,23 @@ pdcp_data_ind(
free_mem_block(sdu_buffer_pP, __func__);
/* TODO: indicate integrity verification failure to upper layer */
return FALSE;
-
} else if (pdcp_p->next_pdcp_rx_sn - sequence_number > reordering_window) {
pdcp_p->rx_hfn++;
rx_hfn_for_count = pdcp_p->rx_hfn;
pdcp_sn_for_count = sequence_number;
pdcp_p->next_pdcp_rx_sn = sequence_number + 1;
-
} else if (sequence_number - pdcp_p->next_pdcp_rx_sn >= reordering_window) {
rx_hfn_for_count = pdcp_p->rx_hfn - 1;
pdcp_sn_for_count = sequence_number;
-
} else if (sequence_number >= pdcp_p->next_pdcp_rx_sn) {
rx_hfn_for_count = pdcp_p->rx_hfn;
pdcp_sn_for_count = sequence_number;
pdcp_p->next_pdcp_rx_sn = sequence_number + 1;
+
if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) {
pdcp_p->next_pdcp_rx_sn = 0;
pdcp_p->rx_hfn++;
}
-
} else { /* sequence_number < pdcp_p->next_pdcp_rx_sn */
rx_hfn_for_count = pdcp_p->rx_hfn;
pdcp_sn_for_count = sequence_number;
@@ -886,20 +884,21 @@ pdcp_data_ind(
* TODO: we also have to deal with re-establishment PDU (control PDUs)
* that contain no SDU.
*/
-
pdcp_p->last_submitted_pdcp_rx_sn = sequence_number;
-
break;
} /* case RLC_MODE_AM */
case RLC_MODE_UM:
+
/* process as described in 36.323 5.1.2.1.3 */
if (sequence_number < pdcp_p->next_pdcp_rx_sn) {
pdcp_p->rx_hfn++;
}
+
rx_hfn_for_count = pdcp_p->rx_hfn;
pdcp_sn_for_count = sequence_number;
pdcp_p->next_pdcp_rx_sn = sequence_number + 1;
+
if (pdcp_p->next_pdcp_rx_sn > pdcp_p->maximum_pdcp_rx_sn) {
pdcp_p->next_pdcp_rx_sn = 0;
pdcp_p->rx_hfn++;
@@ -1275,7 +1274,8 @@ pdcp_run (
} while(msg_p != NULL);
// IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer
- if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) {
+ // if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) {
+ if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) {
pdcp_fifo_read_input_sdus(ctxt_pP);
}
@@ -2193,9 +2193,6 @@ rrc_pdcp_config_req (
}
}
-
-//-----------------------------------------------------------------------------
-
uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
/* temporary enforce netlink when UE_NAS_USE_TUN is set,
this is while switching from noS1 as build option
@@ -2210,9 +2207,17 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
((PDCP_USE_NETLINK)?"usenetlink":""));
if (PDCP_USE_NETLINK) {
+ nas_getparams();
+
if(UE_NAS_USE_TUN) {
- netlink_init_tun();
- } else {
+ netlink_init_tun("ue");
+ LOG_I(PDCP, "UE pdcp will use tun interface\n");
+ } else if(ENB_NAS_USE_TUN) {
+ netlink_init_tun("enb");
+ nas_config(1, 1, 1, "enb");
+ LOG_I(PDCP, "ENB pdcp will use tun interface\n");
+ } else {
+ LOG_I(PDCP, "pdcp will use kernel modules\n");
netlink_init();
}
}
@@ -2220,6 +2225,7 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
return pdcp_params.optmask ;
}
+
//-----------------------------------------------------------------------------
void
pdcp_free (
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index f9173ece17..ce62893170 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -55,6 +55,7 @@
#define LINK_ENB_PDCP_TO_IP_DRIVER_BIT (1<< 13)
#define LINK_ENB_PDCP_TO_GTPV1U_BIT (1<< 14)
#define UE_NAS_USE_TUN_BIT (1<< 15)
+#define ENB_NAS_USE_TUN_BIT (1<< 16)
typedef struct {
uint64_t optmask;
} pdcp_params_t;
@@ -63,6 +64,7 @@ typedef struct {
#define LINK_ENB_PDCP_TO_IP_DRIVER ( get_pdcp_optmask() & LINK_ENB_PDCP_TO_IP_DRIVER_BIT)
#define LINK_ENB_PDCP_TO_GTPV1U ( get_pdcp_optmask() & LINK_ENB_PDCP_TO_GTPV1U_BIT)
#define UE_NAS_USE_TUN ( get_pdcp_optmask() & UE_NAS_USE_TUN_BIT)
+#define ENB_NAS_USE_TUN ( get_pdcp_optmask() & ENB_NAS_USE_TUN_BIT)
uint64_t get_pdcp_optmask(void);
extern pthread_t pdcp_thread;
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 47f2946e27..7324a7c7ea 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -125,7 +125,9 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) );
} else if (UE_NAS_USE_TUN) {
ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
- } else if (PDCP_USE_NETLINK) {//UE_NAS_USE_TUN
+ } else if (ENB_NAS_USE_TUN) {
+ ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
+ } else if (PDCP_USE_NETLINK) {
memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) sdu_p->data, sizeToWrite);
nas_nlh_tx->nlmsg_len = sizeToWrite;
ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0);
@@ -144,7 +146,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) {
pdcp_data_req_header_t pdcp_read_header_g;
- if (UE_NAS_USE_TUN) {
+ if (UE_NAS_USE_TUN || ENB_NAS_USE_TUN) {
protocol_ctxt_t ctxt = *ctxt_pP;
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
hashtable_rc_t h_rc;
@@ -155,20 +157,29 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) {
do {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 );
- len = read(nas_sock_fd[ctxt_pP->module_id], &nl_rx_buf, NL_MAX_PAYLOAD);
+ len = read(UE_NAS_USE_TUN?nas_sock_fd[ctxt_pP->module_id]:nas_sock_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 );
if (len<=0) continue;
- LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
- ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
+ if (UE_NAS_USE_TUN) {
key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
+ } else {
+ ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0];
+ ctxt.enb_flag=ENB_FLAG_YES;
+ ctxt.module_id=0;
+ key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_YES);
+ h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
+ }
+
+ LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
+ ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
if (h_rc == HASH_TABLE_OK) {
LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n",
ctxt.frame, ctxt.instance, len, rab_id);
- LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n",
+ LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %u]\n",
ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
ctxt.rnti, rab_id);
MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
@@ -192,7 +203,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) {
MSC_AS_TIME_ARGS(ctxt_pP),
ctxt.instance, rab_id, rab_id, len);
LOG_D(PDCP,
- "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n",
+ "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n",
ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
ctxt.rnti, rab_id, key);
}
diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c
index 2cb92a4208..d30f0fe27c 100644
--- a/openair2/LAYER2/RLC/rlc.c
+++ b/openair2/LAYER2/RLC/rlc.c
@@ -593,14 +593,12 @@ void rlc_data_ind (
const sdu_size_t sdu_sizeP,
mem_block_t *sdu_pP) {
//-----------------------------------------------------------------------------
-#if defined(TRACE_RLC_PAYLOAD)
LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] Display of rlc_data_ind: size %u\n",
PROTOCOL_CTXT_ARGS(ctxt_pP),
(srb_flagP) ? "SRB" : "DRB",
rb_idP,
sdu_sizeP);
rlc_util_print_hex_octets(RLC, (unsigned char *)sdu_pP->data, sdu_sizeP);
-#endif
#if T_TRACER
if (ctxt_pP->enb_flag)
diff --git a/openair2/NETWORK_DRIVER/MESH/constant.h b/openair2/NETWORK_DRIVER/MESH/constant.h
index 1c756765c6..5347c5a784 100644
--- a/openair2/NETWORK_DRIVER/MESH/constant.h
+++ b/openair2/NETWORK_DRIVER/MESH/constant.h
@@ -47,7 +47,8 @@
#define NAS_INET6_ADDRSTRLEN 46
#define NAS_INET_ADDRSTRLEN 16
-#define NAS_CX_MAX 128 // 32 //Identical to RRC constant
+#define NAS_CX_MAX 32 //128 //Identical to RRC constant: no you cannot
+/* increase to 128 without risking stack problems: KEEP ATTENTION TO COMPILATION WARNINGS */
//#define NAS_CX_MULTICAST_ALLNODE 2
#define NAS_RETRY_LIMIT_DEFAULT 5
diff --git a/openair2/NETWORK_DRIVER/MESH/ioctl.h b/openair2/NETWORK_DRIVER/MESH/ioctl.h
index ffa9b4e79b..904105b1d1 100644
--- a/openair2/NETWORK_DRIVER/MESH/ioctl.h
+++ b/openair2/NETWORK_DRIVER/MESH/ioctl.h
@@ -64,7 +64,8 @@
// Max number of entry of a message list
#define NAS_LIST_CX_MAX 32
#define NAS_LIST_RB_MAX 32
-#define NAS_LIST_CLASS_MAX 32
+#define NAS_LIST_CLASS_MAX 16 // 32 is too high!!:
+/* risk of stack problems: KEEP ATTENTION TO COMPILATION WARNINGS */
typedef unsigned short nasMsgType_t;
diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c
index cddd409922..a00bc53759 100644
--- a/openair2/RRC/LTE/rrc_UE.c
+++ b/openair2/RRC/LTE/rrc_UE.c
@@ -801,7 +801,6 @@ rrc_ue_establish_drb(
(void)ip_addr_offset4;
LOG_I(RRC,"[UE %d] Frame %d: processing RRCConnectionReconfiguration: reconfiguring DRB %ld/LCID %d\n",
ue_mod_idP, frameP, DRB_config->drb_Identity, (int)*DRB_config->logicalChannelIdentity);
-
/*
rrc_pdcp_config_req (ue_mod_idP+NB_eNB_INST, frameP, 0, CONFIG_ACTION_ADD,
(eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity, UNDEF_SECURITY_MODE);
@@ -810,34 +809,34 @@ rrc_ue_establish_drb(
(eNB_index * NB_RB_MAX) + *DRB_config->logicalChannelIdentity,
RADIO_ACCESS_BEARER,Rlc_info_um);
*/
- if(PDCP_USE_NETLINK) {
-# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U)
- ip_addr_offset3 = 0;
- ip_addr_offset4 = 1;
- LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oai%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP,
- ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1);
- oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP, // interface_id
- ip_addr_offset3+ue_mod_idP+1, // third_octet
- ip_addr_offset4+ue_mod_idP+1); // fourth_octet
+ // if(!EPC_MODE_ENABLED) {
+ //# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET) && !defined(LINK_ENB_PDCP_TO_GTPV1U)
+ ip_addr_offset3 = 0;
+ ip_addr_offset4 = 1;
+ LOG_I(OIP,"[UE %d] trying to bring up the OAI interface oip%d, IP 10.0.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP,
+ ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1);
+ oip_ifup=nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id
+ ip_addr_offset3+ue_mod_idP+1, // third_octet
+ ip_addr_offset4+ue_mod_idP+1, // fourth_octet
+ "oip"); // interface suffix
- if (oip_ifup == 0 ) { // interface is up --> send a config the DRB
- LOG_I(OIP,"[UE %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n",
- ue_mod_idP,
- ip_addr_offset3+ue_mod_idP,
- (long int)((eNB_index * maxDRB) + DRB_config->drb_Identity));
- rb_conf_ipv4(0,//add
- ue_mod_idP,//cx align with the UE index
- ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index
- (eNB_index * maxDRB) + DRB_config->drb_Identity,//rb
- 0,//dscp
- ipv4_address(ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1),//saddr
- ipv4_address(ip_addr_offset3+ue_mod_idP+1,eNB_index+1));//daddr
- LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index);
- }
-
-# endif
+ if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB
+ LOG_I(OIP,"[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n",
+ ue_mod_idP,
+ ip_addr_offset3+ue_mod_idP,
+ (long int)((eNB_index * LTE_maxDRB) + DRB_config->drb_Identity));
+ rb_conf_ipv4(0,//add
+ ue_mod_idP,//cx align with the UE index
+ ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index
+ (eNB_index * LTE_maxDRB) + DRB_config->drb_Identity,//rb
+ 0,//dscp
+ ipv4_address(ip_addr_offset3+ue_mod_idP+1,ip_addr_offset4+ue_mod_idP+1),//saddr
+ ipv4_address(ip_addr_offset3+ue_mod_idP+1,eNB_index+1));//daddr
+ LOG_D(RRC,"[UE %d] State = Attached (eNB %d)\n",ue_mod_idP,eNB_index);
}
+ //# endif
+ // }
return(0);
}
@@ -1930,7 +1929,7 @@ rrc_ue_process_rrcConnectionReconfiguration(
for (i=0; (
icriticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count)
- && (i < maxDRB); i++) {
+ && (i < LTE_maxDRB); i++) {
// why minus 1 in RRC code for drb_identity ?
connection_reestablishment_ind.drb_id[i] =
rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity;
@@ -2241,7 +2240,7 @@ rrc_ue_decode_dcch(
for (i=0; (
imessage.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count)
- && (i < maxDRB); i++) {
+ && (i < LTE_maxDRB); i++) {
// why minus 1 in RRC code for drb_identity ?
connection_reconfiguration_ho_ind.drb_id[i] =
dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity;
@@ -2295,7 +2294,7 @@ rrc_ue_decode_dcch(
for (i=0; (
imessage.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.count)
- && (i < maxDRB); i++) {
+ && (i < LTE_maxDRB); i++) {
// why minus 1 in RRC code for drb_identity ?
connection_reconfiguration_ind.drb_id[i] =
dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity;
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index 70d45944c1..e8df9782cb 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -344,7 +344,8 @@ typedef enum HO_STATE_e {
HO_COMPLETE, // initiated by the target eNB
HO_REQUEST,
HO_ACK,
- HO_CONFIGURED
+ HO_CONFIGURED,
+ HO_RELEASE
} HO_STATE_t;
typedef enum SL_TRIGGER_e {
@@ -451,12 +452,14 @@ typedef struct HANDOVER_INFO_s {
HO_STATE_t state; //current state of handover
uint32_t modid_s; //module_idP of serving cell
uint32_t modid_t; //module_idP of target cell
+ int assoc_id;
uint8_t ueid_s; //UE index in serving cell
uint8_t ueid_t; //UE index in target cell
LTE_AS_Config_t as_config; /* these two parameters are taken from 36.331 section 10.2.2: HandoverPreparationInformation-r8-IEs */
LTE_AS_Context_t as_context; /* They are mandatory for HO */
uint8_t buf[RRC_BUF_SIZE]; /* ASN.1 encoded handoverCommandMessage */
int size; /* size of above message in bytes */
+ int x2_id; /* X2AP UE ID in the target eNB */
} HANDOVER_INFO;
#define RRC_HEADER_SIZE_MAX 64
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 35046a4b36..85fdf8f4df 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -105,6 +105,9 @@ extern uint16_t two_tier_hexagonal_cellIds[7];
mui_t rrc_eNB_mui = 0;
extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw);
+extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, security_capabilities_t *security_capabilities_pP);
+extern void process_eNB_security_key (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP);
+extern int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, const bool is_rel8_only, uint8_t * kenb_star);
void
openair_rrc_on(
@@ -858,7 +861,8 @@ rrc_eNB_free_mem_UE_context(
ue_context_pP->ue_context.measGapConfig = NULL;
}*/
if (ue_context_pP->ue_context.handover_info) {
- ASN_STRUCT_FREE(asn_DEF_LTE_Handover, ue_context_pP->ue_context.handover_info);
+ /* TODO: be sure free is enough here (check memory leaks) */
+ free(ue_context_pP->ue_context.handover_info);
ue_context_pP->ue_context.handover_info = NULL;
}
@@ -922,34 +926,37 @@ rrc_eNB_free_UE(
}
if(EPC_MODE_ENABLED) {
- if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) {
- if (RC.rrc[enb_mod_idP]->node_type == ngran_eNB
- || RC.rrc[enb_mod_idP]->node_type == ngran_eNB_CU
- || RC.rrc[enb_mod_idP]->node_type == ngran_gNB_CU) {
- LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ RNTI %x\n", enb_mod_idP, rnti);
- rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(
- enb_mod_idP,
- ue_context_pP,
- S1AP_CAUSE_RADIO_NETWORK,
- 21); // send cause 21: connection with ue lost
+ if (RC.rrc[enb_mod_idP]->node_type == ngran_eNB
+ || RC.rrc[enb_mod_idP]->node_type == ngran_eNB_CU
+ || RC.rrc[enb_mod_idP]->node_type == ngran_gNB_CU) {
+ if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) {
+ LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n",
+ enb_mod_idP,
+ rnti);
+ rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP,
+ ue_context_pP,
+ S1AP_CAUSE_RADIO_NETWORK,
+ 21); // send cause 21: radio connection with ue lost
+ /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered)
+ * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before
+ * triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery
+ * procedure, see TS 23.401 [17].
+ */
+ return;
}
- /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered)
- * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before
- * triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery
- * procedure, see TS 23.401 [17].
- */
- return;
- }
- if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres) &&
- (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED) &&
- (RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres > 0)) {
- LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n",
- enb_mod_idP,
- rnti);
- rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 20);
- // send cause 20: user inactivity
- return;
+ if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres) &&
+ (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED) &&
+ (RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres > 0)) {
+ LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n",
+ enb_mod_idP,
+ rnti);
+ rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP,
+ ue_context_pP,
+ S1AP_CAUSE_RADIO_NETWORK,
+ 20); // send cause 20: user inactivity
+ return;
+ }
}
}
@@ -1132,7 +1139,9 @@ rrc_eNB_process_RRCConnectionSetupComplete(
if (EPC_MODE_ENABLED == 1) {
// Forward message to S1AP layer
+#if defined(ENABLE_USE_MME)
rrc_eNB_send_S1AP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcConnectionSetupComplete);
+#endif
} else {
// RRC loop back (no S1AP), send SecurityModeCommand to UE
rrc_eNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP);
@@ -3936,6 +3945,9 @@ rrc_eNB_process_MeasurementReport(
int neighboring_cells=-1;
int ncell_index = 0;
long ncell_max = -150;
+ uint32_t earfcn_dl;
+ uint8_t KeNB_star[32] = { 0 };
+
T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
@@ -4053,8 +4065,7 @@ rrc_eNB_process_MeasurementReport(
ue_context_pP,
X2AP_HANDOVER_REQ(msg).rrc_buffer,
&X2AP_HANDOVER_REQ(msg).rrc_buffer_size);
- X2AP_HANDOVER_REQ(msg).source_rnti = ctxt_pP->rnti;
- X2AP_HANDOVER_REQ(msg).old_eNB_ue_x2ap_id = 0;
+ X2AP_HANDOVER_REQ(msg).rnti = ctxt_pP->rnti;
X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice.
measResultListEUTRA.list.array[ncell_index]->physCellId;
X2AP_HANDOVER_REQ(msg).ue_gummei.mcc = ue_context_pP->ue_context.ue_gummei.mcc;
@@ -4065,9 +4076,11 @@ rrc_eNB_process_MeasurementReport(
// Don't know how to get this ID?
X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ue_context_pP->ue_context.mme_ue_s1ap_id;
X2AP_HANDOVER_REQ(msg).security_capabilities = ue_context_pP->ue_context.security_capabilities;
- memcpy (X2AP_HANDOVER_REQ(msg).kenb,
- ue_context_pP->ue_context.kenb,
- 32);
+ // compute keNB*
+ earfcn_dl = (uint32_t)to_earfcn_DL(RC.rrc[ctxt_pP->module_id]->carrier[0].eutra_band, RC.rrc[ctxt_pP->module_id]->carrier[0].dl_CarrierFreq,
+ RC.rrc[ctxt_pP->module_id]->carrier[0].N_RB_DL);
+ derive_keNB_star(ue_context_pP->ue_context.kenb, X2AP_HANDOVER_REQ(msg).target_physCellId, earfcn_dl, true, KeNB_star);
+ memcpy(X2AP_HANDOVER_REQ(msg).kenb, KeNB_star, 32);
X2AP_HANDOVER_REQ(msg).kenb_ncc = ue_context_pP->ue_context.kenb_ncc;
//X2AP_HANDOVER_REQ(msg).ue_ambr=ue_context_pP->ue_context.ue_ambr;
X2AP_HANDOVER_REQ(msg).nb_e_rabs_tobesetup = ue_context_pP->ue_context.setup_e_rabs;
@@ -4109,114 +4122,15 @@ rrc_eNB_generate_HandoverPreparationInformation(
*_size = ho_size;
}
-#if 0
-//-----------------------------------------------------------------------------
-void
-rrc_eNB_generate_HandoverPreparationInformation(
- const protocol_ctxt_t *const ctxt_pP,
- rrc_eNB_ue_context_t *const ue_context_pP,
- LTE_PhysCellId_t targetPhyId
-)
-//-----------------------------------------------------------------------------
-{
- struct rrc_eNB_ue_context_s *ue_context_target_p = NULL;
- //uint8_t UE_id_target = -1;
- uint8_t mod_id_target = get_adjacent_cell_mod_id(targetPhyId);
- HANDOVER_INFO *handoverInfo = CALLOC(1, sizeof(*handoverInfo));
- /*
- uint8_t buffer[100];
- uint8_t size;
- struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &RC.rrc[enb_mod_idP]->physicalConfigDedicated[ue_mod_idP];
- RadioResourceConfigDedicated_t *radioResourceConfigDedicated = CALLOC(1,sizeof(RadioResourceConfigDedicated_t));
- */
- T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
- T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
- handoverInfo->as_config.antennaInfoCommon.antennaPortsCount = 0; //Not used 0- but check value
- handoverInfo->as_config.sourceDl_CarrierFreq = 36090; //Verify!
- memcpy((void *)&handoverInfo->as_config.sourceMasterInformationBlock,
- (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.mib, sizeof(LTE_MasterInformationBlock_t));
- memcpy((void *)&handoverInfo->as_config.sourceMeasConfig,
- (void *)ue_context_pP->ue_context.measConfig, sizeof(LTE_MeasConfig_t));
- // FIXME handoverInfo not used...
- free( handoverInfo );
- handoverInfo = 0;
- //to be configured
- memset((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSecurityAlgorithmConfig,
- 0, sizeof(LTE_SecurityAlgorithmConfig_t));
- memcpy((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType1,
- (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB1, sizeof(LTE_SystemInformationBlockType1_t));
- memcpy((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType2,
- (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB23, sizeof(LTE_SystemInformationBlockType2_t));
- ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo =
- CALLOC(1, sizeof(LTE_ReestablishmentInfo_t));
- ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->sourcePhysCellId =
- RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.physCellId;
- ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.buf = NULL; // Check values later
- ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.size = 0;
- ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.bits_unused = 0;
- ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->additionalReestabInfoList = NULL;
- ue_context_pP->ue_context.handover_info->ho_prepare = 0xFF; //0xF0;
- ue_context_pP->ue_context.handover_info->ho_complete = 0;
-
- if (mod_id_target != 0xFF) {
- //UE_id_target = rrc_find_free_ue_index(modid_target);
- ue_context_target_p =
- rrc_eNB_get_ue_context(
- RC.rrc[mod_id_target],
- ue_context_pP->ue_context.rnti);
-
- /*UE_id_target = rrc_eNB_get_next_free_UE_index(
- mod_id_target,
- RC.rrc[ctxt_pP->module_id]->Info.UE_list[ue_mod_idP]); //this should return a new index*/
-
- if (ue_context_target_p == NULL) { // if not already in target cell
- ue_context_target_p = rrc_eNB_allocate_new_UE_context(RC.rrc[ctxt_pP->module_id]);
- ue_context_target_p->ue_id_rnti = ue_context_pP->ue_context.rnti; // LG: should not be the same
- ue_context_target_p->ue_context.rnti = ue_context_target_p->ue_id_rnti; // idem
- LOG_I(RRC,
- "[eNB %d] Frame %d : Emulate sending HandoverPreparationInformation msg from eNB source %d to eNB target %ld: source UE_id %x target UE_id %x source_modId: %d target_modId: %d\n",
- ctxt_pP->module_id,
- ctxt_pP->frame,
- RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.physCellId,
- targetPhyId,
- ue_context_pP->ue_context.rnti,
- ue_context_target_p->ue_id_rnti,
- ctxt_pP->module_id,
- mod_id_target);
- ue_context_target_p->ue_context.handover_info =
- CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info)));
- memcpy((void *)&ue_context_target_p->ue_context.handover_info->as_context,
- (void *)&ue_context_pP->ue_context.handover_info->as_context,
- sizeof(LTE_AS_Context_t));
- memcpy((void *)&ue_context_target_p->ue_context.handover_info->as_config,
- (void *)&ue_context_pP->ue_context.handover_info->as_config,
- sizeof(LTE_AS_Config_t));
- ue_context_target_p->ue_context.handover_info->ho_prepare = 0x00;// 0xFF;
- ue_context_target_p->ue_context.handover_info->ho_complete = 0;
- ue_context_pP->ue_context.handover_info->modid_t = mod_id_target;
- ue_context_pP->ue_context.handover_info->ueid_s = ue_context_pP->ue_context.rnti;
- ue_context_pP->ue_context.handover_info->modid_s = ctxt_pP->module_id;
- ue_context_target_p->ue_context.handover_info->modid_t = mod_id_target;
- ue_context_target_p->ue_context.handover_info->modid_s = ctxt_pP->module_id;
- ue_context_target_p->ue_context.handover_info->ueid_t = ue_context_target_p->ue_context.rnti;
- } else {
- LOG_E(RRC, "\nError in obtaining free UE id in target eNB %ld for handover \n", targetPhyId);
- }
- } else {
- LOG_E(RRC, "\nError in obtaining Module ID of target eNB for handover \n");
- }
-}
-#endif
-
void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m) {
struct rrc_eNB_ue_context_s *ue_context_target_p = NULL;
/* TODO: get proper UE rnti */
int rnti = taus() & 0xffff;
int i;
//global_rnti = rnti;
- //HandoverPreparationInformation_t *ho = NULL;
- //HandoverPreparationInformation_r8_IEs_t *ho_info;
- //asn_dec_rval_t dec_rval;
+ LTE_HandoverPreparationInformation_t *ho = NULL;
+ LTE_HandoverPreparationInformation_r8_IEs_t *ho_info;
+ asn_dec_rval_t dec_rval;
ue_context_target_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
if (ue_context_target_p != NULL) {
@@ -4236,30 +4150,30 @@ 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.handover_info->source_x2id = m->source_x2id;
ue_context_target_p->ue_context.Status = RRC_HO_EXECUTION;
ue_context_target_p->ue_context.handover_info->state = HO_ACK;
- /* TODO: remove this hack */
- //ue_context_target_p->ue_context.handover_info->modid_t = mod_id;
- ue_context_target_p->ue_context.handover_info->modid_t = m->target_mod_id;
- //ue_context_target_p->ue_context.handover_info->modid_s = 1-mod_id;
- //ue_context_target_p->ue_context.handover_info->ueid_s = m->source_rnti;
+ ue_context_target_p->ue_context.handover_info->x2_id = m->x2_id;
+ ue_context_target_p->ue_context.handover_info->assoc_id = m->target_assoc_id;
memset (ue_context_target_p->ue_context.nh, 0, 32);
ue_context_target_p->ue_context.nh_ncc = -1;
memcpy (ue_context_target_p->ue_context.kenb, m->kenb, 32);
ue_context_target_p->ue_context.kenb_ncc = m->kenb_ncc;
ue_context_target_p->ue_context.security_capabilities.encryption_algorithms = m->security_capabilities.encryption_algorithms;
ue_context_target_p->ue_context.security_capabilities.integrity_algorithms = m->security_capabilities.integrity_algorithms;
- /*
+
dec_rval = uper_decode(NULL,
- &asn_DEF_HandoverPreparationInformation,
+ &asn_DEF_LTE_HandoverPreparationInformation,
(void **)&ho,
m->rrc_buffer,
m->rrc_buffer_size, 0, 0);
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+ xer_fprint(stdout, &asn_DEF_LTE_HandoverPreparationInformation, ho);
+ }
+
if (dec_rval.code != RC_OK ||
- ho->criticalExtensions.present != HandoverPreparationInformation__criticalExtensions_PR_c1 ||
- ho->criticalExtensions.choice.c1.present != HandoverPreparationInformation__criticalExtensions__c1_PR_handoverPreparationInformation_r8) {
+ ho->criticalExtensions.present != LTE_HandoverPreparationInformation__criticalExtensions_PR_c1 ||
+ ho->criticalExtensions.choice.c1.present != LTE_HandoverPreparationInformation__criticalExtensions__c1_PR_handoverPreparationInformation_r8) {
LOG_E(RRC, "could not decode Handover Preparation\n");
abort();
}
@@ -4268,13 +4182,13 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re
if (ue_context_target_p->ue_context.UE_Capability) {
LOG_I(RRC, "freeing old UE capabilities for UE %x\n", rnti);
- ASN_STRUCT_FREE(asn_DEF_UE_EUTRA_Capability,
+ ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability,
ue_context_target_p->ue_context.UE_Capability);
ue_context_target_p->ue_context.UE_Capability = 0;
}
dec_rval = uper_decode(NULL,
- &asn_DEF_UE_EUTRA_Capability,
+ &asn_DEF_LTE_UE_EUTRA_Capability,
(void **)&ue_context_target_p->ue_context.UE_Capability,
ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.buf,
ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.size, 0, 0);
@@ -4282,16 +4196,16 @@ void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_re
ue_context_target_p->ue_context.UE_Capability_size = ho_info->ue_RadioAccessCapabilityInfo.list.array[0]->ueCapabilityRAT_Container.size;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
- xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, ue_context_target_p->ue_context.UE_Capability);
+ xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_target_p->ue_context.UE_Capability);
}
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
LOG_E(RRC, "Failed to decode UE capabilities (%zu bytes)\n", dec_rval.consumed);
- ASN_STRUCT_FREE(asn_DEF_UE_EUTRA_Capability,
+ ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability,
ue_context_target_p->ue_context.UE_Capability);
ue_context_target_p->ue_context.UE_Capability = 0;
}
- */
+
ue_context_target_p->ue_context.nb_of_e_rabs = m->nb_e_rabs_tobesetup;
ue_context_target_p->ue_context.setup_e_rabs = m->nb_e_rabs_tobesetup;
ue_context_target_p->ue_context.mme_ue_s1ap_id = m->mme_ue_s1ap_id;
@@ -4347,27 +4261,43 @@ void rrc_eNB_process_handoverCommand(
ue_context->ue_context.handover_info->size = size;
}
-#if 0
-//-----------------------------------------------------------------------------
-void
-rrc_eNB_process_handoverPreparationInformation(
- const protocol_ctxt_t *const ctxt_pP,
- rrc_eNB_ue_context_t *const ue_context_pP
-)
-//-----------------------------------------------------------------------------
-{
- T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
- T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
- LOG_I(RRC,
- "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending LTE_RRCConnectionReconfiguration to UE %d \n",
- ctxt_pP->module_id, ctxt_pP->frame, ue_context_pP->ue_context.rnti);
- rrc_eNB_generate_RRCConnectionReconfiguration_handover(
- ctxt_pP,
- ue_context_pP,
- NULL,
- 0);
+#if defined(ENABLE_USE_MME)
+void rrc_eNB_handover_ue_context_release(
+protocol_ctxt_t *const ctxt_pP,
+struct rrc_eNB_ue_context_s *ue_context_p) {
+ int e_rab = 0;
+ //MessageDef *msg_release_p = NULL;
+ MessageDef *msg_delete_tunnels_p = NULL;
+ uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;
+
+ //msg_release_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE);
+ //itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_release_p);
+ s1ap_ue_context_release(ctxt_pP->instance, ue_context_p->ue_context.eNB_ue_s1ap_id);
+
+ //MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id);
+ msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
+ memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
+
+ GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
+
+ for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
+ GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
+ ue_context_p->ue_context.enb_gtp_ebi[e_rab];
+ // erase data
+ ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
+ memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
+ ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
+ }
+
+ itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
+ struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
+ rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id);
+
+ if (rrc_ue_s1ap_ids != NULL) {
+ rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids);
+ }
}
-#endif
+#endif /* defined(ENABLE_USE_MME) */
void
check_handovers(
@@ -4375,7 +4305,6 @@ check_handovers(
)
//-----------------------------------------------------------------------------
{
- int result;
struct rrc_eNB_ue_context_s *ue_context_p;
RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
ctxt_pP->rnti = ue_context_p->ue_id_rnti;
@@ -4392,19 +4321,15 @@ check_handovers(
LOG_I(RRC,
"[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending RRCConnectionReconfiguration to UE %d \n",
ctxt_pP->module_id, ctxt_pP->frame, ue_context_p->ue_context.rnti);
- result = pdcp_data_req(ctxt_pP,
- SRB_FLAG_YES,
+ rrc_data_req(
+ ctxt_pP,
DCCH,
rrc_eNB_mui++,
SDU_CONFIRM_NO,
ue_context_p->ue_context.handover_info->size,
ue_context_p->ue_context.handover_info->buf,
- PDCP_TRANSMISSION_MODE_CONTROL
-#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
- ,NULL, NULL
-#endif
- );
- AssertFatal(result == TRUE, "PDCP data request failed!\n");
+ PDCP_TRANSMISSION_MODE_CONTROL);
+
ue_context_p->ue_context.handover_info->state = HO_COMPLETE;
LOG_I(RRC, "RRC Sends RRCConnectionReconfiguration to UE %d at frame %d and subframe %d \n", ue_context_p->ue_context.rnti, ctxt_pP->frame,ctxt_pP->subframe);
}
@@ -4418,10 +4343,10 @@ check_handovers(
rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p, X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer,
&X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size);
rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP);
- /* TODO: remove this hack */
- //X2AP_HANDOVER_REQ_ACK(msg).target_mod_id = 1 - ctxt_pP->module_id;
- X2AP_HANDOVER_REQ_ACK(msg).target_mod_id = ue_context_p->ue_context.handover_info->modid_t;
- //X2AP_HANDOVER_REQ_ACK(msg).source_x2id = ue_context_p->ue_context.handover_info->source_x2id;
+
+ X2AP_HANDOVER_REQ_ACK(msg).rnti = ue_context_p->ue_context.rnti;
+ X2AP_HANDOVER_REQ_ACK(msg).x2_id_target = ue_context_p->ue_context.handover_info->x2_id;
+ X2AP_HANDOVER_REQ_ACK(msg).source_assoc_id = ue_context_p->ue_context.handover_info->assoc_id;
/* Call admission control not implemented yet */
X2AP_HANDOVER_REQ_ACK(msg).nb_e_rabs_tobesetup = ue_context_p->ue_context.setup_e_rabs;
@@ -4436,70 +4361,6 @@ check_handovers(
}
}
-#if 0
-//-----------------------------------------------------------------------------
-void
-check_handovers(
- protocol_ctxt_t *const ctxt_pP
-)
-//-----------------------------------------------------------------------------
-{
- int result;
- struct rrc_eNB_ue_context_s *ue_context_p;
- RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head) {
- ctxt_pP->rnti = ue_context_p->ue_id_rnti;
-
- if (ue_context_p->ue_context.handover_info != NULL) {
- if (ue_context_p->ue_context.handover_info->ho_prepare == 0xFF) {
- LOG_D(RRC,
- "[eNB %d] Frame %d: Incoming handover detected for new UE_idx %d (source eNB %d->target eNB %d) \n",
- ctxt_pP->module_id,
- ctxt_pP->frame,
- ctxt_pP->rnti,
- ctxt_pP->module_id,
- ue_context_p->ue_context.handover_info->modid_t);
- // source eNB generates LTE_RRCConnectionreconfiguration to prepare the HO
- rrc_eNB_process_handoverPreparationInformation(
- ctxt_pP,
- ue_context_p);
- ue_context_p->ue_context.handover_info->ho_prepare = 0xF1;
- }
-
- if (ue_context_p->ue_context.handover_info->ho_complete == 0xF1) {
- LOG_D(RRC,
- "[eNB %d] Frame %d: handover Command received for new UE_id %x current eNB %d target eNB: %d \n",
- ctxt_pP->module_id,
- ctxt_pP->frame,
- ctxt_pP->rnti,
- ctxt_pP->module_id,
- ue_context_p->ue_context.handover_info->modid_t);
- //rrc_eNB_process_handoverPreparationInformation(enb_mod_idP,frameP,i);
- result = pdcp_data_req(ctxt_pP,
- SRB_FLAG_YES,
- DCCH,
- rrc_eNB_mui++,
- SDU_CONFIRM_NO,
- ue_context_p->ue_context.handover_info->size,
- ue_context_p->ue_context.handover_info->buf,
- PDCP_TRANSMISSION_MODE_CONTROL
-#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
- ,NULL, NULL
-#endif
- );
-
- //AssertFatal(result == TRUE, "PDCP data request failed!\n");
- if(result != TRUE) {
- LOG_I(RRC, "PDCP data request failed!\n");
- return;
- }
-
- ue_context_p->ue_context.handover_info->ho_complete = 0xF2;
- }
- }
- }
-}
-#endif
-
void
rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP,
rrc_eNB_ue_context_t *const ue_context_pP,
@@ -5446,6 +5307,21 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc
, 0, 0
#endif
);
+#if defined(ENABLE_USE_MME)
+ rrc_eNB_process_security (
+ ctxt_pP,
+ ue_context_p,
+ &ue_context_p->ue_context.security_capabilities);
+ process_eNB_security_key (
+ ctxt_pP,
+ ue_context_p,
+ ue_context_p->ue_context.kenb);
+ rrc_pdcp_config_security(
+ ctxt_pP,
+ ue_context_p,
+ FALSE);
+#endif
+
// Add a new user (called during the HO procedure)
LOG_I(RRC, "rrc_eNB_target_add_ue_handover module_id %d rnti %d\n", ctxt_pP->module_id, ctxt_pP->rnti);
// Configure MAC for the target
@@ -6296,9 +6172,6 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
int i, drb_id;
int oip_ifup = 0;
int dest_ip_offset = 0;
- /* avoid gcc warnings */
- (void)oip_ifup;
- (void)dest_ip_offset;
uint8_t *kRRCenc = NULL;
uint8_t *kRRCint = NULL;
uint8_t *kUPenc = NULL;
@@ -6423,16 +6296,15 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
"[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n",
ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity);
- if (PDCP_USE_NETLINK && (!LINK_ENB_PDCP_TO_GTPV1U)) {
- // can mean also IPV6 since ether -> ipv6 autoconf
-# if !defined(OAI_NW_DRIVER_TYPE_ETHERNET) && !defined(EXMIMO) && !defined(OAI_USRP) && !defined(OAI_BLADERF) && !defined(ETHERNET)
+ if (!EPC_MODE_ENABLED && !ENB_NAS_USE_TUN) {
LOG_I(OIP, "[eNB %d] trying to bring up the OAI interface oai%d\n",
ctxt_pP->module_id,
ctxt_pP->module_id);
oip_ifup = nas_config(
ctxt_pP->module_id, // interface index
- ctxtReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA_pP->module_id + 1, // thrid octet
- ctxt_pP->module_id + 1); // fourth octet
+ ctxt_pP->module_id + 1, // thrid octet
+ ctxt_pP->module_id + 1, // fourth octet
+ "oai");
if (oip_ifup == 0) { // interface is up --> send a config the DRB
module_id_t ue_module_id;
@@ -6440,21 +6312,19 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
LOG_I(OIP,
"[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n",
ctxt_pP->module_id, ctxt_pP->module_id,
- (long int)((ue_context_pP->local_uid * maxDRB) + DRB_configList->list.array[i]->drb_Identity));
+ (long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity));
ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid];
rb_conf_ipv4(0, //add
ue_module_id, //cx
ctxt_pP->module_id, //inst
- (ue_module_id * maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB
+ (ue_module_id * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity, // RB
0, //dscp
ipv4_address(ctxt_pP->module_id + 1, ctxt_pP->module_id + 1), //saddr
ipv4_address(ctxt_pP->module_id + 1, dest_ip_offset + ue_module_id + 1)); //daddr
LOG_D(RRC, "[eNB %d] State = Attached (UE rnti %x module id %u)\n",
ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ue_module_id);
- }
-
-# endif
- }
+ } /* oip_ifup */
+ } /* !EPC_MODE_ENABLED && ENB_NAS_USE_TUN*/
LOG_D(RRC,
PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n",
@@ -7972,9 +7842,11 @@ rrc_eNB_decode_dcch(
if (EPC_MODE_ENABLED) {
if (EPC_MODE_ENABLED == 1) {
+#if defined(ENABLE_USE_MME)
rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP,
ue_context_p,
ul_dcch_msg);
+#endif
}
} else {
ue_context_p->ue_context.nb_of_e_rabs = 1;
@@ -8022,9 +7894,11 @@ rrc_eNB_decode_dcch(
sdu_sizeP);
if (EPC_MODE_ENABLED == 1) {
+#if defined(ENABLE_USE_MME)
rrc_eNB_send_S1AP_UPLINK_NAS(ctxt_pP,
ue_context_p,
ul_dcch_msg);
+#endif
}
break;
@@ -8274,19 +8148,270 @@ void rrc_enb_init(void) {
memset(&rrc_release_info,0,sizeof(RRC_release_list_t));
}
+//-----------------------------------------------------------------------------
+void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id)
+{
+ int32_t current_timestamp_ms = 0;
+ int32_t ref_timestamp_ms = 0;
+ struct timeval ts;
+ struct rrc_eNB_ue_context_s *ue_context_p = NULL;
+ struct rrc_eNB_ue_context_s *ue_to_be_removed = NULL;
+#ifdef LOCALIZATION
+ double estimated_distance = 0;
+ protocol_ctxt_t ctxt;
+#endif
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN);
+ check_handovers(ctxt_pP); // counter, get the value and aggregate
+ // check for UL failure or for UE to be released
+ RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
+ ctxt_pP->rnti = ue_context_p->ue_id_rnti;
+
+ if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) {
+ if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
+ LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n",
+ ue_context_p->ue_context.rnti,
+ ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
+ ue_context_p->ue_context.ul_failure_timer);
+ } else {
+ LOG_I(RRC, "UE rnti %x failure timer %d/8\n",
+ ue_context_p->ue_context.rnti,
+ ue_context_p->ue_context.ul_failure_timer);
+ }
+ }
+
+ if (ue_context_p->ue_context.ul_failure_timer > 0) {
+ ue_context_p->ue_context.ul_failure_timer++;
+
+ if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
+ // remove UE after 20 seconds after MAC (or else) has indicated UL failure
+ LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n",
+ ue_context_p->ue_context.rnti);
+ ue_to_be_removed = ue_context_p;
+ break; // break RB_FOREACH
+ }
+ }
+
+ if (ue_context_p->ue_context.ue_release_timer_s1 > 0) {
+ ue_context_p->ue_context.ue_release_timer_s1++;
+
+ if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) {
+ LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n",
+ ue_context_p->ue_context.rnti,
+ ue_context_p->ue_context.ue_release_timer_thres_s1);
+
+ if (EPC_MODE_ENABLED)
+ rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p);
+ else
+ ue_to_be_removed = ue_context_p;
+
+ ue_context_p->ue_context.ue_release_timer_s1 = 0;
+ break; // break RB_FOREACH
+ } // end if timer_s1 timeout
+ } // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing)
+
+ if (ue_context_p->ue_context.ue_release_timer_rrc > 0) {
+ ue_context_p->ue_context.ue_release_timer_rrc++;
+
+ if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) {
+ LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n",
+ ue_context_p->ue_context.rnti);
+ ue_context_p->ue_context.ue_release_timer_rrc = 0;
+ ue_to_be_removed = ue_context_p;
+ break; // break RB_FOREACH
+ }
+ }
+
+#if defined(ENABLE_USE_MME)
+ if (ue_context_p->ue_context.handover_info != NULL) {
+ if (ue_context_p->ue_context.handover_info->state == HO_RELEASE) {
+ ue_to_be_removed = ue_context_p;
+ rrc_eNB_handover_ue_context_release(ctxt_pP, ue_context_p);
+ break; //break RB_FOREACH (why to break ?)
+ }
+ }
+#endif
+
+ pthread_mutex_lock(&rrc_release_freelist);
+
+ if (rrc_release_info.num_UEs > 0) {
+ uint16_t release_total = 0;
+
+ for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
+ if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) {
+ release_total++;
+ }
+
+ if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) &&
+ (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) {
+ ue_context_p->ue_context.ue_release_timer_rrc = 1;
+ ue_context_p->ue_context.ue_release_timer_thres_rrc = 100;
+
+ if (EPC_MODE_ENABLED) {
+ int e_rab = 0;
+ MessageDef *msg_complete_p = NULL;
+ MessageDef *msg_delete_tunnels_p = NULL;
+ uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;
+
+ if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0
+ MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0,
+ "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
+ eNB_ue_s1ap_id);
+ msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
+ S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
+ itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p);
+ }
+
+ MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id);
+ msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
+ memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
+ // do not wait response
+ GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
+
+ for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
+ GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
+ ue_context_p->ue_context.enb_gtp_ebi[e_rab];
+ // erase data
+ ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
+ memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
+ ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
+ }
+
+ itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
+ struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
+ rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id);
+
+ if (rrc_ue_s1ap_ids != NULL) {
+ rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids);
+ }
+ } /* EPC_MODE_ENABLED */
+
+ rrc_release_info.RRC_release_ctrl[release_num].flag = 0;
+ rrc_release_info.num_UEs--;
+ break; // break for (release_num)
+ } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ...
+
+ if (release_total >= rrc_release_info.num_UEs) {
+ break; // break for (release_num)
+ }
+ } // end for (release_num)
+ } // end if (rrc_release_info.num_UEs > 0)
+
+ pthread_mutex_unlock(&rrc_release_freelist);
+
+ if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) {
+ ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer
+
+ if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) {
+ LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n",
+ ue_context_p->ue_context.rnti);
+ ue_to_be_removed = ue_context_p;
+ break; // break RB_FOREACH
+ }
+ }
+
+ if (ue_context_p->ue_context.ue_reestablishment_timer > 0) {
+ ue_context_p->ue_context.ue_reestablishment_timer++;
+
+ if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) {
+ LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n",
+ ue_context_p->ue_context.rnti);
+ ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ
+ ue_to_be_removed = ue_context_p;
+ ue_context_p->ue_context.ue_reestablishment_timer = 0;
+ break; // break RB_FOREACH
+ }
+ }
+
+ if (ue_context_p->ue_context.ue_release_timer > 0) {
+ ue_context_p->ue_context.ue_release_timer++;
+
+ if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) {
+ LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n",
+ ue_context_p->ue_context.rnti);
+ /*
+ * TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent.
+ * It is no more the case.
+ * The timer should be renamed.
+ */
+ ue_to_be_removed = ue_context_p;
+ ue_context_p->ue_context.ue_release_timer = 0;
+ break; // break RB_FOREACH
+ }
+ }
+ } // end RB_FOREACH
+
+ if (ue_to_be_removed) {
+ if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) ||
+ ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) &&
+ (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) {
+ ue_to_be_removed->ue_context.ue_release_timer_s1 = 1;
+ ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100;
+ ue_to_be_removed->ue_context.ue_release_timer = 0;
+ ue_to_be_removed->ue_context.ue_reestablishment_timer = 0;
+ }
+
+ rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed);
+
+ if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) {
+ ue_to_be_removed->ue_context.ul_failure_timer = 0;
+ }
+
+ if ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) &&
+ (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) {
+ ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent
+ }
+ }
+
+#ifdef RRC_LOCALIZATION
+ /* for the localization, only primary CC_id might be relevant*/
+ gettimeofday(&ts, NULL);
+ current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000;
+ ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms;
+ RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
+ ctxt = *ctxt_pP;
+ ctxt.rnti = ue_context_p->ue_context.rnti;
+ estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type);
+
+ if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) &&
+ estimated_distance != -1) {
+ LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n",
+ ctxt.rnti,
+ ctxt_pP->module_id,
+ current_timestamp_ms,
+ ctxt_pP->frame,
+ estimated_distance);
+ LOG_D(LOCALIZE, "RRC status %d\n",
+ ue_context_p->ue_context.Status);
+ push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance);
+ RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms;
+ } // end if
+ } // end RB_FOREACH
+#endif
+ (void)ts; /* remove gcc warning "unused variable" */
+ (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */
+ (void)current_timestamp_ms; /* remove gcc warning "unused variable" */
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT);
+}
+
//-----------------------------------------------------------------------------
void *rrc_enb_process_itti_msg(void *notUsed) {
MessageDef *msg_p;
const char *msg_name_p;
instance_t instance;
- int rrc_inst;
int result;
+ SRB_INFO *srb_info_p;
+ int CC_id;
protocol_ctxt_t ctxt;
+
+ memset(&ctxt, 0, sizeof(ctxt));
+
// Wait for a message
itti_receive_msg(TASK_RRC_ENB, &msg_p);
msg_name_p = ITTI_MSG_NAME(msg_p);
instance = ITTI_MSG_INSTANCE(msg_p);
- LOG_I(RRC,"Received message %s\n",msg_name_p);
+ /* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */
+ if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS)
+ LOG_I(RRC,"Received message %s\n",msg_name_p);
switch (ITTI_MSG_ID(msg_p)) {
case TERMINATE_MESSAGE:
@@ -8300,16 +8425,16 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
/* Messages from MAC */
case RRC_MAC_CCCH_DATA_IND:
-
- rrc_inst = RRC_MAC_CCCH_DATA_IND(msg_p).enb_index;
-
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
- rrc_inst,
+ RRC_MAC_CCCH_DATA_IND(msg_p).enb_index,
ENB_FLAG_YES,
RRC_MAC_CCCH_DATA_IND(msg_p).rnti,
msg_p->ittiMsgHeader.lte_time.frame,
msg_p->ittiMsgHeader.lte_time.slot);
+ LOG_I(RRC,"Decoding CCCH : inst %d, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n",
+ instance,CC_id,&ctxt, RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
+
if (RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= RRC_BUFFER_SIZE_MAX) {
LOG_I(RRC, "CCCH message has size %d > %d\n",
RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,RRC_BUFFER_SIZE_MAX);
@@ -8322,6 +8447,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
RRC_MAC_CCCH_DATA_IND(msg_p).CC_id);
break;
+
/* Messages from PDCP */
case RRC_DCCH_DATA_IND:
PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt,
@@ -8387,18 +8513,17 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND(msg_p, msg_name_p, instance);
break;
- case GTPV1U_ENB_DELETE_TUNNEL_RESP:
+ case GTPV1U_ENB_DELETE_TUNNEL_RESP: {
+ rrc_eNB_ue_context_t *ue = rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti);
- /* Nothing to do. Apparently everything is done in S1AP processing */
- //LOG_I(RRC, "[eNB %d] Received message %s, not processed because procedure not synched\n",
- //instance, msg_name_p);
- if (rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)
- && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0) {
- rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc =
- rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_thres_rrc;
+ if (ue != NULL
+ && ue->ue_context.ue_release_timer_rrc > 0
+ && (ue->ue_context.handover_info == NULL || ue->ue_context.handover_info->state != HO_RELEASE)) {
+ ue->ue_context.ue_release_timer_rrc = ue->ue_context.ue_release_timer_thres_rrc;
}
break;
+ }
case S1AP_PATH_SWITCH_REQ_ACK:
LOG_I(RRC, "[eNB %d] received path switch ack %s\n", instance, msg_name_p);
@@ -8406,16 +8531,20 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
break;
case X2AP_HANDOVER_REQ:
- LOG_I(RRC, "[eNB %d] target eNB Receives X2 HO Req %s at frame %d subframe %d\n", instance, msg_name_p,
- ctxt.frame, ctxt.subframe);
+ LOG_I(RRC, "[eNB %d] target eNB Receives X2 HO Req %s\n", instance, msg_name_p);
rrc_eNB_process_handoverPreparationInformation(instance, &X2AP_HANDOVER_REQ(msg_p));
break;
case X2AP_HANDOVER_REQ_ACK: {
struct rrc_eNB_ue_context_s *ue_context_p = NULL;
- ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], ctxt.rnti);
- LOG_I(RRC, "[eNB %d] source eNB receives the X2 HO ACK %s at frame %d subframe %d \n", instance, msg_name_p,
- ctxt.frame,ctxt.subframe);
+ ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_HANDOVER_REQ_ACK(msg_p).rnti);
+ if (ue_context_p == NULL) {
+ /* is it possible? */
+ LOG_E(RRC, "could not find UE (rnti %x) while processing X2AP_HANDOVER_REQ_ACK\n",
+ X2AP_HANDOVER_REQ_ACK(msg_p).rnti);
+ exit(1);
+ }
+ LOG_I(RRC, "[eNB %d] source eNB receives the X2 HO ACK %s\n", instance, msg_name_p);
DevAssert(ue_context_p != NULL);
if (ue_context_p->ue_context.handover_info->state != HO_REQUEST) abort();
@@ -8425,21 +8554,36 @@ void *rrc_enb_process_itti_msg(void *notUsed) {
break;
}
+ case X2AP_UE_CONTEXT_RELEASE: {
+ struct rrc_eNB_ue_context_s *ue_context_p = NULL;
+ ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_UE_CONTEXT_RELEASE(msg_p).rnti);
+ LOG_I(RRC, "[eNB %d] source eNB receives the X2 UE CONTEXT RELEASE %s\n", instance, msg_name_p);
+ DevAssert(ue_context_p != NULL);
+
+ if (ue_context_p->ue_context.handover_info->state != HO_COMPLETE) abort();
+
+ ue_context_p->ue_context.handover_info->state = HO_RELEASE;
+ break;
+ }
+
/* Messages from eNB app */
case RRC_CONFIGURATION_REQ:
LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p));
openair_rrc_eNB_configuration(ENB_INSTANCE_TO_MODULE_ID(instance), &RRC_CONFIGURATION_REQ(msg_p));
break;
- /* Messages from F1AP task */
+
+ /* Messages from F1AP task */
case F1AP_SETUP_REQ:
AssertFatal(RC.rrc[0]->node_type == ngran_eNB_CU || RC.rrc[0]->node_type == ngran_ng_eNB_CU,
"should not receive F1AP_SETUP_REQUEST, need call by CU!\n");
LOG_I(RRC,"[eNB %d] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p));
-
-
handle_f1_setup_req(&F1AP_SETUP_REQ(msg_p));
-
break;
+
+ case RRC_SUBFRAME_PROCESS:
+ rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id);
+ break;
+
default:
LOG_E(RRC, "[eNB %d] Received unexpected message %s\n", instance, msg_name_p);
break;
@@ -8815,222 +8959,10 @@ rrc_rx_tx(
)
//-----------------------------------------------------------------------------
{
- int32_t current_timestamp_ms = 0;
- int32_t ref_timestamp_ms = 0;
- struct timeval ts;
- struct rrc_eNB_ue_context_s *ue_context_p = NULL;
- struct rrc_eNB_ue_context_s *ue_to_be_removed = NULL;
-#ifdef LOCALIZATION
- double estimated_distance = 0;
- protocol_ctxt_t ctxt;
-#endif
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN);
- check_handovers(ctxt_pP); // counter, get the value and aggregate
- // check for UL failure or for UE to be released
- RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
- ctxt_pP->rnti = ue_context_p->ue_id_rnti;
-
- if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) {
- if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
- LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n",
- ue_context_p->ue_context.rnti,
- ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
- ue_context_p->ue_context.ul_failure_timer);
- } else {
- LOG_I(RRC, "UE rnti %x failure timer %d/8\n",
- ue_context_p->ue_context.rnti,
- ue_context_p->ue_context.ul_failure_timer);
- }
- }
-
- if (ue_context_p->ue_context.ul_failure_timer > 0) {
- ue_context_p->ue_context.ul_failure_timer++;
-
- if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
- // remove UE after 20 seconds after MAC (or else) has indicated UL failure
- LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n",
- ue_context_p->ue_context.rnti);
- ue_to_be_removed = ue_context_p;
- break; // break RB_FOREACH
- }
- }
-
- if (ue_context_p->ue_context.ue_release_timer_s1 > 0) {
- ue_context_p->ue_context.ue_release_timer_s1++;
-
- if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) {
- LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n",
- ue_context_p->ue_context.rnti,
- ue_context_p->ue_context.ue_release_timer_thres_s1);
-
- if (EPC_MODE_ENABLED && RC.rrc[ctxt_pP->module_id]->node_type != ngran_eNB_DU)
- rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p);
- else
- ue_to_be_removed = ue_context_p;
-
- ue_context_p->ue_context.ue_release_timer_s1 = 0;
- break; // break RB_FOREACH
- } // end if timer_s1 timeout
- } // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing)
-
- if (ue_context_p->ue_context.ue_release_timer_rrc > 0) {
- ue_context_p->ue_context.ue_release_timer_rrc++;
-
- if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) {
- LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n",
- ue_context_p->ue_context.rnti);
- ue_context_p->ue_context.ue_release_timer_rrc = 0;
- ue_to_be_removed = ue_context_p;
- break; // break RB_FOREACH
- }
- }
-
- pthread_mutex_lock(&rrc_release_freelist);
-
- if (rrc_release_info.num_UEs > 0) {
- uint16_t release_total = 0;
-
- for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) {
- if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) {
- release_total++;
- }
-
- if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) &&
- (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) {
- ue_context_p->ue_context.ue_release_timer_rrc = 1;
- ue_context_p->ue_context.ue_release_timer_thres_rrc = 100;
-
- if (EPC_MODE_ENABLED && RC.rrc[ctxt_pP->module_id]->node_type != ngran_eNB_DU) {
- if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0
- rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(ctxt_pP->module_id,
- ue_context_p->ue_context.eNB_ue_s1ap_id);
- }
-
- rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(ctxt_pP->module_id,
- ue_context_p);
- // erase data of GTP tunnels in UE context
- for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
- ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
- memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab],
- 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
- ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
- }
-
- struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
- rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0,
- ue_context_p->ue_context.eNB_ue_s1ap_id);
-
- if (rrc_ue_s1ap_ids != NULL) {
- rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids);
- }
- } /* EPC_MODE_ENABLED && node_type != ngran_eNB_DU */
-
- rrc_release_info.RRC_release_ctrl[release_num].flag = 0;
- rrc_release_info.num_UEs--;
- break; // break for (release_num)
- } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ...
-
- if (release_total >= rrc_release_info.num_UEs) {
- break; // break for (release_num)
- }
- } // end for (release_num)
- } // end if (rrc_release_info.num_UEs > 0)
-
- pthread_mutex_unlock(&rrc_release_freelist);
-
- if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) {
- ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer
-
- if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) {
- LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n",
- ue_context_p->ue_context.rnti);
- ue_to_be_removed = ue_context_p;
- break; // break RB_FOREACH
- }
- }
-
- if (ue_context_p->ue_context.ue_reestablishment_timer > 0) {
- ue_context_p->ue_context.ue_reestablishment_timer++;
-
- if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) {
- LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n",
- ue_context_p->ue_context.rnti);
- ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ
- ue_to_be_removed = ue_context_p;
- ue_context_p->ue_context.ue_reestablishment_timer = 0;
- break; // break RB_FOREACH
- }
- }
-
- if (ue_context_p->ue_context.ue_release_timer > 0) {
- ue_context_p->ue_context.ue_release_timer++;
-
- if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) {
- LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n",
- ue_context_p->ue_context.rnti);
- /*
- * TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent.
- * It is no more the case.
- * The timer should be renamed.
- */
- ue_to_be_removed = ue_context_p;
- ue_context_p->ue_context.ue_release_timer = 0;
- break; // break RB_FOREACH
- }
- }
- } // end RB_FOREACH
-
- if (ue_to_be_removed) {
- if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) ||
- ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) &&
- (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) {
- ue_to_be_removed->ue_context.ue_release_timer_s1 = 1;
- ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100;
- ue_to_be_removed->ue_context.ue_release_timer = 0;
- ue_to_be_removed->ue_context.ue_reestablishment_timer = 0;
- }
-
- rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed);
-
- if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) {
- ue_to_be_removed->ue_context.ul_failure_timer = 0;
- }
-
- if ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) &&
- (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) {
- ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent
- }
- }
-
-#ifdef RRC_LOCALIZATION
- /* for the localization, only primary CC_id might be relevant*/
- gettimeofday(&ts, NULL);
- current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000;
- ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms;
- RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
- ctxt = *ctxt_pP;
- ctxt.rnti = ue_context_p->ue_context.rnti;
- estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type);
-
- if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) &&
- estimated_distance != -1) {
- LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n",
- ctxt.rnti,
- ctxt_pP->module_id,
- current_timestamp_ms,
- ctxt_pP->frame,
- estimated_distance);
- LOG_D(LOCALIZE, "RRC status %d\n",
- ue_context_p->ue_context.Status);
- push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance);
- RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms;
- } // end if
- } // end RB_FOREACH
-#endif
- (void)ts; /* remove gcc warning "unused variable" */
- (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */
- (void)current_timestamp_ms; /* remove gcc warning "unused variable" */
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT);
+ MessageDef *message_p;
+ message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_SUBFRAME_PROCESS);
+ RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt_pP;
+ RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id;
+ itti_send_msg_to_task(TASK_RRC_ENB, ctxt_pP->module_id, message_p);
return RRC_OK;
}
-
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index 233529d59e..b26e2c1cb0 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -426,7 +426,7 @@ static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_inte
*\param security_capabilities The security capabilities received from S1AP.
*\return TRUE if at least one algorithm has been changed else FALSE.
*/
-static int
+int
rrc_eNB_process_security(
const protocol_ctxt_t *const ctxt_pP,
rrc_eNB_ue_context_t *const ue_context_pP,
@@ -477,7 +477,7 @@ rrc_eNB_process_security(
*\param security_key_pP The security key received from S1AP.
*/
//------------------------------------------------------------------------------
-static void process_eNB_security_key (
+void process_eNB_security_key (
const protocol_ctxt_t *const ctxt_pP,
rrc_eNB_ue_context_t *const ue_context_pP,
uint8_t *security_key_pP
@@ -2001,7 +2001,7 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr = create_tunnel_resp.enb_addr;
LOG_I (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d): nb_of_e_rabs %d, e_rab_id %d, teid: %u, addr: %d.%d.%d.%d \n ",
e_rabs_done, e_rab, ue_context_pP->ue_context.e_rab[inde_list[e_rab]].status,
- ue_context_pP->ue_context.nb_of_e_rabs,
+ S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs,
S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].e_rab_id,
S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].gtp_teid,
S1AP_PATH_SWITCH_REQ (msg_p).e_rabs_tobeswitched[e_rab].eNB_addr.buffer[0],
@@ -2013,7 +2013,7 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
// NN: add conditions for e_rabs_failed
if (e_rabs_done > 0) {
LOG_I(RRC,"S1AP_PATH_SWITCH_REQ: sending the message: nb_of_erabstobeswitched %d, total e_rabs %d, index %d\n",
- ue_context_pP->ue_context.nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab);
+ S1AP_PATH_SWITCH_REQ (msg_p).nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab);
MSC_LOG_TX_MESSAGE(
MSC_RRC_ENB,
MSC_S1AP_ENB,
@@ -2060,46 +2060,64 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg
ue_context_p->ue_context.mme_ue_s1ap_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).mme_ue_s1ap_id;
/* Save e RAB information for later */
{
+ ue_context_p->ue_context.nb_release_of_e_rabs = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobereleased;
+
for (i = 0;
i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg
i++) {
// assume that we are releasing all the DRBs
- ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE;
+ ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_REESTABLISHED;
+ if (ue_context_p->ue_context.nb_release_of_e_rabs==0) {
+ LOG_I(RRC,"Bearer re-established with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
+ }
}
//memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req));
- //uint8_t nb_e_rabs_tobeswitched = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobeswitched;
+ uint8_t nb_e_rabs_tobeswitched = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobeswitched;
// keep the previous bearer
// the index for the rec
+ if (nb_e_rabs_tobeswitched>0) {
+ int e_rab_switch_index=0;
for (i = 0;
- i < 1;//nb_e_rabs_tobeswitched; // go over total number of e_rabs received through x2_ho_req msg
+ i < ue_context_p->ue_context.setup_e_rabs; // go over total number of e_rabs received through x2_ho_req msg
i++) {
- LOG_I(RRC,"Bearer re-established with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
/* Harmonize with enb_gtp_teid, enb_gtp_addrs, and enb_gtp_rbi vars in the top level structure */
- ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_REESTABLISHED;
- //ue_context_p->ue_context.e_rab[i].param.e_rab_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[i].e_rab_id;
- //ue_context_p->ue_context.e_rab[i].param.sgw_addr= S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[i].sgw_addr;
- //ue_context_p->ue_context.e_rab[i].param.gtp_teid = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[i].gtp_teid;
- /* Tunnel must have been already created in X2_HO_REQ procedure */
+ if (ue_context_p->ue_context.e_rab[i].param.e_rab_id == S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].e_rab_id) {
+ ue_context_p->ue_context.e_rab[i].param.e_rab_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].e_rab_id;
+ ue_context_p->ue_context.e_rab[i].param.sgw_addr= S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].sgw_addr;
+ ue_context_p->ue_context.e_rab[i].param.gtp_teid = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobeswitched[e_rab_switch_index].gtp_teid;
+ e_rab_switch_index++;
+ }
+ }
}
-
- ue_context_p->ue_context.setup_e_rabs=i;
- ue_context_p->ue_context.nb_of_e_rabs=i;
}
ue_context_p->ue_context.ue_ambr=S1AP_PATH_SWITCH_REQ_ACK (msg_p).ue_ambr;
- ue_context_p->ue_context.nb_release_of_e_rabs = S1AP_PATH_SWITCH_REQ_ACK (msg_p).nb_e_rabs_tobereleased;
- memset(&delete_tunnel_req, 0, sizeof(delete_tunnel_req));
- for (i = 0;
- i < ue_context_p->ue_context.nb_release_of_e_rabs;
- i++) {
- LOG_I(RRC,"Bearer released with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
- ue_context_p->ue_context.e_rabs_tobereleased[i]=S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[i].e_rab_id;
- delete_tunnel_req.eps_bearer_id[i] = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[i].e_rab_id;
- }
+ ue_context_p->ue_context.setup_e_rabs = ue_context_p->ue_context.setup_e_rabs - ue_context_p->ue_context.nb_release_of_e_rabs;
+ ue_context_p->ue_context.nb_of_e_rabs = ue_context_p->ue_context.nb_of_e_rabs - ue_context_p->ue_context.nb_release_of_e_rabs;
+
+ memset(&delete_tunnel_req, 0 , sizeof(delete_tunnel_req));
if (ue_context_p->ue_context.nb_release_of_e_rabs>0) {
+ int e_rab_release_index=0;
+ for (i = 0;
+ i < ue_context_p->ue_context.setup_e_rabs;
+ i++) {
+ if (ue_context_p->ue_context.e_rab[i].param.e_rab_id == S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id) {
+ LOG_I(RRC,"Bearer released with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
+ ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE;
+ ue_context_p->ue_context.e_rabs_tobereleased[e_rab_release_index]=S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id;
+ delete_tunnel_req.eps_bearer_id[e_rab_release_index] = S1AP_PATH_SWITCH_REQ_ACK (msg_p).e_rabs_tobereleased[e_rab_release_index].e_rab_id;
+ e_rab_release_index++;
+ }
+ else {
+ LOG_I(RRC,"Bearer re-established with ID: %d\n", ue_context_p->ue_context.e_rab[i].param.e_rab_id);
+ }
+ }
+ }
+
+ if (ue_context_p->ue_context.nb_release_of_e_rabs>0){
delete_tunnel_req.rnti= ue_context_p->ue_context.rnti;
delete_tunnel_req.num_erab= ue_context_p->ue_context.nb_release_of_e_rabs;
/* this could also be done through ITTI message */
@@ -2114,7 +2132,57 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg
memcpy ( ue_context_p->ue_context.next_security_key,
S1AP_PATH_SWITCH_REQ_ACK (msg_p).next_security_key,
SECURITY_KEY_LENGTH);
+
+ rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(&ctxt, ue_context_p);
+
return (0);
}
}
+int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP) {
+
+ MessageDef *msg_p = NULL;
+
+ msg_p = itti_alloc_new_message (TASK_RRC_ENB, X2AP_UE_CONTEXT_RELEASE);
+
+ X2AP_UE_CONTEXT_RELEASE (msg_p).rnti = ue_context_pP->ue_context.rnti;
+ X2AP_UE_CONTEXT_RELEASE (msg_p).source_assoc_id = ue_context_pP->ue_context.handover_info->assoc_id;
+ itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p);
+ return (0);
+}
+
+int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id){
+ s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL;
+ struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
+
+ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);
+ DevAssert(s1ap_eNB_instance_p != NULL);
+
+ if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
+ eNB_ue_s1ap_id)) == NULL) {
+ /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
+ LOG_W(RRC,"Failed to find ue context associated with eNB ue s1ap id: %u\n",
+ eNB_ue_s1ap_id);
+ return -1;
+ }
+
+ // release UE context
+ struct s1ap_eNB_ue_context_s *ue_context2_p = NULL;
+
+ if ((ue_context2_p = RB_REMOVE(s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head, ue_context_p))
+ != NULL) {
+ LOG_W(RRC,"Removed UE context eNB_ue_s1ap_id %u\n",
+ ue_context2_p->eNB_ue_s1ap_id);
+ s1ap_eNB_free_ue_context(ue_context2_p);
+ } else {
+ LOG_W(RRC,"Removing UE context eNB_ue_s1ap_id %u: did not find context\n",
+ ue_context_p->eNB_ue_s1ap_id);
+ }
+ /*RB_FOREACH(ue_context_p, s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head) {
+ S1AP_WARN("in s1ap_ue_map: UE context eNB_ue_s1ap_id %u mme_ue_s1ap_id %u state %u\n",
+ ue_context_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id,
+ ue_context_p->ue_state);
+ }*/
+
+ return 0;
+}
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h
index b24f7be24e..5feb55d635 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.h
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h
@@ -280,4 +280,8 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP,
rrc_eNB_ue_context_t *const ue_context_pP);
int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, const char *msg_name, instance_t instance);
+int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP);
+
+int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id);
+
#endif /* RRC_ENB_S1AP_H_ */
diff --git a/openair2/RRC/NAS/nas_config.c b/openair2/RRC/NAS/nas_config.c
index c0f6d622aa..61909df5ec 100644
--- a/openair2/RRC/NAS/nas_config.c
+++ b/openair2/RRC/NAS/nas_config.c
@@ -44,48 +44,56 @@
#include "nas_config.h"
#include "common/utils/LOG/log.h"
-
+#include "targets/RT/USER/lte-softmodem.h"
+#include "common/config/config_userapi.h"
//default values according to the examples,
-char *baseNetAddress = "10.0" ;
-char *netMask = "255.255.255.0" ;
-char *broadcastAddr = "10.0.255.255" ;
+char *baseNetAddress ;
+char *netMask ;
+char *broadcastAddr ;
+#define NASHLP_NETPREFIX "\n"
+#define NASHLP_NETMASK "\n"
+#define NASHLP_BROADCASTADDR "\n"
+void nas_getparams(void) {
+ paramdef_t nasoptions[] = {
+ /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+ /* configuration parameters for netlink, includes network parameters when running in noS1 mode */
+ /* optname helpstr paramflags XXXptr defXXXval type numelt */
+ /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+ {"NetworkPrefix", NASHLP_NETPREFIX, 0, strptr:&baseNetAddress, defstrval:"10.0", TYPE_STRING, 0 },
+ {"NetworkMask", NASHLP_NETMASK, 0, strptr:&netMask, defstrval:"255.255.255.0", TYPE_STRING, 0 },
+ {"BroadcastAddr", NASHLP_BROADCASTADDR, 0, strptr:&broadcastAddr, defstrval:"10.0.255.255", TYPE_STRING, 0 },
+ };
+ config_get( nasoptions,sizeof(nasoptions)/sizeof(paramdef_t),"nas.noS1");
+}
-
-void setBaseNetAddress (char* baseAddr)
-{
+void setBaseNetAddress (char *baseAddr) {
strcpy(baseNetAddress,baseAddr);
}
-char* getBaseNetAddress (void)
-{
+char *getBaseNetAddress (void) {
return baseNetAddress;
}
-void setNetMask (char* baseAddr)
-{
+void setNetMask (char *baseAddr) {
strcpy(netMask,baseAddr);
}
-char* getNetMask (void)
-{
+char *getNetMask (void) {
return netMask;
}
-void setBroadcastAddress (char* baseAddr)
-{
+void setBroadcastAddress (char *baseAddr) {
strcpy(broadcastAddr, baseAddr);
}
-char* getBroadcastAddress (void)
-{
+char *getBroadcastAddress (void) {
return broadcastAddr;
}
//Add Gateway to the interface
-int set_gateway(char *interfaceName, char *gateway)
-{
+int set_gateway(char *interfaceName, char *gateway) {
int sock_fd;
struct rtentry rt;
struct sockaddr_in addr;
@@ -96,20 +104,16 @@ int set_gateway(char *interfaceName, char *gateway)
}
memset (&rt, 0, sizeof (rt));
-
addr.sin_family = AF_INET;
/*set Destination addr*/
inet_aton("0.0.0.0",&addr.sin_addr);
memcpy(&rt.rt_dst, &addr, sizeof(struct sockaddr_in));
-
/*set gateway addr*/
inet_aton(gateway,&addr.sin_addr);
memcpy(&rt.rt_gateway, &addr, sizeof(struct sockaddr_in));
-
/*set genmask addr*/
inet_aton("0.0.0.0",&addr.sin_addr);
memcpy(&rt.rt_genmask, &addr, sizeof(struct sockaddr_in));
-
rt.rt_dev = interfaceName;
//rt.rt_flags = RTF_UP|RTF_GATEWAY|RTF_DEFAULT;
/* SR: rt_flags on 16 bits but RTF_DEFAULT = 0x00010000
@@ -129,19 +133,16 @@ int set_gateway(char *interfaceName, char *gateway)
LOG_I(OIP,"set_gateway OK!\n");
return 0;
}
-
}
close(sock_fd);
-
LOG_D(OIP,"Set Gateway OK!\n");
return 0;
}
// sets a genneric interface parameter
// (SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS)
-int setInterfaceParameter(char *interfaceName, char *settingAddress, int operation)
-{
+int setInterfaceParameter(char *interfaceName, char *settingAddress, int operation) {
int sock_fd;
struct ifreq ifr;
struct sockaddr_in addr;
@@ -154,10 +155,8 @@ int setInterfaceParameter(char *interfaceName, char *settingAddress, int operati
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name)-1);
-
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
-
inet_aton(settingAddress,&addr.sin_addr);
memcpy(&ifr.ifr_ifru.ifru_addr,&addr,sizeof(struct sockaddr_in));
@@ -169,15 +168,13 @@ int setInterfaceParameter(char *interfaceName, char *settingAddress, int operati
}
close(sock_fd);
-
// printf("Set OK!\n");
return 0;
}
// sets a genneric interface parameter
// (SIOCSIFADDR, SIOCSIFNETMASK, SIOCSIFBRDADDR, SIOCSIFFLAGS)
-int bringInterfaceUp(char *interfaceName, int up)
-{
+int bringInterfaceUp(char *interfaceName, int up) {
int sock_fd;
struct ifreq ifr;
@@ -213,8 +210,7 @@ int bringInterfaceUp(char *interfaceName, int up)
return 0;
}
// non blocking full configuration of the interface (address, net mask, and broadcast mask)
-int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress)
-{
+int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) {
bringInterfaceUp(interfaceName, 0);
// sets the machine address
int returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR);
@@ -229,26 +225,21 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br
// if(!returnValue)
// returnValue=set_gateway(interfaceName, broadcastAddress);
-
bringInterfaceUp(interfaceName, 1);
-
return returnValue;
}
// non blocking full configuration of the interface (address, and the two lest octets of the address)
-int nas_config(int interface_id, int thirdOctet, int fourthOctet)
-{
+int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifname) {
//char buf[5];
char ipAddress[20];
char broadcastAddress[20];
- char interfaceName[8];
+ char interfaceName[20];
int returnValue;
sprintf(ipAddress, "10.0.%d.%d", thirdOctet,fourthOctet);
-
sprintf(broadcastAddress, "10.0.%d.255", thirdOctet);
-
- sprintf(interfaceName, "oai%d", interface_id);
-
+ sprintf(interfaceName, "%s%s%d", (UE_NAS_USE_TUN || ENB_NAS_USE_TUN)?"oaitun_":ifname,
+ UE_NAS_USE_TUN?"ue": (ENB_NAS_USE_TUN?"enb":""),interface_id);
bringInterfaceUp(interfaceName, 0);
// sets the machine address
returnValue= setInterfaceParameter(interfaceName, ipAddress,SIOCSIFADDR);
@@ -262,18 +253,13 @@ int nas_config(int interface_id, int thirdOctet, int fourthOctet)
returnValue= setInterfaceParameter(interfaceName, broadcastAddress,SIOCSIFBRDADDR);
bringInterfaceUp(interfaceName, 1);
-
return returnValue;
-
}
// Blocking full configuration of the interface (address, net mask, and broadcast mask)
-int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress)
-{
-
+int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *broadcastAddress) {
char command[200];
command[0]='\0';
-
strcat(command, "ifconfig ");
strncat(command, interfaceName, sizeof(command) - strlen(command) - 1);
strncat(command, " ", sizeof(command) - strlen(command) - 1);
@@ -282,16 +268,13 @@ int blocking_NAS_config(char *interfaceName, char *ipAddress, char *networkMask,
strncat(command, networkMask, sizeof(command) - strlen(command) - 1);
strncat(command, " broadcast ", sizeof(command) - strlen(command) - 1);
strncat(command, broadcastAddress, sizeof(command) - strlen(command) - 1);
-
// ifconfig nasmesh0 10.0.1.1 networkMask 255.255.255.0 broadcast 10.0.1.255
int i = system (command);
-
return i;
}
// program help
-void helpOptions(char **argv)
-{
+void helpOptions(char **argv) {
printf("Help for %s\n", argv[0]);
printf(" -i \n");
printf(" -a \n");
@@ -303,13 +286,11 @@ void helpOptions(char **argv)
printf(" IP Address: 10.0.1.1\n");
printf(" Net mask: 255.255.255.0\n");
printf(" Broadcast address: [Beginning of the IP address].255\n");
-
exit(1);
}
// creates the broadcast address if it wasn't set before
-void createBroadcast(char *broadcastAddress)
-{
+void createBroadcast(char *broadcastAddress) {
int pos=strlen(broadcastAddress)-1;
while(broadcastAddress[pos]!='.')
@@ -331,7 +312,6 @@ int main(int argc,char **argv)
char ipAddress[100];
char networkMask[100];
char broadcastAddress[100];
-
strcpy(interfaceName, "oai0");
strcpy(ipAddress, "10.0.1.1");
strcpy(networkMask, "255.255.255.0");
@@ -339,38 +319,38 @@ int main(int argc,char **argv)
while ((c = getopt (argc, argv, "i:a:n:b:h")) != -1)
switch (c) {
- case 'h':
- helpOptions(argv);
- break;
+ case 'h':
+ helpOptions(argv);
+ break;
- case 'i':
- strcpy(interfaceName,optarg);
- break;
+ case 'i':
+ strcpy(interfaceName,optarg);
+ break;
- case 'a':
- strcpy(ipAddress,optarg);
- break;
+ case 'a':
+ strcpy(ipAddress,optarg);
+ break;
- case 'n':
- strcpy(networkMask,optarg);
- break;
+ case 'n':
+ strcpy(networkMask,optarg);
+ break;
- case 'b':
- strcpy(broadcastAddress,optarg);
- break;
+ case 'b':
+ strcpy(broadcastAddress,optarg);
+ break;
- case '?':
- if (isprint (optopt))
- fprintf (stderr, "Unknown option `-%c'.\n", optopt);
- else
- fprintf (stderr,
- "Unknown option character `\\x%x'.\n",
- optopt);
+ case '?':
+ if (isprint (optopt))
+ fprintf (stderr, "Unknown option `-%c'.\n", optopt);
+ else
+ fprintf (stderr,
+ "Unknown option character `\\x%x'.\n",
+ optopt);
- return 1;
+ return 1;
- default:
- abort ();
+ default:
+ abort ();
}
if(strlen(broadcastAddress)==0) {
@@ -383,7 +363,6 @@ int main(int argc,char **argv)
//test
// setBaseNetAddress("11.11");
// nas_config(interfaceName, 33, 44);
-
}
#endif
diff --git a/openair2/RRC/NAS/nas_config.h b/openair2/RRC/NAS/nas_config.h
index 4426ca9a1a..fdc3c98f1b 100644
--- a/openair2/RRC/NAS/nas_config.h
+++ b/openair2/RRC/NAS/nas_config.h
@@ -31,6 +31,13 @@
#include
+/*! \fn void void nas_getparams(void)(void)
+ * \brief This function get parameters used to configure network interface when running in noS1 mode
+ * \note
+ * @ingroup ?????
+ */
+void nas_getparams(void);
+
/*! \fn int NAS_config(char*, char*, char*, char*)
* \brief This function initializes the nasmesh interface
* \param[in] interfaceName, the name of the interface, e.g. nasmesh0 or nasmesh1
@@ -54,7 +61,7 @@ int NAS_config(char *interfaceName, char *ipAddress, char *networkMask, char *br
* \note
* @ingroup ?????
*/
-int nas_config(int interface_id, int thirdOctet, int fourthOctet);
+int nas_config(int interface_id, int thirdOctet, int fourthOctet, char *ifsuffix);
/*! \fn int blocking_NAS_config(char*, char*, char*, char*)
* \brief This function initializes the nasmesh interface, in a blocking way,
@@ -98,7 +105,7 @@ int set_gateway(char *interfaceName, char *gateway);
* \note
* @ingroup ?????
*/
-void setBaseNetAddress(char* baseAddr);
+void setBaseNetAddress(char *baseAddr);
/*! \fn char* getBaseNetAddress()
* \brief This function returns the basic network address used
@@ -106,7 +113,7 @@ void setBaseNetAddress(char* baseAddr);
* \note
* @ingroup ?????
*/
-char* getBaseNetAddress(void);
+char *getBaseNetAddress(void);
/*! \fn void setNetMask(char*)
* \brief This function sets the new default network mask used
@@ -114,7 +121,7 @@ char* getBaseNetAddress(void);
* \note
* @ingroup ?????
*/
-void setNetMask(char* baseAddr);
+void setNetMask(char *baseAddr);
/*! \fn char* getNetMask()
* \brief This function returns the network mask address in use
@@ -122,7 +129,7 @@ void setNetMask(char* baseAddr);
* \note
* @ingroup ?????
*/
-char* getNetMask(void);
+char *getNetMask(void);
/*! \fn coid setBroadcastAddress(char*)
* \brief This function sets the new broadcast address used
@@ -130,7 +137,7 @@ char* getNetMask(void);
* \note
* @ingroup ?????
*/
-void setBroadcastAddress(char* baseAddr);
+void setBroadcastAddress(char *baseAddr);
/*! \fn char* getBroadcastAddress()
* \brief This function returns the broadcast address in use
@@ -138,7 +145,7 @@ void setBroadcastAddress(char* baseAddr);
* \note
* @ingroup ?????
*/
-char* getBroadcastAddress(void);
+char *getBroadcastAddress(void);
int bringInterfaceUp(char *interfaceName, int up);
diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c
index 9305c34ac7..bd6ecd6cb4 100644
--- a/openair2/X2AP/x2ap_eNB.c
+++ b/openair2/X2AP/x2ap_eNB.c
@@ -40,6 +40,7 @@
#include "x2ap_eNB_handler.h"
#include "x2ap_eNB_generate_messages.h"
#include "x2ap_common.h"
+#include "x2ap_ids.h"
#include "queue.h"
#include "assertions.h"
@@ -79,6 +80,11 @@ static
void x2ap_eNB_handle_handover_req_ack(instance_t instance,
x2ap_handover_req_ack_t *x2ap_handover_req_ack);
+static
+void x2ap_eNB_ue_context_release(instance_t instance,
+ x2ap_ue_context_release_t *x2ap_ue_context_release);
+
+
static
void x2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
int result;
@@ -130,7 +136,7 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
sctp_new_association_resp->sctp_state,
instance,
sctp_new_association_resp->ulp_cnx_id);
- x2ap_handle_x2_setup_message(x2ap_enb_data_p,
+ x2ap_handle_x2_setup_message(instance_p, x2ap_enb_data_p,
sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
return;
}
@@ -294,6 +300,8 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
new_instance->mnc_digit_length = x2ap_register_eNB->mnc_digit_length;
new_instance->num_cc = x2ap_register_eNB->num_cc;
+ x2ap_id_manager_init(&new_instance->id_manager);
+
for (int i = 0; i< x2ap_register_eNB->num_cc; i++) {
new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i];
new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i];
@@ -371,30 +379,31 @@ static
void x2ap_eNB_handle_handover_req(instance_t instance,
x2ap_handover_req_t *x2ap_handover_req)
{
- /* TODO: remove this hack (the goal is to find the correct
- * eNodeB structure for the target) - we need a proper way for RRC
- * and X2AP to identify eNodeBs
- * RRC knows about mod_id and X2AP knows about eNB_id (eNB_ID in
- * the configuration file)
- * as far as I understand.. CROUX
- */
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *target;
+ x2ap_id_manager *id_manager;
+ int ue_id;
- int target_enb_id = x2ap_handover_req->target_physCellId;
+ int target_pci = x2ap_handover_req->target_physCellId;
- instance_p = x2ap_eNB_pci_get_instance(target_enb_id);
+ instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
- //instance_p = x2ap_eNB_get_instance(instance);
- //DevAssert(instance_p != NULL);
-
- target = x2ap_is_eNB_id_in_list(instance_p->eNB_id);
+ target = x2ap_is_eNB_pci_in_list(target_pci);
DevAssert(target != NULL);
- /* store rnti at index 0 */
- //x2id_to_source_rnti[0] = x2ap_handover_req->source_rnti;
- x2ap_eNB_generate_x2_handover_request(target, x2ap_handover_req);
+ /* allocate x2ap ID */
+ id_manager = &instance_p->id_manager;
+ ue_id = x2ap_allocate_new_id(id_manager);
+ if (ue_id == -1) {
+ X2AP_ERROR("could not allocate a new X2AP UE ID\n");
+ /* TODO: cancel handover: send (to be defined) message to RRC */
+ exit(1);
+ }
+ /* id_source is ue_id, id_target is unknown yet */
+ x2ap_set_ids(id_manager, ue_id, x2ap_handover_req->rnti, ue_id, -1);
+
+ x2ap_eNB_generate_x2_handover_request(instance_p, target, x2ap_handover_req, ue_id);
}
static
@@ -410,17 +419,49 @@ void x2ap_eNB_handle_handover_req_ack(instance_t instance,
*/
x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *target;
- int target_enb_id = x2ap_handover_req_ack->target_mod_id;
+ int source_assoc_id = x2ap_handover_req_ack->source_assoc_id;
+ int ue_id;
+ int id_source;
+ int id_target;
instance_p = x2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
- target = x2ap_is_eNB_id_in_list(target_enb_id);
+ target = x2ap_get_eNB(NULL, source_assoc_id, 0);
DevAssert(target != NULL);
- x2ap_eNB_generate_x2_handover_request_ack(target, x2ap_handover_req_ack);
- //x2ap_eNB_generate_x2_handover_req_ack(instance_p, target, x2ap_handover_req_ack->source_x2id,
- //x2ap_handover_req_ack->rrc_buffer, x2ap_handover_req_ack->rrc_buffer_size);
+ /* rnti is a new information, save it */
+ ue_id = x2ap_handover_req_ack->x2_id_target;
+ id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+ id_target = ue_id;
+ x2ap_set_ids(&instance_p->id_manager, ue_id, x2ap_handover_req_ack->rnti, id_source, id_target);
+
+ x2ap_eNB_generate_x2_handover_request_ack(instance_p, target, x2ap_handover_req_ack);
+}
+
+static
+void x2ap_eNB_ue_context_release(instance_t instance,
+ x2ap_ue_context_release_t *x2ap_ue_context_release)
+{
+ x2ap_eNB_instance_t *instance_p;
+ x2ap_eNB_data_t *target;
+ int source_assoc_id = x2ap_ue_context_release->source_assoc_id;
+ int ue_id;
+ instance_p = x2ap_eNB_get_instance(instance);
+ DevAssert(instance_p != NULL);
+
+ target = x2ap_get_eNB(NULL, source_assoc_id, 0);
+ DevAssert(target != NULL);
+
+ x2ap_eNB_generate_x2_ue_context_release(instance_p, target, x2ap_ue_context_release);
+
+ /* free the X2AP UE ID */
+ ue_id = x2ap_find_id_from_rnti(&instance_p->id_manager, x2ap_ue_context_release->rnti);
+ if (ue_id == -1) {
+ X2AP_ERROR("could not find UE %x\n", x2ap_ue_context_release->rnti);
+ exit(1);
+ }
+ x2ap_release_id(&instance_p->id_manager, ue_id);
}
void *x2ap_task(void *arg) {
@@ -454,6 +495,11 @@ void *x2ap_task(void *arg) {
&X2AP_HANDOVER_REQ_ACK(received_msg));
break;
+ case X2AP_UE_CONTEXT_RELEASE:
+ x2ap_eNB_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+ &X2AP_UE_CONTEXT_RELEASE(received_msg));
+ break;
+
case SCTP_INIT_MSG_MULTI_CNF:
x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c
index 553cf8e559..a5b19fe2cc 100644
--- a/openair2/X2AP/x2ap_eNB_decoder.c
+++ b/openair2/X2AP/x2ap_eNB_decoder.c
@@ -48,6 +48,10 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu)
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu);
X2AP_INFO("x2ap_eNB_decode_initiating_message!\n");
break;
+ case X2AP_ProcedureCode_id_uEContextRelease:
+ //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_X2AP_X2AP_PDU, pdu);
+ X2AP_INFO("x2ap_eNB_decode_initiating_message!\n");
+ break;
default:
X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h
index b3b95b8dd7..06e97cec2e 100644
--- a/openair2/X2AP/x2ap_eNB_defs.h
+++ b/openair2/X2AP/x2ap_eNB_defs.h
@@ -33,6 +33,8 @@
#include "sctp_eNB_defs.h"
+#include "x2ap_ids.h"
+
#ifndef X2AP_ENB_DEFS_H_
#define X2AP_ENB_DEFS_H_
@@ -114,6 +116,10 @@ typedef struct x2ap_eNB_data_s {
/* SCTP association id */
int32_t assoc_id;
+ /* Nid cells */
+ uint32_t Nid_cell[MAX_NUM_CCs];
+ int num_cc;
+
/* Only meaningfull in virtual mode */
struct x2ap_eNB_instance_s *x2ap_eNB_instance;
} x2ap_eNB_data_t;
@@ -163,7 +169,6 @@ typedef struct x2ap_eNB_instance_s {
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
- uint32_t Nid_target_cell[MAX_NUM_CCs];
int16_t N_RB_DL[MAX_NUM_CCs];
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
@@ -177,6 +182,8 @@ typedef struct x2ap_eNB_instance_s {
uint16_t sctp_out_streams;
uint32_t enb_port_for_X2C;
int multi_sd;
+
+ x2ap_id_manager id_manager;
} x2ap_eNB_instance_t;
typedef struct {
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c
index 76d6053b59..c13469d5d4 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.c
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.c
@@ -35,6 +35,7 @@
#include "x2ap_eNB_generate_messages.h"
#include "x2ap_eNB_encoder.h"
#include "x2ap_eNB_decoder.h"
+#include "x2ap_ids.h"
#include "x2ap_eNB_itti_messaging.h"
@@ -180,7 +181,7 @@ int x2ap_eNB_generate_x2_setup_request(
return ret;
}
-int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data_t *x2ap_eNB_data_p)
+int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p)
{
X2AP_X2AP_PDU_t pdu;
X2AP_X2SetupResponse_t *out;
@@ -189,18 +190,12 @@ int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data_t *x2ap_eNB_data_p)
ServedCells__Member *servedCellMember;
X2AP_GU_Group_ID_t *gu;
- x2ap_eNB_instance_t *instance_p;
-
uint8_t *buffer;
uint32_t len;
int ret = 0;
- DevAssert(x2ap_eNB_data_p != NULL);
-
- /* get the eNB instance */
- instance_p = x2ap_eNB_data_p->x2ap_eNB_instance;
-
DevAssert(instance_p != NULL);
+ DevAssert(x2ap_eNB_data_p != NULL);
/* Prepare the X2AP message to encode */
memset(&pdu, 0, sizeof(pdu));
@@ -414,8 +409,8 @@ int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p,
return 0;
}
-int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p,
- x2ap_handover_req_t *x2ap_handover_req)
+int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
+ x2ap_handover_req_t *x2ap_handover_req, int ue_id)
{
X2AP_X2AP_PDU_t pdu;
@@ -425,19 +420,12 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p,
X2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item;
X2AP_LastVisitedCell_Item_t *lastVisitedCell_Item;
- x2ap_eNB_instance_t *instance_p;
-
uint8_t *buffer;
uint32_t len;
int ret = 0;
- DevAssert(x2ap_eNB_data_p != NULL);
-
- /* get the eNB instance */
- instance_p = x2ap_eNB_data_p->x2ap_eNB_instance;
-
DevAssert(instance_p != NULL);
-
+ DevAssert(x2ap_eNB_data_p != NULL);
/* Prepare the X2AP handover message to encode */
memset(&pdu, 0, sizeof(pdu));
@@ -452,7 +440,7 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p,
ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID;
ie->criticality = X2AP_Criticality_reject;
ie->value.present = X2AP_HandoverRequest_IEs__value_PR_UE_X2AP_ID;
- ie->value.choice.UE_X2AP_ID = x2ap_handover_req->old_eNB_ue_x2ap_id;
+ ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
@@ -471,7 +459,7 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p,
ie->value.present = X2AP_HandoverRequest_IEs__value_PR_ECGI;
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
&ie->value.choice.ECGI.pLMN_Identity);
- MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier);
+ MACRO_ENB_ID_TO_CELL_IDENTITY(x2ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
@@ -576,7 +564,7 @@ int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p,
return ret;
}
-int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p,
+int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
x2ap_handover_req_ack_t *x2ap_handover_req_ack)
{
@@ -585,19 +573,20 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p,
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;
+ int ue_id;
+ int id_source;
+ int id_target;
uint8_t *buffer;
uint32_t len;
int ret = 0;
+ DevAssert(instance_p != NULL);
DevAssert(x2ap_eNB_data_p != NULL);
- /* get the eNB instance */
- instance_p = x2ap_eNB_data_p->x2ap_eNB_instance;
-
- DevAssert(instance_p != NULL);
+ ue_id = x2ap_handover_req_ack->x2_id_target;
+ id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+ id_target = ue_id;
/* Prepare the X2AP handover message to encode */
memset(&pdu, 0, sizeof(pdu));
@@ -612,15 +601,15 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p,
ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID;
ie->criticality = X2AP_Criticality_ignore;
ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
- ie->value.choice.UE_X2AP_ID = 0;
+ ie->value.choice.UE_X2AP_ID = id_source;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (X2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_HandoverRequestAcknowledge_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID;
ie->criticality = X2AP_Criticality_ignore;
- ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID;
- ie->value.choice.UE_X2AP_ID = 0;
+ ie->value.present = X2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_X2AP_ID_1;
+ ie->value.choice.UE_X2AP_ID_1 = id_target;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
@@ -668,25 +657,30 @@ int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p,
return ret;
}
-int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p)
+int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ue_context_release_t *x2ap_ue_context_release)
{
X2AP_X2AP_PDU_t pdu;
X2AP_UEContextRelease_t *out;
X2AP_UEContextRelease_IEs_t *ie;
-
- x2ap_eNB_instance_t *instance_p;
+ int ue_id;
+ int id_source;
+ int id_target;
uint8_t *buffer;
uint32_t len;
int ret = 0;
+ DevAssert(instance_p != NULL);
DevAssert(x2ap_eNB_data_p != NULL);
- /* get the eNB instance */
- instance_p = x2ap_eNB_data_p->x2ap_eNB_instance;
-
- DevAssert(instance_p != NULL);
+ ue_id = x2ap_find_id_from_rnti(&instance_p->id_manager, x2ap_ue_context_release->rnti);
+ if (ue_id == -1) {
+ X2AP_ERROR("could not find UE %x\n", x2ap_ue_context_release->rnti);
+ exit(1);
+ }
+ id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id);
+ id_target = ue_id;
/* Prepare the X2AP ue context relase message to encode */
memset(&pdu, 0, sizeof(pdu));
@@ -701,15 +695,15 @@ int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p)
ie->id = X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID;
ie->criticality = X2AP_Criticality_reject;
ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID;
- ie->value.choice.UE_X2AP_ID = 0;
+ ie->value.choice.UE_X2AP_ID = id_source;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (X2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(X2AP_UEContextRelease_IEs_t));
ie->id = X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID;
ie->criticality = X2AP_Criticality_reject;
- ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID;
- ie->value.choice.UE_X2AP_ID = 0;
+ ie->value.present = X2AP_UEContextRelease_IEs__value_PR_UE_X2AP_ID_1;
+ ie->value.choice.UE_X2AP_ID_1 = id_target;
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h
index 0cadc88c07..4f88469553 100644
--- a/openair2/X2AP/x2ap_eNB_generate_messages.h
+++ b/openair2/X2AP/x2ap_eNB_generate_messages.h
@@ -35,7 +35,7 @@
int x2ap_eNB_generate_x2_setup_request(x2ap_eNB_instance_t *instance_p,
x2ap_eNB_data_t *x2ap_eNB_data_p);
-int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data_t *x2ap_eNB_data_p);
+int x2ap_eNB_generate_x2_setup_response(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p);
int x2ap_eNB_generate_x2_setup_failure(instance_t instance,
uint32_t assoc_id,
@@ -47,11 +47,12 @@ int x2ap_eNB_set_cause (X2AP_Cause_t * cause_p,
X2AP_Cause_PR cause_type,
long cause_value);
-int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_data_t *x2ap_eNB_data_p,
- x2ap_handover_req_t *x2ap_handover_req);
+int x2ap_eNB_generate_x2_handover_request (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
+ x2ap_handover_req_t *x2ap_handover_req, int ue_id);
-int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_data_t *x2ap_eNB_data_p,
+int x2ap_eNB_generate_x2_handover_request_ack (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
x2ap_handover_req_ack_t *x2ap_handover_req_ack);
-int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_data_t *x2ap_eNB_data_p);
+int x2ap_eNB_generate_x2_ue_context_release (x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p,
+ x2ap_ue_context_release_t *x2ap_ue_context_release);
#endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */
diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c
index 27dfc8bd85..9da9278741 100644
--- a/openair2/X2AP/x2ap_eNB_handler.c
+++ b/openair2/X2AP/x2ap_eNB_handler.c
@@ -36,6 +36,7 @@
#include "x2ap_eNB_defs.h"
#include "x2ap_eNB_handler.h"
#include "x2ap_eNB_decoder.h"
+#include "x2ap_ids.h"
#include "x2ap_eNB_management_procedures.h"
#include "x2ap_eNB_generate_messages.h"
@@ -71,6 +72,12 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
uint32_t stream,
X2AP_X2AP_PDU_t *pdu);
+static
+int x2ap_eNB_handle_ue_context_release (instance_t instance,
+ uint32_t assoc_id,
+ uint32_t stream,
+ X2AP_X2AP_PDU_t *pdu);
+
/* Handlers matrix. Only eNB related procedure present here */
x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
{ x2ap_eNB_handle_handover_preparation, x2ap_eNB_handle_handover_response, 0 }, /* handoverPreparation */
@@ -78,7 +85,7 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = {
{ 0, 0, 0 }, /* loadIndication */
{ 0, 0, 0 }, /* errorIndication */
{ 0, 0, 0 }, /* snStatusTransfer */
- { 0, 0, 0 }, /* uEContextRelease */
+ { x2ap_eNB_handle_ue_context_release, 0, 0 }, /* uEContextRelease */
{ x2ap_eNB_handle_x2_setup_request, x2ap_eNB_handle_x2_setup_response, x2ap_eNB_handle_x2_setup_failure }, /* x2Setup */
{ 0, 0, 0 }, /* reset */
{ 0, 0, 0 }, /* eNBConfigurationUpdate */
@@ -112,7 +119,7 @@ static char *x2ap_direction_String[] = {
return(x2ap_direction_String[x2ap_dir]);
}
-void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown)
+void x2ap_handle_x2_setup_message(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown)
{
if (sctp_shutdown) {
/* A previously connected eNB has been shutdown */
@@ -121,38 +128,38 @@ void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *enb_desc_p, int sctp_shutdown
if (enb_desc_p->state == X2AP_ENB_STATE_CONNECTED) {
enb_desc_p->state = X2AP_ENB_STATE_DISCONNECTED;
- if (enb_desc_p->x2ap_eNB_instance-> x2_target_enb_associated_nb > 0) {
+ if (instance_p-> x2_target_enb_associated_nb > 0) {
/* Decrease associated eNB number */
- enb_desc_p->x2ap_eNB_instance-> x2_target_enb_associated_nb --;
+ instance_p-> x2_target_enb_associated_nb --;
}
/* If there are no more associated eNB, inform eNB app */
- if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_associated_nb == 0) {
+ if (instance_p->x2_target_enb_associated_nb == 0) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_X2AP, X2AP_DEREGISTERED_ENB_IND);
X2AP_DEREGISTERED_ENB_IND(message_p).nb_x2 = 0;
- itti_send_msg_to_task(TASK_ENB_APP, enb_desc_p->x2ap_eNB_instance->instance, message_p);
+ itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p);
}
}
} else {
/* Check that at least one setup message is pending */
- DevCheck(enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb > 0,
- enb_desc_p->x2ap_eNB_instance->instance,
- enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb, 0);
+ DevCheck(instance_p->x2_target_enb_pending_nb > 0,
+ instance_p->instance,
+ instance_p->x2_target_enb_pending_nb, 0);
- if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb > 0) {
+ if (instance_p->x2_target_enb_pending_nb > 0) {
/* Decrease pending messages number */
- enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb --;
+ instance_p->x2_target_enb_pending_nb --;
}
/* If there are no more pending messages, inform eNB app */
- if (enb_desc_p->x2ap_eNB_instance->x2_target_enb_pending_nb == 0) {
+ if (instance_p->x2_target_enb_pending_nb == 0) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_X2AP, X2AP_REGISTER_ENB_CNF);
- X2AP_REGISTER_ENB_CNF(message_p).nb_x2 = enb_desc_p->x2ap_eNB_instance->x2_target_enb_associated_nb;
- itti_send_msg_to_task(TASK_ENB_APP, enb_desc_p->x2ap_eNB_instance->instance, message_p);
+ X2AP_REGISTER_ENB_CNF(message_p).nb_x2 = instance_p->x2_target_enb_associated_nb;
+ itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p);
}
}
}
@@ -276,6 +283,7 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance,
X2AP_X2SetupRequest_IEs_t *ie;
ServedCells__Member *servedCellMember;
+ x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
uint32_t eNB_id = 0;
@@ -358,8 +366,7 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance,
*/
X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", eNB_id, x2ap_eNB_data->assoc_id, assoc_id);
- DevAssert(x2ap_eNB_data->x2ap_eNB_instance != NULL);
- x2ap_eNB_generate_x2_setup_failure (x2ap_eNB_data->x2ap_eNB_instance->instance,
+ x2ap_eNB_generate_x2_setup_failure (instance,
assoc_id,
X2AP_Cause_PR_protocol,
X2AP_CauseProtocol_unspecified,
@@ -374,19 +381,22 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance,
/* Set proper pci */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupRequest_IEs_t, ie, x2SetupRequest,
X2AP_ProtocolIE_ID_id_ServedCells, true);
-
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
- } else if (ie->value.choice.ServedCells.list.count > 0) {
- x2ap_eNB_data->x2ap_eNB_instance->num_cc = ie->value.choice.ServedCells.list.count;
+ }
+ if (ie->value.choice.ServedCells.list.count > 0) {
+ x2ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count;
for (int i=0; ivalue.choice.ServedCells.list.count;i++) {
servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i];
- x2ap_eNB_data->x2ap_eNB_instance->Nid_target_cell[i] = servedCellMember->servedCellInfo.pCI;
+ x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI;
}
}
- return x2ap_eNB_generate_x2_setup_response(x2ap_eNB_data);
+ instance_p = x2ap_eNB_get_instance(instance);
+ DevAssert(instance_p != NULL);
+
+ return x2ap_eNB_generate_x2_setup_response(instance_p, x2ap_eNB_data);
}
static
@@ -400,6 +410,7 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
X2AP_X2SetupResponse_IEs_t *ie;
ServedCells__Member *servedCellMember;
+ x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
uint32_t eNB_id = 0;
@@ -429,7 +440,7 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
- }
+ }
if (ie->value.choice.GlobalENB_ID.eNB_ID.present == X2AP_ENB_ID_PR_home_eNB_ID) {
// Home eNB ID = 28 bits
uint8_t *eNB_id_buf = ie->value.choice.GlobalENB_ID.eNB_ID.choice.home_eNB_ID.buf;
@@ -478,15 +489,16 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
/* Set proper pci */
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupResponse_IEs_t, ie, x2SetupResponse,
X2AP_ProtocolIE_ID_id_ServedCells, true);
-
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
- } else if (ie->value.choice.ServedCells.list.count > 0) {
- x2ap_eNB_data->x2ap_eNB_instance->num_cc = ie->value.choice.ServedCells.list.count;
+ }
+
+ if (ie->value.choice.ServedCells.list.count > 0) {
+ x2ap_eNB_data->num_cc = ie->value.choice.ServedCells.list.count;
for (int i=0; ivalue.choice.ServedCells.list.count;i++) {
servedCellMember = (ServedCells__Member *)ie->value.choice.ServedCells.list.array[i];
- x2ap_eNB_data->x2ap_eNB_instance->Nid_target_cell[i] = servedCellMember->servedCellInfo.pCI;
+ x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedCellInfo.pCI;
}
}
@@ -496,8 +508,12 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
* Mark the association as connected.
*/
x2ap_eNB_data->state = X2AP_ENB_STATE_READY;
- x2ap_eNB_data->x2ap_eNB_instance->x2_target_enb_associated_nb ++;
- x2ap_handle_x2_setup_message(x2ap_eNB_data, 0);
+
+ instance_p = x2ap_eNB_get_instance(instance);
+ DevAssert(instance_p != NULL);
+
+ instance_p->x2_target_enb_associated_nb ++;
+ x2ap_handle_x2_setup_message(instance_p, x2ap_eNB_data, 0);
return 0;
}
@@ -512,6 +528,7 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance,
X2AP_X2SetupFailure_t *x2SetupFailure;
X2AP_X2SetupFailure_IEs_t *ie;
+ x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
DevAssert(pdu != NULL);
@@ -542,7 +559,7 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
- }
+ }
// need a FSM to handle all cases
if ((ie->value.choice.Cause.present == X2AP_Cause_PR_misc) &&
(ie->value.choice.Cause.choice.misc == X2AP_CauseMisc_unspecified)) {
@@ -552,7 +569,11 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance,
}
x2ap_eNB_data->state = X2AP_ENB_STATE_WAITING;
- x2ap_handle_x2_setup_message(x2ap_eNB_data, 0);
+
+ instance_p = x2ap_eNB_get_instance(instance);
+ DevAssert(instance_p != NULL);
+
+ x2ap_handle_x2_setup_message(instance_p, x2ap_eNB_data, 0);
return 0;
}
@@ -570,8 +591,10 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
X2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs;
X2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item;
+ x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
MessageDef *msg;
+ int ue_id;
DevAssert (pdu != NULL);
x2HandoverRequest = &pdu->choice.initiatingMessage.value.choice.HandoverRequest;
@@ -587,19 +610,30 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
DevAssert(x2ap_eNB_data != NULL);
+ instance_p = x2ap_eNB_get_instance(instance);
+ DevAssert(instance_p != NULL);
+
msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ);
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest,
X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true);
- //X2AP_HANDOVER_REQ(msg).source_rnti = ctxt_pP->rnti;
- //X2AP_HANDOVER_REQ(m).source_x2id = x2HandoverRequest->old_eNB_UE_X2AP_ID;
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
return -1;
- } else {
- X2AP_HANDOVER_REQ(msg).old_eNB_ue_x2ap_id = ie->value.choice.UE_X2AP_ID;
}
+ /* allocate a new X2AP UE ID */
+ ue_id = x2ap_allocate_new_id(&instance_p->id_manager);
+ if (ue_id == -1) {
+ X2AP_ERROR("could not allocate a new X2AP UE ID\n");
+ /* TODO: cancel handover: send HO preparation failure to source eNB */
+ exit(1);
+ }
+ /* rnti is unknown yet, must not be set to -1, 0 is fine */
+ x2ap_set_ids(&instance_p->id_manager, ue_id, 0, ie->value.choice.UE_X2AP_ID, ue_id);
+
+ X2AP_HANDOVER_REQ(msg).x2_id = ue_id;
+
//X2AP_HANDOVER_REQ(msg).target_physCellId = measResults2->measResultNeighCells->choice.
//measResultListEUTRA.list.array[ncell_index]->physCellId;
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest,
@@ -619,7 +653,11 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
}
X2AP_HANDOVER_REQ(msg).mme_ue_s1ap_id = ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID;
- X2AP_HANDOVER_REQ(msg).target_mod_id = x2ap_eNB_data->x2ap_eNB_instance->eNB_id;
+
+ /* TODO: properly store Target Cell ID */
+
+ X2AP_HANDOVER_REQ(msg).target_assoc_id = assoc_id;
+
X2AP_HANDOVER_REQ(msg).security_capabilities.encryption_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms);
X2AP_HANDOVER_REQ(msg).security_capabilities.integrity_algorithms =
@@ -671,10 +709,10 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s*/)
{ printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); }
- memcpy(X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, c->buf, c->size);
- X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size = c->size;
+ memcpy(X2AP_HANDOVER_REQ(msg).rrc_buffer, c->buf, c->size);
+ X2AP_HANDOVER_REQ(msg).rrc_buffer_size = c->size;
- itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, msg);
+ itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
return 0;
}
@@ -688,8 +726,13 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
X2AP_HandoverRequestAcknowledge_t *x2HandoverRequestAck;
X2AP_HandoverRequestAcknowledge_IEs_t *ie;
+ x2ap_eNB_instance_t *instance_p;
x2ap_eNB_data_t *x2ap_eNB_data;
MessageDef *msg;
+ int ue_id;
+ int id_source;
+ int id_target;
+ int rnti;
DevAssert (pdu != NULL);
x2HandoverRequestAck = &pdu->choice.successfulOutcome.value.choice.HandoverRequestAcknowledge;
@@ -705,12 +748,44 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
DevAssert(x2ap_eNB_data != NULL);
+ instance_p = x2ap_eNB_get_instance(instance);
+ DevAssert(instance_p != NULL);
msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ_ACK);
- /* TODO: fill the message */
- //extern int x2id_to_source_rnti[1];
- //X2AP_HANDOVER_REQ_ACK(m).source_x2id = x2HandoverRequestAck->old_eNB_UE_X2AP_ID;
- //X2AP_HANDOVER_REQ_ACK(m).source_rnti = x2id_to_source_rnti[x2HandoverRequestAck->old_eNB_UE_X2AP_ID];
+
+ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck,
+ X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true);
+
+ if (ie == NULL ) {
+ X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ return -1;
+ }
+
+ id_source = ie->value.choice.UE_X2AP_ID;
+
+ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck,
+ X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true);
+
+ if (ie == NULL ) {
+ X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ return -1;
+ }
+
+ id_target = ie->value.choice.UE_X2AP_ID_1;
+
+ ue_id = id_source;
+
+ if (id_source != x2ap_id_get_id_source(&instance_p->id_manager, ue_id)) {
+ X2AP_ERROR("incorrect X2AP IDs for UE (old ID %d new ID %d)\n", id_source, id_target);
+ exit(1);
+ }
+
+ rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id);
+
+ /* id_target is a new information, store it */
+ x2ap_set_ids(&instance_p->id_manager, ue_id, rnti, id_source, id_target);
+
+ X2AP_HANDOVER_REQ_ACK(msg).rnti = rnti;
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck,
X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true);
@@ -723,6 +798,81 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
memcpy(X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, c->buf, c->size);
X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size = c->size;
- itti_send_msg_to_task(TASK_RRC_ENB, x2ap_eNB_data->x2ap_eNB_instance->instance, msg);
+ itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
+ return 0;
+}
+
+
+static
+int x2ap_eNB_handle_ue_context_release (instance_t instance,
+ uint32_t assoc_id,
+ uint32_t stream,
+ X2AP_X2AP_PDU_t *pdu)
+{
+ X2AP_UEContextRelease_t *x2UEContextRelease;
+ X2AP_UEContextRelease_IEs_t *ie;
+
+ x2ap_eNB_instance_t *instance_p;
+ x2ap_eNB_data_t *x2ap_eNB_data;
+ MessageDef *msg;
+ int ue_id;
+ int id_source;
+ int id_target;
+
+ DevAssert (pdu != NULL);
+ x2UEContextRelease = &pdu->choice.initiatingMessage.value.choice.UEContextRelease;
+
+ if (stream == 0) {
+ X2AP_ERROR ("Received new x2 ue context release on stream == 0\n");
+ /* TODO: send a x2 failure response */
+ return 0;
+ }
+
+ X2AP_DEBUG ("Received a new X2 ue context release\n");
+
+ x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0);
+ DevAssert(x2ap_eNB_data != NULL);
+
+ instance_p = x2ap_eNB_get_instance(instance);
+ DevAssert(instance_p != NULL);
+
+ msg = itti_alloc_new_message(TASK_X2AP, X2AP_UE_CONTEXT_RELEASE);
+
+ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease,
+ X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true);
+
+ if (ie == NULL ) {
+ X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ return -1;
+ }
+
+ id_source = ie->value.choice.UE_X2AP_ID;
+
+ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease,
+ X2AP_ProtocolIE_ID_id_New_eNB_UE_X2AP_ID, true);
+
+ if (ie == NULL ) {
+ X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ return -1;
+ }
+
+ id_target = ie->value.choice.UE_X2AP_ID_1;
+
+ ue_id = id_source;
+
+ if (id_target != x2ap_id_get_id_target(&instance_p->id_manager, ue_id)) {
+ X2AP_ERROR("UE context release: bad id_target for UE %x (id_source %d) expected %d got %d\n",
+ x2ap_id_get_rnti(&instance_p->id_manager, ue_id),
+ id_source,
+ x2ap_id_get_id_target(&instance_p->id_manager, ue_id),
+ id_target);
+ }
+
+ X2AP_UE_CONTEXT_RELEASE(msg).rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id);
+
+ itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg);
+
+ x2ap_release_id(&instance_p->id_manager, ue_id);
+
return 0;
}
diff --git a/openair2/X2AP/x2ap_eNB_handler.h b/openair2/X2AP/x2ap_eNB_handler.h
index 5826ffc54c..65f411895f 100644
--- a/openair2/X2AP/x2ap_eNB_handler.h
+++ b/openair2/X2AP/x2ap_eNB_handler.h
@@ -31,7 +31,7 @@
#include "x2ap_eNB_defs.h"
-void x2ap_handle_x2_setup_message(x2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
+void x2ap_handle_x2_setup_message(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
int x2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length);
diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.c b/openair2/X2AP/x2ap_eNB_management_procedures.c
index cd329e50d0..986ca10902 100644
--- a/openair2/X2AP/x2ap_eNB_management_procedures.c
+++ b/openair2/X2AP/x2ap_eNB_management_procedures.c
@@ -169,23 +169,6 @@ x2ap_eNB_instance_t *x2ap_eNB_get_instance(instance_t instance)
return NULL;
}
-x2ap_eNB_instance_t *x2ap_eNB_pci_get_instance(uint32_t pci)
-{
- x2ap_eNB_instance_t *temp = NULL;
-
- STAILQ_FOREACH(temp, &x2ap_eNB_internal_data.x2ap_eNB_instances_head,
- x2ap_eNB_entries) {
- for (int i=0; inum_cc;i++) {
- if (temp->Nid_target_cell[i] == pci) {
- /* Matching occurence */
- return temp;
- }
- }
- }
-
- return NULL;
-}
-
/// utility functions
void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref);
@@ -222,6 +205,22 @@ void x2ap_dump_eNB (x2ap_eNB_data_t * eNB_ref) {
indent--;
}
+x2ap_eNB_data_t * x2ap_is_eNB_pci_in_list (const uint32_t pci)
+{
+ x2ap_eNB_instance_t *inst;
+ struct x2ap_eNB_data_s *elm;
+
+ STAILQ_FOREACH(inst, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) {
+ RB_FOREACH(elm, x2ap_enb_map, &inst->x2ap_enb_head) {
+ for (int i = 0; inum_cc; i++) {
+ if (elm->Nid_cell[i] == pci) {
+ return elm;
+ }
+ }
+ }
+ }
+ return NULL;
+}
x2ap_eNB_data_t * x2ap_is_eNB_id_in_list (const uint32_t eNB_id)
{
diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.h b/openair2/X2AP/x2ap_eNB_management_procedures.h
index 6eb430b2b0..c5217341c5 100644
--- a/openair2/X2AP/x2ap_eNB_management_procedures.h
+++ b/openair2/X2AP/x2ap_eNB_management_procedures.h
@@ -37,8 +37,6 @@ void x2ap_eNB_insert_new_instance(x2ap_eNB_instance_t *new_instance_p);
x2ap_eNB_instance_t *x2ap_eNB_get_instance(uint8_t mod_id);
-x2ap_eNB_instance_t *x2ap_eNB_pci_get_instance(uint32_t pci);
-
uint16_t x2ap_eNB_fetch_add_global_cnx_id(void);
void x2ap_eNB_prepare_internal_data(void);
@@ -47,6 +45,8 @@ x2ap_eNB_data_t* x2ap_is_eNB_id_in_list(uint32_t eNB_id);
x2ap_eNB_data_t* x2ap_is_eNB_assoc_id_in_list(uint32_t sctp_assoc_id);
+x2ap_eNB_data_t* x2ap_is_eNB_pci_in_list (const uint32_t pci);
+
struct x2ap_eNB_data_s *x2ap_get_eNB(x2ap_eNB_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id);
diff --git a/openair2/X2AP/x2ap_ids.c b/openair2/X2AP/x2ap_ids.c
new file mode 100644
index 0000000000..b5607821fe
--- /dev/null
+++ b/openair2/X2AP/x2ap_ids.c
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+#include "x2ap_ids.h"
+
+#include
+
+void x2ap_id_manager_init(x2ap_id_manager *m)
+{
+ int i;
+ memset(m, 0, sizeof(x2ap_id_manager));
+ for (i = 0; i < X2AP_MAX_IDS; i++)
+ m->ids[i].rnti = -1;
+}
+
+int x2ap_allocate_new_id(x2ap_id_manager *m)
+{
+ int i;
+ for (i = 0; i < X2AP_MAX_IDS; i++)
+ if (m->ids[i].rnti == -1) {
+ m->ids[i].rnti = 0;
+ m->ids[i].id_source = -1;
+ m->ids[i].id_target = -1;
+ return i;
+ }
+ return -1;
+}
+
+void x2ap_release_id(x2ap_id_manager *m, int id)
+{
+ m->ids[id].rnti = -1;
+}
+
+int x2ap_find_id(x2ap_id_manager *m, int id_source, int id_target)
+{
+ int i;
+ for (i = 0; i < X2AP_MAX_IDS; i++)
+ if (m->ids[i].rnti != -1 &&
+ m->ids[i].id_source == id_source &&
+ m->ids[i].id_target == id_target)
+ return i;
+ return -1;
+}
+
+int x2ap_find_id_from_rnti(x2ap_id_manager *m, int rnti)
+{
+ int i;
+ for (i = 0; i < X2AP_MAX_IDS; i++)
+ if (m->ids[i].rnti == rnti)
+ return i;
+ return -1;
+}
+
+void x2ap_set_ids(x2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target)
+{
+ m->ids[ue_id].rnti = rnti;
+ m->ids[ue_id].id_source = id_source;
+ m->ids[ue_id].id_target = id_target;
+}
+
+int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id)
+{
+ return m->ids[ue_id].id_source;
+}
+
+int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id)
+{
+ return m->ids[ue_id].id_target;
+}
+
+int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id)
+{
+ return m->ids[ue_id].rnti;
+}
diff --git a/openair2/X2AP/x2ap_ids.h b/openair2/X2AP/x2ap_ids.h
new file mode 100644
index 0000000000..2232308f73
--- /dev/null
+++ b/openair2/X2AP/x2ap_ids.h
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+#ifndef X2AP_IDS_H_
+#define X2AP_IDS_H_
+
+#define X2AP_MAX_IDS 16
+
+typedef struct {
+ int rnti; /* -1 when free */
+ int id_source;
+ int id_target;
+} x2ap_id;
+
+typedef struct {
+ x2ap_id ids[X2AP_MAX_IDS];
+} x2ap_id_manager;
+
+void x2ap_id_manager_init(x2ap_id_manager *m);
+int x2ap_allocate_new_id(x2ap_id_manager *m);
+void x2ap_release_id(x2ap_id_manager *m, int id);
+int x2ap_find_id(x2ap_id_manager *, int id_source, int id_target);
+int x2ap_find_id_from_rnti(x2ap_id_manager *, int rnti);
+void x2ap_set_ids(x2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target);
+int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id);
+int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id);
+int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id);
+
+#endif /* X2AP_IDS_H_ */
diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c
index 3fea17cc6f..4b0945f5ea 100644
--- a/openair3/SCTP/sctp_eNB_task.c
+++ b/openair3/SCTP/sctp_eNB_task.c
@@ -324,7 +324,12 @@ sctp_handle_new_association_req_multi(
}
}
- ns = sctp_peeloff(sd,assoc_id);
+ ns = sctp_peeloff(sd, assoc_id);
+ if (ns == -1) {
+ perror("sctp_peeloff");
+ printf("sctp_peeloff: sd=%d assoc_id=%d\n", sd, assoc_id);
+ exit(1);
+ }
sctp_cnx = calloc(1, sizeof(*sctp_cnx));
@@ -1006,7 +1011,9 @@ sctp_eNB_read_from_socket(
sctp_itti_send_new_message_ind(sctp_cnx->task_id,
sctp_cnx->instance,
sinfo.sinfo_assoc_id,
- buffer, n, sinfo.sinfo_stream);
+ buffer,
+ n,
+ sinfo.sinfo_stream);
}
}
diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c
index 94bffa0520..3f81816aa1 100644
--- a/targets/ARCH/COMMON/common_lib.c
+++ b/targets/ARCH/COMMON/common_lib.c
@@ -19,8 +19,8 @@
* contact@openairinterface.org
*/
-/*! \file common_lib.c
- * \brief common APIs for different RF frontend device
+/*! \file common_lib.c
+ * \brief common APIs for different RF frontend device
* \author HongliangXU, Navid Nikaein
* \date 2015
* \version 0.2
@@ -37,108 +37,124 @@
#include "common_lib.h"
#include "common/utils/load_module_shlib.h"
+#include "targets/RT/USER/lte-softmodem.h"
int set_device(openair0_device *device) {
-
switch (device->type) {
-
- case EXMIMO_DEV:
- printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- break;
- case USRP_B200_DEV:
- printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- break;
- case USRP_X300_DEV:
- printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- break;
- case BLADERF_DEV:
- printf("[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- break;
- case LMSSDR_DEV:
- printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- break;
- case IRIS_DEV:
- printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- break;
- case NONE_DEV:
- printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- break;
- default:
- printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- return -1;
+ case EXMIMO_DEV:
+ printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ break;
+
+ case USRP_B200_DEV:
+ printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ break;
+
+ case USRP_X300_DEV:
+ printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ break;
+
+ case BLADERF_DEV:
+ printf("[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ break;
+
+ case LMSSDR_DEV:
+ printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ break;
+
+ case IRIS_DEV:
+ printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ break;
+
+ case NONE_DEV:
+ printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ break;
+
+ default:
+ printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ return -1;
}
+
return 0;
}
int set_transport(openair0_device *device) {
-
switch (device->transp_type) {
-
- case ETHERNET_TP:
- printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- return 0;
- break;
- case NONE_TP:
- printf("[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- return 0;
- break;
- default:
- printf("[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
- return -1;
- break;
+ case ETHERNET_TP:
+ printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ return 0;
+ break;
+
+ case NONE_TP:
+ printf("[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ return 0;
+ break;
+
+ default:
+ printf("[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
+ return -1;
+ break;
}
-
}
typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *);
/* look for the interface library and load it */
-int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * cfg, uint8_t flag) {
-
+int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *cfg, uint8_t flag) {
loader_shlibfunc_t shlib_fdesc[1];
int ret=0;
char *libname;
- if (flag == RAU_LOCAL_RADIO_HEAD) {
- libname=OAI_RF_LIBNAME;
- shlib_fdesc[0].fname="device_init";
- } else {
- libname=OAI_TP_LIBNAME;
- shlib_fdesc[0].fname="transport_init";
- }
- ret=load_module_shlib(libname,shlib_fdesc,1,NULL);
- if (ret < 0) {
- fprintf(stderr,"Library %s couldn't be loaded\n",libname);
+
+ if ( IS_SOFTMODEM_BASICSIM ) {
+ libname=OAI_BASICSIM_LIBNAME;
+ shlib_fdesc[0].fname="device_init";
+ } else if ( IS_SOFTMODEM_RFSIM ) {
+ libname=OAI_RFSIM_LIBNAME;
+ shlib_fdesc[0].fname="device_init";
+ } else if (flag == RAU_LOCAL_RADIO_HEAD) {
+ libname=OAI_RF_LIBNAME;
+ shlib_fdesc[0].fname="device_init";
} else {
- ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
- }
- return ret;
+ libname=OAI_TP_LIBNAME;
+ shlib_fdesc[0].fname="transport_init";
+ }
+
+ ret=load_module_shlib(libname,shlib_fdesc,1,NULL);
+
+ if (ret < 0) {
+ fprintf(stderr,"Library %s couldn't be loaded\n",libname);
+ } else {
+ ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
+ }
+
+ return ret;
}
int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) {
-
int rc=0;
rc=load_lib(device, openair0_cfg, NULL,RAU_LOCAL_RADIO_HEAD );
- if ( rc >= 0) {
- if ( set_device(device) < 0) {
+ if ( rc >= 0) {
+ if ( set_device(device) < 0) {
fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__);
- return -1;
- }
+ return -1;
+ }
}
+
return rc;
}
-int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params) {
+int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params) {
int rc;
rc=load_lib(device, openair0_cfg, eth_params, RAU_REMOTE_RADIO_HEAD);
- if ( rc >= 0) {
+
+ if ( rc >= 0) {
if ( set_transport(device) < 0) {
fprintf(stderr, "%s %d:Unsupported transport protocol\n",__FILE__, __LINE__);
- return -1;
- }
+ return -1;
+ }
}
- return rc;
+ return rc;
}
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index 084ef9fcd9..0af6fa9c5e 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -19,8 +19,8 @@
* contact@openairinterface.org
*/
-/*! \file common_lib.h
- * \brief common APIs for different RF frontend device
+/*! \file common_lib.h
+ * \brief common APIs for different RF frontend device
* \author HongliangXU, Navid Nikaein
* \date 2015
* \version 0.2
@@ -39,19 +39,22 @@
#define OAI_RF_LIBNAME "oai_device"
/* name of shared library implementing the transport */
#define OAI_TP_LIBNAME "oai_transpro"
-
+/* name of shared library implementing the basic/rf simulator */
+#define OAI_RFSIM_LIBNAME "rfsimulator"
+/* name of shared library implementing the basic/rf simulator */
+#define OAI_BASICSIM_LIBNAME "tcp_bridge_oai"
/* flags for BBU to determine whether the attached radio head is local or remote */
#define RAU_LOCAL_RADIO_HEAD 0
#define RAU_REMOTE_RADIO_HEAD 1
#ifndef MAX_CARDS
-#define MAX_CARDS 8
+ #define MAX_CARDS 8
#endif
typedef int64_t openair0_timestamp;
typedef volatile int64_t openair0_vtimestamp;
-
+
/*!\brief structrue holds the parameters to configure USRP devices*/
typedef struct openair0_device_t openair0_device;
@@ -120,16 +123,16 @@ typedef enum {
/*!\brief openair0 device host type */
typedef enum {
MIN_HOST_TYPE = 0,
- /*!\brief device functions within a RAU */
+ /*!\brief device functions within a RAU */
RAU_HOST,
- /*!\brief device functions within a RRU */
+ /*!\brief device functions within a RRU */
RRU_HOST,
MAX_HOST_TYPE
-}host_type_t;
+} host_type_t;
-/*! \brief RF Gain clibration */
+/*! \brief RF Gain clibration */
typedef struct {
//! Frequency for which RX chain was calibrated
double freq;
@@ -157,7 +160,7 @@ typedef struct {
duplex_mode_t duplex_mode;
//! number of downlink resource blocks
int num_rb_dl;
- //! number of samples per frame
+ //! number of samples per frame
unsigned int samples_per_frame;
//! the sample rate for both transmit and receive.
double sample_rate;
@@ -172,9 +175,9 @@ typedef struct {
//! number of TX channels (=TX antennas)
int tx_num_channels;
//! \brief RX base addresses for mmapped_dma
- int32_t* rxbase[4];
+ int32_t *rxbase[4];
//! \brief TX base addresses for mmapped_dma
- int32_t* txbase[4];
+ int32_t *txbase[4];
//! \brief Center frequency in Hz for RX.
//! index: [0..rx_num_channels[
double rx_freq[4];
@@ -185,7 +188,7 @@ typedef struct {
//! \brief Pointer to Calibration table for RX gains
rx_gain_calib_table_t *rx_gain_calib_table;
- //! mode for rxgain (ExpressMIMO2)
+ //! mode for rxgain (ExpressMIMO2)
rx_gain_t rxg_mode[4];
//! \brief Gain for RX in dB.
//! index: [0..rx_num_channels]
@@ -199,14 +202,14 @@ typedef struct {
double rx_bw;
//! TX bandwidth in Hz
double tx_bw;
- //! clock source
+ //! clock source
clock_source_t clock_source;
//! Manual SDR IP address
char *sdr_addrs;
//! Auto calibration flag
int autocal[4];
//! rf devices work with x bits iqs when oai have its own iq format
- //! the two following parameters are used to convert iqs
+ //! the two following parameters are used to convert iqs
int iq_txshift;
int iq_rxrescale;
//! Configuration file for LMS7002M
@@ -219,10 +222,10 @@ typedef struct {
unsigned int sf_read_delay; // read delay in replay mode
unsigned int sf_write_delay; // write delay in replay mode
unsigned int eth_mtu; // ethernet MTU
-#endif
+#endif
} openair0_config_t;
-/*! \brief RF mapping */
+/*! \brief RF mapping */
typedef struct {
//! card id
int card;
@@ -269,14 +272,14 @@ struct openair0_device_t {
/*!brief Component Carrier ID of this device */
int CC_id;
-
+
/*!brief Type of this device */
dev_type_t type;
/*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */
transport_type_t transp_type;
- /*!brief Type of the device's host (RAU/RRU) */
+ /*!brief Type of the device's host (RAU/RRU) */
host_type_t host_type;
/* !brief RF frontend parameters set by application */
@@ -298,25 +301,25 @@ struct openair0_device_t {
/*! \brief Called to send a request message between RAU-RRU on control port
@param device pointer to the device structure specific to the RF hardware target
@param msg pointer to the message structure passed between RAU-RRU
- @param msg_len length of the message
- */
+ @param msg_len length of the message
+ */
int (*trx_ctlsend_func)(openair0_device *device, void *msg, ssize_t msg_len);
/*! \brief Called to receive a reply message between RAU-RRU on control port
@param device pointer to the device structure specific to the RF hardware target
@param msg pointer to the message structure passed between RAU-RRU
- @param msg_len length of the message
- */
+ @param msg_len length of the message
+ */
int (*trx_ctlrecv_func)(openair0_device *device, void *msg, ssize_t msg_len);
/*! \brief Called to send samples to the RF target
@param device pointer to the device structure specific to the RF hardware target
- @param timestamp The timestamp at whicch the first sample MUST be sent
+ @param timestamp The timestamp at whicch the first sample MUST be sent
@param buff Buffer which holds the samples
@param nsamps number of samples to be sent
@param antenna_id index of the antenna if the device has multiple anteannas
@param flags flags must be set to TRUE if timestamp parameter needs to be applied
- */
+ */
int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags);
/*! \brief Receive samples from hardware.
@@ -332,55 +335,55 @@ struct openair0_device_t {
*/
int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id);
- /*! \brief print the device statistics
+ /*! \brief print the device statistics
* \param device the hardware to use
* \returns 0 on success
*/
int (*trx_get_stats_func)(openair0_device *device);
- /*! \brief Reset device statistics
+ /*! \brief Reset device statistics
* \param device the hardware to use
- * \returns 0 in success
+ * \returns 0 in success
*/
int (*trx_reset_stats_func)(openair0_device *device);
- /*! \brief Terminate operation of the transceiver -- free all associated resources
+ /*! \brief Terminate operation of the transceiver -- free all associated resources
* \param device the hardware to use
*/
void (*trx_end_func)(openair0_device *device);
- /*! \brief Stop operation of the transceiver
+ /*! \brief Stop operation of the transceiver
*/
int (*trx_stop_func)(openair0_device *device);
/* Functions API related to UE*/
- /*! \brief Set RX feaquencies
+ /*! \brief Set RX feaquencies
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
- * \param exmimo_dump_config dump EXMIMO configuration
- * \returns 0 in success
+ * \param exmimo_dump_config dump EXMIMO configuration
+ * \returns 0 in success
*/
- int (*trx_set_freq_func)(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
-
+ int (*trx_set_freq_func)(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
+
/*! \brief Set gains
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
- * \returns 0 in success
+ * \returns 0 in success
*/
- int (*trx_set_gains_func)(openair0_device* device, openair0_config_t *openair0_cfg);
+ int (*trx_set_gains_func)(openair0_device *device, openair0_config_t *openair0_cfg);
/*! \brief RRU Configuration callback
* \param idx RU index
* \param arg pointer to capabilities or configuration
*/
- void (*configure_rru)(int idx, void* arg);
+ void (*configure_rru)(int idx, void *arg);
};
/* type of device init function, implemented in shared lib */
typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg);
/* type of transport init function, implemented in shared lib */
-typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params);
+typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
#ifdef __cplusplus
extern "C"
@@ -388,23 +391,23 @@ extern "C"
#endif
- /*! \brief Initialize openair RF target. It returns 0 if OK */
- int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg);
- /*! \brief Initialize transport protocol . It returns 0 if OK */
- int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params);
+/*! \brief Initialize openair RF target. It returns 0 if OK */
+int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg);
+/*! \brief Initialize transport protocol . It returns 0 if OK */
+int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
-
- /*! \brief Get current timestamp of USRP
- * \param device the hardware to use
- */
- openair0_timestamp get_usrp_time(openair0_device *device);
- /*! \brief Set RX frequencies
- * \param device the hardware to use
- * \param openair0_cfg RF frontend parameters set by application
- * \returns 0 in success
- */
- int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
+/*! \brief Get current timestamp of USRP
+ * \param device the hardware to use
+ */
+openair0_timestamp get_usrp_time(openair0_device *device);
+
+/*! \brief Set RX frequencies
+ * \param device the hardware to use
+ * \param openair0_cfg RF frontend parameters set by application
+ * \returns 0 in success
+ */
+int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg);
/*@}*/
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
index acb4c2ec9b..2c8e55d14f 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
@@ -138,7 +138,7 @@ int eth_socket_init_raw(openair0_device *device) {
return 0;
}
-
+/* 09/03/2019: fix obvious inconsistencies, but this code hasn't be tested for sure */
int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {
int bytes_sent=0;
@@ -148,7 +148,12 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi
//sendto_flag|=flags;
eth->tx_nsamps=nsamps;
-
+ int pktsize;
+ if (eth->compression == ALAW_COMPRESS) {
+ pktsize = RAW_PACKET_SIZE_BYTES_ALAW(nsamps);
+ } else {
+ pktsize = RAW_PACKET_SIZE_BYTES(nsamps);
+ }
for (i=0;iehd,MAC_HEADER_SIZE_BYTES);
*(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t))=1+(i<<1);
- *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp;
-
- int sent_byte;
-
+ *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp;
/*printf("[RRU]write mod_%d %d , len %d, buff %p \n",
Mod_id,eth->sockfd[Mod_id],RAW_PACKET_SIZE_BYTES(nsamps), buff2);*/
- while(bytes_sent < sent_byte) {
-#if DEBUG
- printf("------- TX ------: buff2 current position=%d remaining_bytes=%d bytes_sent=%d \n",
- (void *)(buff2+bytes_sent),
- sent_byte - bytes_sent,
- bytes_sent);
-#endif
+ while(bytes_sent < pktsize) {
+
/* Send packet */
bytes_sent += send(eth->sockfdd,
buff2,
- sent_byte,
+ pktsize,
sendto_flag);
if ( bytes_sent == -1) {
eth->num_tx_errors++;
perror("ETHERNET WRITE: ");
exit(-1);
} else {
-#if DEBUG
- printf("------- TX ------: nu=%x an_id=%d ts%d bytes_sent=%d\n",
- *(uint8_t *)(buff2+ETH_ALEN),
- *(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t)),
- *(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)),
- bytes_sent);
- dump_packet((device->host_type == RAU_HOST)? "RAU":"RRU", buff2, sent_byte, TX_FLAG);
-
-#endif
- eth->tx_actual_nsamps=bytes_sent>>2;
- eth->tx_count++;
+ eth->tx_actual_nsamps=bytes_sent>>2;
+ eth->tx_count++;
}
}
diff --git a/targets/ARCH/rfsimulator/README.md b/targets/ARCH/rfsimulator/README.md
new file mode 100644
index 0000000000..89964decd5
--- /dev/null
+++ b/targets/ARCH/rfsimulator/README.md
@@ -0,0 +1,68 @@
+#General
+This is a RF simulator that allows to test OAI without a RF board.
+It replaces a actual RF board driver.
+
+As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound)
+
+#build
+
+## From build_oai
+You can build it the same way, and together with actual RF driver
+
+Example:
+```bash
+./build_oai --ue-nas-use-tun --UE --eNB -w SIMU
+```
+It is also possible to build actual RF and use choose on each run:
+```bash
+./build_oai --ue-nas-use-tun --UE --eNB -w USRP --rfsimulator
+```
+Will build both the eNB (lte-softmodem) and the UE (lte-uesoftmodem)
+We recommend to use the option --ue-nas-use-tun that is much simpler to use than the OAI kernel driver.
+
+## Add the rfsimulator after initial build
+After any regular build, you can compile the driver
+```bash
+cd /build
+make rfsimulator
+```
+Then, you can use it freely
+
+# Usage
+Setting the env variable RFSIMULATOR enables the RF board simulator
+It should the set to "enb" in the eNB
+
+## 4G case
+For the UE, it should be set to the IP address of the eNB
+example:
+```bash
+sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50
+```
+Except this, the UE and the eNB can be used as it the RF is real
+
+If you reach 'RA not active' on UE, be careful to generate a valid SIM
+```bash
+$OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o .
+```
+## 5G case
+After regular build, add the simulation driver
+(don't use ./build_oai -w SIMU until we merge 4G and 5G branches)
+```bash
+cd ran_build/build
+make rfsimulator
+```
+### Launch gNB in one window
+```bash
+sudo RFSIMULATOR=enb ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD
+```
+### Launch UE in another window
+```bash
+sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000
+```
+Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine
+In UE, you can add "-d" to get the softscope
+
+#Caveacts
+Still issues in power control: txgain, rxgain are not used
+
+no S1 mode is currently broken, so we were not able to test the simulator in noS1 mode
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
new file mode 100644
index 0000000000..a17327b03e
--- /dev/null
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -0,0 +1,475 @@
+/*
+ Author: Laurent THOMAS, Open Cells for Nokia
+ copyleft: OpenAirInterface Software Alliance and it's licence
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include "common_lib.h"
+#include
+#include "openair1/PHY/defs_UE.h"
+
+#define PORT 4043 //TCP port for this simulator
+#define CirSize 3072000 // 100ms is enough
+#define sample_t uint32_t // 2*16 bits complex number
+#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
+#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
+#define MAGICeNB 0xA5A5A5A5A5A5A5A5
+#define MAGICUE 0x5A5A5A5A5A5A5A5A
+
+typedef struct {
+ uint64_t magic;
+ uint32_t size;
+ uint32_t nbAnt;
+ uint64_t timestamp;
+} transferHeader;
+
+typedef struct buffer_s {
+ int conn_sock;
+ bool alreadyRead;
+ uint64_t lastReceivedTS;
+ bool headerMode;
+ transferHeader th;
+ char *transferPtr;
+ uint64_t remainToTransfer;
+ char *circularBufEnd;
+ sample_t *circularBuf;
+} buffer_t;
+
+typedef struct {
+ int listen_sock, epollfd;
+ uint64_t nextTimestamp;
+ uint64_t typeStamp;
+ uint64_t initialAhead;
+ char *ip;
+ buffer_t buf[FD_SETSIZE];
+} rfsimulator_state_t;
+
+void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
+ buffer_t *ptr=&bridge->buf[sock];
+ AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
+ ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
+ ptr->conn_sock=sock;
+ ptr->headerMode=true;
+ ptr->transferPtr=(char *)&ptr->th;
+ ptr->remainToTransfer=sizeof(transferHeader);
+ int sendbuff=1000*1000*10;
+ AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, "");
+ struct epoll_event ev= {0};
+ ev.events = EPOLLIN | EPOLLRDHUP;
+ ev.data.fd = sock;
+ AssertFatal(epoll_ctl(bridge->epollfd, EPOLL_CTL_ADD, sock, &ev) != -1, "");
+}
+
+void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
+ AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, "");
+ close(sock);
+ free(bridge->buf[sock].circularBuf);
+ memset(&bridge->buf[sock], 0, sizeof(buffer_t));
+ bridge->buf[sock].conn_sock=-1;
+}
+
+void socketError(rfsimulator_state_t *bridge, int sock) {
+ if (bridge->buf[sock].conn_sock!=-1) {
+ LOG_W(HW,"Lost socket \n");
+ removeCirBuf(bridge, sock);
+
+ if (bridge->typeStamp==MAGICUE)
+ exit(1);
+ }
+}
+
+
+#define helpTxt "\
+\x1b[31m\
+rfsimulator: error: you have to run one UE and one eNB\n\
+For this, export RFSIMULATOR=enb (eNB case) or \n\
+ RFSIMULATOR= (UE case)\n\
+\x1b[m"
+
+enum blocking_t {
+ notBlocking,
+ blocking
+};
+
+void setblocking(int sock, enum blocking_t active) {
+ int opts;
+ AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,"");
+
+ if (active==blocking)
+ opts = opts & ~O_NONBLOCK;
+ else
+ opts = opts | O_NONBLOCK;
+
+ AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, "");
+}
+
+static bool flushInput(rfsimulator_state_t *t);
+
+void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
+ char *buf = _buf;
+ int l;
+ setblocking(fd, notBlocking);
+
+ while (count) {
+ l = write(fd, buf, count);
+
+ if (l <= 0) {
+ if (errno==EINTR)
+ continue;
+
+ if(errno==EAGAIN) {
+ flushInput(t);
+ continue;
+ } else
+ return;
+ }
+
+ count -= l;
+ buf += l;
+ }
+}
+
+int server_start(openair0_device *device) {
+ rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
+ t->typeStamp=MAGICeNB;
+ AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
+ int enable = 1;
+ AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
+ struct sockaddr_in addr = {
+sin_family:
+ AF_INET,
+sin_port:
+ htons(PORT),
+sin_addr:
+ { s_addr: INADDR_ANY }
+ };
+ bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr));
+ AssertFatal(listen(t->listen_sock, 5) == 0, "");
+ struct epoll_event ev;
+ ev.events = EPOLLIN;
+ ev.data.fd = t->listen_sock;
+ AssertFatal(epoll_ctl(t->epollfd, EPOLL_CTL_ADD, t->listen_sock, &ev) != -1, "");
+ return 0;
+}
+
+int start_ue(openair0_device *device) {
+ rfsimulator_state_t *t = device->priv;
+ t->typeStamp=MAGICUE;
+ int sock;
+ AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
+ struct sockaddr_in addr = {
+sin_family:
+ AF_INET,
+sin_port:
+ htons(PORT),
+sin_addr:
+ { s_addr: INADDR_ANY }
+ };
+ addr.sin_addr.s_addr = inet_addr(t->ip);
+ bool connected=false;
+
+ while(!connected) {
+ LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", t->ip, PORT);
+
+ if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
+ LOG_I(HW,"rfsimulator: connection established\n");
+ connected=true;
+ }
+
+ perror("rfsimulator");
+ sleep(1);
+ }
+
+ setblocking(sock, notBlocking);
+ allocCirBuf(t, sock);
+ t->buf[sock].alreadyRead=true; // UE will start blocking on read
+ return 0;
+}
+
+int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
+ rfsimulator_state_t *t = device->priv;
+
+ for (int i=0; ibuf[i];
+
+ if (ptr->conn_sock >= 0 ) {
+ transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp};
+ fullwrite(ptr->conn_sock,&header, sizeof(header), t);
+ sample_t tmpSamples[nsamps][nbAnt];
+
+ for(int a=0; aconn_sock >= 0 )
+ fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
+ }
+ }
+
+ LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
+ nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
+ return nsamps;
+}
+
+static bool flushInput(rfsimulator_state_t *t) {
+ // Process all incoming events on sockets
+ // store the data in lists
+ struct epoll_event events[FD_SETSIZE]= {0};
+ int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 200);
+
+ if ( nfds==-1 ) {
+ if ( errno==EINTR || errno==EAGAIN )
+ return false;
+ else
+ AssertFatal(false,"error in epoll_wait\n");
+ }
+
+ for (int nbEv = 0; nbEv < nfds; ++nbEv) {
+ int fd=events[nbEv].data.fd;
+
+ if (events[nbEv].events & EPOLLIN && fd == t->listen_sock) {
+ int conn_sock;
+ AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, "");
+ setblocking(conn_sock, notBlocking);
+ allocCirBuf(t, conn_sock);
+ LOG_I(HW,"A ue connected\n");
+ } else {
+ if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) {
+ socketError(t,fd);
+ continue;
+ }
+
+ buffer_t *b=&t->buf[fd];
+
+ if ( b->circularBuf == NULL ) {
+ LOG_E(HW, "received data on not connected socket %d\n", events[nbEv].data.fd);
+ continue;
+ }
+
+ int blockSz;
+
+ if ( b->headerMode)
+ blockSz=b->remainToTransfer;
+ else
+ blockSz= b->transferPtr+b->remainToTransfer < b->circularBufEnd ?
+ b->remainToTransfer :
+ b->circularBufEnd - 1 - b->transferPtr ;
+
+ int sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT);
+
+ if ( sz < 0 ) {
+ if ( errno != EAGAIN ) {
+ LOG_E(HW,"socket failed %s\n", strerror(errno));
+ abort();
+ }
+ } else if ( sz == 0 )
+ continue;
+
+ AssertFatal((b->remainToTransfer-=sz) >= 0, "");
+ b->transferPtr+=sz;
+
+ if (b->transferPtr==b->circularBufEnd - 1)
+ b->transferPtr=(char *)b->circularBuf;
+
+ // check the header and start block transfer
+ if ( b->headerMode==true && b->remainToTransfer==0) {
+ AssertFatal( (t->typeStamp == MAGICUE && b->th.magic==MAGICeNB) ||
+ (t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol");
+ b->headerMode=false;
+ b->alreadyRead=true;
+
+ if ( b->lastReceivedTS != b->th.timestamp) {
+ int nbAnt= b->th.nbAnt;
+
+ for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ )
+ for (int a=0; a < nbAnt; a++)
+ b->circularBuf[(index*nbAnt+a)%CirSize]=0;
+
+ LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS );
+ }
+
+ b->lastReceivedTS=b->th.timestamp;
+ b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
+ b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
+ }
+
+ if ( b->headerMode==false ) {
+ b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt);
+
+ if ( b->remainToTransfer==0) {
+ LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS);
+
+ // First block in UE, resync with the eNB current TS
+ if ( t->nextTimestamp == 0 )
+ t->nextTimestamp=b->lastReceivedTS-b->th.size;
+
+ b->headerMode=true;
+ b->transferPtr=(char *)&b->th;
+ b->remainToTransfer=sizeof(transferHeader);
+ b->th.magic=-1;
+ }
+ }
+ }
+ }
+
+ return nfds>0;
+}
+
+int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
+ if (nbAnt != 1) {
+ LOG_E(HW, "rfsimulator: only 1 antenna tested\n");
+ exit(1);
+ }
+
+ rfsimulator_state_t *t = device->priv;
+ LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps);
+ // deliver data from received data
+ // check if a UE is connected
+ int first_sock;
+
+ for (first_sock=0; first_sockbuf[first_sock].circularBuf != NULL )
+ break;
+
+ if ( first_sock == FD_SETSIZE ) {
+ // no connected device (we are eNB, no UE is connected)
+ if (!flushInput(t)) {
+ for (int x=0; x < nbAnt; x++)
+ memset(samplesVoid[x],0,sampleToByte(nsamps,1));
+
+ t->nextTimestamp+=nsamps;
+ LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
+ *ptimestamp = t->nextTimestamp-nsamps;
+ return nsamps;
+ }
+ } else {
+ bool have_to_wait;
+
+ do {
+ have_to_wait=false;
+
+ for ( int sock=0; sockbuf[sock].circularBuf &&
+ t->buf[sock].alreadyRead && //>= t->initialAhead &&
+ (t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
+ have_to_wait=true;
+ break;
+ }
+
+ if (have_to_wait)
+ /*printf("Waiting on socket, current last ts: %ld, expected at least : %ld\n",
+ ptr->lastReceivedTS,
+ t->nextTimestamp+nsamps);
+ */
+ flushInput(t);
+ } while (have_to_wait);
+ }
+
+ // Clear the output buffer
+ for (int a=0; abuf[sock];
+
+ if ( ptr->circularBuf && ptr->alreadyRead ) {
+ for (int a=0; acircularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize]<<1;
+ }
+ }
+ }
+
+ *ptimestamp = t->nextTimestamp; // return the time of the first sample
+ t->nextTimestamp+=nsamps;
+ LOG_D(HW,"Rx to upper layer: %d from %ld to %ld, energy in first antenna %d\n",
+ nsamps,
+ *ptimestamp, t->nextTimestamp,
+ signal_energy(samplesVoid[0], nsamps));
+ return nsamps;
+}
+
+
+int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) {
+ abort();
+ return 0;
+}
+int rfsimulator_reply(openair0_device *device, void *msg, ssize_t msg_len) {
+ abort();
+ return 0;
+}
+int rfsimulator_get_stats(openair0_device *device) {
+ return 0;
+}
+int rfsimulator_reset_stats(openair0_device *device) {
+ return 0;
+}
+void rfsimulator_end(openair0_device *device) {}
+int rfsimulator_stop(openair0_device *device) {
+ return 0;
+}
+int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) {
+ return 0;
+}
+int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
+ return 0;
+}
+
+
+__attribute__((__visibility__("default")))
+int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
+ //set_log(HW,OAILOG_DEBUG);
+ rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
+
+ if ((rfsimulator->ip=getenv("RFSIMULATOR")) == NULL ) {
+ LOG_E(HW,helpTxt);
+ exit(1);
+ }
+
+ rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ?
+ MAGICeNB:
+ MAGICUE;
+ LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE");
+ device->trx_start_func = rfsimulator->typeStamp == MAGICeNB ?
+ server_start :
+ start_ue;
+ device->trx_get_stats_func = rfsimulator_get_stats;
+ device->trx_reset_stats_func = rfsimulator_reset_stats;
+ device->trx_end_func = rfsimulator_end;
+ device->trx_stop_func = rfsimulator_stop;
+ device->trx_set_freq_func = rfsimulator_set_freq;
+ device->trx_set_gains_func = rfsimulator_set_gains;
+ device->trx_write_func = rfsimulator_write;
+ device->trx_read_func = rfsimulator_read;
+ /* let's pretend to be a b2x0 */
+ device->type = USRP_B200_DEV;
+ device->openair0_cfg=&openair0_cfg[0];
+ device->priv = rfsimulator;
+
+ for (int i=0; ibuf[i].conn_sock=-1;
+
+ AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,"");
+ rfsimulator->initialAhead=openair0_cfg[0].sample_rate/1000; // One sub frame
+ return 0;
+}
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf
index df98111cfc..0e0ee94470 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf
@@ -13,7 +13,7 @@ eNBs =
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
- tracking_area_code = "1";
+ tracking_area_code = 1;
plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2;} );
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 89ca097bb5..787e630d17 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -1381,12 +1381,11 @@ int setup_RU_buffers(RU_t *ru) {
else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2;
else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4;
-#if BASIC_SIMULATOR
- /* this is required for the basic simulator in TDD mode
- * TODO: find a proper cleaner solution
- */
- ru->N_TA_offset = 0;
-#endif
+ if(IS_SOFTMODEM_BASICSIM)
+ /* this is required for the basic simulator in TDD mode
+ * TODO: find a proper cleaner solution
+ */
+ ru->N_TA_offset = 0;
}
if (ru->openair0_cfg.mmapped_dma == 1) {
diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c
index 0a63797536..242d0b76d7 100644
--- a/targets/RT/USER/lte-softmodem-common.c
+++ b/targets/RT/USER/lte-softmodem-common.c
@@ -58,6 +58,8 @@ void get_common_options(void) {
uint32_t noS1;
uint32_t nokrnmod;
uint32_t nonbiot;
+ uint32_t rfsim;
+ uint32_t basicsim;
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
checkedparam_t cmdline_log_CheckParams[] = CMDLINE_LOGPARAMS_CHECK_DESC;
@@ -90,6 +92,18 @@ void get_common_options(void) {
set_softmodem_optmask(SOFTMODEM_NONBIOT_BIT);
}
+ if (rfsim) {
+ set_softmodem_optmask(SOFTMODEM_RFSIM_BIT);
+ }
+
+ if (basicsim) {
+ set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT);
+ }
+
+#if BASIC_SIMULATOR
+ set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT);
+#endif
+
if(parallel_config != NULL) set_parallel_conf(parallel_config);
if(worker_config != NULL) set_worker_conf(worker_config);
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 174c33387f..8464e9747c 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -664,7 +664,11 @@ int main( int argc, char **argv ) {
flexran_agent_start(i);
}
- pdcp_module_init( ( IS_SOFTMODEM_NOS1 && !(IS_SOFTMODEM_NOKRNMOD))? (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT);
+ uint32_t pdcp_initmask = ( IS_SOFTMODEM_NOS1 )? ( PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
+ if ( IS_SOFTMODEM_NOS1)
+ pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ;
+
+ pdcp_module_init(pdcp_initmask);
if (RC.nb_inst > 0) {
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index 39f997a71f..9b820e6e19 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -87,6 +87,7 @@
#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
#define CONFIG_HLP_NOS1 "Disable s1 interface\n"
+#define CONFIG_HLP_RFSIM "Run in rf simulator mode (also known as basic simulator)\n"
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
@@ -199,7 +200,9 @@
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
- {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \
+ {"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \
+ {"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_INT, 0}, \
+ {"basicsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&basicsim, defintval:0, TYPE_INT, 0}, \
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
}
@@ -238,8 +241,8 @@
#define SOFTMODEM_NOS1_BIT (1<<0)
#define SOFTMODEM_NOKRNMOD_BIT (1<<1)
#define SOFTMODEM_NONBIOT_BIT (1<<2)
-#define SOFTMODEM_BASICSIM_BIT (1<<10)
-
+#define SOFTMODEM_RFSIM_BIT (1<<10)
+#define SOFTMODEM_BASICSIM_BIT (1<<11)
typedef struct {
uint64_t optmask;
THREAD_STRUCT thread_struct;
@@ -260,6 +263,7 @@ typedef struct {
#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT)
#define IS_SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT)
#define IS_SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT)
+#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT)
#define IS_SOFTMODEM_BASICSIM ( get_softmodem_optmask() & SOFTMODEM_BASICSIM_BIT)
extern uint64_t get_softmodem_optmask(void);
extern uint64_t set_softmodem_optmask(uint64_t bitmask);
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 1e68c06d26..bb2319774c 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -80,12 +80,12 @@ void init_UE_threads_stub(int);
void init_UE_single_thread_stub(int);
void *UE_thread(void *arg);
void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correction, int phy_test, int UE_scan, int UE_scan_carrier, runmode_t mode,int rxgain,int txpowermax,LTE_DL_FRAME_PARMS *fp);
-void init_UE_stub(int nb_inst,int,int,char*);
-void init_UE_stub_single_thread(int nb_inst,int,int,char*);
+void init_UE_stub(int nb_inst,int,int,char *);
+void init_UE_stub_single_thread(int nb_inst,int,int,char *);
int init_timer_thread(void);
extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
extern void multicast_link_start(void (*rx_handlerP) (unsigned int, char *),
- unsigned char _multicast_group, char *multicast_ifname);
+ unsigned char _multicast_group, char *multicast_ifname);
extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind);
@@ -169,21 +169,18 @@ struct sched_param sched_param_UE_thread;
void get_uethreads_params(void) {
paramdef_t cmdline_threadsparams[] =CMDLINE_UETHREADSPARAMS_DESC;
-
-
config_process_cmdline( cmdline_threadsparams,sizeof(cmdline_threadsparams)/sizeof(paramdef_t),NULL);
}
void phy_init_lte_ue_transport(PHY_VARS_UE *ue,int absraction_flag);
-PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
- uint8_t UE_id,
- uint8_t abstraction_flag)
+PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
+ uint8_t UE_id,
+ uint8_t abstraction_flag)
{
-
- PHY_VARS_UE* ue = (PHY_VARS_UE *)malloc(sizeof(PHY_VARS_UE));
+ PHY_VARS_UE *ue = (PHY_VARS_UE *)malloc(sizeof(PHY_VARS_UE));
memset(ue,0,sizeof(PHY_VARS_UE));
if (frame_parms!=(LTE_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in
@@ -195,13 +192,12 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
ue->mac_enabled = 1;
// In phy_stub_UE (MAC-to-MAC) mode these init functions don't need to get called. Is this correct?
- if (nfapi_mode!=3)
- {
- // initialize all signal buffers
- init_lte_ue_signal(ue,1,abstraction_flag);
- // intialize transport
- init_lte_ue_transport(ue,abstraction_flag);
- }
+ if (nfapi_mode!=3) {
+ // initialize all signal buffers
+ init_lte_ue_signal(ue,1,abstraction_flag);
+ // intialize transport
+ init_lte_ue_transport(ue,abstraction_flag);
+ }
return(ue);
}
@@ -211,9 +207,9 @@ char uecap_xer[1024];
-void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name) {
-
+void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char *name) {
#ifdef DEADLINE_SCHEDULER
+
if (sched_runtime!=0) {
struct sched_attr attr= {0};
attr.size = sizeof(attr);
@@ -222,60 +218,64 @@ void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_
attr.sched_deadline = sched_deadline;
attr.sched_period = 0;
AssertFatal(sched_setattr(0, &attr, 0) == 0,
- "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno));
+ "[SCHED] %s thread: sched_setattr failed %s \n", name, strerror(errno));
LOG_I(HW,"[SCHED][eNB] %s deadline thread %lu started on CPU %d\n",
- name, (unsigned long)gettid(), sched_getcpu());
+ name, (unsigned long)gettid(), sched_getcpu());
}
+
#else
+
if (CPU_COUNT(cpuset) > 0)
AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), cpuset), "");
+
struct sched_param sp;
sp.sched_priority = sched_fifo;
AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
- "Can't set thread priority, Are you root?\n");
+ "Can't set thread priority, Are you root?\n");
/* Check the actual affinity mask assigned to the thread */
cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE);
+
if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) {
- char txt[512]={0};
+ char txt[512]= {0};
+
for (int j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, cset))
- sprintf(txt+strlen(txt), " %d ", j);
+ sprintf(txt+strlen(txt), " %d ", j);
+
printf("CPU Affinity of thread %s is %s\n", name, txt);
}
+
CPU_FREE(cset);
#endif
-
}
void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correction, int phy_test, int UE_scan, int UE_scan_carrier, runmode_t mode,int rxgain,int txpowermax,LTE_DL_FRAME_PARMS *fp0) {
-
PHY_VARS_UE *UE;
int inst;
int ret;
LTE_DL_FRAME_PARMS *fp;
-
LOG_I(PHY,"UE : Calling Layer 2 for initialization\n");
-
l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
- 0,// cba_group_active
- 0); // HO flag
+ 0,// cba_group_active
+ 0); // HO flag
+
+ if (PHY_vars_UE_g==NULL) PHY_vars_UE_g = (PHY_VARS_UE ***)calloc(1+nb_inst,sizeof(PHY_VARS_UE **));
+
+ for (inst=0; instframe_parms.nb_antennas_rx = fp0->nb_antennas_rx;
- RC.ru[0]->frame_parms.nb_antennas_tx = fp0->nb_antennas_tx;
- PHY_vars_UE_g[inst][0] = init_ue_vars(&RC.ru[0]->frame_parms,inst,0);
+ RC.ru[0]->frame_parms.nb_antennas_rx = fp0->nb_antennas_rx;
+ RC.ru[0]->frame_parms.nb_antennas_tx = fp0->nb_antennas_tx;
+ PHY_vars_UE_g[inst][0] = init_ue_vars(&RC.ru[0]->frame_parms,inst,0);
}
+
// turn off timing control loop in UE
PHY_vars_UE_g[inst][0]->no_timing_correction = timing_correction;
-
UE = PHY_vars_UE_g[inst][0];
fp = &UE->frame_parms;
printf("PHY_vars_UE_g[0][0] = %p\n",UE);
@@ -290,7 +290,6 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti
UE->pusch_config_dedicated[i].betaOffset_ACK_Index = 0;
UE->pusch_config_dedicated[i].betaOffset_RI_Index = 0;
UE->pusch_config_dedicated[i].betaOffset_CQI_Index = 2;
-
UE->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0;
UE->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3);
UE->scheduling_request_config[i].dsr_TransMax = sr_n4;
@@ -305,69 +304,75 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti
if (UE->mac_enabled == 1) {
UE->pdcch_vars[0][0]->crnti = 0x1234;
UE->pdcch_vars[1][0]->crnti = 0x1234;
- }else {
+ } else {
UE->pdcch_vars[0][0]->crnti = 0x1235;
UE->pdcch_vars[1][0]->crnti = 0x1235;
}
+
UE->rx_total_gain_dB = rxgain;
UE->tx_power_max_dBm = txpowermax;
-
UE->frame_parms.nb_antennas_tx = fp0->nb_antennas_tx;
- UE->frame_parms.nb_antennas_rx = fp0->nb_antennas_rx;
+ UE->frame_parms.nb_antennas_rx = fp0->nb_antennas_rx;
if (fp->frame_type == TDD) {
switch (fp->N_RB_DL) {
+ case 100:
+ if (fp->threequarter_fs) UE->N_TA_offset = (624*3)/4;
+ else UE->N_TA_offset = 624;
- case 100:
- if (fp->threequarter_fs) UE->N_TA_offset = (624*3)/4;
- else UE->N_TA_offset = 624;
- break;
- case 75:
- UE->N_TA_offset = (624*3)/4;
- break;
- case 50:
- UE->N_TA_offset = 624/2;
- break;
- case 25:
- UE->N_TA_offset = 624/4;
- break;
- case 15:
- UE->N_TA_offset = 624/8;
- break;
- case 6:
- UE->N_TA_offset = 624/16;
- break;
- default:
- AssertFatal(1==0,"illegal N_RB_DL %d\n",fp->N_RB_DL);
- break;
+ break;
+
+ case 75:
+ UE->N_TA_offset = (624*3)/4;
+ break;
+
+ case 50:
+ UE->N_TA_offset = 624/2;
+ break;
+
+ case 25:
+ UE->N_TA_offset = 624/4;
+ break;
+
+ case 15:
+ UE->N_TA_offset = 624/8;
+ break;
+
+ case 6:
+ UE->N_TA_offset = 624/16;
+ break;
+
+ default:
+ AssertFatal(1==0,"illegal N_RB_DL %d\n",fp->N_RB_DL);
+ break;
}
- }
- else UE->N_TA_offset = 0;
+ } else UE->N_TA_offset = 0;
-#if BASIC_SIMULATOR
- /* this is required for the basic simulator in TDD mode
- * TODO: find a proper cleaner solution
- */
- UE->N_TA_offset = 0;
-#endif
+ if( IS_SOFTMODEM_BASICSIM)
+ /* this is required for the basic simulator in TDD mode
+ * TODO: find a proper cleaner solution
+ */
+ UE->N_TA_offset = 0;
if (simL1flag == 1) init_ue_devices(UE);
+
LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
init_UE_threads(inst);
if (simL1flag == 0) {
ret = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
- if (ret !=0){
- exit_fun("Error loading device library");
+
+ if (ret !=0) {
+ exit_fun("Error loading device library");
}
}
+
UE->rfdevice.host_type = RAU_HOST;
// UE->rfdevice.type = NONE_DEV;
-
AssertFatal(0 == pthread_create(&UE->proc.pthread_ue,
&UE->proc.attr_ue,
UE_thread,
- (void*)UE), "");
+ (void *)UE), "");
}
printf("UE threads created by %ld\n", gettid());
@@ -376,31 +381,24 @@ void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correcti
// Initiating all UEs within a single set of threads for PHY_STUB. Future extensions -> multiple
// set of threads for multiple UEs.
void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface) {
-
int inst;
-
LOG_I(PHY,"UE : Calling Layer 2 for initialization, nb_inst: %d \n", nb_inst);
-
l2_init_ue(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
- 0,// cba_group_active
- 0); // HO flag
-
- for (inst=0;instMod_id);
init_thread(100000, 500000, FIFO_PRIORITY-1, &cpuset, threadname);
-
printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch);
ind = 0;
found = 0;
-
if (UE->UE_scan == 0) {
do {
current_band = eutra_bands[ind].band;
printf( "Scanning band %d, dl_min %"PRIu32", ul_min %"PRIu32"\n", current_band, eutra_bands[ind].dl_min,eutra_bands[ind].ul_min);
if ((eutra_bands[ind].dl_min <= UE->frame_parms.dl_CarrierFreq) && (eutra_bands[ind].dl_max >= UE->frame_parms.dl_CarrierFreq)) {
- for (i=0; i<4; i++)
- uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min;
+ for (i=0; i<4; i++)
+ uplink_frequency_offset[CC_id][i] = eutra_bands[ind].ul_min - eutra_bands[ind].dl_min;
found = 1;
break;
@@ -501,241 +489,240 @@ static void *UE_thread_synch(void *arg)
return &UE_thread_synch_retval;
}
+ LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", UE->frame_parms.dl_CarrierFreq, UE->frame_parms.ul_CarrierFreq,oai_exit,
+ openair0_cfg[0].rx_num_channels);
- LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu32", UL %"PRIu32" (oai_exit %d, rx_num_channels %d)\n", UE->frame_parms.dl_CarrierFreq, UE->frame_parms.ul_CarrierFreq,oai_exit, openair0_cfg[0].rx_num_channels);
-
- for (i=0;irf_map.card].rx_num_channels;i++) {
+ for (i=0; irf_map.card].rx_num_channels; i++) {
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq;
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq;
openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
+
if (uplink_frequency_offset[CC_id][i] != 0) //
- openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD;
+ openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD;
else //FDD
- openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD;
+ openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD;
}
sync_mode = pbch;
-
} else if (UE->UE_scan == 1) {
current_band=0;
for (i=0; irf_map.card].rx_num_channels; i++) {
downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[CC_id].dl_min;
uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] =
- bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min;
+ bands_to_scan.band_info[CC_id].ul_min-bands_to_scan.band_info[CC_id].dl_min;
openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
- downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
+ downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
}
}
-/*
- while (sync_var<0)
- pthread_cond_wait(&sync_cond, &sync_mutex);
- pthread_mutex_unlock(&sync_mutex);
-*/
+ /*
+ while (sync_var<0)
+ pthread_cond_wait(&sync_cond, &sync_mutex);
+ pthread_mutex_unlock(&sync_mutex);
+ */
wait_sync("UE_thread_sync");
-
printf("Started device, unlocked sync_mutex (UE_sync_thread)\n");
while (oai_exit==0) {
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
+
while (UE->proc.instance_cnt_synch < 0)
// the thread waits here most of the time
pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch );
+
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
switch (sync_mode) {
- case pss:
- LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
- lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
- current_offset += 20000000; // increase by 20 MHz
+ case pss:
+ LOG_I(PHY,"[SCHED][UE] Scanning band %d (%d), freq %u\n",bands_to_scan.band_info[current_band].band, current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
+ lte_sync_timefreq(UE,current_band,bands_to_scan.band_info[current_band].dl_min+current_offset);
+ current_offset += 20000000; // increase by 20 MHz
- if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
- current_band++;
- current_offset=0;
- }
+ if (current_offset > bands_to_scan.band_info[current_band].dl_max-bands_to_scan.band_info[current_band].dl_min) {
+ current_band++;
+ current_offset=0;
+ }
- if (current_band==bands_to_scan.nbands) {
- current_band=0;
- oai_exit=1;
- }
+ if (current_band==bands_to_scan.nbands) {
+ current_band=0;
+ oai_exit=1;
+ }
- for (i=0; irf_map.card].rx_num_channels; i++) {
- downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
- uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
+ for (i=0; irf_map.card].rx_num_channels; i++) {
+ downlink_frequency[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].dl_min+current_offset;
+ uplink_frequency_offset[UE->rf_map.card][UE->rf_map.chain+i] = bands_to_scan.band_info[current_band].ul_min-bands_to_scan.band_info[0].dl_min + current_offset;
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
+ openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
+ openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
- openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i];
- openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i];
- openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;
- if (UE->UE_scan_carrier) {
- openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
- }
- }
+ if (UE->UE_scan_carrier) {
+ openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
+ }
+ }
- break;
+ break;
- case pbch:
+ case pbch:
+ LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
-#if DISABLE_LOG_X
- printf("[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
-#else
- LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
-#endif
- if (initial_sync( UE, UE->mode ) == 0) {
+ if (initial_sync( UE, UE->mode ) == 0) {
+ LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
+ (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti,
+ freq_offset,
+ UE->rx_total_gain_dB,
+ downlink_frequency[0][0]+freq_offset,
+ downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
+ UE->UE_scan_carrier );
- LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
- (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti,
- freq_offset,
- UE->rx_total_gain_dB,
- downlink_frequency[0][0]+freq_offset,
- downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
- UE->UE_scan_carrier );
+ // rerun with new cell parameters and frequency-offset
+ for (i=0; irf_map.card].rx_num_channels; i++) {
+ openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
+ if (UE->UE_scan_carrier == 1) {
+ if (freq_offset >= 0)
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset);
+ else
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset);
- // rerun with new cell parameters and frequency-offset
- for (i=0; irf_map.card].rx_num_channels; i++) {
- openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
- if (UE->UE_scan_carrier == 1) {
- if (freq_offset >= 0)
- openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset);
- else
- openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset);
- openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
- openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
- downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
- freq_offset=0;
- }
- }
+ openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
+ downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
+ freq_offset=0;
+ }
+ }
- // reconfigure for potentially different bandwidth
- switch(UE->frame_parms.N_RB_DL) {
- case 6:
- openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
- openair0_cfg[UE->rf_map.card].rx_bw =.96e6;
- openair0_cfg[UE->rf_map.card].tx_bw =.96e6;
- // openair0_cfg[0].rx_gain[0] -= 12;
- break;
- case 25:
- openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
- openair0_cfg[UE->rf_map.card].rx_bw =2.5e6;
- openair0_cfg[UE->rf_map.card].tx_bw =2.5e6;
- // openair0_cfg[0].rx_gain[0] -= 6;
- break;
- case 50:
- openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
- openair0_cfg[UE->rf_map.card].rx_bw =5.0e6;
- openair0_cfg[UE->rf_map.card].tx_bw =5.0e6;
- // openair0_cfg[0].rx_gain[0] -= 3;
- break;
- case 100:
- openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
- openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
- openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
- // openair0_cfg[0].rx_gain[0] -= 0;
- break;
- }
+ // reconfigure for potentially different bandwidth
+ switch(UE->frame_parms.N_RB_DL) {
+ case 6:
+ openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
+ openair0_cfg[UE->rf_map.card].rx_bw =.96e6;
+ openair0_cfg[UE->rf_map.card].tx_bw =.96e6;
+ // openair0_cfg[0].rx_gain[0] -= 12;
+ break;
- UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
- //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
- //UE->rfdevice.trx_stop_func(&UE->rfdevice);
- sleep(1);
- init_frame_parms(&UE->frame_parms,1);
- /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
- LOG_E(HW,"Could not start the device\n");
- oai_exit=1;
- }*/
+ case 25:
+ openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
+ openair0_cfg[UE->rf_map.card].rx_bw =2.5e6;
+ openair0_cfg[UE->rf_map.card].tx_bw =2.5e6;
+ // openair0_cfg[0].rx_gain[0] -= 6;
+ break;
- if (UE->UE_scan_carrier == 1) {
+ case 50:
+ openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
+ openair0_cfg[UE->rf_map.card].rx_bw =5.0e6;
+ openair0_cfg[UE->rf_map.card].tx_bw =5.0e6;
+ // openair0_cfg[0].rx_gain[0] -= 3;
+ break;
- UE->UE_scan_carrier = 0;
- } else {
- AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
- UE->is_synchronized = 1;
- AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
+ case 100:
+ openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
+ openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
+ openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
+ // openair0_cfg[0].rx_gain[0] -= 0;
+ break;
+ }
- if( UE->mode == rx_dump_frame ) {
- FILE *fd;
- if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present
- if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
- fwrite((void*)&UE->common_vars.rxdata[0][0],
- sizeof(int32_t),
- 10*UE->frame_parms.samples_per_tti,
- fd);
- LOG_I(PHY,"Dummping Frame ... bye bye \n");
- fclose(fd);
- exit(0);
- } else {
- LOG_E(PHY,"Cannot open file for writing\n");
- exit(0);
- }
- } else {
- AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
- UE->is_synchronized = 0;
- AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
+ UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
+ //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
+ //UE->rfdevice.trx_stop_func(&UE->rfdevice);
+ sleep(1);
+ init_frame_parms(&UE->frame_parms,1);
- }
- }
- }
- } else {
- // initial sync failed
- // calculate new offset and try again
- if (UE->UE_scan_carrier == 1) {
- if (freq_offset >= 0)
- freq_offset += 100;
- freq_offset *= -1;
+ /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
+ LOG_E(HW,"Could not start the device\n");
+ oai_exit=1;
+ }*/
- if (abs(freq_offset) > 7500) {
- LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" );
- FILE *fd;
- if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) {
- fwrite((void*)&UE->common_vars.rxdata[0][0],
- sizeof(int32_t),
- 10*UE->frame_parms.samples_per_tti,
- fd);
- LOG_I(PHY,"Dummping Frame ... bye bye \n");
- fclose(fd);
- exit(0);
- }
- AssertFatal(1==0,"No cell synchronization found, abandoning");
- return &UE_thread_synch_retval; // not reached
- }
- }
-#if DISABLE_LOG_X
- printf("[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
- freq_offset,
- UE->rx_total_gain_dB,
- downlink_frequency[0][0]+freq_offset,
- downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
-#else
- LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
- freq_offset,
- UE->rx_total_gain_dB,
- downlink_frequency[0][0]+freq_offset,
- downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
-#endif
+ if (UE->UE_scan_carrier == 1) {
+ UE->UE_scan_carrier = 0;
+ } else {
+ AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
+ UE->is_synchronized = 1;
+ AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
- for (i=0; irf_map.card].rx_num_channels; i++) {
- openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
- openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
- openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
- if (UE->UE_scan_carrier==1)
- openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
- }
- UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
- }// initial_sync=0
- break;
- case si:
- default:
- break;
+ if( UE->mode == rx_dump_frame ) {
+ FILE *fd;
+
+ if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) { // this guarantees SIB1 is present
+ if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
+ fwrite((void *)&UE->common_vars.rxdata[0][0],
+ sizeof(int32_t),
+ 10*UE->frame_parms.samples_per_tti,
+ fd);
+ LOG_I(PHY,"Dummping Frame ... bye bye \n");
+ fclose(fd);
+ exit(0);
+ } else {
+ LOG_E(PHY,"Cannot open file for writing\n");
+ exit(0);
+ }
+ } else {
+ AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
+ UE->is_synchronized = 0;
+ AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
+ }
+ }
+ }
+ } else {
+ // initial sync failed
+ // calculate new offset and try again
+ if (UE->UE_scan_carrier == 1) {
+ if (freq_offset >= 0)
+ freq_offset += 100;
+
+ freq_offset *= -1;
+
+ if (abs(freq_offset) > 7500) {
+ LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" );
+ FILE *fd;
+
+ if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) {
+ fwrite((void *)&UE->common_vars.rxdata[0][0],
+ sizeof(int32_t),
+ 10*UE->frame_parms.samples_per_tti,
+ fd);
+ LOG_I(PHY,"Dummping Frame ... bye bye \n");
+ fclose(fd);
+ exit(0);
+ }
+
+ AssertFatal(1==0,"No cell synchronization found, abandoning");
+ return &UE_thread_synch_retval; // not reached
+ }
+ }
+
+ LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
+ freq_offset,
+ UE->rx_total_gain_dB,
+ downlink_frequency[0][0]+freq_offset,
+ downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
+
+ for (i=0; irf_map.card].rx_num_channels; i++) {
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
+ openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
+ openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
+
+ if (UE->UE_scan_carrier==1)
+ openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
+ }
+
+ UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
+ }// initial_sync=0
+
+ break;
+
+ case si:
+ default:
+ break;
}
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
// indicate readiness
UE->proc.instance_cnt_synch--;
AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
-
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 );
} // while !oai_exit
@@ -749,15 +736,18 @@ static void *UE_thread_synch(void *arg)
* \param arg is a pointer to a \ref PHY_VARS_UE structure.
* \returns a pointer to an int. The storage is not on the heap and must not be freed.
*/
-const char * get_connectionloss_errstr(int errcode) {
- switch (errcode) {
- case CONNECTION_LOST:
- return "RRC Connection lost, returning to PRACH";
- case PHY_RESYNCH:
- return "RRC Connection lost, trying to resynch";
- case RESYNCH:
- return "return to PRACH and perform a contention-free access";
- };
+const char *get_connectionloss_errstr(int errcode) {
+ switch (errcode) {
+ case CONNECTION_LOST:
+ return "RRC Connection lost, returning to PRACH";
+
+ case PHY_RESYNCH:
+ return "RRC Connection lost, trying to resynch";
+
+ case RESYNCH:
+ return "return to PRACH and perform a contention-free access";
+ };
+
return "UNKNOWN RETURN CODE";
}
@@ -766,9 +756,7 @@ static void *UE_thread_rxn_txnp4(void *arg) {
struct rx_tx_thread_data *rtd = arg;
UE_rxtx_proc_t *proc = rtd->proc;
PHY_VARS_UE *UE = rtd->UE;
-
proc->subframe_rx=proc->sub_frame_start;
-
char threadname[256];
sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start);
cpu_set_t cpuset;
@@ -776,55 +764,56 @@ static void *UE_thread_rxn_txnp4(void *arg) {
if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 )
CPU_SET(threads.one, &cpuset);
+
if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 )
CPU_SET(threads.two, &cpuset);
+
if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 )
CPU_SET(threads.three, &cpuset);
+
//CPU_SET(threads.three, &cpuset);
- init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
- threadname);
+ init_thread(900000,1000000, FIFO_PRIORITY-1, &cpuset,
+ threadname);
while (!oai_exit) {
if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("nothing to add");
}
+
while (proc->instance_cnt_rxtx < 0) {
// most of the time, the thread is waiting here
pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );
}
- if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
- LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
- exit_fun("nothing to add");
- }
+ //printf("Processing sub frqme %d in %s\n", proc->subframe_rx, threadname);
initRefTimes(t2);
initRefTimes(t3);
pickTime(current);
updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");
-
// Process Rx data for one sub-frame
lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx);
- if ((sf_type == SF_DL) ||
- (UE->frame_parms.frame_type == FDD) ||
- (sf_type == SF_S)) {
+ if ((sf_type == SF_DL) ||
+ (UE->frame_parms.frame_type == FDD) ||
+ (sf_type == SF_S)) {
if (UE->frame_parms.frame_type == TDD) {
- LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n",
- threadname,
- UE->frame_parms.tdd_config,
- (sf_type==SF_DL? "SF_DL" :
- (sf_type==SF_UL? "SF_UL" :
- (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
+ LOG_D(PHY, "%s,TDD%d,%s: calling UE_RX\n",
+ threadname,
+ UE->frame_parms.tdd_config,
+ (sf_type==SF_DL? "SF_DL" :
+ (sf_type==SF_UL? "SF_UL" :
+ (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
} else {
- LOG_D(PHY, "%s,%s,%s: calling UE_RX\n",
- threadname,
- (UE->frame_parms.frame_type==FDD? "FDD":
- (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")),
- (sf_type==SF_DL? "SF_DL" :
- (sf_type==SF_UL? "SF_UL" :
- (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
+ LOG_D(PHY, "%s,%s,%s: calling UE_RX\n",
+ threadname,
+ (UE->frame_parms.frame_type==FDD? "FDD":
+ (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")),
+ (sf_type==SF_DL? "SF_DL" :
+ (sf_type==SF_UL? "SF_UL" :
+ (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
}
+
#ifdef UE_SLOT_PARALLELISATION
phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
@@ -835,49 +824,46 @@ static void *UE_thread_rxn_txnp4(void *arg) {
#if UE_TIMING_TRACE
start_meas(&UE->generic_stat);
#endif
- if (UE->mac_enabled==1) {
+ if (UE->mac_enabled==1) {
int ret = ue_scheduler(UE->Mod_id,
- proc->frame_rx,
- proc->subframe_rx,
- proc->frame_tx,
- proc->subframe_tx,
- subframe_select(&UE->frame_parms,proc->subframe_tx),
- 0,
- 0/*FIXME CC_id*/);
+ proc->frame_rx,
+ proc->subframe_rx,
+ proc->frame_tx,
+ proc->subframe_tx,
+ subframe_select(&UE->frame_parms,proc->subframe_tx),
+ 0,
+ 0/*FIXME CC_id*/);
+
if ( ret != CONNECTION_OK) {
- LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n",
- UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) );
+ LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n",
+ UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) );
}
}
+
#if UE_TIMING_TRACE
stop_meas(&UE->generic_stat);
#endif
-
// Prepare the future Tx data
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
- (UE->frame_parms.frame_type == FDD) )
+ (UE->frame_parms.frame_type == FDD) )
if (UE->mode != loop_through_memory)
- phy_procedures_UE_TX(UE,proc,0,0,UE->mode);
-
-
+ phy_procedures_UE_TX(UE,proc,0,0,UE->mode);
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_S) &&
- (UE->frame_parms.frame_type == TDD))
+ (UE->frame_parms.frame_type == TDD))
if (UE->mode != loop_through_memory)
- phy_procedures_UE_S_TX(UE,0,0);
- updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)");
+ phy_procedures_UE_S_TX(UE,0,0);
- if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
- LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
- exit_fun("noting to add");
- }
+ updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)");
proc->instance_cnt_rxtx--;
-#if BASIC_SIMULATOR
- if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort();
-#endif
+
+ if ( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) {
+ if (pthread_cond_signal(&proc->cond_rxtx) != 0) abort();
+ }
+
if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" );
exit_fun("noting to add");
@@ -894,61 +880,57 @@ static void *UE_thread_rxn_txnp4(void *arg) {
unsigned int emulator_absSF;
void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) {
-
PHY_VARS_UE *UE;
UE = PHY_vars_UE_g[0][0];
+ UE_tport_t *pdu = (UE_tport_t *)rx_buffer;
+ SLSCH_t *slsch = (SLSCH_t *)&pdu->slsch;
+ SLDCH_t *sldch = (SLDCH_t *)&pdu->sldch;
- UE_tport_t *pdu = (UE_tport_t*)rx_buffer;
- SLSCH_t *slsch = (SLSCH_t*)&pdu->slsch;
- SLDCH_t *sldch = (SLDCH_t*)&pdu->sldch;
+ switch (((UE_tport_header_t *)rx_buffer)->packet_type) {
+ case TTI_SYNC:
+ emulator_absSF = ((UE_tport_header_t *)rx_buffer)->absSF;
+ wakeup_thread(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread");
+ break;
- switch (((UE_tport_header_t*)rx_buffer)->packet_type) {
- case TTI_SYNC:
- emulator_absSF = ((UE_tport_header_t*)rx_buffer)->absSF;
- wakeup_thread(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread");
- break;
- case SLSCH:
+ case SLSCH:
+ LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLSCH packet\n",emulator_absSF/10,emulator_absSF%10);
+ LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLSCH payload (%d bytes) to MAC\n",num_bytes,
+ pdu->header.absSF/10,pdu->header.absSF%10,
+ slsch->payload_length);
+ printf("SLSCH:");
+ for (int i=0; iheader.absSF/10,pdu->header.absSF%10,
- slsch->payload_length);
- printf("SLSCH:");
- for (int i=0;iheader.absSF/10,
+ pdu->header.absSF%10,
+ pdu->payload,
+ slsch->payload_length,
+ 0,
+ SL_DISCOVERY_FLAG_NO);
+ break;
- ue_send_sl_sdu(0,
- 0,
- pdu->header.absSF/10,
- pdu->header.absSF%10,
- pdu->payload,
- slsch->payload_length,
- 0,
- SL_DISCOVERY_FLAG_NO);
- break;
+ case SLDCH:
+ LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLDCH packet\n",emulator_absSF/10,emulator_absSF%10);
+ LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLDCH payload (%d bytes) to MAC\n",num_bytes,
+ pdu->header.absSF/10,pdu->header.absSF%10,
+ sldch->payload_length);
+ printf("SLDCH:");
- case SLDCH:
-
-
- LOG_I(PHY,"Emulator SFN.SF %d.%d, Got SLDCH packet\n",emulator_absSF/10,emulator_absSF%10);
- LOG_I(PHY,"Received %d bytes on UE-UE link for SFN.SF %d.%d, sending SLDCH payload (%d bytes) to MAC\n",num_bytes,
- pdu->header.absSF/10,pdu->header.absSF%10,
- sldch->payload_length);
- printf("SLDCH:");
- for (int i=0;iheader.absSF/10,
- pdu->header.absSF%10,
- sldch->payload,
- sldch->payload_length,
- 0,
- SL_DISCOVERY_FLAG_YES);
- break;
+ for (int i=0; iheader.absSF/10,
+ pdu->header.absSF%10,
+ sldch->payload,
+ sldch->payload_length,
+ 0,
+ SL_DISCOVERY_FLAG_YES);
+ break;
}
}
@@ -962,21 +944,19 @@ void ue_stub_rx_handler(unsigned int num_bytes, char *rx_buffer) {
*/
static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
-
- thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L);
-
- // for multipule UE's L2-emulator
- //module_id_t Mod_id = 0;
-
- //int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames
+ thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L);
+ // for multipule UE's L2-emulator
+ //module_id_t Mod_id = 0;
+ //int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames
static __thread int UE_thread_rxtx_retval;
struct rx_tx_thread_data *rtd = arg;
- if (rtd == NULL) {
- LOG_E( MAC, "[SCHED][UE] rx_tx_thread_data *rtd: NULL pointer\n" );
- exit_fun("nothing to add");
- }
- UE_rxtx_proc_t *proc = rtd->proc;
+ if (rtd == NULL) {
+ LOG_E( MAC, "[SCHED][UE] rx_tx_thread_data *rtd: NULL pointer\n" );
+ exit_fun("nothing to add");
+ }
+
+ UE_rxtx_proc_t *proc = rtd->proc;
// settings for nfapi-L2-emulator mode
module_id_t ue_thread_id = rtd->ue_thread_id;
uint16_t ue_index = 0;
@@ -987,11 +967,9 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
uint8_t end_flag;
proc = &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0];
phy_stub_ticking->num_single_thread[ue_thread_id] = -1;
-
UE = rtd->UE;
-
- if(ue_thread_id == 0){
+ if(ue_thread_id == 0) {
phy_stub_ticking->ticking_var = -1;
proc->subframe_rx=proc->sub_frame_start;
// Initializations for nfapi-L2-emulator mode
@@ -1001,296 +979,287 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
tx_request_pdu_list = NULL;
// waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1.
- do{
+ do {
end_flag = 1;
- for(uint16_t i = 0;i< NB_THREAD_INST;i++){
- if(phy_stub_ticking->num_single_thread[i] == 0){
+
+ for(uint16_t i = 0; i< NB_THREAD_INST; i++) {
+ if(phy_stub_ticking->num_single_thread[i] == 0) {
end_flag = 0;
}
}
- }while(end_flag == 0);
+ } while(end_flag == 0);
sync_var=0;
}
-
//PANOS: CAREFUL HERE!
wait_sync("UE_phy_stub_single_thread_rxn_txnp4");
while (!oai_exit) {
- if(ue_thread_id == 0){
- if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) {
- LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" );
- exit_fun("nothing to add");
- }
- while (phy_stub_ticking->ticking_var < 0) {
- // most of the time, the thread is waiting here
- //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx )
- LOG_D(MAC,"Waiting for ticking_var\n");
- pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking);
- }
- phy_stub_ticking->ticking_var--;
- if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) {
- LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
- exit_fun("nothing to add");
- }
+ if(ue_thread_id == 0) {
+ if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) {
+ LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" );
+ exit_fun("nothing to add");
+ }
- proc->subframe_rx=timer_subframe;
- proc->frame_rx = timer_frame;
+ while (phy_stub_ticking->ticking_var < 0) {
+ // most of the time, the thread is waiting here
+ //pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx )
+ LOG_D(MAC,"Waiting for ticking_var\n");
+ pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking);
+ }
- // FDD and TDD tx timing settings.
- // XXX:It is the result of timing adjustment in debug.
- // It is necessary to investigate why this will work in the future.
- proc->subframe_tx=(timer_subframe+sf_ahead)%10;
- proc->frame_tx = proc->frame_rx + (proc->subframe_rx>(9-sf_ahead)?1:0);
- //oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
+ phy_stub_ticking->ticking_var--;
- if (UE != NULL) {
- if (UE->frame_parms.frame_type == FDD) {
- oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
+ if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) {
+ LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
+ exit_fun("nothing to add");
+ }
+
+ proc->subframe_rx=timer_subframe;
+ proc->frame_rx = timer_frame;
+ // FDD and TDD tx timing settings.
+ // XXX:It is the result of timing adjustment in debug.
+ // It is necessary to investigate why this will work in the future.
+ proc->subframe_tx=(timer_subframe+sf_ahead)%10;
+ proc->frame_tx = proc->frame_rx + (proc->subframe_rx>(9-sf_ahead)?1:0);
+ //oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
+
+ if (UE != NULL) {
+ if (UE->frame_parms.frame_type == FDD) {
+ oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
+ } else {
+ oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
+ }
} else {
- oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
+ // Default will be FDD
+ oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
+ }
+
+ //Guessing that the next 4 lines are not needed for the phy_stub mode.
+ /*initRefTimes(t2);
+ initRefTimes(t3);
+ pickTime(current);
+ updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");*/
+ // Not sure whether we should put the memory allocation here and not sure how much memory
+ //we should allocate for each subframe cycle.
+ UL_INFO = (UL_IND_t *)malloc(sizeof(UL_IND_t));
+ UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t));
+ UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
+ UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t));
+ UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0;
+ UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_harq_indication_pdu_t));
+ UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0;
+ UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t));
+ UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
+ UL_INFO->cqi_ind.cqi_pdu_list = (nfapi_cqi_indication_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t));
+ UL_INFO->cqi_ind.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t));
+ UL_INFO->cqi_ind.number_of_cqis = 0;
+
+ if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) {
+ LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
+ exit_fun("nothing to add");
+ }
+
+ memset(&phy_stub_ticking->num_single_thread[0],0,sizeof(int)*NB_THREAD_INST);
+ pthread_cond_broadcast(&phy_stub_ticking->cond_single_thread);
+
+ if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) {
+ LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
+ exit_fun("nothing to add");
}
} else {
- // Default will be FDD
- oai_subframe_ind(proc->frame_rx, proc->subframe_rx);
- }
+ if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) {
+ LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
+ exit_fun("nothing to add");
+ }
- //Guessing that the next 4 lines are not needed for the phy_stub mode.
- /*initRefTimes(t2);
- initRefTimes(t3);
- pickTime(current);
- updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");*/
+ while (phy_stub_ticking->num_single_thread[ue_thread_id] < 0) {
+ // most of the time, the thread is waiting here
+ LOG_D(MAC,"Waiting for single_thread (ue_thread_id %d)\n",ue_thread_id);
+ pthread_cond_wait( &phy_stub_ticking->cond_single_thread, &phy_stub_ticking->mutex_single_thread);
+ }
-
- // Not sure whether we should put the memory allocation here and not sure how much memory
- //we should allocate for each subframe cycle.
- UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t));
-
- UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = (nfapi_rx_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_rx_indication_pdu_t));
- UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
-
-
- UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = (nfapi_crc_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_crc_indication_pdu_t));
- UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0;
-
- UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_harq_indication_pdu_t));
- UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0;
-
- UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t));
- UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
-
- UL_INFO->cqi_ind.cqi_pdu_list = (nfapi_cqi_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t));
- UL_INFO->cqi_ind.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t));
- UL_INFO->cqi_ind.number_of_cqis = 0;
-
- if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) {
- LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
- exit_fun("nothing to add");
- }
- memset(&phy_stub_ticking->num_single_thread[0],0,sizeof(int)*NB_THREAD_INST);
- pthread_cond_broadcast(&phy_stub_ticking->cond_single_thread);
-
- if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) {
- LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
- exit_fun("nothing to add");
- }
- }else{
- if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) {
- LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
- exit_fun("nothing to add");
- }
- while (phy_stub_ticking->num_single_thread[ue_thread_id] < 0) {
- // most of the time, the thread is waiting here
- LOG_D(MAC,"Waiting for single_thread (ue_thread_id %d)\n",ue_thread_id);
- pthread_cond_wait( &phy_stub_ticking->cond_single_thread, &phy_stub_ticking->mutex_single_thread);
- }
- if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) {
- LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
- exit_fun("nothing to add");
- }
+ if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) {
+ LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id);
+ exit_fun("nothing to add");
+ }
}
//for (Mod_id=0; Mod_idframe_parms, proc->subframe_rx);
- if ((sf_type == SF_DL) ||
- (UE->frame_parms.frame_type == FDD) ||
- (sf_type == SF_S)) {
+ ue_Mod_id = ue_thread_id + NB_THREAD_INST*ue_index;
+ UE = PHY_vars_UE_g[ue_Mod_id][0];
+ //LOG_D(MAC, "UE_phy_stub_single_thread_rxn_txnp4, NB_UE_INST:%d, Mod_id:%d \n", NB_UE_INST, Mod_id);
+ //UE = PHY_vars_UE_g[Mod_id][0];
+ lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx);
- if (UE->frame_parms.frame_type == TDD) {
- LOG_D(PHY, "TDD%d,%s: calling UE_RX\n",
- UE->frame_parms.tdd_config,
- (sf_type==SF_DL? "SF_DL" :
- (sf_type==SF_UL? "SF_UL" :
- (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
- } else {
- LOG_D(PHY, "%s,%s: calling UE_RX\n",
- (UE->frame_parms.frame_type==FDD? "FDD":
- (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")),
- (sf_type==SF_DL? "SF_DL" :
- (sf_type==SF_UL? "SF_UL" :
- (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
+ if ((sf_type == SF_DL) ||
+ (UE->frame_parms.frame_type == FDD) ||
+ (sf_type == SF_S)) {
+ if (UE->frame_parms.frame_type == TDD) {
+ LOG_D(PHY, "TDD%d,%s: calling UE_RX\n",
+ UE->frame_parms.tdd_config,
+ (sf_type==SF_DL? "SF_DL" :
+ (sf_type==SF_UL? "SF_UL" :
+ (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
+ } else {
+ LOG_D(PHY, "%s,%s: calling UE_RX\n",
+ (UE->frame_parms.frame_type==FDD? "FDD":
+ (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")),
+ (sf_type==SF_DL? "SF_DL" :
+ (sf_type==SF_UL? "SF_UL" :
+ (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
+ }
+
+ phy_procedures_UE_SL_RX(UE,proc);
+
+ if (dl_config_req!=NULL && tx_request_pdu_list!=NULL) {
+ //if(dl_config_req!= NULL) {
+ dl_config_req_UE_MAC(dl_config_req, ue_Mod_id);
+ }
+
+ if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) {
+ hi_dci0_req_UE_MAC(hi_dci0_req, ue_Mod_id);
+ }
+
+ if(nfapi_mode!=3)
+ phy_procedures_UE_SL_TX(UE,proc);
}
+#if UE_TIMING_TRACE
+ start_meas(&UE->generic_stat);
+#endif
+
+ if (UE->mac_enabled==1) {
+ ret = ue_scheduler(ue_Mod_id,
+ proc->frame_rx,
+ proc->subframe_rx,
+ proc->frame_tx,
+ proc->subframe_tx,
+ subframe_select(&UE->frame_parms,proc->subframe_tx),
+ 0,
+ 0/*FIXME CC_id*/);
+
+ if ( ret != CONNECTION_OK) {
+ LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n",
+ UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) );
+ }
+ }
+
+#if UE_TIMING_TRACE
+ stop_meas(&UE->generic_stat);
+#endif
+
+ // Prepare the future Tx data
+
+ if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
+ (UE->frame_parms.frame_type == FDD) )
+ if (UE->mode != loop_through_memory) {
+ // We make the start of RA between consecutive UEs differ by 20 frames
+ //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) {
+ if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH && ue_Mod_id == next_Mod_id) {
+ next_ra_frame++;
+
+ if(next_ra_frame > 200) {
+ // check if we have PRACH opportunity
+ if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1) {
+ // The one working strangely...
+ //if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) {
+ PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
+
+ if(prach_resources!=NULL ) {
+ UE_mac_inst[ue_Mod_id].ra_frame = proc->frame_rx;
+ LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id,proc->frame_tx, proc->subframe_tx);
+ fill_rach_indication_UE_MAC(ue_Mod_id, proc->frame_tx,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
+ Msg1_transmitted(ue_Mod_id, 0, proc->frame_tx, 0);
+ UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE;
+ next_Mod_id = ue_Mod_id + 1;
+ //next_ra_frame = (proc->frame_rx + 20)%1000;
+ next_ra_frame = 0;
+ }
+
+ //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+ }
+ }
+ } // mode is PRACH
+
+ // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
+ // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
+ // Generate UL_indications which correspond to UL traffic.
+ if(ul_config_req!=NULL) { //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
+ ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, ue_Mod_id);
+ }
+ }
phy_procedures_UE_SL_RX(UE,proc);
-
- if (dl_config_req!=NULL && tx_request_pdu_list!=NULL){
- //if(dl_config_req!= NULL) {
- dl_config_req_UE_MAC(dl_config_req, ue_Mod_id);
-
- }
-
- if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
- hi_dci0_req_UE_MAC(hi_dci0_req, ue_Mod_id);
- }
-
- if(nfapi_mode!=3)
- phy_procedures_UE_SL_TX(UE,proc);
-
- }
-
-#if UE_TIMING_TRACE
- start_meas(&UE->generic_stat);
-#endif
-
- if (UE->mac_enabled==1) {
-
- ret = ue_scheduler(ue_Mod_id,
- proc->frame_rx,
- proc->subframe_rx,
- proc->frame_tx,
- proc->subframe_tx,
- subframe_select(&UE->frame_parms,proc->subframe_tx),
- 0,
- 0/*FIXME CC_id*/);
- if ( ret != CONNECTION_OK) {
- LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n",
- UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) );
- }
- }
-#if UE_TIMING_TRACE
- stop_meas(&UE->generic_stat);
-#endif
-
-
- // Prepare the future Tx data
-
- if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
- (UE->frame_parms.frame_type == FDD) )
- if (UE->mode != loop_through_memory){
-
- // We make the start of RA between consecutive UEs differ by 20 frames
- //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) {
- if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH && ue_Mod_id == next_Mod_id) {
- next_ra_frame++;
- if(next_ra_frame > 200){
- // check if we have PRACH opportunity
-
- if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1) {
-
- // The one working strangely...
- //if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) {
-
- PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
- if(prach_resources!=NULL ) {
- UE_mac_inst[ue_Mod_id].ra_frame = proc->frame_rx;
- LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id ,proc->frame_tx, proc->subframe_tx);
- fill_rach_indication_UE_MAC(ue_Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
- Msg1_transmitted(ue_Mod_id, 0, proc->frame_tx, 0);
- UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE;
- next_Mod_id = ue_Mod_id + 1;
- //next_ra_frame = (proc->frame_rx + 20)%1000;
- next_ra_frame = 0;
- }
-
- //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
- }
- }
- } // mode is PRACH
- // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
- // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
- // Generate UL_indications which correspond to UL traffic.
- if(ul_config_req!=NULL){ //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
- ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, ue_Mod_id);
- }
- }
-
- phy_procedures_UE_SL_RX(UE,proc);
-
-
} //for (Mod_id=0; Mod_idnum_single_thread[ue_thread_id] = -1;
// waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1.
- if(ue_thread_id == 0){
- do{
+ if(ue_thread_id == 0) {
+ do {
end_flag = 1;
- for(uint16_t i = 0;i< NB_THREAD_INST;i++){
- if(phy_stub_ticking->num_single_thread[i] == 0){
- end_flag = 0;
+
+ for(uint16_t i = 0; i< NB_THREAD_INST; i++) {
+ if(phy_stub_ticking->num_single_thread[i] == 0) {
+ end_flag = 0;
}
}
- }while(end_flag == 0);
+ } while(end_flag == 0);
+ if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0) {
+ //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf));
+ //LOG_I(MAC, "ul_config_req_UE_MAC 2.2, SFN/SF of PNF counter:%d.%d, number_of_crcs: %d \n", timer_frame, timer_subframe, UL_INFO->crc_ind.crc_indication_body.number_of_crcs);
+ oai_nfapi_crc_indication(&UL_INFO->crc_ind);
+ //LOG_I(MAC, "ul_config_req_UE_MAC 2.21 \n");
+ UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0;
+ }
- if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0)
- {
- //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf));
- //LOG_I(MAC, "ul_config_req_UE_MAC 2.2, SFN/SF of PNF counter:%d.%d, number_of_crcs: %d \n", timer_frame, timer_subframe, UL_INFO->crc_ind.crc_indication_body.number_of_crcs);
- oai_nfapi_crc_indication(&UL_INFO->crc_ind);
- //LOG_I(MAC, "ul_config_req_UE_MAC 2.21 \n");
- UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0;
- }
- if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus>0)
- {
- //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf));
- //LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus);
- oai_nfapi_rx_ind(&UL_INFO->rx_ind);
- for(uint8_t num_pdu = 0;num_pdu < UL_INFO->rx_ind.rx_indication_body.number_of_pdus;num_pdu++){
- free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[num_pdu].data);
- }
- //LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n");
- UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
- }
- if(UL_INFO->harq_ind.harq_indication_body.number_of_harqs>0)
- {
- //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs);
- oai_nfapi_harq_indication(&UL_INFO->harq_ind);
- //LOG_I(MAC, "ul_config_req_UE_MAC 2.41 \n");
- UL_INFO->harq_ind.harq_indication_body.number_of_harqs =0;
+ if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus>0) {
+ //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf));
+ //LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus);
+ oai_nfapi_rx_ind(&UL_INFO->rx_ind);
+ for(uint8_t num_pdu = 0; num_pdu < UL_INFO->rx_ind.rx_indication_body.number_of_pdus; num_pdu++) {
+ free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[num_pdu].data);
+ }
+
+ //LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n");
+ UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0;
}
- if(UL_INFO->sr_ind.sr_indication_body.number_of_srs>0)
- {
- //LOG_I(MAC, "ul_config_req_UE_MAC 2.5, SFN/SF of PNF counter:%d.%d, number_of_srs: %d \n", timer_frame, timer_subframe, UL_INFO->sr_ind.sr_indication_body.number_of_srs);
- oai_nfapi_sr_indication(&UL_INFO->sr_ind);
- //LOG_I(MAC, "ul_config_req_UE_MAC 2.51 \n");
- UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
+
+ if(UL_INFO->harq_ind.harq_indication_body.number_of_harqs>0) {
+ //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs);
+ oai_nfapi_harq_indication(&UL_INFO->harq_ind);
+ //LOG_I(MAC, "ul_config_req_UE_MAC 2.41 \n");
+ UL_INFO->harq_ind.harq_indication_body.number_of_harqs =0;
+ }
+
+ if(UL_INFO->sr_ind.sr_indication_body.number_of_srs>0) {
+ //LOG_I(MAC, "ul_config_req_UE_MAC 2.5, SFN/SF of PNF counter:%d.%d, number_of_srs: %d \n", timer_frame, timer_subframe, UL_INFO->sr_ind.sr_indication_body.number_of_srs);
+ oai_nfapi_sr_indication(&UL_INFO->sr_ind);
+ //LOG_I(MAC, "ul_config_req_UE_MAC 2.51 \n");
+ UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0;
}
// Free UL_INFO messages
//if(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list != NULL){
- free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list);
- UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL;
+ free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list);
+ UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL;
//}
//if(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list != NULL){
- free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list);
- UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL;
+ free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list);
+ UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL;
//}
//if(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list !=NULL){
- free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list);
- UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL;
+ free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list);
+ UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL;
//}
//if(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list!=NULL){
- free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list);
- UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL;
+ free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list);
+ UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL;
//}
free(UL_INFO->cqi_ind.cqi_pdu_list);
UL_INFO->cqi_ind.cqi_pdu_list = NULL;
@@ -1300,43 +1269,48 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
UL_INFO = NULL;
// De-allocate memory of nfapi requests copies before next subframe round
- if(dl_config_req!=NULL){
- if(dl_config_req->vendor_extension!=NULL){
- free(dl_config_req->vendor_extension);
- dl_config_req->vendor_extension = NULL;
- }
- if(dl_config_req->dl_config_request_body.dl_config_pdu_list!=NULL){
- free(dl_config_req->dl_config_request_body.dl_config_pdu_list);
- dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL;
- }
- free(dl_config_req);
- dl_config_req = NULL;
- }
- if(tx_request_pdu_list!=NULL){
- free(tx_request_pdu_list);
- tx_request_pdu_list = NULL;
- }
- if(ul_config_req!=NULL){
- if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
- free(ul_config_req->ul_config_request_body.ul_config_pdu_list);
- ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL;
- }
- free(ul_config_req);
- ul_config_req = NULL;
+ if(dl_config_req!=NULL) {
+ if(dl_config_req->vendor_extension!=NULL) {
+ free(dl_config_req->vendor_extension);
+ dl_config_req->vendor_extension = NULL;
+ }
+
+ if(dl_config_req->dl_config_request_body.dl_config_pdu_list!=NULL) {
+ free(dl_config_req->dl_config_request_body.dl_config_pdu_list);
+ dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL;
+ }
+
+ free(dl_config_req);
+ dl_config_req = NULL;
}
- if(hi_dci0_req!=NULL){
- if(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
- free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list);
- hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL;
- }
- free(hi_dci0_req);
- hi_dci0_req = NULL;
+ if(tx_request_pdu_list!=NULL) {
+ free(tx_request_pdu_list);
+ tx_request_pdu_list = NULL;
}
+ if(ul_config_req!=NULL) {
+ if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) {
+ free(ul_config_req->ul_config_request_body.ul_config_pdu_list);
+ ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL;
+ }
+
+ free(ul_config_req);
+ ul_config_req = NULL;
+ }
+
+ if(hi_dci0_req!=NULL) {
+ if(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) {
+ free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list);
+ hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL;
+ }
+
+ free(hi_dci0_req);
+ hi_dci0_req = NULL;
+ }
}
-
}
+
// thread finished
free(arg);
return &UE_thread_rxtx_retval;
@@ -1354,34 +1328,32 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) {
*/
static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
-
- thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L);
-
- module_id_t Mod_id = 0;
+ thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L);
+ module_id_t Mod_id = 0;
static __thread int UE_thread_rxtx_retval;
struct rx_tx_thread_data *rtd = arg;
UE_rxtx_proc_t *proc = rtd->proc;
PHY_VARS_UE *UE = rtd->UE;
-
phy_stub_ticking->ticking_var = -1;
proc->subframe_rx=proc->sub_frame_start;
-
// CAREFUL HERE!
wait_sync("UE_phy_stub_thread_rxn_txnp4");
while (!oai_exit) {
-
if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) {
LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" );
exit_fun("nothing to add");
}
+
while (phy_stub_ticking->ticking_var < 0) {
// most of the time, the thread is waiting here
//pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx )
LOG_D(MAC,"Waiting for ticking_var\n");
pthread_cond_wait( &phy_stub_ticking->cond_ticking, &phy_stub_ticking->mutex_ticking);
}
+
phy_stub_ticking->ticking_var--;
+
if (pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) != 0) {
LOG_E( MAC, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
exit_fun("nothing to add");
@@ -1391,125 +1363,118 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
proc->frame_rx = timer_frame;
proc->subframe_tx=(timer_subframe+4)%10;
proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
-
-
// Process Rx data for one sub-frame
lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx);
+
if ((sf_type == SF_DL) ||
- (UE->frame_parms.frame_type == FDD) ||
- (sf_type == SF_S)) {
-
+ (UE->frame_parms.frame_type == FDD) ||
+ (sf_type == SF_S)) {
if (UE->frame_parms.frame_type == TDD) {
- LOG_D(PHY, "TDD%d,%s: calling UE_RX\n",
- UE->frame_parms.tdd_config,
- (sf_type==SF_DL? "SF_DL" :
- (sf_type==SF_UL? "SF_UL" :
- (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
+ LOG_D(PHY, "TDD%d,%s: calling UE_RX\n",
+ UE->frame_parms.tdd_config,
+ (sf_type==SF_DL? "SF_DL" :
+ (sf_type==SF_UL? "SF_UL" :
+ (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
} else {
- LOG_D(PHY, "%s,%s: calling UE_RX\n",
- (UE->frame_parms.frame_type==FDD? "FDD":
- (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")),
- (sf_type==SF_DL? "SF_DL" :
- (sf_type==SF_UL? "SF_UL" :
- (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
+ LOG_D(PHY, "%s,%s: calling UE_RX\n",
+ (UE->frame_parms.frame_type==FDD? "FDD":
+ (UE->frame_parms.frame_type==TDD? "TDD":"UNKNOWN_DUPLEX_MODE")),
+ (sf_type==SF_DL? "SF_DL" :
+ (sf_type==SF_UL? "SF_UL" :
+ (sf_type==SF_S ? "SF_S" : "UNKNOWN_SF_TYPE"))));
}
-
phy_procedures_UE_SL_RX(UE,proc);
-
- oai_subframe_ind(timer_frame, timer_subframe);
+ oai_subframe_ind(timer_frame, timer_subframe);
if(dl_config_req!= NULL) {
-
- dl_config_req_UE_MAC(dl_config_req, Mod_id);
-
+ dl_config_req_UE_MAC(dl_config_req, Mod_id);
}
+
//if(UE_mac_inst[Mod_id].hi_dci0_req!= NULL){
- if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
- hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id);
- //if(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
- free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list);
- hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL;
- //}
- free(hi_dci0_req);
- hi_dci0_req = NULL;
+ if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL) {
+ hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id);
+ //if(UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){
+ free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list);
+ hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL;
+ //}
+ free(hi_dci0_req);
+ hi_dci0_req = NULL;
+ } else if(hi_dci0_req!=NULL) {
+ free(hi_dci0_req);
+ hi_dci0_req = NULL;
}
- else if(hi_dci0_req!=NULL){
- free(hi_dci0_req);
- hi_dci0_req = NULL;
- }
-
if (nfapi_mode != 3)
phy_procedures_UE_SL_TX(UE,proc);
-
}
#if UE_TIMING_TRACE
start_meas(&UE->generic_stat);
#endif
- if (UE->mac_enabled==1) {
+ if (UE->mac_enabled==1) {
int ret = ue_scheduler(UE->Mod_id,
- proc->frame_rx,
- proc->subframe_rx,
- proc->frame_tx,
- proc->subframe_tx,
- subframe_select(&UE->frame_parms,proc->subframe_tx),
- 0,
- 0);
+ proc->frame_rx,
+ proc->subframe_rx,
+ proc->frame_tx,
+ proc->subframe_tx,
+ subframe_select(&UE->frame_parms,proc->subframe_tx),
+ 0,
+ 0);
+
if (ret != CONNECTION_OK)
- LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n",
- UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) );
+ LOG_E( PHY, "[UE %"PRIu8"] Frame %"PRIu32", subframe %u %s\n",
+ UE->Mod_id, proc->frame_rx, proc->subframe_tx,get_connectionloss_errstr(ret) );
}
+
#if UE_TIMING_TRACE
stop_meas(&UE->generic_stat);
#endif
-
// Prepare the future Tx data
if ((subframe_select( &UE->frame_parms, proc->subframe_tx) == SF_UL) ||
- (UE->frame_parms.frame_type == FDD) )
- if (UE->mode != loop_through_memory){
+ (UE->frame_parms.frame_type == FDD) )
+ if (UE->mode != loop_through_memory) {
+ if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH) ) {
+ // check if we have PRACH opportunity
+ if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx)) {
+ PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
- if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH) ) {
+ if(prach_resources!=NULL) {
+ fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
+ Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0);
+ UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE;
+ }
- // check if we have PRACH opportunity
+ //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+ }
+ } // mode is PRACH
- if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx)) {
- PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx);
- if(prach_resources!=NULL) {
- fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI);
- Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0);
- UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE;
- }
+ // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
+ // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
+ // Generate UL_indications which correspond to UL traffic.
+ if(ul_config_req!= NULL && ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) {
+ //LOG_I(MAC, "UE_phy_stub_thread_rxn_txnp4 ul_config_req is not NULL \n");
+ ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id);
- //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
- }
- } // mode is PRACH
- // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger
- // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB).
- // Generate UL_indications which correspond to UL traffic.
- if(ul_config_req!= NULL && ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
- //LOG_I(MAC, "UE_phy_stub_thread_rxn_txnp4 ul_config_req is not NULL \n");
- ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id);
- if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){
- free(ul_config_req->ul_config_request_body.ul_config_pdu_list);
- ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL;
- }
- free(ul_config_req);
- ul_config_req = NULL;
- }
- else if(ul_config_req!=NULL){
- free(ul_config_req);
- ul_config_req = NULL;
- }
+ if(ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) {
+ free(ul_config_req->ul_config_request_body.ul_config_pdu_list);
+ ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL;
+ }
+
+ free(ul_config_req);
+ ul_config_req = NULL;
+ } else if(ul_config_req!=NULL) {
+ free(ul_config_req);
+ ul_config_req = NULL;
+ }
}
phy_procedures_UE_SL_RX(UE,proc);
-
}
+
// thread finished
free(arg);
return &UE_thread_rxtx_retval;
@@ -1528,39 +1493,34 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) {
*/
void *UE_thread(void *arg) {
-
-
PHY_VARS_UE *UE = (PHY_VARS_UE *) arg;
// int tx_enabled = 0;
int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32)));
openair0_timestamp timestamp,timestamp1;
- void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
+ void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
int start_rx_stream = 0;
int i;
int th_id;
-
static uint8_t thread_idx = 0;
-
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
+
if ( threads.iq != -1 )
CPU_SET(threads.iq, &cpuset);
- init_thread(100000, 500000, FIFO_PRIORITY, &cpuset,
- "UHD Threads");
+ init_thread(100000, 500000, FIFO_PRIORITY, &cpuset,
+ "UHD Threads");
/*
while (sync_var<0)
pthread_cond_wait(&sync_cond, &sync_mutex);
pthread_mutex_unlock(&sync_mutex);
*/
-
wait_sync("UE thread");
#ifdef NAS_UE
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE);
itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p);
#endif
-
int sub_frame=-1;
//int cumulated_shift=0;
@@ -1570,12 +1530,11 @@ void *UE_thread(void *arg) {
}
while (!oai_exit) {
-#if BASIC_SIMULATOR
- while (!(UE->proc.instance_cnt_synch < 0)) {
- printf("ue sync not ready\n");
- usleep(500*1000);
- }
-#endif
+ if (IS_SOFTMODEM_BASICSIM)
+ while (!(UE->proc.instance_cnt_synch < 0)) {
+ printf("ue sync not ready\n");
+ usleep(500*1000);
+ }
AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
int instance_cnt_synch = UE->proc.instance_cnt_synch;
@@ -1584,217 +1543,241 @@ void *UE_thread(void *arg) {
if (is_synchronized == 0) {
if (instance_cnt_synch < 0) { // we can invoke the synch
- // grab 10 ms of signal and wakeup synch thread
- for (int i=0; iframe_parms.nb_antennas_rx; i++)
- rxp[i] = (void*)&UE->common_vars.rxdata[i][0];
+ // grab 10 ms of signal and wakeup synch thread
+ for (int i=0; iframe_parms.nb_antennas_rx; i++)
+ rxp[i] = (void *)&UE->common_vars.rxdata[i][0];
- if (UE->mode != loop_through_memory)
- AssertFatal( UE->frame_parms.samples_per_tti*10 ==
- UE->rfdevice.trx_read_func(&UE->rfdevice,
- ×tamp,
- rxp,
- UE->frame_parms.samples_per_tti*10,
- UE->frame_parms.nb_antennas_rx), "");
- AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
- instance_cnt_synch = ++UE->proc.instance_cnt_synch;
- if (instance_cnt_synch == 0) {
- AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), "");
- } else {
- LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" );
- exit_fun("nothing to add");
- }
- AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
+ if (UE->mode != loop_through_memory)
+ AssertFatal( UE->frame_parms.samples_per_tti*10 ==
+ UE->rfdevice.trx_read_func(&UE->rfdevice,
+ ×tamp,
+ rxp,
+ UE->frame_parms.samples_per_tti*10,
+ UE->frame_parms.nb_antennas_rx), "");
+
+ AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
+ instance_cnt_synch = ++UE->proc.instance_cnt_synch;
+
+ if (instance_cnt_synch == 0) {
+ AssertFatal( 0 == pthread_cond_signal(&UE->proc.cond_synch), "");
+ } else {
+ LOG_E( PHY, "[SCHED][UE] UE sync thread busy!!\n" );
+ exit_fun("nothing to add");
+ }
+
+ AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
} else {
#if OAISIM
- (void)dummy_rx; /* avoid gcc warnings */
- usleep(500);
+ (void)dummy_rx; /* avoid gcc warnings */
+ usleep(500);
#else
- // grab 10 ms of signal into dummy buffer
- if (UE->mode != loop_through_memory) {
- for (int i=0; iframe_parms.nb_antennas_rx; i++)
- rxp[i] = (void*)&dummy_rx[i][0];
- for (int sf=0; sf<10; sf++)
- // printf("Reading dummy sf %d\n",sf);
- UE->rfdevice.trx_read_func(&UE->rfdevice,
- ×tamp,
- rxp,
- UE->frame_parms.samples_per_tti,
- UE->frame_parms.nb_antennas_rx);
- }
+
+ // grab 10 ms of signal into dummy buffer
+ if (UE->mode != loop_through_memory) {
+ for (int i=0; iframe_parms.nb_antennas_rx; i++)
+ rxp[i] = (void *)&dummy_rx[i][0];
+
+ for (int sf=0; sf<10; sf++)
+ // printf("Reading dummy sf %d\n",sf);
+ UE->rfdevice.trx_read_func(&UE->rfdevice,
+ ×tamp,
+ rxp,
+ UE->frame_parms.samples_per_tti,
+ UE->frame_parms.nb_antennas_rx);
+ }
+
#endif
- }
+ }
+ } // UE->is_synchronized==0
+ else {
+ if (start_rx_stream==0) {
+ start_rx_stream=1;
- } // UE->is_synchronized==0
- else {
- if (start_rx_stream==0) {
- start_rx_stream=1;
- if (UE->mode != loop_through_memory) {
- if (UE->no_timing_correction==0) {
- LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
- AssertFatal(UE->rx_offset ==
- UE->rfdevice.trx_read_func(&UE->rfdevice,
- ×tamp,
- (void**)UE->common_vars.rxdata,
- UE->rx_offset,
- UE->frame_parms.nb_antennas_rx),"");
- }
- UE->rx_offset=0;
- UE->time_sync_cell=0;
- //UE->proc.proc_rxtx[0].frame_rx++;
- //UE->proc.proc_rxtx[1].frame_rx++;
- for (th_id=0; th_id < RX_NB_TH; th_id++) {
- UE->proc.proc_rxtx[th_id].frame_rx++;
- }
+ if (UE->mode != loop_through_memory) {
+ if (UE->no_timing_correction==0) {
+ LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
+ AssertFatal(UE->rx_offset ==
+ UE->rfdevice.trx_read_func(&UE->rfdevice,
+ ×tamp,
+ (void **)UE->common_vars.rxdata,
+ UE->rx_offset,
+ UE->frame_parms.nb_antennas_rx),"");
+ }
- // read in first symbol
- AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
- UE->rfdevice.trx_read_func(&UE->rfdevice,
- ×tamp,
- (void**)UE->common_vars.rxdata,
- UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
- UE->frame_parms.nb_antennas_rx),"");
- slot_fep(UE,0, 0, 0, 0, 0);
- } //UE->mode != loop_through_memory
- else
- rt_sleep_ns(1000*1000);
+ UE->rx_offset=0;
+ UE->time_sync_cell=0;
+ //UE->proc.proc_rxtx[0].frame_rx++;
+ //UE->proc.proc_rxtx[1].frame_rx++;
+ for (th_id=0; th_id < RX_NB_TH; th_id++) {
+ UE->proc.proc_rxtx[th_id].frame_rx++;
+ }
+
+ // read in first symbol
+ AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
+ UE->rfdevice.trx_read_func(&UE->rfdevice,
+ ×tamp,
+ (void **)UE->common_vars.rxdata,
+ UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
+ UE->frame_parms.nb_antennas_rx),"");
+ slot_fep(UE,0, 0, 0, 0, 0);
+ } //UE->mode != loop_through_memory
+ else
+ rt_sleep_ns(1000*1000);
+ } else {
+ sub_frame++;
+ sub_frame%=10;
+ UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx];
+ // update thread index for received subframe
+ UE->current_thread_id[sub_frame] = thread_idx;
+
+ if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM ) {
+ int t;
+
+ for (t = 0; t < 2; t++) {
+ UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t];
+ pthread_mutex_lock(&proc->mutex_rxtx);
+
+ while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );
+
+ pthread_mutex_unlock(&proc->mutex_rxtx);
+ }
+ }
+
+ LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]);
+ thread_idx++;
+
+ if(thread_idx>=RX_NB_TH)
+ thread_idx = 0;
+
+ if (UE->mode != loop_through_memory) {
+ for (i=0; iframe_parms.nb_antennas_rx; i++)
+ rxp[i] = (void *)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+
+ UE->frame_parms.nb_prefix_samples0+
+ sub_frame*UE->frame_parms.samples_per_tti];
+
+ for (i=0; iframe_parms.nb_antennas_tx; i++)
+ txp[i] = (void *)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti];
+
+ int readBlockSize, writeBlockSize;
+
+ if (sub_frame<9) {
+ readBlockSize=UE->frame_parms.samples_per_tti;
+ writeBlockSize=UE->frame_parms.samples_per_tti;
+ } else {
+ // set TO compensation to zero
+ UE->rx_offset_diff = 0;
+
+ // compute TO compensation that should be applied for this frame
+
+ if (UE->no_timing_correction == 0) {
+ if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti &&
+ UE->rx_offset > 0 )
+ UE->rx_offset_diff = -1 ;
+
+ if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti &&
+ UE->rx_offset < 10*UE->frame_parms.samples_per_tti )
+ UE->rx_offset_diff = 1;
+ }
+
+ LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset);
+ readBlockSize=UE->frame_parms.samples_per_tti -
+ UE->frame_parms.ofdm_symbol_size -
+ UE->frame_parms.nb_prefix_samples0 -
+ UE->rx_offset_diff;
+ writeBlockSize=UE->frame_parms.samples_per_tti -
+ UE->rx_offset_diff;
+ }
+
+ AssertFatal(readBlockSize ==
+ UE->rfdevice.trx_read_func(&UE->rfdevice,
+ ×tamp,
+ rxp,
+ readBlockSize,
+ UE->frame_parms.nb_antennas_rx),"");
+ AssertFatal( writeBlockSize ==
+ UE->rfdevice.trx_write_func(&UE->rfdevice,
+ timestamp+
+ (2*UE->frame_parms.samples_per_tti) -
+ UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
+ openair0_cfg[0].tx_sample_advance,
+ txp,
+ writeBlockSize,
+ UE->frame_parms.nb_antennas_tx,
+ 1),"");
+
+ if( sub_frame==9) {
+ // read in first symbol of next frame and adjust for timing drift
+ int first_symbols=writeBlockSize-readBlockSize;
+
+ if ( first_symbols > 0 )
+ AssertFatal(first_symbols ==
+ UE->rfdevice.trx_read_func(&UE->rfdevice,
+ ×tamp1,
+ (void **)UE->common_vars.rxdata,
+ first_symbols,
+ UE->frame_parms.nb_antennas_rx),"");
+
+ if ( first_symbols <0 )
+ LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
+ }
+
+ pickTime(gotIQs);
+ struct timespec tv= {0};
+ tv.tv_nsec=10*1000;
+
+ if( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM)
+ tv.tv_sec=INT_MAX;
+
+ // operate on thread sf mod 2
+ if (pthread_mutex_timedlock(&proc->mutex_rxtx, &tv) !=0) {
+ if ( errno == ETIMEDOUT) {
+ LOG_E(PHY,"Missed real time\n");
+ continue;
} else {
- sub_frame++;
- sub_frame%=10;
- UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx];
- // update thread index for received subframe
- UE->current_thread_id[sub_frame] = thread_idx;
+ LOG_E(PHY,"System error\n");
+ abort();
+ }
+ }
-#if BASIC_SIMULATOR
- {
- int t;
- for (t = 0; t < 2; t++) {
- UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[t];
- pthread_mutex_lock(&proc->mutex_rxtx);
- while (proc->instance_cnt_rxtx >= 0) pthread_cond_wait( &proc->cond_rxtx, &proc->mutex_rxtx );
- pthread_mutex_unlock(&proc->mutex_rxtx);
- }
- }
-#endif
- LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]);
+ //usleep(3000);
+ if(sub_frame == 0) {
+ //UE->proc.proc_rxtx[0].frame_rx++;
+ //UE->proc.proc_rxtx[1].frame_rx++;
+ for (th_id=0; th_id < RX_NB_TH; th_id++) {
+ UE->proc.proc_rxtx[th_id].frame_rx++;
+ }
+ }
- thread_idx++;
- if(thread_idx>=RX_NB_TH)
- thread_idx = 0;
+ //UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
+ //UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
+ for (th_id=0; th_id < RX_NB_TH; th_id++) {
+ UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs);
+ }
+ proc->subframe_rx=sub_frame;
+ proc->subframe_tx=(sub_frame+4)%10;
+ proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
+ proc->timestamp_tx = timestamp+
+ (4*UE->frame_parms.samples_per_tti)-
+ UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
+ proc->instance_cnt_rxtx++;
+ LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
+ AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0,"");
+ AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
+ initRefTimes(t1);
+ initStaticTime(lastTime);
+ updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)");
+ pickStaticTime(lastTime);
+ } else {
+ printf("Processing subframe %d",proc->subframe_rx);
+ getchar();
+ }
+ } // start_rx_stream==1
+ } // UE->is_synchronized==1
+ } // while !oai_exit
- if (UE->mode != loop_through_memory) {
- for (i=0; iframe_parms.nb_antennas_rx; i++)
- rxp[i] = (void*)&UE->common_vars.rxdata[i][UE->frame_parms.ofdm_symbol_size+
- UE->frame_parms.nb_prefix_samples0+
- sub_frame*UE->frame_parms.samples_per_tti];
- for (i=0; iframe_parms.nb_antennas_tx; i++)
- txp[i] = (void*)&UE->common_vars.txdata[i][((sub_frame+2)%10)*UE->frame_parms.samples_per_tti];
-
- int readBlockSize, writeBlockSize;
- if (sub_frame<9) {
- readBlockSize=UE->frame_parms.samples_per_tti;
- writeBlockSize=UE->frame_parms.samples_per_tti;
- } else {
- // set TO compensation to zero
-
- UE->rx_offset_diff = 0;
-
- // compute TO compensation that should be applied for this frame
-
- if (UE->no_timing_correction == 0) {
- if ( UE->rx_offset < 5*UE->frame_parms.samples_per_tti &&
- UE->rx_offset > 0 )
- UE->rx_offset_diff = -1 ;
- if ( UE->rx_offset > 5*UE->frame_parms.samples_per_tti &&
- UE->rx_offset < 10*UE->frame_parms.samples_per_tti )
- UE->rx_offset_diff = 1;
- }
-
- LOG_D(PHY,"AbsSubframe %d.%d SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,sub_frame,UE->rx_offset_diff,UE->rx_offset);
- readBlockSize=UE->frame_parms.samples_per_tti -
- UE->frame_parms.ofdm_symbol_size -
- UE->frame_parms.nb_prefix_samples0 -
- UE->rx_offset_diff;
- writeBlockSize=UE->frame_parms.samples_per_tti -
- UE->rx_offset_diff;
- }
-
- AssertFatal(readBlockSize ==
- UE->rfdevice.trx_read_func(&UE->rfdevice,
- ×tamp,
- rxp,
- readBlockSize,
- UE->frame_parms.nb_antennas_rx),"");
- AssertFatal( writeBlockSize ==
- UE->rfdevice.trx_write_func(&UE->rfdevice,
- timestamp+
- (2*UE->frame_parms.samples_per_tti) -
- UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0 -
- openair0_cfg[0].tx_sample_advance,
- txp,
- writeBlockSize,
- UE->frame_parms.nb_antennas_tx,
- 1),"");
- if( sub_frame==9) {
- // read in first symbol of next frame and adjust for timing drift
- int first_symbols=writeBlockSize-readBlockSize;
- if ( first_symbols > 0 )
- AssertFatal(first_symbols ==
- UE->rfdevice.trx_read_func(&UE->rfdevice,
- ×tamp1,
- (void**)UE->common_vars.rxdata,
- first_symbols,
- UE->frame_parms.nb_antennas_rx),"");
- if ( first_symbols <0 )
- LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
- }
- pickTime(gotIQs);
- // operate on thread sf mod 2
- AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,"");
- if(sub_frame == 0) {
- //UE->proc.proc_rxtx[0].frame_rx++;
- //UE->proc.proc_rxtx[1].frame_rx++;
- for (th_id=0; th_id < RX_NB_TH; th_id++) {
- UE->proc.proc_rxtx[th_id].frame_rx++;
- }
- }
- //UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
- //UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
- for (th_id=0; th_id < RX_NB_TH; th_id++) {
- UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs);
- }
- proc->subframe_rx=sub_frame;
- proc->subframe_tx=(sub_frame+4)%10;
- proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
- proc->timestamp_tx = timestamp+
- (4*UE->frame_parms.samples_per_tti)-
- UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
-
- proc->instance_cnt_rxtx++;
- LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
- if (proc->instance_cnt_rxtx != 0) {
- LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", UE->Mod_id, proc->instance_cnt_rxtx);
- if (proc->instance_cnt_rxtx > 2)
- exit_fun("instance_cnt_rxtx > 2");
- }
-
- AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,"");
- AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
- initRefTimes(t1);
- initStaticTime(lastTime);
- updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)");
- pickStaticTime(lastTime);
-
- } else {
- printf("Processing subframe %d",proc->subframe_rx);
- getchar();
- }
- } // start_rx_stream==1
- } // UE->is_synchronized==1
-
- } // while !oai_exit
- return NULL;
+ return NULL;
}
@@ -1813,28 +1796,26 @@ void *UE_thread(void *arg) {
void init_UE_threads(int inst) {
struct rx_tx_thread_data *rtd;
PHY_VARS_UE *UE;
-
AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n");
AssertFatal(PHY_vars_UE_g[inst]!=NULL,"PHY_vars_UE_g[inst] is NULL\n");
AssertFatal(PHY_vars_UE_g[inst][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n");
UE = PHY_vars_UE_g[inst][0];
-
pthread_attr_init (&UE->proc.attr_ue);
pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN);
-
pthread_mutex_init(&UE->proc.mutex_synch,NULL);
pthread_cond_init(&UE->proc.cond_synch,NULL);
UE->proc.instance_cnt_synch = -1;
UE->is_synchronized = 0;
-
// the threads are not yet active, therefore access is allowed without locking
int nb_threads=RX_NB_TH;
+
for (int i=0; iUE = UE;
rtd->proc = &UE->proc.proc_rxtx[i];
-
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
UE->proc.proc_rxtx[i].instance_cnt_rxtx = -1;
@@ -1842,19 +1823,17 @@ void init_UE_threads(int inst) {
UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i);
pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd);
-
#ifdef UE_SLOT_PARALLELISATION
//pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot0_dl_processing,NULL);
//pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot0_dl_processing,NULL);
//pthread_create(&UE->proc.proc_rxtx[i].pthread_slot0_dl_processing,NULL,UE_thread_slot0_dl_processing, rtd);
-
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot1_dl_processing,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot1_dl_processing,NULL);
pthread_create(&UE->proc.proc_rxtx[i].pthread_slot1_dl_processing,NULL,UE_thread_slot1_dl_processing, rtd);
#endif
-
}
- pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
+
+ pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void *)UE);
}
@@ -1874,40 +1853,42 @@ void init_UE_single_thread_stub(int nb_inst) {
struct rx_tx_thread_data *rtd;
PHY_VARS_UE *UE;
- for (int i=0; iproc.attr_ue);
pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN);
-
// Don't need synch for phy_stub mode
//pthread_mutex_init(&UE->proc.mutex_synch,NULL);
//pthread_cond_init(&UE->proc.cond_synch,NULL);
-
// the threads are not yet active, therefore access is allowed without locking
// In phy_stub_UE mode due to less heavy processing operations we don't need two threads
//int nb_threads=RX_NB_TH;
int nb_threads=1;
- for(uint16_t ue_thread_id = 0;ue_thread_id < NB_THREAD_INST;ue_thread_id++){
+
+ for(uint16_t ue_thread_id = 0; ue_thread_id < NB_THREAD_INST; ue_thread_id++) {
UE = PHY_vars_UE_g[ue_thread_id][0];
+
for (int i=0; iUE = UE;
rtd->proc = &UE->proc.proc_rxtx[i];
rtd->ue_thread_id = ue_thread_id;
-
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
UE->proc.proc_rxtx[i].sub_frame_start=i;
@@ -1916,6 +1897,7 @@ void init_UE_single_thread_stub(int nb_inst) {
pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_single_thread_rxn_txnp4, rtd);
}
}
+
// Remove thread for UE_sync in phy_stub_UE mode.
//pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
}
@@ -1937,38 +1919,35 @@ void init_UE_single_thread_stub(int nb_inst) {
void init_UE_threads_stub(int inst) {
struct rx_tx_thread_data *rtd;
PHY_VARS_UE *UE;
-
AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n");
AssertFatal(PHY_vars_UE_g[inst]!=NULL,"PHY_vars_UE_g[inst] is NULL\n");
AssertFatal(PHY_vars_UE_g[inst][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n");
UE = PHY_vars_UE_g[inst][0];
-
pthread_attr_init (&UE->proc.attr_ue);
pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN);
-
// Don't need synch for phy_stub mode
//pthread_mutex_init(&UE->proc.mutex_synch,NULL);
//pthread_cond_init(&UE->proc.cond_synch,NULL);
-
// the threads are not yet active, therefore access is allowed without locking
// In phy_stub_UE mode due to less heavy processing operations we don't need two threads
//int nb_threads=RX_NB_TH;
int nb_threads=1;
+
for (int i=0; iUE = UE;
rtd->proc = &UE->proc.proc_rxtx[i];
-
pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
UE->proc.proc_rxtx[i].sub_frame_start=i;
UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i);
pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_thread_rxn_txnp4, rtd);
-
-
}
+
// Remove thread for UE_sync in phy_stub_UE mode.
//pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
}
@@ -1978,61 +1957,54 @@ void init_UE_threads_stub(int inst) {
#ifdef OPENAIR2
void fill_ue_band_info(void) {
-
LTE_UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability;
int i,j;
-
bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count;
for (i=0; irf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA) {
- memcpy(&bands_to_scan.band_info[i],
- &eutra_bands[j],
- sizeof(eutra_band_t));
-
- printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n",
- bands_to_scan.band_info[i].band,
- UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA,
- bands_to_scan.band_info[i].dl_min,
- bands_to_scan.band_info[i].dl_max,
- bands_to_scan.band_info[i].ul_min,
- bands_to_scan.band_info[i].ul_max,
- (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD");
- break;
+ memcpy(&bands_to_scan.band_info[i],
+ &eutra_bands[j],
+ sizeof(eutra_band_t));
+ printf("Band %d (%lu) : DL %u..%u Hz, UL %u..%u Hz, Duplex %s \n",
+ bands_to_scan.band_info[i].band,
+ UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.array[i]->bandEUTRA,
+ bands_to_scan.band_info[i].dl_min,
+ bands_to_scan.band_info[i].dl_max,
+ bands_to_scan.band_info[i].ul_min,
+ bands_to_scan.band_info[i].ul_max,
+ (bands_to_scan.band_info[i].frame_type==FDD) ? "FDD" : "TDD");
+ break;
}
}
}
#endif
int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg) {
-
int i, CC_id;
LTE_DL_FRAME_PARMS *frame_parms;
for (CC_id=0; CC_idframe_parms);
-
// replace RX signal buffers with mmaped HW versions
- rxdata = (int32_t**)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t*) );
- txdata = (int32_t**)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t*) );
+ rxdata = (int32_t **)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t *) );
+ txdata = (int32_t **)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t *) );
for (i=0; inb_antennas_rx; i++) {
LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %u on card %d, chain %d\n",
- CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
+ CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
free( phy_vars_ue[CC_id]->common_vars.rxdata[i] );
- rxdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
+ rxdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) );
phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
}
for (i=0; inb_antennas_tx; i++) {
LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %u on card %d, chain %d\n",
- CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
+ CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
free( phy_vars_ue[CC_id]->common_vars.txdata[i] );
- txdata[i] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
+ txdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) );
phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i];
}
@@ -2041,6 +2013,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg)
// be careful when releasing memory!
// because no "release_ue_buffers"-function is available, at least rxdata and txdata memory will leak (only some bytes)
}
+
return 0;
}
@@ -2053,7 +2026,7 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg)
// playing the role of nfapi-pnf.
//02/02/2018
-static void* timer_thread( void* param ) {
+static void *timer_thread( void *param ) {
thread_top_init("timer_thread",1,870000L,1000000L,1000000L);
timer_subframe =9;
timer_frame =1023;
@@ -2063,43 +2036,48 @@ static void* timer_thread( void* param ) {
UE = PHY_vars_UE_g[0][0];
//double t_diff;
int external_timer = 0;
-
-
wait_sync("timer_thread");
-
opp_enabled = 1;
// first check if we are receiving timing indications
if(nfapi_mode==4) {
- usleep(10000);
- if (UE->instance_cnt_timer > 0) {
- external_timer = 1;
- int absSFm1 = ((emulator_absSF+10239)%10240);
- timer_frame = absSFm1/10;
- timer_subframe = absSFm1%10;
- pthread_mutex_lock(&UE->timer_mutex);
- UE->instance_cnt_timer = -1;
- pthread_mutex_unlock(&UE->timer_mutex);
- LOG_I(PHY,"Running with external timer\n");
- }
- else LOG_I(PHY,"Running with internal timer\n");
+ usleep(10000);
+
+ if (UE->instance_cnt_timer > 0) {
+ external_timer = 1;
+ int absSFm1 = ((emulator_absSF+10239)%10240);
+ timer_frame = absSFm1/10;
+ timer_subframe = absSFm1%10;
+ pthread_mutex_lock(&UE->timer_mutex);
+ UE->instance_cnt_timer = -1;
+ pthread_mutex_unlock(&UE->timer_mutex);
+ LOG_I(PHY,"Running with external timer\n");
+ } else LOG_I(PHY,"Running with internal timer\n");
}
struct timespec t_start;
+
struct timespec t_now;
+
struct timespec t_sleep;
+
uint64_t T_0;
+
uint64_t T_now;
+
uint64_t T_next_SF;
+
uint64_t T_sleep;
+
uint64_t sf_cnt = 0; //Total Subframe counter
clock_gettime(CLOCK_MONOTONIC, &t_start);
+
T_0 = (uint64_t) t_start.tv_sec*1000000000 + t_start.tv_nsec;
+
LOG_D(MAC, "timer_thread(), T_0 value: %" PRId64 "\n", T_0);
while (!oai_exit) {
-
// these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
// They are set on the first rx/tx in the underly FH routines.
if (timer_subframe==9) {
@@ -2113,74 +2091,72 @@ static void* timer_thread( void* param ) {
//AssertFatal( 0 == pthread_cond_signal(&phy_stub_ticking->cond_ticking), "");
AssertFatal(pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) ==0,"");
phy_stub_ticking->ticking_var++;
+
// This should probably be a call to pthread_cond_broadcast when we introduce support for multiple UEs (threads)
- if(phy_stub_ticking->ticking_var == 0){
+ if(phy_stub_ticking->ticking_var == 0) {
//AssertFatal(phy_stub_ticking->ticking_var == 0,"phy_stub_ticking->ticking_var = %d",
- //phy_stub_ticking->ticking_var);
+ //phy_stub_ticking->ticking_var);
if (pthread_cond_signal(&phy_stub_ticking->cond_ticking) != 0) {
- //LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
- LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n");
- exit_fun("nothing to add");
+ //LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
+ LOG_E( PHY, "timer_thread ERROR pthread_cond_signal for UE_thread\n");
+ exit_fun("nothing to add");
}
- }
- else
- LOG_D(MAC, "timer_thread() Timing problem! ticking_var value:%d \n \n \n", phy_stub_ticking->ticking_var);
+ } else
+ LOG_D(MAC, "timer_thread() Timing problem! ticking_var value:%d \n \n \n", phy_stub_ticking->ticking_var);
AssertFatal(pthread_mutex_unlock(&phy_stub_ticking->mutex_ticking) ==0,"");
start_meas(&UE->timer_stats);
-
//clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); // get initial time-stamp
if (external_timer == 0) {
- clock_gettime(CLOCK_MONOTONIC, &t_now);
- sf_cnt++;
- T_next_SF = T_0 + sf_cnt*1000000;
- T_now =(uint64_t) t_now.tv_sec*1000000000 + t_now.tv_nsec;
- if(T_now > T_next_SF){
- t_sleep.tv_sec =0;
- t_sleep.tv_nsec =0;
- }
- else{
- T_sleep = T_next_SF - T_now;
- t_sleep.tv_sec =0;
- t_sleep.tv_nsec = (__syscall_slong_t) T_sleep;
- }
+ clock_gettime(CLOCK_MONOTONIC, &t_now);
+ sf_cnt++;
+ T_next_SF = T_0 + sf_cnt*1000000;
+ T_now =(uint64_t) t_now.tv_sec*1000000000 + t_now.tv_nsec;
+
+ if(T_now > T_next_SF) {
+ t_sleep.tv_sec =0;
+ t_sleep.tv_nsec =0;
+ } else {
+ T_sleep = T_next_SF - T_now;
+ t_sleep.tv_sec =0;
+ t_sleep.tv_nsec = (__syscall_slong_t) T_sleep;
+ }
+
nanosleep(&t_sleep, (struct timespec *)NULL);
UE_tport_t pdu;
pdu.header.packet_type = TTI_SYNC;
pdu.header.absSF = (timer_frame*10)+timer_subframe;
- if (nfapi_mode!=3){
- multicast_link_write_sock(0,
- (char *)&pdu,
- sizeof(UE_tport_header_t));
- }
- }
- else {
+ if (nfapi_mode!=3) {
+ multicast_link_write_sock(0,
+ (char *)&pdu,
+ sizeof(UE_tport_header_t));
+ }
+ } else {
wait_on_condition(&UE->timer_mutex,&UE->timer_cond,&UE->instance_cnt_timer,"timer_thread");
release_thread(&UE->timer_mutex,&UE->instance_cnt_timer,"timer_thread");
}
-
/*stop_meas(&UE->timer_stats);
t_diff = get_time_meas_us(&UE->timer_stats);
stop_meas(&UE->timer_stats);
t_diff = get_time_meas_us(&UE->timer_stats);*/
}
+
free(phy_stub_ticking);
pthread_cond_destroy(&phy_stub_ticking->cond_ticking);
pthread_mutex_destroy(&phy_stub_ticking->mutex_ticking);
return 0;
-
}
int init_timer_thread(void) {
//PHY_VARS_UE *UE=PHY_vars_UE_g[0];
- PHY_VARS_UE *UE=PHY_vars_UE_g[0][0];
- phy_stub_ticking = (SF_ticking*)malloc(sizeof(SF_ticking));
+ PHY_VARS_UE *UE=PHY_vars_UE_g[0][0];
+ phy_stub_ticking = (SF_ticking *)malloc(sizeof(SF_ticking));
pthread_mutex_init(&UE->timer_mutex,NULL);
pthread_cond_init(&UE->timer_cond,NULL);
UE->instance_cnt_timer = -1;
@@ -2197,8 +2173,7 @@ int init_timer_thread(void) {
/* HACK: this function is needed to compile the UE
* fix it somehow
*/
-int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
-{
+int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) {
printf("you cannot read this\n");
abort();
}
diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
index 5b2e6e4918..159cde39ae 100644
--- a/targets/RT/USER/lte-uesoftmodem.c
+++ b/targets/RT/USER/lte-uesoftmodem.c
@@ -440,10 +440,6 @@ static void get_options(void) {
if (dumpframe > 0) mode = rx_dump_frame;
-# if BASIC_SIMULATOR
- set_softmodem_optmask(SOFTMODEM_BASICSIM_BIT); //this BASIC_SIMULATOR should be a config option
-# endif
-
for (CC_id=0; CC_iddl_CarrierFreq = downlink_frequency[0][0];
}
@@ -754,7 +750,6 @@ int main( int argc, char **argv ) {
cpuf=get_cpu_freq_GHz();
pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL);
-#if defined(ENABLE_ITTI)
printf("ITTI init\n");
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
@@ -764,22 +759,22 @@ int main( int argc, char **argv ) {
}
MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
-#endif
init_opt();
- uint32_t pdcp_initmask = ((!IS_SOFTMODEM_NOS1) || IS_SOFTMODEM_NOKRNMOD)? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT);
+ uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1 )? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT);
- if ( IS_SOFTMODEM_BASICSIM || (nfapi_mode == 3) ) {
+ if ( IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_mode == 3) ) {
pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
}
+ if ( IS_SOFTMODEM_NOKRNMOD)
+ pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT;
+
pdcp_module_init( pdcp_initmask );
//TTN for D2D
-#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
printf ("RRC control socket\n");
rrc_control_socket_init();
printf ("PDCP PC5S socket\n");
pdcp_pc5_socket_init();
-#endif
// to make a graceful exit when ctrl-c is pressed
signal(SIGSEGV, signal_handler);
signal(SIGINT, signal_handler);