Commit 626d1079 authored by Raymond Knopp's avatar Raymond Knopp

Merge branch 'develop' into enhancement-10-harmony

Conflicts:
	cmake_targets/CMakeLists.txt
	openair1/SCHED/phy_mac_stub.c
	targets/RT/USER/lte-softmodem.c
	targets/RT/USER/lte-ue.c
parents a33bb694 889262e1
......@@ -32,3 +32,8 @@ job1:
- sshpass -p "$OAI_PASS" rsync -az -e "ssh -o StrictHostKeyChecking=no " --rsync-path="mkdir -p $NFS_TEST_RESULTS_DIR && rsync" $OPENAIR_DIR/cmake_targets/autotests/log $OAI_USER@localhost:$NFS_TEST_RESULTS_DIR
- sshpass -p "$OAI_PASS" rsync -az -e "ssh -o StrictHostKeyChecking=no " --rsync-path="mkdir -p $EXTERNAL_SHARE_DIR && rsync" $OPENAIR_DIR/cmake_targets/autotests/log $OAI_USER@localhost:$EXTERNAL_SHARE_DIR
- cat $OPENAIR_DIR/cmake_targets/autotests/log/results_autotests.xml
- exce_log=`egrep -i 'warning|error|critical|exception' $NFS_TEST_RESULTS_DIR/log/python_autotest.log `
- if [ -n "$exce_log" ]; then echo -e "\e[31mThere are errors in $NFS_TEST_RESULTS_DIR/log/python_autotest.log. Please check the logs\e[0m" ; fi
- exce_log=`egrep -i 'warning|error|critical|exception' $NFS_TEST_RESULTS_DIR/log/python_autotest_cleanup.log `
- if [ -n "$exce_log" ]; then echo -e "\e[31mThere are errors in $NFS_TEST_RESULTS_DIR/log/python_autotest_cleanup.log. Please check the logs\e[0m" ; fi
OpenAirInterface is under GNU GPLv3 license. The full GNU General Public License is included in this distribution in the file called "COPYING".
The OpenAirInterface (OAI) software is composed of six different parts:
openair1: 3GPP LTE Rel-8 PHY layer + PHY RF simulation
openair2: 3GPP LTE Rel-9 RLC/MAC/PDCP/RRC implementations, eNB application, X2AP. Note that for RLC, the following versions are userL UM_v9.3.0, TM_v9.3.0, and AM_v9.3.0. For PDCP, PDCP_v10.1.0 is used. For RRC, only LITE is used.
openair3: 3GPP LTE Rel9 and 10 MME/NAS, S+P-GW, HSS, S1AP (ENB and MME).
common: some common OAI utilities, other tools can be found at openair2/UTILS
targets: scripts to compile and lauch different system targets (simulation, emulation and real-time platforms, user-space tools for these platforms (tbd))
see README files in these subdirectories for more information
see also https://twiki.eurecom.fr/twiki/bin/view/OpenAirInterface/WebHome
OpenAirInterface is under OpenAirInterface Software Alliance license.
├── http://www.openairinterface.org/?page_id=101
├── http://www.openairinterface.org/?page_id=698
The OpenAirInterface (OAI) software is composed of the following parts:
openairinterface5g
├── cmake_targets: build utilities to compile (simulation, emulation and real-time platforms), and generated build files
├── common : some common OAI utilities, other tools can be found at openair2/UTILS
├── COPYING
├── maketags : script to generate emacs tags
├── openair1 : 3GPP LTE Rel-10 PHY layer + PHY RF simulation and a subset of Rel 12 Features.
├── openair2 :3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP implementation.
├── LAYER2/RLC/ with the following subdirectories: UM_v9.3.0, TM_v9.3.0, and AM_v9.3.0.
├── LAYER2/PDCP/PDCP_v10.1.0.
├── RRC/LITE
├── PHY_INTERFACE
├── X2AP
├── ENB_APP
├── openair3: 3GPP LTE Rel10 for S1AP, NAS GTPV1-U for both ENB and UE.
├── GTPV1-U
├── NAS
├── S1AP
├── SCTP
├── SECU
├── UDP
└── targets: top level wrapper for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW.
......@@ -260,6 +260,7 @@ endif (${ENABLE_ITTI})
add_boolean_option(RTAI False "Use RTAI")
#############################
# ASN.1 grammar C code generation & dependancies
################################
......@@ -596,7 +597,7 @@ endif (${TRANSP_PRO} STREQUAL "ETHERNET")
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
Message("LOWLATENCY flag is ${LOWLATENCY}")
Message("DEADLINE_SCHEDULER flag is ${DEADLINE_SCHEDULER}")
Message("CPU_Affinity flag is ${CPU_AFFINITY}")
##############################################################
......@@ -610,7 +611,7 @@ add_boolean_option(RRC_DEFAULT_RAB_IS_AM False "set the RLC mode to AM for the d
add_boolean_option(OAI_NW_DRIVER_TYPE_ETHERNET False "????")
add_boolean_option(DISABLE_USE_NAS False "???")
add_boolean_option(LOWLATENCY True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14")
add_boolean_option(DEADLINE_SCHEDULER True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14")
add_boolean_option(CPU_AFFINITY False "Enable CPU Affinity of threads (only valid without deadline scheduler). It is enabled only with >2 CPUs")
add_boolean_option(NAS_ADDRESS_FIX False "specific to oaisim: for nasmesh driver")
add_boolean_option(NAS_NETLINK False "???? Must be True to compile nasmesh driver without rtai")
......
......@@ -29,10 +29,7 @@
# *******************************************************************************/
# \file test01.py
# \brief test 01 for OAI
# \author Navid Nikaein
# \date 2013 - 2015
# \author Rohit Gupta
# \version 0.1
# @ingroup _test
......@@ -316,12 +313,12 @@ def SSHSessionWrapper(machine, username, key_file, password, logdir_remote, logd
# \param CleanUpAluLteBox program to terminate AlU Bell Labs LTE Box
# \param ExmimoRfStop String to stop EXMIMO card (specified in test_case_list.xml)
def cleanOldPrograms(oai, programList, CleanUpAluLteBox, ExmimoRfStop):
cmd = 'killall -q -r ' + programList
cmd = 'killall -9 -q -r ' + programList
result = oai.send(cmd, True)
print "Killing old programs..." + result
programArray = programList.split()
programListJoin = '|'.join(programArray)
cmd = " ( date ;echo \"Starting cleaning old programs.. \" ; dmesg|tail )>& $HOME/.oai_test_setup_cleanup.log.`hostname` 2>&1 ; sync"
cmd = " ( date ;echo \"Starting cleaning old programs.. \" ; dmesg|tail ; echo \"Current disk space.. \" ; df -h )>& $HOME/.oai_test_setup_cleanup.log.`hostname` 2>&1 ; sync"
result=oai.send_recv(cmd)
cmd = cleanupOldProgramsScript + ' ' + '\''+programListJoin+'\''
#result = oai.send_recv(cmd)
......@@ -330,7 +327,7 @@ def cleanOldPrograms(oai, programList, CleanUpAluLteBox, ExmimoRfStop):
print "Looking for old programs..." + result
res=oai.send_recv(CleanUpAluLteBox, True)
cmd = "( " + ExmimoRfStop + " ) >> $HOME/.oai_test_setup_cleanup.log.`hostname` ; sync "
res=oai.send_recv(cmd, False)
res=oai.send_recv(cmd, False, timeout=600)
#res = oai.send_recv(ExmimoRfStop, False)
cmd = " ( date ;echo \"Finished cleaning old programs.. \" ; dmesg | tail)>> $HOME/.oai_test_setup_cleanup.log.`hostname` 2>&1 ; sync"
res=oai.send_recv(cmd)
......@@ -1529,9 +1526,8 @@ for testcase in testcaseList:
print "Now copying files to NFS Share"
oai_localhost = openair('localdomain','localhost')
oai_localhost.connect(user,pw)
cmd = ' rm -fr ' + NFSTestsResultsDir + ' ; mkdir -p ' + NFSTestsResultsDir
cmd = ' mkdir -p ' + NFSTestsResultsDir
res = oai_localhost.send_recv(cmd)
print "Deleting NFSTestResults Dir..." + res
print "Copying files from GilabCI Runner Machine : " + host + " .locallogdir = " + locallogdir + ", NFSTestsResultsDir = " + NFSTestsResultsDir
SSHSessionWrapper('localhost', user, None, pw , NFSTestsResultsDir , locallogdir, "put_all")
......@@ -1568,12 +1564,15 @@ res=os.system(cmd)
print "Now copying files to NFS Share"
oai_localhost = openair('localdomain','localhost')
oai_localhost.connect(user,pw)
cmd = ' rm -fr ' + NFSTestsResultsDir + ' ; mkdir -p ' + NFSTestsResultsDir
cmd = 'mkdir -p ' + NFSTestsResultsDir
res = oai_localhost.send_recv(cmd)
print "Deleting NFSTestResults Dir..." + res
print "Copying files from GilabCI Runner Machine : " + host + " .locallogdir = " + locallogdir + ", NFSTestsResultsDir = " + NFSTestsResultsDir
SSHSessionWrapper('localhost', user, None, pw , NFSTestsResultsDir , locallogdir, "put_all")
cmd = "cat " + NFSTestsResultsDir + "/log/*/*.xml > " + NFSTestsResultsDir + "/log/results_autotests.xml"
res = oai_localhost.send_recv(cmd)
oai_localhost.disconnect()
sys.exit()
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -141,6 +141,7 @@ def send_command (cmd, response, timeout):
error = error + ' In function: ' + sys._getframe().f_code.co_name + ': *** Caught exception: ' + str(e.__class__) + " : " + str( e)
error = error + traceback.format_exc()
print error
time.sleep(1)
def start_ue () :
......@@ -200,10 +201,12 @@ def reset_ue():
ProductId=res[0][3]
usb_dir= find_usb_path(VendorId, ProductId)
print "Bandrich 4G LTE Adapter found in..." + usb_dir
print "Sleeping now for 45 seconds...please wait..."
cmd = "sudo sh -c \"echo 0 > " + usb_dir + "/authorized\""
os.system(cmd + " ; sleep 15" )
cmd = "sudo sh -c \"echo 1 > " + usb_dir + "/authorized\""
os.system(cmd + " ; sleep 30" )
stop_ue()
i=1
gw='192.172.0.1'
......@@ -218,6 +221,7 @@ while i < len(sys.argv):
print 'Using Serial port : ' + serial_port
stop_ue()
elif arg == '--reset-ue' :
find_open_port()
reset_ue()
elif arg == '-gw' :
gw = sys.argv[i+1]
......
......@@ -143,6 +143,7 @@ def send_command (cmd, response, timeout):
error = error + ' In function: ' + sys._getframe().f_code.co_name + ': *** Caught exception: ' + str(e.__class__) + " : " + str( e)
error = error + traceback.format_exc()
print error
time.sleep(1)
def start_ue () :
......@@ -211,6 +212,7 @@ def reset_ue():
os.system(cmd + " ; sleep 15" )
cmd = "sudo sh -c \"echo 1 > " + usb_dir + "/authorized\""
os.system(cmd + " ; sleep 30" )
stop_ue()
i=1
gw='192.172.0.1'
......@@ -225,6 +227,7 @@ while i < len(sys.argv):
print 'Using Serial port : ' + serial_port
stop_ue()
elif arg == '--reset-ue' :
find_open_port()
reset_ue()
elif arg == '-gw' :
gw = sys.argv[i+1]
......
......@@ -43,7 +43,8 @@ def kill_processes(name):
cmd = 'sudo adb -s ' + device_id +' shell "ps |grep ' + name + '"'
status, out = commands.getstatusoutput(cmd)
if status != 0:
print "Error execting command to kill process " + name
print "Error executing command to kill process " + name
print "Error =" + out
sys.exit(1)
print "Out = " + out
if out=='':
......@@ -51,7 +52,7 @@ def kill_processes(name):
out_arr = out.split()
pid_to_kill = out_arr[1]
print "Now killing process ID " + pid_to_kill + " on Phone"
cmd = 'sudo adb -s ' + device_id +' shell "kill ' + pid_to_kill + '"'
cmd = 'sudo adb -s ' + device_id +' shell "kill -9 ' + pid_to_kill + '"'
status, out = commands.getstatusoutput(cmd)
if status != 0:
print "Error execting command to kill process " + name
......@@ -62,6 +63,7 @@ def start_ue () :
#print 'Enter your commands below.\r\nInsert "exit" to leave the application.'
print 'Killing old iperf/ping sessions'
kill_processes('iperf')
kill_processes('iperf3')
kill_processes('ping')
print "Turning off airplane mode"
os.system('sudo -E adb devices')
......@@ -93,6 +95,7 @@ def stop_ue():
os.system('sudo adb -s ' + device_id + ' shell \"settings put global airplane_mode_on 1; am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true\" ')
print "Killing iperf/ping sessions"
kill_processes('iperf')
kill_processes('iperf3')
kill_processes('ping')
i=1
......
#!/bin/bash
#******************************************************************************
# OpenAirInterface
# Copyright(c) 1999 - 2014 Eurecom
# OpenAirInterface is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# OpenAirInterface is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with OpenAirInterface.The full GNU General Public License is
# included in this distribution in the file called "COPYING". If not,
# see <http://www.gnu.org/licenses/>.
# Contact Information
# OpenAirInterface Admin: openair_admin@eurecom.fr
# OpenAirInterface Tech : openair_tech@eurecom.fr
# OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
# Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
# *******************************************************************************/
# \author Navid Nikaein, Rohit Gupta
#arg1 timeout to wait before running the script
#arg2 interface
#arg3 iperf arguments
args=($*)
timeout=${args[0]}
iface=${args[1]}
iperf3_args=(${args[@]:2})
#array=${1:-1}
echo "args = ${args[@]}"
echo "timeout = $timeout"
echo "iface = $iface"
echo "iperf3_args = ${iperf3_args[@]}"
sleep $timeout
while true; do var=`ifconfig $iface` ;sleep 1; if [ "$var" != "" ]; then break; fi ; done ; sleep 5
iperf3 ${iperf3_args[@]}
#!/bin/bash
#******************************************************************************
# OpenAirInterface
# Copyright(c) 1999 - 2014 Eurecom
# OpenAirInterface is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# OpenAirInterface is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with OpenAirInterface.The full GNU General Public License is
# included in this distribution in the file called "COPYING". If not,
# see <http://www.gnu.org/licenses/>.
# Contact Information
# OpenAirInterface Admin: openair_admin@eurecom.fr
# OpenAirInterface Tech : openair_tech@eurecom.fr
# OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
# Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
# *******************************************************************************/
# \author Navid Nikaein, Rohit Gupta
#arg1 timeout to wait before running the script
#arg2 interface
#arg3 iperf3 arguments
args=($*)
timeout=${args[0]}
device_id=${args[1]}
iperf3_args=(${args[@]:2})
#array=${1:-1}
echo "args = ${args[@]}"
echo "timeout = $timeout"
echo "device_id = $device_id"
echo "iperf3_args = ${iperf3_args[@]}"
sleep $timeout
while true ; do
cmd=`sudo adb -s $device_id shell netcfg |grep 192.`
if [ -z "$cmd" ]; then
echo "Wating for UE to connect and get IP Address..."
sleep 1
else
echo "UE is now connected. IP Address settings are... $cmd"
break
fi
done
echo "Starting iperf3 now..."
sudo adb -s $device_id shell /data/local/tmp/iperf3 ${iperf3_args[@]}
......@@ -54,9 +54,9 @@ file.close()
if keyword == 'mme_ip_address':
replacement_text = keyword + ' = ( { ' + replacement_text + ' } ) ; '
string = re.sub(r"mme_ip_address\s*=\s*\(([^\$]+?)\)\s*;", replacement_text, string, re.M)
elif keyword == 'IPV4_LIST':
elif keyword == 'IPV4_LIST' or keyword=='GUMMEI_LIST' or keyword == 'TAI_LIST':
replacement_text = keyword + ' = ( ' + replacement_text + ' ) ; '
string = re.sub(r"IPV4_LIST\s*=\s*\(([^\$]+?)\)\s*;", replacement_text, string, re.M)
string = re.sub(r"%s\s*=\s*\(([^\$]+?)\)\s*;" % keyword, replacement_text, string, re.M)
elif keyword == 'rrh_gw_config':
replacement_text = keyword + ' = ( { ' + replacement_text + ' } ) ; '
string = re.sub(r"rrh_gw_config\s*=\s*\(([^\$]+?)\)\s*;", replacement_text, string, re.M)
......
......@@ -45,8 +45,8 @@ MSC_GEN="False"
XFORMS="True"
PRINT_STATS="False"
VCD_TIMING="False"
LOWLATENCY_FLAG_USER="False"
FORCE_LOWLATENCY_FLAG_USER=""
DEADLINE_SCHEDULER_FLAG_USER="False"
FORCE_DEADLINE_SCHEDULER_FLAG_USER=""
CPU_AFFINITY_FLAG_USER="True" #Only valid when lowlatecy flag is set to False
REL="Rel10"
HW="None"
......@@ -125,7 +125,7 @@ Options
--disable-deadline
Disables deadline scheduler of Linux kernel (>=3.14.x).
--enable-deadline
Disables deadline scheduler of Linux kernel (>=3.14.x).
Enable deadline scheduler of Linux kernel (>=3.14.x).
--disable-cpu-affinity
Disables CPU Affinity between UHD/TX/RX Threads (Valid only when deadline scheduler is disabled). By defaulT, CPU Affinity is enabled when not using deadline scheduler. It is enabled only with >2 CPUs. For eNB, CPU_0-> Device library (UHD), CPU_1->TX Threads, CPU_2...CPU_MAX->Rx Threads. For UE, CPU_0->Device Library(UHD), CPU_1..CPU_MAX -> All the UE threads
Usage (first build):
......@@ -259,11 +259,11 @@ function main() {
echo_info "Will build doxygen support"
shift;;
--disable-deadline)
FORCE_LOWLATENCY_FLAG_USER="False"
FORCE_DEADLINE_SCHEDULER_FLAG_USER="False"
echo_info "Disabling the usage of deadline scheduler"
shift 1;;
--enable-deadline)
FORCE_LOWLATENCY_FLAG_USER="True"
FORCE_DEADLINE_SCHEDULER_FLAG_USER="True"
echo_info "Enabling the usage of deadline scheduler"
shift 1;;
--disable-cpu-affinity)
......@@ -314,33 +314,33 @@ function main() {
#By default: USRP: disable,
#By default: BLADERF: enable,
#By default: EXMIMO: enable
if [ "$FORCE_LOWLATENCY_FLAG_USER" = "" ]; then
if [ "$FORCE_DEADLINE_SCHEDULER_FLAG_USER" = "" ]; then
if [ "$HW" = "EXMIMO" ] ; then
LOWLATENCY_FLAG_USER="False"
DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "ETHERNET" ] ; then
LOWLATENCY_FLAG_USER="True"
DEADLINE_SCHEDULER_FLAG_USER="True"
elif [ "$HW" = "OAI_USRP" ] ; then
LOWLATENCY_FLAG_USER="False"
DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "OAI_BLADERF" ] ; then
LOWLATENCY_FLAG_USER="False"
DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "OAI_LMSSDR" ] ; then
LOWLATENCY_FLAG_USER="False"
DEADLINE_SCHEDULER_FLAG_USER="False"
elif [ "$HW" = "None" ] ; then
LOWLATENCY_FLAG_USER="False"
DEADLINE_SCHEDULER_FLAG_USER="False"
else
echo_error "Unknown HW type $HW. Exiting now..."
exit
fi
else
LOWLATENCY_FLAG_USER=$FORCE_LOWLATENCY_FLAG_USER
DEADLINE_SCHEDULER_FLAG_USER=$FORCE_DEADLINE_SCHEDULER_FLAG_USER
fi
#Disable CPU Affinity for deadline scheduler
if [ "$LOWLATENCY_FLAG_USER" = "True" ] ; then
if [ "$DEADLINE_SCHEDULER_FLAG_USER" = "True" ] ; then
CPU_AFFINITY_FLAG_USER="False"
fi
echo_info "Flags for Deadline scheduler: $LOWLATENCY_FLAG_USER"
echo_info "Flags for Deadline scheduler: $DEADLINE_SCHEDULER_FLAG_USER"
echo_info "Flags for CPU Affinity: $CPU_AFFINITY_FLAG_USER"
############################################
......@@ -432,7 +432,7 @@ function main() {
echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file
echo "set ( TRANSP_PRO \"${TP}\")" >> $cmake_file
echo "set(PACKAGE_NAME \"${lte_exec}\")" >> $cmake_file
echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )" >>$cmake_file
echo "set (DEADLINE_SCHEDULER \"${DEADLINE_SCHEDULER_FLAG_USER}\" )" >>$cmake_file
echo "set (CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >>$cmake_file
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
cd $DIR/$lte_build_dir/build
......@@ -660,7 +660,7 @@ function main() {
echo "set(RF_BOARD \"${HW}\")" >> $cmake_file
echo "set(TRANSP_PRO \"${TP}\")" >> $cmake_file
echo 'set(PACKAGE_NAME "\"rrh_gw\"")' >> $cmake_file
echo "set (LOWLATENCY \"${LOWLATENCY_FLAG_USER}\" )" >>$cmake_file
echo "set (DEADLINE_SCHEDULER \"${DEADLINE_SCHEDULER_FLAG_USER}\" )" >>$cmake_file
echo "set (CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )" >>$cmake_file
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
cd $DIR/$rrh_build_dir/build
......
......@@ -29,7 +29,7 @@ set ( LINUX_LIST False )
set ( LINUX True )
set ( LOCALIZATION False )
set ( LOG_NO_THREAD True )
set ( LOWLATENCY False )
set ( DEADLINE_SCHEDULER False )
set ( MAC_CONTEXT 1 )
set ( MAX_NUM_CCs 1 )
set ( MESSAGE_CHART_GENERATOR False)
......
......@@ -28,7 +28,7 @@ set ( LINUX_LIST False )
set ( LINUX True )
set ( LOCALIZATION False )
set ( LOG_NO_THREAD True )
set ( LOWLATENCY False )
set ( DEADLINE_SCHEDULER False )
set ( MAC_CONTEXT 1 )
set ( MAX_NUM_CCs 1 )
set ( MESSAGE_CHART_GENERATOR False)
......
......@@ -29,7 +29,7 @@ set ( LINUX_LIST False )
set ( LINUX False )
set ( LOCALIZATION False )
set ( LOG_NO_THREAD False )
set ( LOWLATENCY False )
set ( DEADLINE_SCHEDULER False )
set ( MAC_CONTEXT 1 )
set ( MAX_NUM_CCs 1 )
set ( MIH_C_MEDIEVAL_EXTENSIONS False )
......
......@@ -28,7 +28,7 @@ set ( LINUX_LIST False )
set ( LINUX True )
set ( LOCALIZATION False )
set ( LOG_NO_THREAD 1 )
set ( LOWLATENCY False )
set ( DEADLINE_SCHEDULER False )
set ( MAC_CONTEXT 1 )
set ( MAX_NUM_CCs 1 )
set ( MESSAGE_CHART_GENERATOR False )
......
......@@ -29,7 +29,7 @@ set ( LINUX_LIST False )
set ( LINUX True )
set ( LOCALIZATION False )
set ( LOG_NO_THREAD True )
set ( LOWLATENCY False )
set ( DEADLINE_SCHEDULER False )
set ( MAC_CONTEXT 1 )
set ( MAX_NUM_CCs 1 )
set ( MESSAGE_CHART_GENERATOR False)
......
......@@ -293,7 +293,8 @@ check_install_oai_software() {
python-numpy \
sshpass \
libxslt1-dev \
android-tools-adb
android-tools-adb \
iperf3
$SUDO update-alternatives --set liblapack.so /usr/lib/atlas-base/atlas/liblapack.so
......
......@@ -8,8 +8,12 @@ if [ "$OPENAIR_DIR" == "" ]; then
fi
sudo -E bash -c 'echo 3 > /proc/sys/vm/drop_caches'
#load the module
sudo -E $OPENAIR_DIR/cmake_targets/tools/init_exmimo2
exmimo_mod=`lsmod |grep openair_rf`
#load the module only if absent to avoid kernel crashes
if [ -z "$exmimo_mod" ]
then
sudo -E $OPENAIR_DIR/cmake_targets/tools/init_exmimo2
fi
#now we stop the card from transmitting anything
cd $OPENAIR_DIR/targets/bin
......
......@@ -159,7 +159,7 @@ uint16_t extract_crc(uint8_t *dci,uint8_t dci_len)
// dci[(dci_len>>3)+1] = 0;
// dci[(dci_len>>3)+2] = 0;
return((uint16_t)crc16);
}
......
......@@ -50,6 +50,7 @@
* @defgroup _GENERIC_PHY_RF_INTERFACE_ Generic PHY - RF Interface
* @defgroup _USRP_PHY_RF_INTERFACE_ PHY - USRP RF Interface
* @defgroup _BLADERF_PHY_RF_INTERFACE_ PHY - BLADERF RF Interface
* @defgroup _LMSSDR_PHY_RF_INTERFACE_ PHY - LMSSDR RF Interface
* @}
*
* @ingroup _ref_implementation_
......
......@@ -583,7 +583,6 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
{
//uint8_t cooperation_flag = eNB->cooperation_flag;
uint8_t transmission_mode = eNB->transmission_mode[0];
......
......@@ -37,6 +37,7 @@
#include <stdlib.h>
#include <inttypes.h>
#include "bladerf_lib.h"
#include "math.h"
/** @addtogroup _BLADERF_PHY_RF_INTERFACE_
* @{
......@@ -58,14 +59,16 @@ int num_devices=0;
/*! \brief BladeRF Init function (not used at the moment)
* \param device RF frontend parameters set by application
* \returns 0 on success
*/
int trx_brf_init(openair0_device *device) {
return 0;
}
/*! \brief get current timestamp
*\param device the hardware to use
*\param module the bladeRf module
*\returns timestamp of BladeRF
*/
openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module module) {
......@@ -83,28 +86,22 @@ openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module mod
}
/*! \brief Start BladeRF
*\param device the hardware to use
* \param device the hardware to use
* \returns 0 on success
*/
int trx_brf_start(openair0_device *device) {
return 0;
}
/*! \brief Get BladeRF stats
*\param device the hardware to use
*/
static void trx_brf_stats(openair0_device *device){
}
/*! \brief Called to send samples to the BladeRF RF target
@param device pointer to the device structure specific to the RF hardware target
@param timestamp The timestamp at whicch the first sample MUST be sent
@param buff Buffer which holds the samples
@param nsamps number of samples to be sent
@param cc index of the component carrier
@param flags Ignored for the moment
\param device pointer to the device structure specific to the RF hardware target
\param timestamp The timestamp at whicch the first sample MUST be sent
\param buff Buffer which holds the samples
\param nsamps number of samples to be sent
\param cc index of the component carrier
\param flags Ignored for the moment
\returns 0 on success
*/
static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp, void **buff, int nsamps, int cc, int flags) {
......@@ -156,6 +153,7 @@ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp,
* \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
* \param cc Index of component carrier
* \returns number of samples read
*/
static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
......@@ -176,9 +174,10 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
brf->num_rx_errors++;
} else if ( brf->meta_rx.status & BLADERF_META_STATUS_OVERRUN) {
brf->num_overflows++;
printf("RX overrun (%d) is detected. t=%u. Got %u samples. nsymps %d\n",
printf("RX overrun (%d) is detected. t=" "%" PRIu64 "Got %u samples. nsymps %d\n",
brf->num_overflows,brf->meta_rx.timestamp, brf->meta_rx.actual_count, nsamps);
}
//printf("Current RX timestampe %u\n", brf->meta_rx.timestamp);
//printf("[BRF] (buff %p) ts=0x%"PRIu64" %s\n",samples, brf->meta_rx.timestamp,bladerf_strerror(status));
brf->rx_current_ts=brf->meta_rx.timestamp;
......@@ -196,7 +195,7 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
/*! \brief Terminate operation of the BladeRF transceiver -- free all associated resources
* \param device the hardware to use
*/
int trx_brf_end(openair0_device *device) {
void trx_brf_end(openair0_device *device) {
int status;
brf_state_t *brf = (brf_state_t*)device->priv;
......@@ -208,7 +207,6 @@ int trx_brf_end(openair0_device *device) {
fprintf(stderr, "Failed to disable TX module: %s\n", bladerf_strerror(status));
}
bladerf_close(brf->dev);
return 0;
}
/*! \brief print the BladeRF statistics
......@@ -231,10 +229,11 @@ int trx_brf_reset_stats(openair0_device* device) {
}
/*! \brief Stop USRP
* \param device the hardware to use
/*! \brief Stop BladeRF
* \param card the hardware to use
* \returns 0 in success
*/
int trx_brf_stop(openair0_device* device) {
int trx_brf_stop(int card) {
return(0);
......@@ -242,9 +241,11 @@ int trx_brf_stop(openair0_device* device) {
/*! \brief Set frequencies (TX/RX)
* \param device the hardware to use
* \param openair0_cfg1 openair0 Config structure (ignored. It is there to comply with RF common API)
* \param exmimo_dump_config (ignored)
* \returns 0 in success
*/
int trx_brf_set_freq(openair0_device* device) {
int trx_brf_set_freq(openair0_device* device, openair0_config_t *openair0_cfg1,int exmimo_dump_config) {
int status;
brf_state_t *brf = (brf_state_t *)device->priv;
......@@ -269,9 +270,10 @@ int trx_brf_set_freq(openair0_device* device) {
/*! \brief Set Gains (TX/RX)
* \param device the hardware to use
* \param openair0_cfg openair0 Config structure
* \returns 0 in success
*/
int trx_brf_set_gains(openair0_device* device) {
int trx_brf_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) {
return(0);
......@@ -283,12 +285,17 @@ int trx_brf_set_gains(openair0_device* device) {
int16_t cos_fsover8[8] = {2047, 1447, 0, -1448, -2047, -1448, 0, 1447};
int16_t cos_3fsover8[8] = {2047, -1448, 0, 1447, -2047, 1447, 0, -1448};
/*! \brief calibration table for BladeRF */
rx_gain_calib_table_t calib_table_fx4[] = {
{2300000000.0,53.5},
{1880000000.0,57.0},
{816000000.0,73.0},
{-1,0}};
/*! \brief set RX gain offset from calibration table
* \param openair0_cfg RF frontend parameters set by application
* \param chain_index RF chain ID
*/
void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) {
int i=0;
......@@ -310,6 +317,9 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) {
}
/*! \brief Calibrate LMSSDR RF
* \param device the hardware to use
*/
void calibrate_rf(openair0_device *device) {
......@@ -885,11 +895,10 @@ void calibrate_rf(openair0_device *device) {
/*! \brief Initialize Openair BLADERF target. It returns 0 if OK
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 on success
*/
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
int status;
int card=0;
brf_state_t *brf = (brf_state_t*)malloc(sizeof(brf_state_t));
memset(brf, 0, sizeof(brf_state_t));
/* device specific */
......@@ -1063,8 +1072,6 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
}else
printf("[BRF] RX module calibrated DC \n");
bladerf_log_set_verbosity(get_brf_log_level(openair0_cfg->log_level));
printf("BLADERF: Initializing openair0_device\n");
......@@ -1091,16 +1098,18 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
/*! \brief bladeRF error report
* \param status
* \returns 0 on success
*/
int brf_error(int status) {
//exit(-1);
//return 1; // or status error code
return status; // or status error code
}
/*! \brief Open BladeRF from serial port
* \param serial name of serial port on which to open BladeRF device
* \returns bladerf device structure
*/
struct bladerf * open_bladerf_from_serial(const char *serial) {
......@@ -1131,6 +1140,7 @@ struct bladerf * open_bladerf_from_serial(const char *serial) {
/*! \brief Get BladeRF log level
* \param log_level log level
* \returns log level of BLADERF device
*/
int get_brf_log_level(int log_level){
......
......@@ -106,6 +106,27 @@ typedef struct {
/*
* func prototypes
*/
/*! \brief BladeRF Init function (not used at the moment)
* \param device RF frontend parameters set by application
*/
int trx_brf_init(openair0_device *device);
/*! \brief get current timestamp
*\param device the hardware to use
*\param module the bladeRf module
*/
openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module module);
/*! \brief Get BladeRF log level
* \param log_level log level
* \returns log level of BLADERF device
*/
int get_brf_log_level(int log_level);
/*! \brief bladeRF error report
* \param status
* \returns 0 on success
*/
int brf_error(int status);
/*@}*/
......@@ -49,6 +49,9 @@
#include <cmath>
/** @addtogroup _LMSSDR_PHY_RF_INTERFACE_
* @{
*/
///define for parameter enumeration if prefix might be needed
#define LMS7param(id) id
......@@ -69,6 +72,15 @@ extern "C"
int write_output(const char *fname,const char *vname,void *data,int length,int dec,char format);
}
/*! \brief Called to send samples to the LMSSDR RF target
\param device pointer to the device structure specific to the RF hardware target
\param timestamp The timestamp at whicch the first sample MUST be sent
\param buff Buffer which holds the samples
\param nsamps number of samples to be sent
\param antenna_id index of the antenna
\param flags Ignored for the moment
\returns 0 on success
*/
int trx_lms_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int antenna_id, int flags) {
LMS_TRxWrite((int16_t*)buff[0], nsamps,0, timestamp);
......@@ -76,7 +88,17 @@ int trx_lms_write(openair0_device *device, openair0_timestamp timestamp, void **
return nsamps;
}
/*! \brief Receive samples from hardware.
* Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
* the first channel. *ptimestamp is the time at which the first sample
* was received.
* \param device the hardware to use
* \param[out] ptimestamp the time at which the first sample was received.
* \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
* \param antenna_id Index of antenna port
* \returns number of samples read
*/
int trx_lms_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int antenna_id) {
uint64_t timestamp;
......@@ -87,6 +109,11 @@ int trx_lms_read(openair0_device *device, openair0_timestamp *ptimestamp, void *
return ret;
}
/*! \brief set RX gain offset from calibration table
* \param openair0_cfg RF frontend parameters set by application
* \param chain_index RF chain ID
*/
void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) {
int i=0;
......@@ -107,469 +134,12 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) {
}
}
/*
void calibrate_rf(openair0_device *device) {
openair0_timestamp ptimestamp;
int16_t *calib_buffp,*calib_tx_buffp;
int16_t calib_buff[2*RXDCLENGTH];
int16_t calib_tx_buff[2*RXDCLENGTH];
int i,j;
int8_t offI,offQ,offIold,offQold,offInew,offQnew,offphase,offphaseold,offphasenew,offgain,offgainold,offgainnew;
int32_t meanI,meanQ,meanIold,meanQold;
int cnt=0,loop;
liblms7_status opStatus;
int16_t dcoffi;
int16_t dcoffq;
int16_t dccorri;
int16_t dccorrq;
const int16_t firCoefs[] =
{
-2531,
-517,
2708,
188,
-3059,
216,
3569,
-770,
-4199,
1541,
4886,
-2577,
-5552,
3909,
6108,
-5537,
-6457,
7440,
6507,
-9566,
-6174,
11845,
5391,
-14179,
-4110,
16457,
2310,
-18561,
0,
20369,
-2780,
-21752,
5963,
22610,
-9456,
-22859,
13127,
22444,
-16854,
-21319,
20489,
19492,
-23883,
-17002,
26881,
13902,
-29372,
-10313,
31226,
6345,
-32380,
-2141,
32767,
-2141,
-32380,
6345,
31226,
-10313,
-29372,
13902,
26881,
-17002,
-23883,
19492,
20489,
-21319,
-16854,
22444,
13127,
-22859,
-9456,
22610,
5963,
-21752,
-2780,
20369,
0,
-18561,
2310,
16457,
-4110,
-14179,
5391,
11845,
-6174,
-9566,
6507,
7440,
-6457,
-5537,
6108,
3909,
-5552,
-2577,
4886,
1541,
-4199,
-770,
3569,
216,
-3059,
188,
2708,
-517,
-2531
};
j=0;
for (i=0;i<RXDCLENGTH;i++) {
calib_tx_buff[j++] = cos_fsover8[i&7];
calib_tx_buff[j++] = cos_fsover8[(i+6)&7]; // sin
}
calib_buffp = &calib_buff[0];
calib_tx_buffp = &calib_tx_buff[0];
lms7->BackupAllRegisters();
uint8_t ch = (uint8_t)lms7->Get_SPI_Reg_bits(LMS7param(MAC));
//Stage 1
uint8_t sel_band1_trf = (uint8_t)lms7->Get_SPI_Reg_bits(LMS7param(SEL_BAND1_TRF));
uint8_t sel_band2_trf = (uint8_t)lms7->Get_SPI_Reg_bits(LMS7param(SEL_BAND2_TRF));
{
uint16_t requiredRegs[] = { 0x0400, 0x040A, 0x010D, 0x040C };
uint16_t requiredMask[] = { 0x6000, 0x3007, 0x0040, 0x00FF }; //CAPSEL, AGC_MODE, AGC_AVG, EN_DCOFF, Bypasses
uint16_t requiredValue[] = { 0x0000, 0x1007, 0x0040, 0x00BD };
lms7->Modify_SPI_Reg_mask(requiredRegs, requiredMask, requiredValue, 0, 3);
}
// opStatus = lms7->SetFrequencySX(LMS7002M::Rx, device->openair0_cfg[0].tx_freq[0]/1e6,30.72);
// put TX on fs/4
opStatus = lms7->CalibrateRxSetup(device->openair0_cfg[0].sample_rate/1e6);
if (opStatus != LIBLMS7_SUCCESS) {
printf("Cannot calibrate for %f MHz\n",device->openair0_cfg[0].sample_rate/1e6);
exit(-1);
}
// fill TX buffer with fs/8 complex sinusoid
offIold=offQold=64;
lms7->SetRxDCOFF(offIold,offQold);
LMS_RxStart();
for (i=0;i<NUMBUFF;i++)
trx_lms_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0);
for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) {
meanIold+=calib_buff[j++];
meanQold+=calib_buff[j++];
}
meanIold/=RXDCLENGTH;
meanQold/=RXDCLENGTH;
printf("[LMS] RX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold);
offI=offQ=-64;
lms7->SetRxDCOFF(offI,offQ);
for (i=0;i<NUMBUFF;i++)
trx_lms_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0);
for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) {
meanI+=calib_buff[j++];
meanQ+=calib_buff[j++];
}
meanI/=RXDCLENGTH;
meanQ/=RXDCLENGTH;
printf("[LMS] RX DC: (%d,%d) => (%d,%d)\n",offI,offQ,meanI,meanQ);
while (cnt++ < 7) {
offInew=(offIold+offI)>>1;
offQnew=(offQold+offQ)>>1;
if (meanI*meanI < meanIold*meanIold) {
meanIold = meanI;
offIold = offI;
printf("[LMS] *** RX DC: offI %d => %d\n",offIold,meanI);
}
if (meanQ*meanQ < meanQold*meanQold) {
meanQold = meanQ;
offQold = offQ;
printf("[LMS] *** RX DC: offQ %d => %d\n",offQold,meanQ);
}
offI = offInew;
offQ = offQnew;
lms7->SetRxDCOFF(offI,offQ);
for (i=0;i<NUMBUFF;i++)
trx_lms_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0);
for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) {
meanI+=calib_buff[j++];
meanQ+=calib_buff[j++];
}
meanI/=RXDCLENGTH;
meanQ/=RXDCLENGTH;
printf("[LMS] RX DC: (%d,%d) => (%d,%d)\n",offI,offQ,meanI,meanQ);
}
if (meanI*meanI < meanIold*meanIold) {
meanIold = meanI;
offIold = offI;
printf("[LMS] *** RX DC: offI %d => %d\n",offIold,meanI);
}
if (meanQ*meanQ < meanQold*meanQold) {
meanQold = meanQ;
offQold = offQ;
printf("[LMS] *** RX DC: offQ %d => %d\n",offQold,meanQ);
}
printf("[LMS] RX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold);
lms7->SetRxDCOFF(offIold,offQold);
dcoffi = offIold;
dcoffq = offQold;
lms7->Modify_SPI_Reg_bits(LMS7param(MAC), ch);
lms7->Modify_SPI_Reg_bits(LMS7param(AGC_MODE_RXTSP), 1);
lms7->Modify_SPI_Reg_bits(LMS7param(CAPSEL), 0);
// TX LO leakage
offQold=offIold=127;
lms7->SPI_write(0x0204,(((int16_t)offIold)<<7)|offQold);
{
uint16_t requiredRegs[] = { 0x0400, 0x040A, 0x010D, 0x040C };
uint16_t requiredMask[] = { 0x6000, 0x3007, 0x0040, 0x00FF }; //CAPSEL, AGC_MODE, AGC_AVG, EN_DCOFF, Bypasses
uint16_t requiredValue[] = { 0x0000, 0x1007, 0x0040, 0x00BD };
lms7->Modify_SPI_Reg_mask(requiredRegs, requiredMask, requiredValue, 0, 3);
}
sel_band1_trf = (uint8_t)lms7->Get_SPI_Reg_bits(LMS7param(SEL_BAND1_TRF));
sel_band2_trf = (uint8_t)lms7->Get_SPI_Reg_bits(LMS7param(SEL_BAND2_TRF));
//B
lms7->Modify_SPI_Reg_bits(0x0100, 0, 0, 1); //EN_G_TRF 1
if (sel_band1_trf == 1)
{
lms7->Modify_SPI_Reg_bits(LMS7param(PD_RLOOPB_1_RFE), 0); //PD_RLOOPB_1_RFE 0
lms7->Modify_SPI_Reg_bits(LMS7param(EN_INSHSW_LB1_RFE), 0); //EN_INSHSW_LB1 0
}
if (sel_band2_trf == 1)
{
lms7->Modify_SPI_Reg_bits(LMS7param(PD_RLOOPB_2_RFE), 0); //PD_RLOOPB_2_RFE 0
lms7->Modify_SPI_Reg_bits(LMS7param(EN_INSHSW_LB2_RFE), 0); // EN_INSHSW_LB2 0
}
// FixRXSaturation();
lms7->Modify_SPI_Reg_bits(LMS7param(GFIR3_BYP_RXTSP), 0); //GFIR3_BYP 0
lms7->Modify_SPI_Reg_bits(LMS7param(HBD_OVR_RXTSP), 2);
lms7->Modify_SPI_Reg_bits(LMS7param(GFIR3_L_RXTSP), 7);
lms7->Modify_SPI_Reg_bits(LMS7param(GFIR3_N_RXTSP), 7);
lms7->SetGFIRCoefficients(LMS7002M::Rx, 2, firCoefs, sizeof(firCoefs) / sizeof(int16_t));
for (i=0;i<NUMBUFF;i++) {
trx_lms_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0);
trx_lms_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0);
}
write_output("calibrx.m","rxs",calib_buffp,RXDCLENGTH,1,1);
exit(-1);
for (meanIold=meanQold=i=j=0;i<RXDCLENGTH;i++) {
switch (i&3) {
case 0:
meanIold+=calib_buff[j++];
break;
case 1:
meanQold+=calib_buff[j++];
break;
case 2:
meanIold-=calib_buff[j++];
break;
case 3:
meanQold-=calib_buff[j++];
break;
}
}
// meanIold/=RXDCLENGTH;
// meanQold/=RXDCLENGTH;
printf("[LMS] TX DC (offI): %d => (%d,%d)\n",offIold,meanIold,meanQold);
offI=-128;
lms7->SPI_write(0x0204,(((int16_t)offI)<<7)|offQold);
for (i=0;i<NUMBUFF;i++) {
trx_lms_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0);
trx_lms_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0);
}
for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) {
switch (i&3) {
case 0:
meanI+=calib_buff[j++];
break;
case 1:
meanQ+=calib_buff[j++];
break;
case 2:
meanI-=calib_buff[j++];
break;
case 3:
meanQ-=calib_buff[j++];
break;
}
}
// meanI/=RXDCLENGTH;
// meanQ/=RXDCLENGTH;
printf("[LMS] TX DC (offI): %d => (%d,%d)\n",offI,meanI,meanQ);
cnt = 0;
while (cnt++ < 8) {
offInew=(offIold+offI)>>1;
if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) {
printf("[LMS] TX DC (offI): ([%d,%d]) => %d : %d\n",offIold,offI,offInew,meanI*meanI+meanQ*meanQ);
meanIold = meanI;
meanQold = meanQ;
offIold = offI;
}
offI = offInew;
lms7->SPI_write(0x0204,(((int16_t)offI)<<7)|offQold);
for (i=0;i<NUMBUFF;i++) {
trx_lms_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0);
trx_lms_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0);
}
for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) {
switch (i&3) {
case 0:
meanI+=calib_buff[j++];
break;
case 1:
meanQ+=calib_buff[j++];
break;
case 2:
meanI-=calib_buff[j++];
break;
case 3:
meanQ-=calib_buff[j++];
break;
}
}
// meanI/=RXDCLENGTH;
// meanQ/=RXDCLENGTH;
// printf("[LMS] TX DC (offI): %d => (%d,%d)\n",offI,meanI,meanQ);
}
if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) {
printf("[LMS] TX DC (offI): ([%d,%d]) => %d : %d\n",offIold,offI,offInew,meanI*meanI+meanQ*meanQ);
meanIold = meanI;
meanQold = meanQ;
offIold = offI;
}
offQ=-128;
lms7->SPI_write(0x0204,(((int16_t)offIold)<<7)|offQ);
for (i=0;i<NUMBUFF;i++) {
trx_lms_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0);
trx_lms_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0);
}
for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) {
switch (i&3) {
case 0:
meanI+=calib_buff[j++];
break;
case 1:
meanQ+=calib_buff[j++];
break;
case 2:
meanI-=calib_buff[j++];
break;
case 3:
meanQ-=calib_buff[j++];
break;
}
}
// meanI/=RXDCLENGTH;
// meanQ/=RXDCLENGTH;
printf("[LMS] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ);
cnt=0;
while (cnt++ < 8) {
offQnew=(offQold+offQ)>>1;
if (meanI*meanI+meanQ*meanQ < meanIold*meanIold +meanQold*meanQold) {
printf("[LMS] TX DC (offQ): ([%d,%d]) => %d : %d\n",offQold,offQ,offQnew,meanI*meanI+meanQ*meanQ);
meanIold = meanI;
meanQold = meanQ;
offQold = offQ;
}
offQ = offQnew;
lms7->SPI_write(0x0204,(((int16_t)offIold)<<7)|offQ);
for (i=0;i<NUMBUFF;i++) {
trx_lms_read(device, &ptimestamp, (void **)&calib_buffp, RXDCLENGTH, 0);
trx_lms_write(device,ptimestamp+5*RXDCLENGTH, (void **)&calib_tx_buffp, RXDCLENGTH, 0, 0);
}
for (meanI=meanQ=i=j=0;i<RXDCLENGTH;i++) {
switch (i&3) {
case 0:
meanI+=calib_buff[j++];
break;
case 1:
meanQ+=calib_buff[j++];
break;
case 2:
meanI-=calib_buff[j++];
break;
case 3:
meanQ-=calib_buff[j++];
break;
}
}
// meanI/=RXDCLENGTH;
// meanQ/=RXDCLENGTH;
// printf("[LMS] TX DC (offQ): %d => (%d,%d)\n",offQ,meanI,meanQ);
}
LMS_RxStop();
printf("[LMS] TX DC: (%d,%d) => (%d,%d)\n",offIold,offQold,meanIold,meanQold);
dccorri = offIold;
dccorrq = offQold;
lms7->RestoreAllRegisters();
lms7->Modify_SPI_Reg_bits(LMS7param(MAC), ch);
lms7->Modify_SPI_Reg_bits(LMS7param(DCOFFI_RFE), dcoffi);
lms7->Modify_SPI_Reg_bits(LMS7param(DCOFFQ_RFE), dcoffq);
lms7->Modify_SPI_Reg_bits(LMS7param(DCCORRI_TXTSP), dccorri);
lms7->Modify_SPI_Reg_bits(LMS7param(DCCORRQ_TXTSP), dccorrq);
// lms7->Modify_SPI_Reg_bits(LMS7param(GCORRI_TXTSP), gcorri);
// lms7->Modify_SPI_Reg_bits(LMS7param(GCORRQ_TXTSP), gcorrq);
// lms7->Modify_SPI_Reg_bits(LMS7param(IQCORR_TXTSP), iqcorr);
// lms7->Modify_SPI_Reg_bits(LMS7param(DC_BYP_TXTSP), 0); //DC_BYP
lms7->Modify_SPI_Reg_bits(0x0208, 1, 0, 0); //GC_BYP PH_BYP
}
*/
/*! \brief Set Gains (TX/RX) on LMSSDR
* \param device the hardware to use
* \param openair0_cfg openair0 Config structure
* \returns 0 in success
*/
int trx_lms_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) {
......@@ -589,6 +159,10 @@ int trx_lms_set_gains(openair0_device* device, openair0_config_t *openair0_cfg)
return(0);
}
/*! \brief Start LMSSDR
* \param device the hardware to use
* \returns 0 on success
*/
int trx_lms_start(openair0_device *device){
......@@ -746,7 +320,10 @@ int trx_lms_start(openair0_device *device){
return 0;
}
/*! \brief Stop LMSSDR
* \param card Index of the RF card to use
* \returns 0 on success
*/
int trx_lms_stop(int card) {
/*
LMS_DeviceClose(usbport);
......@@ -756,6 +333,12 @@ int trx_lms_stop(int card) {
*/
}
/*! \brief Set frequencies (TX/RX)
* \param device the hardware to use
* \param openair0_cfg openair0 Config structure (ignored. It is there to comply with RF common API)
* \param exmimo_dump_config (ignored)
* \returns 0 in success
*/
int trx_lms_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config) {
//Control port must be connected
......@@ -768,6 +351,7 @@ int trx_lms_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,in
}
// 31 = 19 dB => 105 dB total gain @ 2.6 GHz
/*! \brief calibration table for LMSSDR */
rx_gain_calib_table_t calib_table_sodera[] = {
{3500000000.0,70.0},
{2660000000.0,80.0},
......@@ -780,33 +364,30 @@ rx_gain_calib_table_t calib_table_sodera[] = {
/*! \brief Get LMSSDR Statistics
* \param device the hardware to use
* \returns 0 in success
*/
int trx_lms_get_stats(openair0_device* device) {
return(0);
}
/*! \brief Reset LMSSDR Statistics
* \param device the hardware to use
* \returns 0 in success
*/
int trx_lms_reset_stats(openair0_device* device) {
return(0);
}
int openair0_set_gains(openair0_device* device,
openair0_config_t *openair0_cfg) {
return(0);
}
int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg, int dummy) {
return(0);
}
/*! \brief Terminate operation of the LMSSDR transceiver -- free all associated resources
* \param device the hardware to use
*/
void trx_lms_end(openair0_device *device) {
......@@ -877,3 +458,4 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg){
return 0;
}
}
/*@}*/
......@@ -796,7 +796,8 @@ INPUT = $(OPENAIR1_DIR)/PHY/defs.h \
$(OPENAIR_TARGETS)/ARCH/COMMON/common_lib.h \
$(OPENAIR_TARGETS)/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp \
$(OPENAIR_TARGETS)/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c \
$(OPENAIR_TARGETS)/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h
$(OPENAIR_TARGETS)/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.h \
$(OPENAIR_TARGETS)/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
......
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1";
mobile_country_code = "208";
mobile_network_code = "92";
////////// Physical parameters:
component_carriers = (
{
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 32;
rx_gain = 116;
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -16;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -90;
pusch_alpha = "AL1";
pucch_p0_Nominal = -108;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.26";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
log_config :
{
global_log_level ="debug";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
......@@ -151,7 +151,7 @@ rrh_gw_config = (
tr_preference = "raw";
rf_preference = "usrp_b200";
iq_txshift = 4;
tx_sample_advance = 113;
tx_sample_advance = 103;
tx_scheduling_advance = 9;
}
......@@ -185,4 +185,4 @@ rrh_gw_config = (
rrc_log_verbosity ="medium";
};
}
);
);
\ No newline at end of file
......@@ -163,7 +163,7 @@ eNBs =
tr_preference = "raw";
rf_preference = "usrp_b200";
iq_txshift = 4;
tx_sample_advance = 70;
tx_sample_advance = 80;
tx_scheduling_advance = 9;
}
);
......@@ -186,4 +186,4 @@ eNBs =
rrc_log_verbosity ="medium";
};
}
);
);
\ No newline at end of file
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1";
mobile_country_code = "208";
mobile_network_code = "95";
////////// Physical parameters:
component_carriers = (
{
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -26;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -90;
pusch_alpha = "AL1";
pucch_p0_Nominal = -108;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.170.0.1";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0:3";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.170.0.2/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth0:4";
ENB_IPV4_ADDRESS_FOR_S1U = "192.170.1.2/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
log_config :
{
global_log_level ="debug";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
\ No newline at end of file
Active_eNBs = ( "eNB_Eurecom_LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
////////// Identification parameters:
eNB_ID = 0xe00;
cell_type = "CELL_MACRO_ENB";
eNB_name = "eNB_Eurecom_LTEBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = "1";
mobile_country_code = "208";
mobile_network_code = "92";
////////// Physical parameters:
component_carriers = (
{
frame_type = "FDD";
tdd_config = 3;
tdd_config_s = 0;
prefix_type = "NORMAL";
eutra_band = 7;
downlink_frequency = 2660000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 1;
pucch_nCS_AN = 0;
pucch_n1_AN = 32;
pdsch_referenceSignalPower = -26;
pdsch_p_b = 0;
pusch_n_SB = 1;
pusch_enable64QAM = "DISABLE";
pusch_hoppingMode = "interSubFrame";
pusch_hoppingOffset = 0;
pusch_groupHoppingEnabled = "ENABLE";
pusch_groupAssignment = 0;
pusch_sequenceHoppingEnabled = "DISABLE";
pusch_nDMRS1 = 1;
phich_duration = "NORMAL";
phich_resource = "ONESIXTH";
srs_enable = "DISABLE";
/* srs_BandwidthConfig =;
srs_SubframeConfig =;
srs_ackNackST =;
srs_MaxUpPts =;*/
pusch_p0_Nominal = -90;
pusch_alpha = "AL1";
pucch_p0_Nominal = -108;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( {ipv4 = "192.168.12.170";
ipv6="192:168:30::17";
active="yes";
preference="ipv4";});
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth4";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.242/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth4";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.242/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
};
log_config :
{
global_log_level ="debug";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
}
);
......@@ -8,14 +8,14 @@ include $(OPENAIR_TARGETS)/Makefile.common
KERNEL_VERSION:=$(shell echo `uname -r | cut -d. -f-2`)
KERNEL_TYPE:=$(shell echo `uname -r | cut -d. -f-3 | cut -d- -f3`)
LOWLATENCY_KERNEL:=$(shell if [ $(KERNEL_TYPE) = "lowlatency" ]; then echo "1" ; else echo "0" ; fi)
DEADLINE_SCHEDULER_KERNEL:=$(shell if [ $(KERNEL_TYPE) = "lowlatency" ]; then echo "1" ; else echo "0" ; fi)
include $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc
ifdef EXMIMO
#ifdef LOWLATENCY # this ifdef is to be removed after the debugging
ifeq ($(LOWLATENCY_KERNEL),1)
CFLAGS+=-DLOWLATENCY
#ifdef DEADLINE_SCHEDULER # this ifdef is to be removed after the debugging
ifeq ($(DEADLINE_SCHEDULER_KERNEL),1)
CFLAGS+=-DDEADLINE_SCHEDULER
endif
#endif
endif
......@@ -431,7 +431,7 @@ show:
@echo IS_REL10 is $(IS_REL10)
@echo openssl $(OPENSSL_FOUND)
@echo nettle $(NETTLE_FOUND)
@echo lowlatency kernel: $(LOWLATENCY_KERNEL)
@echo lowlatency kernel: $(DEADLINE_SCHEDULER_KERNEL)
beautiful:
astyle --style=gnu -s2 $(SRC)
......
......@@ -254,7 +254,7 @@ void *rrh_eNB_thread(void *arg) {
pthread_mutex_init(&sync_trx_mutex,NULL);
/* create eNB module's TX/RX threads */
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
error_code_eNB_rx = pthread_create(&eNB_rx_thread, NULL, rrh_eNB_rx_thread, (void *)dev);
error_code_eNB_tx = pthread_create(&eNB_tx_thread, NULL, rrh_eNB_tx_thread, (void *)dev);
LOG_I(RRH,"[eNB][SCHED] deadline scheduling applied to eNB TX/RX threads\n");
......@@ -302,7 +302,7 @@ void *rrh_eNB_thread(void *arg) {
timerspec.it_interval.tv_nsec = rt_period%1000000000;
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
error_code_timer = pthread_create(&main_timer_proc_thread, NULL, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[eNB][SCHED] deadline scheduling applied to timer thread \n");
#else
......@@ -368,7 +368,7 @@ void *rrh_eNB_rx_thread(void *arg) {
measurements = dev->measurements;
next_rx_pos = spp_eth;
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
struct sched_attr attr;
unsigned int flags = 0;
......@@ -560,7 +560,7 @@ void *rrh_eNB_tx_thread(void *arg) {
unsigned int subframe=0,frame=0;
unsigned int pck_tx=0;
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
struct sched_attr attr;
unsigned int flags = 0;
......
......@@ -312,8 +312,9 @@ static void* eNB_thread_rxtx( void* param )
MSC_START_USE();
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
struct sched_attr attr;
unsigned int flags = 0;
uint64_t runtime = 850000 ;
uint64_t deadline = 1 * 1000000 ; // each tx thread will finish within 1ms
......@@ -554,7 +555,7 @@ static void* eNB_thread_rxtx( void* param )
}
stop_meas( &softmodem_stats_rxtx_sf );
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
if (opp_enabled){
if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_TX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0);
......@@ -625,7 +626,7 @@ static void* eNB_thread_rx_common( void* param )
MSC_START_USE();
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
struct sched_attr attr;
unsigned int flags = 0;
uint64_t runtime = 870000 ;
......@@ -722,7 +723,7 @@ static void* eNB_thread_rx_common( void* param )
sparam.sched_priority, cpu_affinity);
#endif // LOWLATENCY
#endif // DEADLINE_SCHEDULER
mlockall(MCL_CURRENT | MCL_FUTURE);
......@@ -802,13 +803,13 @@ static void* eNB_thread_rx_common( void* param )
}
stop_meas( &softmodem_stats_rxtx_sf );
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
if (opp_enabled){
if(softmodem_stats_rxtx_sf.diff_now/(cpuf) > attr.sched_runtime){
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_RXTX_ENB, (softmodem_stats_rxtx_sf.diff_now/cpuf - attr.sched_runtime)/1000000.0);
}
}
#endif // LOWLATENCY
#endif // DEADLINE_SCHEDULER
print_meas_now(&softmodem_stats_rx_sf,"eNB_RX_SF", rx_time_file);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 );
......@@ -843,7 +844,7 @@ static void* eNB_thread_prach( void* param )
MSC_START_USE();
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
struct sched_attr attr;
unsigned int flags = 0;
uint64_t runtime = 870000 ;
......@@ -940,7 +941,7 @@ static void* eNB_thread_prach( void* param )
sparam.sched_priority, cpu_affinity);
#endif // LOWLATENCY
#endif // DEADLINE_SCHEDULER
mlockall(MCL_CURRENT | MCL_FUTURE);
......@@ -1012,7 +1013,7 @@ void init_eNB_proc(void)
proc = &eNB->proc;
proc_rxtx = proc->proc_rxtx;
#ifndef LOWLATENCY
#ifndef DEADLINE_SCHEDULER
/*
pthread_attr_init( &attr_eNB_proc_tx[CC_id][i] );
if (pthread_attr_setstacksize( &attr_eNB_proc_tx[CC_id][i], 64 *PTHREAD_STACK_MIN ) != 0)
......@@ -1053,7 +1054,7 @@ void init_eNB_proc(void)
pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL);
pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL);
pthread_cond_init( &proc->cond_prach, NULL);
#ifndef LOWLATENCY
#ifndef DEADLINE_SCHEDULER
pthread_create( &proc_rxtx[0].pthread_rxtx, &proc_rxtx[0].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[0] );
pthread_create( &proc_rxtx[1].pthread_rxtx, &proc_rxtx[1].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[1] );
pthread_create( &proc->pthread_rx, &proc->attr_rx, eNB_thread_rx_common, &eNB->proc );
......
......@@ -147,7 +147,6 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex.
#ifdef XFORMS
static pthread_t forms_thread; //xforms
#endif
......@@ -634,11 +633,6 @@ void *l2l1_task(void *arg)
static void get_options (int argc, char **argv)
{
int c;
......@@ -1539,7 +1533,7 @@ int main( int argc, char **argv )
}
#ifndef LOWLATENCY
#ifndef DEADLINE_SCHEDULER
/* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
......@@ -1808,7 +1802,6 @@ int main( int argc, char **argv )
// start the main thread
if (UE_flag == 1) init_UE();
else init_eNB(node_function);
......
......@@ -226,7 +226,7 @@ static void *UE_thread_synch(void *arg)
printf("UE_thread_sync in with PHY_vars_UE %p\n",arg);
printf("waiting for sync (UE_thread_synch) \n");
#ifndef LOWLATENCY
#ifndef DEADLINE_SCHEDULER
int policy, s, j;
struct sched_param sparam;
char cpu_affinity[1024];
......@@ -666,7 +666,8 @@ static void *UE_thread_tx(void *arg)
UE->instance_cnt_tx=-1;
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
struct sched_attr attr;
unsigned int flags = 0;
......@@ -873,7 +874,9 @@ static void *UE_thread_rx(void *arg)
UE->instance_cnt_rx=-1;
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
struct sched_attr attr;
unsigned int flags = 0;
......@@ -1179,7 +1182,8 @@ void *UE_thread(void *arg)
MessageDef *message_p;
#endif
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
struct sched_attr attr;
unsigned int flags = 0;
......@@ -1535,7 +1539,6 @@ void *UE_thread(void *arg)
/*!
* \brief Initialize the UE theads.
* Creates the UE threads:
......
......@@ -387,7 +387,7 @@ void *timer_proc(void *arg) {
struct itimerspec *old_value;
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
struct sched_attr attr;
unsigned int flags = 0;
......
......@@ -28,7 +28,7 @@
*******************************************************************************/
/*! \file rt_wrapper.h
* \brief provides a wrapper for the timing function, runtime calculations for real-time opeartions depending on weather RTAI or LOWLATENCY kernels are used or not
* \brief provides a wrapper for the timing function, runtime calculations for real-time opeartions depending on weather RTAI or DEADLINE_SCHEDULER kernels are used or not
* \author F. Kaltenberger and Navid Nikaein
* \date 2013
* \version 0.1
......@@ -241,7 +241,7 @@ double get_runtime_rx(int rx_subframe, uint16_t runtime_phy_rx[29][6], uint32_t
return runtime;
}
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
......
......@@ -72,7 +72,7 @@ double get_runtime_rx(int rx_subframe, uint16_t runtime_phy_rx[29][6], uint32_t
* see https://www.kernel.org/doc/Documentation/scheduler/sched-deadline.txt or
* http://www.blaess.fr/christophe/2014/04/05/utiliser-un-appel-systeme-inconnu-de-la-libc/
*/
#ifdef LOWLATENCY
#ifdef DEADLINE_SCHEDULER
#define gettid() syscall(__NR_gettid)
......
......@@ -608,8 +608,9 @@ l2l1_task (void *args_p)
start_meas (&oaisim_stats);
for (frame = 0;
(l2l1_state != L2L1_TERMINATED)
&& (frame < oai_emulation.info.n_frames);
(l2l1_state != L2L1_TERMINATED) &&
((oai_emulation.info.n_frames_flag == 0) ||
(frame < oai_emulation.info.n_frames));
frame++) {
#if defined(ENABLE_ITTI)
......@@ -671,12 +672,6 @@ l2l1_task (void *args_p)
//oai_emulation.info.time_ms += 1;
oai_emulation.info.time_s += 0.01; // emu time in s, each frame lasts for 10 ms // JNote: TODO check the coherency of the time and frame (I corrected it to 10 (instead of 0.01)
// if n_frames not set by the user or is greater than max num frame then set adjust the frame counter
if ((oai_emulation.info.n_frames_flag == 0)
|| (oai_emulation.info.n_frames >= 0xffff)) {
frame %= (oai_emulation.info.n_frames - 1);
}
update_omg (frame); // frequency is defined in the omg_global params configurable by the user
update_omg_ocm ();
......@@ -708,7 +703,7 @@ l2l1_task (void *args_p)
wait_for_slot_isr ();
#if defined(ENABLE_ITTI)
itti_update_lte_time(frame, slot);
itti_update_lte_time(frame % MAX_FRAME_NUMBER, slot);
#endif
last_slot = (slot - 1) % 20;
......@@ -748,7 +743,7 @@ l2l1_task (void *args_p)
LOG_D(EMU,
"PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d) TDD %d/%d Nid_cell %d\n",
eNB_inst,
frame,
frame % MAX_FRAME_NUMBER,
slot,
PHY_vars_eNB_g[eNB_inst][0]->proc[slot >> 1].subframe_tx,
PHY_vars_eNB_g[eNB_inst][0]->proc[slot >> 1].subframe_rx,
......@@ -823,27 +818,27 @@ l2l1_task (void *args_p)
{
LOG_D(EMU,
"PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
UE_inst, frame, slot, next_slot >> 1,
UE_inst, frame % MAX_FRAME_NUMBER, slot, next_slot >> 1,
last_slot >> 1);
if (PHY_vars_UE_g[UE_inst][0]->UE_mode[0]
!= NOT_SYNCHED) {
if (frame > 0) {
PHY_vars_UE_g[UE_inst][0]->frame_rx = frame;
PHY_vars_UE_g[UE_inst][0]->frame_rx = frame % MAX_FRAME_NUMBER;
PHY_vars_UE_g[UE_inst][0]->slot_rx = last_slot;
PHY_vars_UE_g[UE_inst][0]->slot_tx = next_slot;
if (next_slot > 1)
PHY_vars_UE_g[UE_inst][0]->frame_tx = frame;
PHY_vars_UE_g[UE_inst][0]->frame_tx = frame % MAX_FRAME_NUMBER;
else
PHY_vars_UE_g[UE_inst][0]->frame_tx = frame + 1;
PHY_vars_UE_g[UE_inst][0]->frame_tx = (frame + 1) % MAX_FRAME_NUMBER;
#ifdef OPENAIR2
//Application
update_otg_UE (UE_inst, oai_emulation.info.time_ms);
//Access layer
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE_inst, 0, ENB_FLAG_NO, NOT_A_RNTI, frame, next_slot);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE_inst, 0, ENB_FLAG_NO, NOT_A_RNTI, frame % MAX_FRAME_NUMBER, next_slot);
pdcp_run (&ctxt);
#endif
......@@ -895,7 +890,7 @@ l2l1_task (void *args_p)
if(last_slot==2 && frame%10==0) {
if (UE_stats_th[UE_inst]) {
fprintf(UE_stats_th[UE_inst],"%d %d\n",frame, PHY_vars_UE_g[UE_inst][0]->bitrate[0]/1000);
fprintf(UE_stats_th[UE_inst],"%d %d\n",frame % MAX_FRAME_NUMBER, PHY_vars_UE_g[UE_inst][0]->bitrate[0]/1000);
}
}
......@@ -929,7 +924,7 @@ l2l1_task (void *args_p)
exit(-1);
}
PHY_vars_RN_g[RN_id]->frame = frame;
PHY_vars_RN_g[RN_id]->frame = frame % MAX_FRAME_NUMBER;
if ( oai_emulation.info.frame_type == 0) {
// RN == UE
......@@ -937,12 +932,12 @@ l2l1_task (void *args_p)
if (PHY_vars_UE_g[UE_inst][0]->UE_mode[0] != NOT_SYNCHED) {
LOG_D(EMU,"[RN %d] PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
RN_id, UE_inst, frame, slot, next_slot >> 1,last_slot>>1);
PHY_vars_UE_g[UE_inst][0]->frame_rx = frame;
PHY_vars_UE_g[UE_inst][0]->frame_rx = frame % MAX_FRAME_NUMBER;
PHY_vars_UE_g[UE_inst][0]->slot_rx = last_slot;
PHY_vars_UE_g[UE_inst][0]->slot_tx = next_slot;
if (next_slot>1) PHY_vars_UE_g[UE_inst][0]->frame_tx = frame;
else PHY_vars_UE_g[UE_inst][0]->frame_tx = frame+1;
if (next_slot>1) PHY_vars_UE_g[UE_inst][0]->frame_tx = frame % MAX_FRAME_NUMBER;
else PHY_vars_UE_g[UE_inst][0]->frame_tx = (frame+1) % MAX_FRAME_NUMBER;
phy_procedures_UE_lte (PHY_vars_UE_g[UE_inst][0], 0, abstraction_flag,normal_txrx,
r_type, PHY_vars_RN_g[RN_id]);
......@@ -953,7 +948,7 @@ l2l1_task (void *args_p)
// RN == eNB
LOG_D(EMU,"[RN %d] PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
RN_id, eNB_inst, frame, slot, next_slot >> 1,last_slot>>1);
RN_id, eNB_inst, frame % MAX_FRAME_NUMBER, slot, next_slot >> 1,last_slot>>1);
phy_procedures_eNB_lte(slot>>1, PHY_vars_eNB_g[eNB_inst], abstraction_flag,
r_type, PHY_vars_RN_g[RN_id]);
} else {
......@@ -963,7 +958,7 @@ l2l1_task (void *args_p)
}
#endif
emu_transport (frame, last_slot, next_slot, direction,
emu_transport (frame % MAX_FRAME_NUMBER, last_slot, next_slot, direction,
oai_emulation.info.frame_type[0], ethernet_flag);
if ((direction == SF_DL)
......@@ -1009,7 +1004,7 @@ l2l1_task (void *args_p)
enb_data, ue_data, next_slot,
abstraction_flag,
&PHY_vars_eNB_g[0][CC_id]->lte_frame_parms,
frame, CC_id);
frame % MAX_FRAME_NUMBER, CC_id);
}
stop_meas (&ul_chan_stats);
......@@ -1078,7 +1073,7 @@ l2l1_task (void *args_p)
next_slot,
abstraction_flag,
&PHY_vars_eNB_g[0][CC_id]->lte_frame_parms,
frame, CC_id);
frame % MAX_FRAME_NUMBER, CC_id);
}
stop_meas (&ul_chan_stats);
......@@ -1095,7 +1090,7 @@ l2l1_task (void *args_p)
}
}
if ((last_slot == 1) && (frame == 0) && (abstraction_flag == 0)
if ((last_slot == 1) && ((frame % MAX_FRAME_NUMBER) == 0) && (abstraction_flag == 0)
&& (oai_emulation.info.n_frames == 1)) {
write_output ("dlchan0.m",
......@@ -1143,40 +1138,40 @@ l2l1_task (void *args_p)
&&(Channel_Flag==0)
#endif
) {
sprintf (fname, "UEtxsig%d.m", frame);
sprintf (vname, "txs%d", frame);
sprintf (fname, "UEtxsig%d.m", frame % MAX_FRAME_NUMBER);
sprintf (vname, "txs%d", frame % MAX_FRAME_NUMBER);
write_output (fname,
vname,
PHY_vars_UE_g[0][0]->lte_ue_common_vars.txdata[0],
PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti
* 10,
1, 1);
sprintf (fname, "eNBtxsig%d.m", frame);
sprintf (vname, "txs%d", frame);
sprintf (fname, "eNBtxsig%d.m", frame % MAX_FRAME_NUMBER);
sprintf (vname, "txs%d", frame % MAX_FRAME_NUMBER);
write_output (fname,
vname,
PHY_vars_eNB_g[0][0]->lte_eNB_common_vars.txdata[0][0],
PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti
* 10,
1, 1);
sprintf (fname, "eNBtxsigF%d.m", frame);
sprintf (vname, "txsF%d", frame);
sprintf (fname, "eNBtxsigF%d.m", frame % MAX_FRAME_NUMBER);
sprintf (vname, "txsF%d", frame % MAX_FRAME_NUMBER);
write_output (fname,
vname,
PHY_vars_eNB_g[0][0]->lte_eNB_common_vars.txdataF[0][0],
PHY_vars_eNB_g[0][0]->lte_frame_parms.symbols_per_tti
* PHY_vars_eNB_g[0][0]->lte_frame_parms.ofdm_symbol_size,
1, 1);
sprintf (fname, "UErxsig%d.m", frame);
sprintf (vname, "rxs%d", frame);
sprintf (fname, "UErxsig%d.m", frame % MAX_FRAME_NUMBER);
sprintf (vname, "rxs%d", frame % MAX_FRAME_NUMBER);
write_output (fname,
vname,
PHY_vars_UE_g[0][0]->lte_ue_common_vars.rxdata[0],
PHY_vars_UE_g[0][0]->lte_frame_parms.samples_per_tti
* 10,
1, 1);
sprintf (fname, "eNBrxsig%d.m", frame);
sprintf (vname, "rxs%d", frame);
sprintf (fname, "eNBrxsig%d.m", frame % MAX_FRAME_NUMBER);
sprintf (vname, "rxs%d", frame % MAX_FRAME_NUMBER);
write_output (fname,
vname,
PHY_vars_eNB_g[0][0]->lte_eNB_common_vars.rxdata[0][0],
......@@ -1209,7 +1204,7 @@ l2l1_task (void *args_p)
#ifdef SMBV
// Rohde&Schwarz SMBV100A vector signal generator
if ((frame == config_frames[0]) || (frame == config_frames[1]) || (frame == config_frames[2]) || (frame == config_frames[3])) {
if ((frame % MAX_FRAME_NUMBER == config_frames[0]) || (frame % MAX_FRAME_NUMBER == config_frames[1]) || (frame % MAX_FRAME_NUMBER == config_frames[2]) || (frame % MAX_FRAME_NUMBER == config_frames[3])) {
smbv_frame_cnt++;
}
......@@ -1269,7 +1264,7 @@ main (int argc, char **argv)
int port,Process_Flag=0,wgt,Channel_Flag=0,temp;
#endif
//default parameters
oai_emulation.info.n_frames = 0xffff; //1024; //10;
oai_emulation.info.n_frames = MAX_FRAME_NUMBER; //1024; //10;
oai_emulation.info.n_frames_flag = 0; //fixme
snr_dB = 30;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment