diff --git a/NOTICE.txt b/NOTICE.txt
index b9eee02ed5..38d493284a 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,3 +1,8 @@
+The source code of openairinterface5g is distributed under OAI Public License V1.0.
+For more details of the license, refer to LICENSE file in the same directory.
+
+However, the source code also contains third party software that is acknowledged here for reference.
+
Credits for LFDS user space source code located in folder openair2/UTILS/LFDS/liblfds6.1.1/
http://liblfds.org/.
Extract from http://liblfds.org/pages/downloads_and_license.html:
diff --git a/README.txt b/README.txt
index cca50342a0..04d02bf9c7 100644
--- a/README.txt
+++ b/README.txt
@@ -1,36 +1,41 @@
-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
-├── LICENSE
-├── 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.
-
-
-RELEASE NOTES:
-
-v0.1 -> Last stable commit on develop branch before enhancement-10-harmony
-v0.2 -> Merge of enhancement-10-harmony to include NGFI RRH + New Interface for RF/BBU
-v0.3 -> Last stable commit on develop branch before the merge of feature-131-new-license. This is the last commit with GPL License
-v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the license to OAI Public License V1.0
-v0.5 -> Merge of enhancement-10-harmony-lts. It includes fixes for Ubuntu 16.04 support
+OpenAirInterface is under OpenAirInterface Software Alliance license.
+├── http://www.openairinterface.org/?page_id=101
+├── http://www.openairinterface.org/?page_id=698
+
+It is distributed under OAI Public License V1.0.
+The license information is distributed under LICENSE file in the same directory.
+Please see NOTICE.txt for third party software that is included in the sources.
+
+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
+├── LICENSE
+├── 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.
+
+
+RELEASE NOTES:
+
+v0.1 -> Last stable commit on develop branch before enhancement-10-harmony
+v0.2 -> Merge of enhancement-10-harmony to include NGFI RRH + New Interface for RF/BBU
+v0.3 -> Last stable commit on develop branch before the merge of feature-131-new-license. This is the last commit with GPL License
+v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the license to OAI Public License V1.0
+v0.5 -> Merge of enhancement-10-harmony-lts. It includes fixes for Ubuntu 16.04 support
+v0.5.1 -> Merge of bugfix-137-uplink-fixes. It includes stablity fixes for eNB
diff --git a/cmake_targets/autotests/run_exec_lte-softmodem_tests.py b/cmake_targets/autotests/run_exec_lte-softmodem_tests.py
index 1dfd67b682..796235a77f 100755
--- a/cmake_targets/autotests/run_exec_lte-softmodem_tests.py
+++ b/cmake_targets/autotests/run_exec_lte-softmodem_tests.py
@@ -37,6 +37,8 @@ import math #from time import clock
import xml.etree.ElementTree as ET
import re
+from colorama import Fore, Back, Style
+
import numpy as np
import log
@@ -167,7 +169,7 @@ def sftp_module (username, password, hostname, ports, paramList,logfile):
#paramiko logfile path should not be changed with multiple calls. The logs seem to in first file regardless
error = ""
#The lines below are outside exception loop to be sure to terminate the test case if the network connectivity goes down or there is authentication failure
- transport = paramiko.Transport(hostname, ports)
+ transport = paramiko.Transport((hostname, ports))
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
# index =0
@@ -1042,6 +1044,609 @@ def handle_testcaseclass_softmodem (testcase, oldprogramList, logdirOAI5GRepo ,
write_file(xmlFile, xml, mode="w")
+
+
+# \brief handler for executing test cases (lte-softmodem-noS1)
+# \param testcase name of testcase
+# \param oldprogramList list of programs which must be terminated before running a test case
+# \param logdirOAI5GRepo directory on remote machine which has openairinterface5g repo installed
+# \param logdirOpenaircnRepo directory on remote machine which has openair-cn repo installed
+# \param MachineList list of all machines on which test cases can be run
+# \param user username with which to login
+# \param password password with which to login
+# \param CleanupAluLteBox string that contains commands to stop ALU Bell Labs LTEBox (specified in test_case_list.xml)
+# \param ExmimoRfStop command to stop EXMIMO Card
+# \param nruns_lte-softmodem global parameter to override number of runs (nruns) within the test case
+def handle_testcaseclass_softmodem_noS1 (testcase, oldprogramList, logdirOAI5GRepo , logdirOpenaircnRepo, MachineList, user, password, CleanUpAluLteBox, ExmimoRfStop, nruns_lte_softmodem, timeout_cmd):
+ #We ignore the password sent to this function for secuirity reasons for password present in log files
+ #It is recommended to add a line in /etc/sudoers that looks something like below. The line below will run sudo without password prompt
+ # your_user_name ALL=(ALL:ALL) NOPASSWD: ALL
+
+ indent="\t"
+ threads=[]
+
+ #
+ # Test case parameters
+ # -----------------------------------------------------------------------------
+ testcase_verdict = 'PASS'
+ testcase_time_start = datetime.datetime.now()
+ testcase_name = testcase.get('id')
+ testcase_class = testcase.findtext('class',default='')
+ testcase_desc = testcase.findtext('desc',default='')
+ if timeout_cmd == '':
+ timeout_cmd = testcase.findtext('TimeOut_cmd',default='')
+ timeout_cmd = int(float(timeout_cmd))
+ timeout_thread = timeout_cmd + 60 #Timeout_thread is more than that of cmd to have room for compilation time, etc
+ if nruns_lte_softmodem == '':
+ nruns = testcase.findtext('nruns',default='')
+ else:
+ nruns = nruns_lte_softmodem
+ nruns = int(float(nruns))
+ tags = testcase.findtext('tags',default='')
+
+ max_ntries = testcase.findtext('max_ntries',default='')
+ if max_ntries :
+ max_ntries = int(float(max_ntries))
+ else :
+ max_ntries = nruns
+
+ print( indent + "> testcase time start : " + str(testcase_time_start) )
+ print( indent + "> testcase class : " + testcase_class )
+ print( indent + "> testcase description : " + testcase_desc )
+ print( indent + "> testcase timeout : " + str(timeout_cmd) )
+ print( indent + "> testcase thread timeout : " + str(timeout_thread) )
+ print( indent + "> number of runs : " + str(nruns) )
+ print( indent + "> number of max tries : " + str(max_ntries) )
+ print( indent + "> testcase tags : " + tags )
+
+ logdir_local_testcase = openairdir_local + '/cmake_targets/autotests/log/'+ testcasename
+ logdir_eNB_testcase = logdirOAI5GRepo +'/cmake_targets/autotests/log/'+ testcasename
+ logdir_UE_testcase = logdirOAI5GRepo +'/cmake_targets/autotests/log/'+ testcasename
+
+ #
+ # Local checks for test cases
+ # -----------------------------------------------
+
+ # Logging directory
+ if (not os.path.exists(logdir_local_testcase)):
+ os.system('mkdir -p ' + logdir_local_testcase)
+
+ #
+ # REMOTE MACHINE COMPILATION
+ # ------------------------------------------------
+
+ eNBMachine = testcase.findtext('eNB',default='')
+ eNB_config_file = testcase.findtext('eNB_config_file',default='')
+ eNB_compile_prog = testcase.findtext('eNB_compile_prog',default='')
+ eNB_compile_prog_args = testcase.findtext('eNB_compile_prog_args',default='')
+
+ logfile_compile_eNB = logdir_eNB_testcase + '/eNB_compile.log'
+ logfile_task_eNB_compile_out = logdir_eNB_testcase + '/eNB_task_compile_out.log'
+ logfile_task_eNB_compile = logdir_local_testcase + '/eNB_task_compile.log'
+
+ # Check that machine is in test setup machine list
+ print( Fore.WHITE + indent + "> testcase eNB machine :"),
+ if (eNBMachine not in MachineList):
+ print( Fore.RED + eNBMachine + " not in test setup machine list")
+ testcase_verdict = 'INCON'
+ else :
+ print eNBMachine,
+ # get machine description
+ eNBMachineDesc = MachineDescDic[eNBMachine]
+ index_eNBMachine = MachineList.index(eNBMachine)
+ # check that openairinterface is installed on machine
+ oai_eNB = openair('localdomain', eNBMachine)
+ oai_eNB.connect(user, password)
+ cmd = 'cd ' + logdirOAI5GRepo + '; source oaienv ; env|grep --color=never OPENAIR'
+ res= oai_eNB.send_recv(cmd)
+ m = re.search('OPENAIR_HOME', res, re.DOTALL)
+ if m:
+ print
+ # Create testcase directory on remote eNB
+ cmd = 'rm -fr ' + logdir_eNB_testcase + ' ; mkdir -p ' + logdir_eNB_testcase
+ result = oai_eNB.send_recv(cmd)
+
+ # Check if we need to compile lte-softmodem-noS1 on remote machine
+ eNB_compile_cmd = eNB_compile_prog + ' '+ eNB_compile_prog_args
+ if ('last_compile_prog' in eNBMachineDesc) and eNBMachineDesc['last_compile_prog'] == eNB_compile_cmd:
+ print( Fore.WHITE + indent + "> eNB machine compilation : skipped -> "+eNB_compile_cmd )
+ else:
+ print( Fore.WHITE + indent + "> eNB machine compilation : triggered -> "+eNB_compile_cmd )
+ eNBMachineDesc['last_compile_prog'] = eNB_compile_prog + ' '+ eNB_compile_prog_args # if last compilation is the same do not compile again
+ task_eNB_compile = ' ( uname -a ; date \n'
+ task_eNB_compile = task_eNB_compile + 'cd ' + logdirOAI5GRepo + ' ; source oaienv ; source cmake_targets/tools/build_helper \n'
+ task_eNB_compile = task_eNB_compile + 'env |grep OPENAIR \n'
+ task_eNB_compile = task_eNB_compile + update_config_file(oai_eNB, eNB_config_file, logdirOAI5GRepo, '$OPENAIR_DIR/cmake_targets/autotests/tools/search_repl.py') + '\n'
+ if eNB_compile_cmd != "":
+ task_eNB_compile = task_eNB_compile + ' ( ' + eNB_compile_cmd + ' ) > ' + logfile_compile_eNB + ' 2>&1 \n'
+ task_eNB_compile = task_eNB_compile + ' date ) > ' + logfile_task_eNB_compile_out + ' 2>&1 '
+ write_file(logfile_task_eNB_compile, task_eNB_compile, mode="w")
+
+
+ thread_eNB = oaiThread(1, "eNB_thread_compile", eNBMachine, user, password , task_eNB_compile, False, timeout_thread)
+ threads.append(thread_eNB)
+ thread_eNB.start()
+
+ else:
+ print( Fore.RED + " -> OAI5G not properly setup ! please check REMOTE MACHINE PREPARATION step")
+ testcase_verdict = 'INCON'
+
+
+ UEMachine = testcase.findtext('UE',default='')
+ UE_config_file = testcase.findtext('UE_config_file',default='')
+ UE_compile_prog = testcase.findtext('UE_compile_prog',default='')
+ UE_compile_prog_args = testcase.findtext('UE_compile_prog_args',default='')
+
+ logfile_compile_UE = logdir_UE_testcase + '/UE_compile.log'
+ logfile_task_UE_compile_out = logdir_UE_testcase + '/UE_task_compile_out.log'
+ logfile_task_UE_compile = logdir_local_testcase + '/UE_task_compile.log'
+
+ # Check that machine is in test setup machine list
+ print( Fore.WHITE + indent + "> testcase UE machine :"),
+ if (UEMachine not in MachineList):
+ print( Fore.RED + UEMachine + " not in test setup machine list")
+ testcase_verdict = 'INCON'
+ else :
+ print UEMachine,
+ # get machine description
+ UEMachineDesc = MachineDescDic[UEMachine]
+ index_UEMachine = MachineList.index(UEMachine)
+ # check that openairinterface is installed on machine
+ oai_UE = openair('localdomain', UEMachine)
+ oai_UE.connect(user, password)
+ cmd = 'cd ' + logdirOAI5GRepo + '; source oaienv ; env|grep --color=never OPENAIR'
+ res= oai_UE.send_recv(cmd)
+ m = re.search('OPENAIR_HOME', res, re.DOTALL)
+ if m:
+ print
+ # Create testcase directory on remote UE
+ cmd = 'rm -fr ' + logdir_UE_testcase + ' ; mkdir -p ' + logdir_UE_testcase
+ result = oai_UE.send_recv(cmd)
+
+ # Check if we need to compile lte-softmodem-noS1 on remote machine
+ UE_compile_cmd = UE_compile_prog + ' '+ UE_compile_prog_args
+ if ('last_compile_prog' in UEMachineDesc) and UEMachineDesc['last_compile_prog'] == UE_compile_cmd:
+ print( Fore.WHITE + indent + "> UE machine compilation : skipped -> "+UE_compile_cmd )
+ else:
+ print( Fore.WHITE + indent + "> UE machine compilation : triggered -> "+UE_compile_cmd )
+ UEMachineDesc['last_compile_prog'] = UE_compile_prog + ' '+ UE_compile_prog_args
+ task_UE_compile = ' ( uname -a ; date \n'
+ task_UE_compile = task_UE_compile + 'cd ' + logdirOAI5GRepo + ' ; source oaienv ; source cmake_targets/tools/build_helper \n'
+ task_UE_compile = task_UE_compile + 'env |grep OPENAIR \n'
+ task_UE_compile = task_UE_compile + update_config_file(oai_UE, UE_config_file, logdirOAI5GRepo, '$OPENAIR_DIR/cmake_targets/autotests/tools/search_repl.py') + '\n'
+ if UE_compile_cmd != "":
+ task_UE_compile = task_UE_compile + ' ( ' + UE_compile_cmd + ' ) > ' + logfile_compile_UE + ' 2>&1 \n'
+ task_UE_compile = task_UE_compile + ' date ) > ' + logfile_task_UE_compile_out + ' 2>&1 '
+ write_file(logfile_task_UE_compile, task_UE_compile, mode="w")
+
+ thread_UE = oaiThread(2, "UE_thread_compile", UEMachine, user, password , task_UE_compile, False, timeout_thread)
+ threads.append(thread_UE)
+ thread_UE.start()
+
+ else:
+ print( Fore.RED + " -> OAI5G not properly setup ! please check REMOTE MACHINE PREPARATION step")
+ testcase_verdict = 'INCON'
+
+
+
+
+
+
+ # Wait for Compilation thread to terminate
+ #-----------------------------------------
+ for t in threads:
+ t.join()
+
+ # TODO check that compilation is succeed
+
+ #first we compile all the programs
+# thread_UE = oaiThread(3, "UE_thread", UEMachine, user, password , task_UE_compile, False, timeout_thread)
+# threads.append(thread_UE)
+# thread_UE.start()
+
+
+
+
+
+# index_UEMachine = MachineList.index(UEMachine)
+# oai_UE = openair('localdomain', UEMachine)
+# oai_UE.connect(user, password)
+# res = oai_UE.send_recv(cmd)
+# res = oai_eNB.send_recv(cmd)
+
+
+
+ #
+ # RUN LOOP
+ # ------------------------------------------------
+ if testcase_verdict != 'PASS': # if something went wrong to not run test cases
+ max_ntries=0
+
+ runs_results = []
+ nb_runs = 0
+ nb_run_pass = 0
+ nb_run_failed = 0
+ nb_run_inc = 0
+ nb_run_skip = 0
+
+ nb_seg_fault = 0
+
+ for run in range(0,max_ntries):
+
+ if nruns == nb_run_pass + nb_run_failed:
+ break
+
+ nb_runs += 1
+
+ #
+ # RUN initialization
+ # ----------------------------------------------------
+ print (Fore.WHITE + indent + "> RUN_"+str(run).zfill(2)+" : " ),
+
+ sys.stdout.flush()
+
+ run_start_time=datetime.datetime.now()
+
+ logdir_local_run = openairdir_local + '/cmake_targets/autotests/log/'+ testcasename + '/run_' + str(run)
+ logdir_eNB_run = logdirOAI5GRepo +'/cmake_targets/autotests/log/' + testcasename + '/run_' + str(run)
+ logdir_UE_run = logdirOAI5GRepo +'/cmake_targets/autotests/log/' + testcasename + '/run_' + str(run)
+
+ cmd = 'rm -fr ' + logdir_eNB_run + ' ; mkdir -p ' + logdir_eNB_run
+ result = oai_eNB.send_recv(cmd)
+ cmd = 'rm -fr ' + logdir_UE_run + ' ; mkdir -p ' + logdir_UE_run
+ result = oai_UE.send_recv(cmd)
+ cmd = ' rm -fr ' + logdir_local_run + ' ; mkdir -p ' + logdir_local_run
+ result = os.system(cmd)
+
+
+ #
+ # RUN parametrization
+ # ----------------------------------------------------
+ eNB_pre_exec = testcase.findtext('eNB_pre_exec',default='')
+ eNB_pre_exec_args = testcase.findtext('eNB_pre_exec_args',default='')
+ eNB_main_exec = testcase.findtext('eNB_main_exec',default='')
+ eNB_main_exec_args = testcase.findtext('eNB_main_exec_args',default='')
+ eNB_traffic_exec = testcase.findtext('eNB_traffic_exec',default='')
+ eNB_traffic_exec_args = testcase.findtext('eNB_traffic_exec_args',default='')
+ eNB_terminate_missing_procs = testcase.findtext('eNB_terminate_missing_procs',default='True')
+
+ logfile_exec_eNB = logdir_eNB_run + '/eNB_exec' + '_' + str(run) + '_.log'
+ logfile_pre_exec_eNB = logdir_eNB_run + '/eNB_pre_exec' + '_' + str(run) + '_.log'
+ logfile_task_eNB_out = logdir_eNB_run + '/eNB_task_out' + '_' + str(run) + '_.log'
+ logfile_traffic_eNB = logdir_eNB_run + '/eNB_traffic' + '_' + str(run) + '_.log'
+ logfile_task_eNB = logdir_local_run + '/eNB_task' + '_' + str(run) + '_.log'
+
+ task_eNB = ' ( uname -a ; date \n'
+ task_eNB = task_eNB + 'cd ' + logdirOAI5GRepo + ' ; source oaienv ; source cmake_targets/tools/build_helper \n'
+ task_eNB = task_eNB + 'env |grep OPENAIR \n' + 'array_exec_pid=() \n'
+ if eNB_pre_exec != "":
+ task_eNB = task_eNB + ' ( date; ' + eNB_pre_exec + ' '+ eNB_pre_exec_args + ' ) > ' + logfile_pre_exec_eNB + ' 2>&1 \n'
+ if eNB_main_exec != "":
+ task_eNB = task_eNB + ' ( date; ' + addsudo(eNB_main_exec + ' ' + eNB_main_exec_args, '') + ' ) > ' + logfile_exec_eNB + ' 2>&1 & \n'
+ task_eNB = task_eNB + 'array_exec_pid+=($!) \n'
+ task_eNB = task_eNB + 'echo eNB_main_exec PID = $! \n'
+ if eNB_traffic_exec != "":
+ cmd_traffic = eNB_traffic_exec + ' ' + eNB_traffic_exec_args
+ if cmd_traffic.find('-c') >= 0:
+ cmd_traffic = cmd_traffic + ' -t ' + str(timeout_cmd - 80)
+ task_eNB = task_eNB + ' (date; ' + cmd_traffic + ' ) > ' + logfile_traffic_eNB + ' 2>&1 & \n'
+ task_eNB = task_eNB + 'array_exec_pid+=($!) \n'
+ task_eNB = task_eNB + 'echo eNB_traffic_exec PID = $! \n'
+ #terminate the eNB test case after timeout_cmd seconds
+ task_eNB = task_eNB + finalize_deploy_script (timeout_cmd, eNB_terminate_missing_procs) + ' \n'
+ #task_eNB = task_eNB + 'sleep ' + str(timeout_cmd) + ' \n'
+ task_eNB = task_eNB + 'handle_ctrl_c' + '\n'
+ task_eNB = task_eNB + ' ) > ' + logfile_task_eNB_out + ' 2>&1 '
+ write_file(logfile_task_eNB, task_eNB, mode="w")
+
+
+ UE_pre_exec = testcase.findtext('UE_pre_exec',default='')
+ UE_pre_exec_args = testcase.findtext('UE_pre_exec_args',default='')
+ UE_main_exec = testcase.findtext('UE_main_exec',default='')
+ UE_main_exec_args = testcase.findtext('UE_main_exec_args',default='')
+ UE_traffic_exec = testcase.findtext('UE_traffic_exec',default='')
+ UE_traffic_exec_args = testcase.findtext('UE_traffic_exec_args',default='')
+ UE_terminate_missing_procs = testcase.findtext('UE_terminate_missing_procs',default='True')
+ UE_search_expr_true = testcase.findtext('UE_search_expr_true','')
+
+ logfile_exec_UE = logdir_UE_run + '/UE_exec' + '_' + str(run) + '_.log'
+ logfile_pre_exec_UE = logdir_UE_run + '/UE_pre_exec' + '_' + str(run) + '_.log'
+ logfile_task_UE_out = logdir_UE_run + '/UE_task_out' + '_' + str(run) + '_.log'
+ logfile_traffic_UE = logdir_UE_run + '/UE_traffic' + '_' + str(run) + '_.log'
+ logfile_task_UE = logdir_local_run + '/UE_task' + '_' + str(run) + '_.log'
+
+
+ task_UE = ' ( uname -a ; date \n'
+ task_UE = task_UE + 'array_exec_pid=()' + '\n'
+ task_UE = task_UE + 'cd ' + logdirOAI5GRepo + '\n'
+ task_UE = task_UE + 'source oaienv \n'
+ task_UE = task_UE + 'source cmake_targets/tools/build_helper \n'
+ task_UE = task_UE + 'env |grep OPENAIR \n'
+ if UE_pre_exec != "":
+ task_UE = task_UE + ' ( date; ' + UE_pre_exec + ' '+ UE_pre_exec_args + ' ) > ' + logfile_pre_exec_UE + ' 2>&1 \n'
+ if UE_main_exec != "":
+ task_UE = task_UE + ' ( date; ' + addsudo(UE_main_exec + ' ' + UE_main_exec_args, '') + ' ) > ' + logfile_exec_UE + ' 2>&1 & \n'
+ task_UE = task_UE + 'array_exec_pid+=($!) \n'
+ task_UE = task_UE + 'echo UE_main_exec PID = $! \n'
+ if UE_traffic_exec != "":
+ cmd_traffic = UE_traffic_exec + ' ' + UE_traffic_exec_args
+ if cmd_traffic.find('-c') >= 0:
+ cmd_traffic = cmd_traffic + ' -t ' + str(timeout_cmd - 60)
+ task_UE = task_UE + ' ( date; ' + cmd_traffic + ' ) >' + logfile_traffic_UE + ' 2>&1 & \n'
+ task_UE = task_UE + 'array_exec_pid+=($!) \n'
+ task_UE = task_UE + 'echo UE_traffic_exec PID = $! \n'
+ #terminate the UE test case after timeout_cmd seconds
+ task_UE = task_UE + finalize_deploy_script (timeout_cmd, UE_terminate_missing_procs) + ' \n'
+ #task_UE = task_UE + 'sleep ' + str(timeout_cmd) + ' \n'
+ task_UE = task_UE + 'handle_ctrl_c' + '\n'
+ task_UE = task_UE + ' ) > ' + logfile_task_UE_out + ' 2>&1 '
+ write_file(logfile_task_UE, task_UE, mode="w")
+ #task_UE = 'echo \" ' + task_UE + '\" > ' + logfile_script_UE + ' 2>&1 ; ' + task_UE
+
+
+
+
+
+
+
+ #
+ # RUN work
+ # ----------------------------------------------------
+ thread_eNB = oaiThread(1, "eNB_thread", eNBMachine, user, password , task_eNB, False, timeout_thread)
+ thread_UE = oaiThread(2, "UE_thread", UEMachine, user, password , task_UE, False, timeout_thread)
+ threads=[]
+ threads.append(thread_eNB)
+ threads.append(thread_UE)
+ thread_eNB.start()
+ thread_UE.start()
+ for t in threads:
+ t.join()
+
+ #
+ #
+ #-----------------------------------------------------
+ cleanOldProgramsAllMachines([oai_eNB, oai_UE] , oldprogramList, CleanUpAluLteBox, ExmimoRfStop, [logdir_eNB_run, logdir_UE_run], logdirOAI5GRepo)
+
+ SSHSessionWrapper(eNBMachine, user, None, password, logdir_eNB_run, logdir_local_testcase, "get_all")
+ #print "Copying files from UEMachine : " + UEMachine + "logdir_UE = " + logdir_UE
+ SSHSessionWrapper(UEMachine, user, None, password, logdir_UE_run, logdir_local_testcase, "get_all")
+
+ metric_checks_flag = 1
+
+ fname = logdir_local_run+ '/UE_exec' + '_' + str(run) + '_.log'
+ cell_synch_status = analyser.check_cell_synchro(fname)
+ if cell_synch_status == 'CELL_SYNCH':
+ print '!!!!!!!!!!!!!! Cell synchronized !!!!!!!!!!!'
+ else :
+ print '!!!!!!!!!!!!!! Cell NOT NOT synchronized !!!!!!!!!!!'
+ metric_checks_flag = 0
+
+ ue_seg_fault_status = analyser.check_exec_seg_fault(fname)
+ if ue_seg_fault_status == 'SEG_FAULT' :
+ nb_seg_fault += 1
+
+ #
+ # Check metrics
+ #----------------------------------------------------
+ runs_metrics = []
+ run_traffic = []
+
+ if metric_checks_flag :
+ verdict = 'PASS'
+
+ # UE side metrics
+ metricList=testcase.findall('UE_metric')
+ for metric in metricList:
+ metric_def = {}
+ metric_def['id'] = metric.get('id')
+ metric_def['description'] = metric.get('description')
+ metric_def['regex'] = metric.get('regex')
+ metric_def['unit_of_meas'] = metric.get('unit_of_meas')
+ metric_def['pass_fail_stat']= metric.get('pass_fail_stat')
+ metric_min_lim = metric.get('min_limit')
+ if metric_min_lim:
+ metric_def['min_limit'] = float(metric_min_lim)
+ metric_max_lim = metric.get('max_limit')
+ if metric_max_lim:
+ metric_def['max_limit'] = float(metric_max_lim)
+
+ fname = logdir_local_run+ '/UE_exec' + '_' + str(run) + '_.log'
+
+ args = {'metric' : metric_def,
+ 'file' : fname }
+
+ metric_extracted = analyser.do_extract_metrics(args)
+
+ print "\t > Metric "+metric_def['id']+" :"
+ print "\t\t> min = "+ str( metric_extracted['metric_min'] )
+ print "\t\t> min_index = "+ str( metric_extracted['metric_min_index'] )
+ print "\t\t> max = "+ str( metric_extracted['metric_max'] )
+ print "\t\t> max_index = "+ str( metric_extracted['metric_max_index'] )
+ print "\t\t> mean = "+ str( metric_extracted['metric_mean'] )
+ print "\t\t> median = "+ str( metric_extracted['metric_median'] )
+
+ verdict = analyser.do_check_verdict(metric_def, metric_extracted)
+
+ metric_fig = logdir_local_run+ '/UE_metric_'+ metric_def['id']+'_' + str(run) + '_.png'
+ analyser.do_img_metrics(metric_def, metric_extracted, metric_fig)
+
+
+ metric_fig_report = '../log/'+ testcasename + '/run_' + str(run) + '/UE_metric_'+ metric_def['id']+'_' + str(run) + '_.png'
+
+ run_metrics = dict( metric_id = metric_def['id'],
+ metric_desc = metric_def['description'],
+ metric_uom = metric_def['unit_of_meas'],
+ metric_min = metric_extracted['metric_min'],
+ metric_min_index= metric_extracted['metric_min_index'],
+ metric_max = metric_extracted['metric_max'],
+ metric_max_index= metric_extracted['metric_max_index'],
+ metric_mean = metric_extracted['metric_mean'],
+ metric_median = metric_extracted['metric_median'],
+ metric_fig = metric_fig_report)
+
+ if metric_def['pass_fail_stat'] :
+ run_metrics['pass_fail_stat'] = metric_def['pass_fail_stat']
+ if metric_min_lim :
+ run_metrics['pass_fail_min_limit'] = metric_def['min_limit']
+ if metric_max_lim :
+ run_metrics['pass_fail_max_limit'] = metric_def['max_limit']
+
+ runs_metrics.append(run_metrics)
+
+ # Traffic analysis
+ if UE_traffic_exec != "":
+
+ fname = logdir_local_run+ '/UE_traffic' + '_' + str(run) + '_.log'
+ args = {'file' : fname }
+ traffic_metrics = analyser.do_extract_traffic_metrics(args)
+ traffic_fig = logdir_local_run+ '/UE_traffic'+'_' + str(run) + '_.png'
+ analyser.do_img_traffic(traffic_metrics, traffic_fig)
+
+ traffic_fig_report= '../log/'+ testcasename + '/run_' + str(run) + '/UE_traffic'+'_' + str(run) + '_.png'
+
+ dur_pass_fail_crit = 'none'
+ if traffic_metrics['traffic_count'] == 0 :
+ verdict = 'FAIL'
+ elif UE_search_expr_true != "":
+ traffic_duration_limit = float(UE_search_expr_true)
+ dur_pass_fail_crit = str(traffic_duration_limit)
+ # print 'traffic_duration_limit = '+str(traffic_duration_limit)
+ # print 'traffic_metrics[interval_stop_max] = '+str(traffic_metrics['interval_stop_max'])
+ if traffic_metrics['interval_stop_max'] < traffic_duration_limit :
+ verdict = 'FAIL'
+
+
+ run_traffic = dict( traffic_count = traffic_metrics['traffic_count'],
+ bw_min = traffic_metrics['bw_min'],
+ bw_max = traffic_metrics['bw_max'],
+ bw_mean = traffic_metrics['bw_mean'],
+ bw_median = traffic_metrics['bw_median'],
+ jitter_min = traffic_metrics['jitter_min'],
+ jitter_max = traffic_metrics['jitter_max'],
+ jitter_mean = traffic_metrics['jitter_mean'],
+ jitter_median = traffic_metrics['jitter_median'],
+ rl_min = traffic_metrics['rl_min'],
+ rl_max = traffic_metrics['rl_max'],
+ rl_mean = traffic_metrics['rl_mean'],
+ rl_median = traffic_metrics['rl_median'],
+ iperf_duration = traffic_metrics['interval_stop_max'],
+ dur_pass_fail_crit = dur_pass_fail_crit,
+ traffic_fig = traffic_fig_report )
+ else:
+ run_traffic = dict( traffic_count = 0)
+
+ else :
+ verdict = 'SKIP'
+
+
+
+ #
+ # RUN verdict and finalization
+ # ----------------------------------------------------
+ run_stop_time=datetime.datetime.now()
+ run_duration = run_stop_time-run_start_time
+# print (Fore.WHITE + ("duration=" :"),
+ print (Fore.WHITE + indent + "> RUN duration : "+ str(run_duration) +"s" )
+
+ print (Fore.WHITE + indent + "> RUN verdict :"),
+
+ if verdict == 'PASS':
+ nb_run_pass += 1
+ print ( Fore.GREEN + verdict)
+ elif verdict == 'FAIL':
+ nb_run_failed += 1
+ testcase_verdict = 'FAIL'
+ print ( Fore.RED + verdict)
+ elif verdict == 'SKIP':
+ nb_run_skip += 1
+ print ( Fore.YELLOW + verdict)
+ else:
+ nb_run_inc += 1
+ if testcase_verdict == 'PASS' : testcase_verdict = 'INCON'
+ print (Fore.YELLOW+'INCONCLUSIVE')
+
+ run_results = dict( run_id=str(run),
+ run_start_time = run_start_time,
+ run_stop_time = run_stop_time ,
+ run_verdict = verdict,
+ ue_seg_fault_status = ue_seg_fault_status,
+ run_duration = run_duration,
+ runs_metrics = runs_metrics,
+ run_traffic = run_traffic)
+ runs_results.append(run_results)
+
+ # END RUN LOOP
+ #----------------------------------------------------
+
+ # Test case duration
+ # ----------------------------------
+ testcase_time_stop = datetime.datetime.now()
+ print(Fore.WHITE + indent + "> testcase time stop : " + str(testcase_time_start) ),
+ print " -> TestCase duration = "+str(testcase_time_stop - testcase_time_start)
+
+ # Save remote log files
+ # -----------------------------------
+ #Now we change the permissions of the logfiles to avoid some of them being with root permissions
+ cmd = 'sudo -E chown -R ' + user + ' ' + logdir_eNB_testcase
+ res= oai_eNB.send_recv(cmd)
+ cmd = 'sudo -E chown -R ' + user + ' ' + logdir_UE_testcase
+ res= oai_UE.send_recv(cmd)
+
+ # Save remote log files on MTC
+ #print "Copying files from eNBMachine " + eNBMachine + "logdir_eNB = " + logdir_eNB
+ SSHSessionWrapper(eNBMachine, user, None, password, logdir_eNB_testcase, openairdir_local + '/cmake_targets/autotests/log/', "get_all")
+ #print "Copying files from UEMachine : " + UEMachine + "logdir_UE = " + logdir_UE
+ SSHSessionWrapper(UEMachine, user, None, password, logdir_UE_testcase, openairdir_local + '/cmake_targets/autotests/log/', "get_all")
+
+ oai_eNB.disconnect()
+ oai_UE.disconnect()
+
+ # Set test case final verdict
+ # -----------------------------------
+ test_result_string = 'do be completed'
+
+ if testcase_verdict == 'PASS':
+ if nb_run_pass == 0 :
+ testcase_verdict = 'INCON'
+
+ print(Fore.WHITE + indent + "> testcase final verdict :"),
+ if testcase_verdict == 'PASS':
+ print ( Fore.GREEN + testcase_verdict)
+ elif testcase_verdict == 'FAIL':
+ print ( Fore.RED + testcase_verdict)
+ else:
+ print (Fore.YELLOW+'INCONCLUSIVE')
+
+ duration= testcase_time_stop - testcase_time_start
+ xmlFile = logdir_local_testcase + '/test.' + testcasename + '.xml'
+ xml="\n \n"
+ write_file(xmlFile, xml, mode="w")
+
+
+ test_result = dict(testcase_name=testcasename,
+ testcaseclass=testcaseclass,
+ testcase_verdict = testcase_verdict,
+ testcase_time_start=testcase_time_start,
+ testcase_time_stop=testcase_time_stop,
+ tags=tags,
+ nruns=nb_runs,
+ nb_run_pass = nb_run_pass,
+ nb_run_skip = nb_run_skip,
+ nb_run_failed = nb_run_failed,
+ nb_run_inc=nb_run_inc,
+ nb_seg_fault = nb_seg_fault,
+ testcase_timeout=timeout_cmd,
+ testcase_duration = duration,
+ testcase_eNBMachine =eNBMachine,
+ testcase_UEMachine =UEMachine,
+ runs_results = runs_results)
+ #test_results.append(test_result)
+
+ return testcase_verdict
+
+
+
+
# \brief This function searches if test case is present in list of test cases that need to be executed by user
# \param testcasename the test case to search for
# \param testcasegroup list that is passed from the arguments
@@ -1149,12 +1754,14 @@ if openairdir_local is None:
locallogdir = openairdir_local + '/cmake_targets/autotests/log'
MachineList = ''
MachineListGeneric=''
+MachineDescDic={}
flag_remove_logdir=False
flag_start_testcase=False
nruns_lte_softmodem=''
flag_skip_git_head_check=False
flag_skip_oai_install=False
Timeout_cmd=''
+xmlInputFile=''
print "Number of arguments argc = " + str(len(sys.argv))
#for index in range(1,len(sys.argv) ):
# print "argv_" + str(index) + " : " + sys.argv[index]
@@ -1218,6 +1825,9 @@ while i < len (sys.argv):
i = i +1
elif arg == '--skip-oai-install':
flag_skip_oai_install=True
+ elif arg == '--test-suite' :
+ xmlInputFile = sys.argv[i+1]
+ i = i +1
elif arg == '-h' :
print "-s: This flag *MUST* be set to start the test cases"
print "-r: Remove the log directory in autotests"
@@ -1235,6 +1845,7 @@ while i < len (sys.argv):
print "--skip-git-head-check: skip checking of GitHead remote/local branch (only for debugging)"
print "--timeout_cmd: Override the default parameter (timeout_cmd) in test_case_list.xml. This parameter is in seconds and should be > 120"
print "--skip-oai-install: Skips the openairinterface5g installer"
+ print "--test-suite: Select a XML test-suite file"
sys.exit()
else :
print "Unrecongnized Option: <" + arg + ">. Use -h to see valid options"
@@ -1264,6 +1875,13 @@ cmd='ps aux |grep \"/usr/bin/ssh -q -l guptar\"| awk \'{print $2}\' | sudo xargs
os.system(cmd)
+try:
+ analyser = __import__("lib_autotest_analyser")
+except ImportError as err:
+ print('Import error: ' + str(err))
+ exit(0)
+
+
if flag_start_testcase == False:
print "You need to start the testcase by passing option -s. Use -h to see all options. Aborting now..."
sys.exit(1)
@@ -1286,12 +1904,14 @@ os.system(cmd)
print "host = " + host
print "user = " + user
-xmlInputFile=os.environ.get('OPENAIR_DIR')+"/cmake_targets/autotests/test_case_list.xml"
+if xmlInputFile == '':
+ xmlInputFile=os.environ.get('OPENAIR_DIR')+"/cmake_targets/autotests/test_case_list.xml"
NFSResultsDir = '/mnt/sradio'
cleanupOldProgramsScript = '$OPENAIR_DIR/cmake_targets/autotests/tools/remove_old_programs.bash'
logdir = '/tmp/' + 'OAITestFrameWork-' + user + '/'
logdirOAI5GRepo = logdir + 'openairinterface5g/'
logdirOpenaircnRepo = logdir + 'openair-cn/'
+patchdir = logdirOAI5GRepo + 'cmake_targets/autotests/patches/'
if flag_remove_logdir == True:
print "Removing directory: " + locallogdir
@@ -1333,6 +1953,8 @@ ExmimoRfStop = xmlRoot.findtext('ExmimoRfStop',default='')
if nruns_lte_softmodem == '':
nruns_lte_softmodem = xmlRoot.findtext('nruns_lte-softmodem',default='')
+OAI5GpatchFileList=xmlRoot.findall('OAI5GPatchFile')
+
print "MachineList = " + MachineList
print "GitOpenair-cnRepo = " + GitOpenaircnRepo
print "GitOAI5GRepo = " + GitOAI5GRepo
@@ -1365,6 +1987,7 @@ MachineListGeneric = MachineListGeneric.split()
#index=0
for machine in MachineList:
oai_list.append( openair('localdomain',machine))
+ MachineDescDic[machine]={}
#index = index + 1
@@ -1475,6 +2098,7 @@ for oai in oai_list:
cmd = cmd + 'git checkout ' + GitOpenaircnRepoBranch + '\n'
cmd = cmd + 'env |grep OPENAIR' + '\n'
cmd = cmd + ' cd ' + logdir + '\n'
+ cmd = cmd + 'mkdir -p ' + patchdir + '\n'
cmd = cmd + ' ) > ' + setuplogfile + ' 2>&1 \n'
#cmd = cmd + 'echo \' ' + cmd + '\' > ' + setup_script + ' 2>&1 \n '
#result = oai_list[index].send_recv(cmd, False, 300 )
@@ -1500,8 +2124,27 @@ for t in threads_init_setup:
localfile = locallogdir + '/setup_log_' + MachineList[index] + '_.txt'
remotefile = logdir + '/setup_log_' + MachineList[index] + '_.txt'
port = 22
+
+ #Now we copy patch files and apply them
+ print "Installating patch files on machine " + MachineList[index]
+ for patchFile in OAI5GpatchFileList:
+ localfile = os.path.expandvars('$OPENAIR_DIR/cmake_targets/autotests/patches/')+patchFile.get('name')
+ remotefile = logdirOAI5GRepo + '/cmake_targets/autotests/patches/'+patchFile.get('name')
+ if patchFile.get('machine') == MachineList[index] or patchFile.get('machine') == None:
+ if os.path.isfile(localfile):
+ print "\t> PATCH FILE :"+localfile
+ paramList=[]
+ paramList.append ( {"operation":'put', "localfile":localfile, "remotefile":remotefile} )
+ sftp_module (user, pw, MachineList[index], port, paramList, sftp_log)
+ cmd = ' cd ' + logdirOAI5GRepo + ' ;git apply cmake_targets/autotests/patches/'+patchFile.get('name')
+ res = oai_list[index].send_recv(cmd)
paramList=[]
+
+ setuplogfile = logdir + '/setup_log_' + MachineList[index] + '_.txt'
+ setup_script = locallogdir + '/setup_script_' + MachineList[index] + '_.txt'
+ localfile = locallogdir + '/setup_log_' + MachineList[index] + '_.txt'
+ remotefile = logdir + '/setup_log_' + MachineList[index] + '_.txt'
sftp_log = os.path.expandvars(locallogdir + '/sftp_module.log')
paramList.append ( {"operation":'get', "localfile":localfile, "remotefile":remotefile} )
#sftp_module (user, pw, MachineList[index], port, localfile, remotefile, sftp_log, "get")
@@ -1574,6 +2217,23 @@ for testcase in testcaseList:
SSHSessionWrapper('localhost', user, None, pw , NFSTestsResultsDir , locallogdir, "put_all")
oai_localhost.disconnect()
+ elif testcaseclass == 'lte-softmodem-noS1' :
+ eNBMachine = testcase.findtext('eNB',default='')
+ UEMachine = testcase.findtext('UE',default='')
+ if (eNBMachine not in MachineList)|(UEMachine not in MachineList):
+ print "One of the machines is not in the machine list"
+ print "eNBMachine : " + eNBMachine + "UEMachine : " + UEMachine + "MachineList : " + ','.join(MachineList)
+ print "testcasename = " + testcasename + " class = " + testcaseclass
+ threadListGlobal = wait_testcaseclass_generic_threads(threadListGlobal, Timeout_execution)
+
+ handle_testcaseclass_softmodem_noS1 (testcase, CleanUpOldProgs, logdirOAI5GRepo, logdirOpenaircnRepo, MachineList, user, pw, CleanUpAluLteBox, ExmimoRfStop, nruns_lte_softmodem, Timeout_cmd )
+
+ #The lines below are copied from below to trace the failure of some of the machines in test setup. These lines below need to be removed in long term
+ print "Creating xml file for overall results..."
+ cmd = "cat $OPENAIR_DIR/cmake_targets/autotests/log/*/*.xml > $OPENAIR_DIR/cmake_targets/autotests/log/results_autotests.xml "
+ res=os.system(cmd)
+ os.system('sync')
+
elif (testcaseclass == 'compilation'):
threadListGlobal = handle_testcaseclass_generic (testcasename, threadListGlobal, CleanUpOldProgs, logdirOAI5GRepo, MachineListGeneric, user, pw, CleanUpAluLteBox,Timeout_execution, ExmimoRfStop)
elif (testcaseclass == 'execution'):
diff --git a/cmake_targets/autotests/tools/autotest_analyser.py b/cmake_targets/autotests/tools/autotest_analyser.py
new file mode 100755
index 0000000000..a75727ad65
--- /dev/null
+++ b/cmake_targets/autotests/tools/autotest_analyser.py
@@ -0,0 +1,161 @@
+#! /usr/bin/python
+#******************************************************************************
+#
+# \file autotest_analyser.py
+#
+# \par Informations
+# - \b Project : UED Autotest Framework
+# - \b Software :
+#
+# \date 16 september 2016
+#
+# \version 0.1
+#
+# \brief helper to test lib_autotest_analyser.py
+#
+# \author Benoit ROBERT (benoit.robert@syrtem.com)
+#
+# \par Statement of Ownership
+# COPYRIGHT (c) 2016 BY SYRTEM S.A.R.L
+# This software is furnished under license and may be used and copied
+# only in accordance with the terms of such license and with the inclusion
+# of the above COPYRIGHT notice. This SOFTWARE or any other copies thereof
+# may not be provided or otherwise made available to any other person.
+# No title to and ownership of the SOFTWARE is hereby transferred.
+#
+# The information in this SOFTWARE is subject to change without notice
+# and should not be constructed as a commitment by SYRTEM.
+# SYRTEM assumes no responsibility for the use or reliability of its
+# SOFTWARE on equipment or platform not explicitly validated by SYRTEM.
+#
+# *******************************************************************************
+
+import os
+import getopt
+import sys
+from subprocess import call
+
+
+
+#test_cases = ('030001', '030901', '031001', '031601', '031701', '031801', '031901', '032001', '032101', '032201', '032301', '032501', '032601', '032801')
+test_cases = ('030030' , '030030' )
+
+nb_run = 3
+
+def error_opt(msg):
+ print("Option error: " + msg)
+
+
+def main(args):
+ try:
+ analyser = __import__("lib_autotest_analyser")
+ except ImportError as err:
+ print('Import error: ' + str(err))
+ exit(0)
+
+
+ log_path = 'log_save_2016-08-14/log/'
+
+
+
+ metric = {}
+ metric['id'] = 'UE_DLSCH_BITRATE'
+ metric['description'] = 'UE downlink physical throughput'
+ metric['regex'] = '(UE_DLSCH_BITRATE) =\s+(\d+\.\d+) kbps.+frame = (\d+)\)'
+ metric['unit_of_meas'] = 'kbps'
+ metric['min_limit'] = 14668.8
+
+
+#report_path = log_path+'/report/'
+
+#os.system(' mkdir -p ' + report_path)
+
+#analyser.create_report_html(report_path)
+
+#return(0)
+
+ for test_case in test_cases:
+
+# print test_case
+ if test_case == '030001':
+ metric['min_limit'] = 500.0
+ if test_case == '030901':
+ metric['min_limit'] = 640.0
+ if test_case == '031001':
+ metric['min_limit'] = 3200.0
+ if test_case == '031601':
+ metric['min_limit'] = 5920.0
+ if test_case == '031701':
+ metric['min_limit'] = 6000.0
+ if test_case == '031801':
+ metric['min_limit'] = 6200.0
+ if test_case == '031901':
+ metric['min_limit'] = 7000.0
+ if test_case == '032001':
+ metric['min_limit'] = 7800.0
+ if test_case == '032101':
+ metric['min_limit'] = 8000.0
+ if test_case == '032201':
+ metric['min_limit'] = 9000.0
+ if test_case == '032301':
+ metric['min_limit'] = 10000.0
+ if test_case == '032501':
+ metric['min_limit'] = 11000.0
+ if test_case == '032601':
+ metric['min_limit'] = 12000.0
+ if test_case == '032801':
+ metric['min_limit'] = 12500.0
+
+ if test_case == '035201':
+ metric['min_limit'] = 14668.8
+ if test_case == '036001':
+ metric['min_limit'] = 25363.2
+
+
+
+ for i in range(0, nb_run):
+ fname = 'log//'+test_case+'/run_'+str(i)+'/UE_exec_'+str(i)+'_.log'
+ args = {'metric' : metric,
+ 'file' : fname }
+
+ cell_synch_status = analyser.check_cell_synchro(fname)
+ if cell_synch_status == 'CELL_SYNCH':
+ print '!!!!!!!!!!!!!! Cell synchronized !!!!!!!!!!!'
+ metric_checks_flag = 0
+ else :
+ print '!!!!!!!!!!!!!! Cell NOT NOT synchronized !!!!!!!!!!!'
+
+# metric_extracted = analyser.do_extract_metrics(args)
+
+# print "min = "+ str( metric_extracted['metric_min'] )
+# print "min_index = "+ str( metric_extracted['metric_min_index'] )
+# print "max = "+ str( metric_extracted['metric_max'] )
+# print "max_index = "+ str( metric_extracted['metric_max_index'] )
+# print "mean = "+ str( metric_extracted['metric_mean'] )
+# print "median = "+ str( metric_extracted['metric_median'] )
+
+# verdict = analyser.do_check_verdict(metric, metric_extracted)
+# print verdict
+
+# fname= 'report/2016-9-8_toto/'+test_case+'/UE_metric_UE_DLSCH_BITRATE_'+str(i)+'_.png'
+# fname= 'report/UE_metric_UE_DLSCH_BITRATE_'+test_case+'_'+str(i)+'.png'
+
+# print fname
+# analyser.do_img_metrics(metric, metric_extracted, fname)
+
+# fname = 'log//'+test_case+'/run_'+str(i)+'/UE_traffic_'+str(i)+'_.log'
+
+# args = {'file' : fname }
+
+# traffic_metrics = analyser.do_extract_traffic_metrics(args)
+
+# fname= 'report/iperf_'+test_case+'_'+str(i)+'.png'
+
+# print fname
+# analyser.do_img_traffic(traffic_metrics, fname)
+
+
+
+if __name__ == "__main__":
+ main(sys.argv)
+
diff --git a/cmake_targets/autotests/tools/lib_autotest_analyser.py b/cmake_targets/autotests/tools/lib_autotest_analyser.py
new file mode 100644
index 0000000000..92dcc31e48
--- /dev/null
+++ b/cmake_targets/autotests/tools/lib_autotest_analyser.py
@@ -0,0 +1,414 @@
+#******************************************************************************
+#
+# \file lib_autotest_analyser.py
+#
+# \par Informations
+# - \b Project : UED Autotest Framework
+# - \b Software :
+#
+# \date 16 september 2016
+#
+# \version 0.1
+#
+# \brief library to extract metrics from autotest logs and assign a verdict
+#
+# \author Benoit ROBERT (benoit.robert@syrtem.com)
+#
+# \par Statement of Ownership
+# COPYRIGHT (c) 2016 BY SYRTEM S.A.R.L
+# This software is furnished under license and may be used and copied
+# only in accordance with the terms of such license and with the inclusion
+# of the above COPYRIGHT notice. This SOFTWARE or any other copies thereof
+# may not be provided or otherwise made available to any other person.
+# No title to and ownership of the SOFTWARE is hereby transferred.
+#
+# The information in this SOFTWARE is subject to change without notice
+# and should not be constructed as a commitment by SYRTEM.
+# SYRTEM assumes no responsibility for the use or reliability of its
+# SOFTWARE on equipment or platform not explicitly validated by SYRTEM.
+#
+# *******************************************************************************
+
+
+import re
+from pylab import *
+from matplotlib.font_manager import FontProperties
+
+import os
+from jinja2 import Environment, FileSystemLoader
+
+
+PATH = os.path.dirname(os.path.abspath(__file__))
+TEMPLATE_ENVIRONMENT = Environment(
+ autoescape=False,
+ loader=FileSystemLoader(os.path.join(PATH, 'templates')),
+ trim_blocks=False)
+
+
+def render_template(template_filename, context):
+ return TEMPLATE_ENVIRONMENT.get_template(template_filename).render(context)
+
+
+
+def init(args = None):
+ return
+
+
+#
+#
+#
+def do_extract_metrics(args):
+
+# print ""
+# print "do_extract_metrics ... "
+
+ fname = args['file']
+ metric = args['metric']
+# print(fname)
+# print 'metric id = ' + metric['id']
+# print 'metric regex = ' + metric['regex']
+
+ count = 0
+ mmin = 0
+ mmin_index = 0
+ mmax = 0
+ mmax_index = 0
+ mean = 0
+ median = 0
+
+
+ output = np.fromregex(fname,metric['regex'], [('id', 'S20'), ('metric', np.float), ('frame', np.int)] )
+# print 'T0T0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
+# print output
+ count = output['metric'].size
+# print count
+ if count > 0:
+ mmin = np.amin(output['metric']);
+ mmin_index = np.argmin(output['metric']);
+ mmax = np.amax(output['metric']);
+ mmax_index = np.argmax(output['metric']);
+ mean = np.mean(output['metric']);
+ median = np.median(output['metric']);
+
+# print ( ( (metric['min_limit'] > output['metric']).sum() / float(output['metric'].size) ) * 100 )
+
+ ret = { 'metric_count' : count,
+ 'metric_buf' : output,
+ 'metric_min' : mmin,
+ 'metric_min_index' : mmin_index,
+ 'metric_max' : mmax,
+ 'metric_max_index' : mmax_index,
+ 'metric_mean' : mean,
+ 'metric_median' : median,
+ }
+ return(ret)
+
+#
+#
+#
+def do_check_verdict(metric_def, metric_data):
+ verdict = 'INCON'
+
+ pass_fail_stat = metric_def['pass_fail_stat']
+
+ if pass_fail_stat == 'max_value':
+ metric_stat = metric_data['metric_max']
+ elif pass_fail_stat == 'min_value':
+ metric_stat = metric_data['metric_min']
+ elif pass_fail_stat == 'mean_value':
+ metric_stat = metric_data['metric_mean']
+ elif pass_fail_stat == 'median_value':
+ metric_stat = metric_data['metric_median']
+ else :
+ print "do_check_verdict -> undef metric stat (pass_fail_stat in xml file)"
+ return verdict
+
+ if 'max_limit' in metric_def:
+ if metric_stat > metric_def['max_limit']:
+ verdict = 'FAIL'
+ else:
+ verdict = 'PASS'
+
+ if 'min_limit' in metric_def:
+ if metric_stat < metric_def['min_limit']:
+ verdict = 'FAIL'
+ else:
+ verdict = 'PASS'
+ return verdict
+
+
+def do_print_metrics(metric_def, metric_data):
+
+
+ if metric_data['metric_count'] > 0 :
+
+# output = np.array( metric_data['metric_buf'] , [('id', 'S20'), ('metric', np.float), ('frame', np.int)])
+ output = metric_data['metric_buf']
+# print output
+
+ fontP = FontProperties()
+ fontP.set_size('small')
+
+ plt.scatter(output['frame'], output['metric'], color='b', alpha=0.33, s = 1 )
+ plt.plot([0, output['frame'][metric_data['metric_count']-1]],[ metric_def['min_limit'],metric_def['min_limit']], 'r-', lw=2) # Red straight line
+
+ plt.title('Physical throughput ')
+ plt.xlabel('frame')
+ plt.ylabel(metric_def['id'])
+ plt.legend(prop=fontP)
+ mng = plt.get_current_fig_manager()
+ plt.show()
+
+def do_img_metrics(metric_def, metric_data, fname):
+
+
+ if metric_data['metric_count'] > 0 :
+
+# output = np.array( metric_data['metric_buf'] , [('id', 'S20'), ('metric', np.float), ('frame', np.int)])
+ output = metric_data['metric_buf']
+# print 'TITI !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
+# print output
+
+# print metric_def['min_limit']
+# print metric_data['metric_count']
+# print output['frame'][metric_data['metric_count']-1]
+
+ fontP = FontProperties()
+ fontP.set_size('small')
+
+ plt.figure()
+
+# print output['frame'].size
+# print output['metric'].size
+
+ plt.scatter(output['frame'], output['metric'], color='b', alpha=0.33, s = 1 , label=metric_def['id'])
+ plt.plot([0, output['frame'][metric_data['metric_count']-1]],[ metric_def['min_limit'],metric_def['min_limit']], 'r-', lw=2, label='min limit') # Red straight line
+
+ plt.title('Physical throughput ('+metric_def['unit_of_meas']+')')
+ plt.xlabel('frame')
+ plt.ylabel(metric_def['id'])
+
+ # Set graphic minimum Y axis
+ # -------------------------
+ if metric_data['metric_min'] == 0 :
+ plt.ylim(ymin=-metric_def['min_limit']/10)
+ else :
+ plt.ylim(ymin=0)
+
+ y_axis_max = 0
+ if metric_data['metric_max'] > metric_def['min_limit']:
+ y_axis_max =metric_data['metric_max']+metric_data['metric_max']/10
+ else:
+ y_axis_max =metric_def['min_limit']+metric_def['min_limit']/10
+
+ plt.ylim(ymax=y_axis_max)
+
+ lgd = plt.legend(prop=fontP, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
+ mng = plt.get_current_fig_manager()
+ plt.savefig(fname, bbox_extra_artists=(lgd,), bbox_inches='tight')
+ plt.close()
+
+# with open(fname, 'r') as f:
+# for line in f:
+# m = re.search(metric['regex'], line)
+# if m :
+# print m.group(1) + " -> "+m.group(2)
+
+
+
+
+def do_extract_traffic_metrics(args):
+
+ print ""
+ print "do_extract_traffic_metrics ... "
+
+ fname = args['file']
+
+# print(fname)
+# print 'metric id = ' + metric['id']
+
+#[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
+#[ 3] 0.0- 1.0 sec 238 KBytes 1.95 Mbits/sec 0.980 ms 2/ 174 (1.1%)
+# [ 3] 0.0- 1.0 sec 63.2 KBytes 517 Kbits/sec 0.146 ms 1/ 45 (2.2%)
+
+# iperf_regex = '[\s*(\d+)]\s+\d+\.\d+-\s*(\d+\.\d+)\s+sec\s+(\d+).+(\d+\.\d+).+(\d+\.\d+).+(\d+)\/\s*(\d+)\s+\((\d+\.\d+)\%\)'
+ # ID 0.0 1.0 63.2 KByte 517 Kbits/s 0.146
+ iperf_regex = '\[\s*(\d+)\]\s+(\d+\.*\d*)-\s*(\d+\.*\d*)\s+sec\s+(\d+\.*\d*)\s+(\D+)\s+(\d+\.*\d*)\s+(\D+)\s+(\d+\.*\d*)\s+ms\s+(\d+)\/\s*(\d+)\s+\((\d+\.*\d*)\%\)'
+# print 'iperf regex = ' + iperf_regex
+
+ count = 0
+ bw_min = 0
+ bw_max = 0
+ bw_mean = 0
+ bw_median = 0
+ jitter_min = 0
+ jitter_max = 0
+ jitter_mean = 0
+ jitter_median = 0
+
+ rl_min = 0
+ rl_max = 0
+ rl_mean = 0
+ rl_median = 0
+
+ interval_stop_max = 0
+
+ output = np.fromregex(fname,iperf_regex, [('id', np.int) , ('interval_start', np.float), ('interval_stop', np.float), ('transfer', np.float), ('transfer_uom', 'S20') ,('bandwidth', np.float), ('bandwidth_uom', 'S20') ,('jitter', np.float), ('lost', np.int) , ('total', np.int), ('rate_lost', np.float) ] )
+
+ count = output['id'].size -1
+ # remove last line that is an iperf result resume
+
+ if count > 0:
+
+ output= np.delete(output, (count), axis=0 )
+# print output
+
+ bw_min = np.amin(output['bandwidth']);
+ bw_max = np.amax(output['bandwidth']);
+ bw_mean = np.mean(output['bandwidth']);
+ bw_median = np.median(output['bandwidth']);
+
+ jitter_min = np.amin(output['jitter']);
+ jitter_max = np.amax(output['jitter']);
+ jitter_mean = np.mean(output['jitter']);
+ jitter_median = np.median(output['jitter']);
+
+ rl_min = np.amin(output['rate_lost']);
+ rl_max = np.amax(output['rate_lost']);
+ rl_mean = np.mean(output['rate_lost']);
+ rl_median = np.median(output['rate_lost']);
+
+ interval_stop_max = np.amax(output['interval_stop']);
+
+ else :
+ count = 0
+
+
+ ret = { 'traffic_count' : count,
+ 'traffic_buf' : output,
+ 'bw_min' : bw_min,
+ 'bw_max' : bw_max,
+ 'bw_mean' : bw_mean,
+ 'bw_median' : bw_median,
+ 'jitter_min' : jitter_min,
+ 'jitter_max' : jitter_max,
+ 'jitter_mean' : jitter_mean,
+ 'jitter_median' : jitter_median,
+ 'rl_min' : rl_min,
+ 'rl_max' : rl_max,
+ 'rl_mean' : rl_mean,
+ 'rl_median' : rl_median,
+ 'interval_stop_max' : interval_stop_max
+ }
+ return(ret)
+
+
+
+
+def do_img_traffic(traffic_data, fname):
+
+
+ if traffic_data['traffic_count'] > 0 :
+
+ output = traffic_data['traffic_buf']
+
+
+ fontP = FontProperties()
+ fontP.set_size('small')
+
+ fig = plt.figure(1)
+
+ ax1= plt.subplot(311)
+ plt.plot(output['interval_stop'], output['bandwidth'], color='b' )
+ ax1.set_title('Bandwidth (Mbits/s)')
+ ax1.set_ylim(ymin=-1)
+ ax1.set_xlim(xmax=np.amax(output['interval_stop']))
+ text='min: '+str(traffic_data['bw_min'])+'\nmax: '+str(traffic_data['bw_max'])+'\nmean: '+str(traffic_data['bw_mean'])+'\nmedian: '+str(traffic_data['bw_median'])
+ ax1.text( np.amax(output['interval_stop'])+10,0,text)
+
+
+ ax2=plt.subplot(312)
+ plt.plot(output['interval_stop'], output['jitter'], color='b' )
+ ax2.set_title('Jitter (ms)')
+ ax2.set_xlim(xmax=np.amax(output['interval_stop']))
+ ax2.set_ylim(ymin=-1)
+ text='min: '+str(traffic_data['jitter_min'])+'\nmax: '+str(traffic_data['jitter_max'])+'\nmean: '+str(traffic_data['jitter_mean'])+'\nmedian: '+str(traffic_data['jitter_median'])
+ ax2.text( np.amax(output['interval_stop'])+10,0,text)
+
+ ax3=plt.subplot(313)
+ plt.plot(output['interval_stop'], output['rate_lost'], color='b')
+ ax3.set_title('Loss rate %')
+ ax3.set_xlim(xmax=np.amax(output['interval_stop']))
+ ax3.set_ylim(ymin=-1)
+ text='min: '+str(traffic_data['rl_min'])+'\nmax: '+str(traffic_data['rl_max'])+'\nmean: '+str(traffic_data['rl_mean'])+'\nmedian: '+str(traffic_data['rl_median'])
+ ax3.text( np.amax(output['interval_stop'])+10,0,text)
+
+
+# plt.title('Physical throughput ('+metric_def['unit_of_meas']+')')
+ plt.xlabel('time (s)')
+# plt.ylabel(metric_def['id'])
+
+ # Set graphic minimum Y axis
+ # -------------------------
+# if traffic_data['bw_min'] == 0 :
+# plt.ylim(ymin=-metric_def['min_limit']/10)
+# else :
+# plt.ylim(ymin=0)
+
+# y_axis_max = 0
+# if traffic_data['metric_max'] > metric_def['min_limit']:
+# y_axis_max =traffic_data['metric_max']+traffic_data['metric_max']/10
+# else:
+# y_axis_max =metric_def['min_limit']+metric_def['min_limit']/10
+#
+# plt.ylim(ymax=y_axis_max)
+
+ plt.tight_layout()
+
+ lgd = plt.legend(prop=fontP, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
+ mng = plt.get_current_fig_manager()
+ plt.savefig(fname, bbox_inches='tight')
+ plt.close()
+
+
+
+
+def create_report_html(context):
+ fname = context['report_path']+"/index.html"
+
+ #
+ with open(fname, 'w') as f:
+ html = render_template('index.html', context)
+ f.write(html)
+
+
+def create_test_report_detailed_html(context, fname ):
+ with open(fname, 'w') as f:
+ html = render_template('testcase_report.html', context)
+ f.write(html)
+
+
+def check_cell_synchro(fname):
+
+ with open(fname, 'r') as f:
+ for line in f:
+
+ m = re.search('AUTOTEST Cell Sync \:', line)
+ if m :
+ print line
+ return 'CELL_SYNCH'
+
+ return 'CELL_NOT_SYNCH'
+
+
+def check_exec_seg_fault(fname):
+
+ with open(fname, 'r') as f:
+ for line in f:
+ m = re.search('Segmentation fault', line)
+ if m :
+ print line
+ return 'SEG_FAULT'
+
+ return 'NO_SEG_FAULT'
+
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index ac9739e589..c5f2b87704 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -223,13 +223,15 @@ check_install_additional_tools (){
android-tools-adb \
wvdial \
python-numpy \
- sshpass \
- nscd \
- bc \
- ntp
+ sshpass \
+ nscd \
+ bc \
+ ntp \
+ python-scipy \
+ python-matplotlib
$SUDO pip install paramiko
- $SUDO pip install pyroute2
+ $SUDO pip install pyroute2 colorama
$SUDO rm -fr /opt/ssh
$SUDO GIT_SSL_NO_VERIFY=true git clone https://gitlab.eurecom.fr/oai/ssh.git /opt/ssh
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index 321225a597..6e5e0ad7aa 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -61,6 +61,10 @@ ID = ENB_PHY_PUCCH_1_ENERGY
DESC = eNodeB PUCCH 1 energy and threshold
GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,energy : int,threshold
+ID = ENB_PHY_PHICH
+ DESC = eNodeB PHICH
+ GROUP = ALL:PHY:ENB
+ FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid : int,NGROUP : int,NSF : int,ngroup : int,nseq : int,ACK : int,first_rb : int,n_DMRS
#MAC logs
ID = ENB_MAC_UE_DL_SDU
diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder.c b/openair1/PHY/CODING/3gpplte_turbo_decoder.c
index 931758c03b..c6976df164 100644
--- a/openair1/PHY/CODING/3gpplte_turbo_decoder.c
+++ b/openair1/PHY/CODING/3gpplte_turbo_decoder.c
@@ -1058,7 +1058,7 @@ unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y,
break;
}
- if ((crc == oldcrc) && (crc!=0)) {
+ if (crc == oldcrc) {
return(iteration_cnt);
}
diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c
index 49bb9d102c..4efd366bed 100644
--- a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c
+++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c
@@ -1375,7 +1375,7 @@ unsigned char phy_threegpplte_turbo_decoder16avx2(int16_t *y,
fprintf(fdavx2b,"oldcrc %x, crc %x, oldcrc_cw2 %x, crc_cw2 %x\n",oldcrc,crc,oldcrc_cw2,crc_cw2);
#endif
- if ((crc == oldcrc) && (crc!=0) && (crc_cw2 == oldcrc_cw2) && (crc_cw2!=0)) {
+ if (crc == oldcrc && crc_cw2 == oldcrc_cw2) {
return(iteration_cnt);
}
}
diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c
index abcdc0521b..085dbb723c 100644
--- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c
+++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse.c
@@ -2556,7 +2556,7 @@ unsigned char phy_threegpplte_turbo_decoder(short *y,
stop_meas(intl2_stats);
- if ((crc == oldcrc) && (crc!=0)) {
+ if (crc == oldcrc) {
return(iteration_cnt);
}
}
diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c
index dc789d0404..a1e408dcda 100644
--- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c
+++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c
@@ -1612,7 +1612,7 @@ unsigned char phy_threegpplte_turbo_decoder16(short *y,
fprintf(fdsse4,"oldcrc %x, crc %x\n",oldcrc,crc);
#endif
- if ((crc == oldcrc) && (crc!=0)) {
+ if (crc == oldcrc) {
return(iteration_cnt);
}
}
diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
index b56aae4598..ff7e02a239 100644
--- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
+++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
@@ -486,7 +486,7 @@ void compute_beta8(llr_t* alpha,llr_t* beta,llr_t *m_11,llr_t* m_10,unsigned sho
#endif
- if (frame_length > 6143) {
+ if (frame_length > 6144) {
LOG_E(PHY,"compute_beta: frame_length %d\n",frame_length);
return;
}
@@ -1625,7 +1625,7 @@ unsigned char phy_threegpplte_turbo_decoder8(short *y,
if (intl2_stats) stop_meas(intl2_stats);
- if ((crc == oldcrc) && (crc!=0)) {
+ if (crc == oldcrc) {
return(iteration_cnt);
}
}
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index fc307655dd..107fa042a6 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -36,7 +36,10 @@
#include "PHY/vars.h"
#endif
#include "assertions.h"
-
+
+#include "LAYER2/MAC/extern.h"
+#include "LAYER2/MAC/defs.h"
+
//#define DEBUG_DCI
uint32_t localRIV2alloc_LUT6[32];
@@ -3922,10 +3925,10 @@ int generate_ue_dlsch_params_from_dci(int frame,
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
} else {
- if (harq_pid>1) {
- LOG_E(PHY,"Format 1A: harq_pid > 1\n");
- return(-1);
- }
+ //if (harq_pid>1) {
+ // LOG_E(PHY,"Format 1A: harq_pid > 1\n");
+ // return(-1);
+ //}
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
NPRB = RIV2nb_rb_LUT25[rballoc];
@@ -5552,7 +5555,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
#ifdef DEBUG_DCI
- if (dlsch[0]) {
+ if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) {
+ printf("dci_format:%d \n",dci_format);
printf("PDSCH dlsch0 UE: rnti %x\n",dlsch[0]->rnti);
printf("PDSCH dlsch0 UE: NBRB %d\n",dlsch0_harq->nb_rb);
printf("PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]);
@@ -6396,7 +6400,11 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
if ((rnti >= cba_rnti) && (rnti < p_rnti))
ulsch->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1; //+=1 this indicates the number of dci / cba group: not supported in the data struct
else
- ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+ {
+ ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+ //LOG_I(PHY,"[HARQ-UL harqId: %d] DCI0 ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
+
+ }
ulsch->harq_processes[harq_pid]->TPC = TPC;
@@ -6426,7 +6434,42 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
ulsch->harq_processes[harq_pid]->round = 0;
} else {
// ulsch->harq_processes[harq_pid]->Ndi = 0;
- // ulsch->harq_processes[harq_pid]->round++; // This is done in phich RX
+ //ulsch->harq_processes[harq_pid]->round++; // This is done in phich RX
+
+ //#ifdef DEBUG_PHICH
+ //LOG_I(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d Adaptative Retrans, NDI not toggled => Nack. maxHARQ_Tx %d \n",
+ // ue->Mod_id,harq_pid,
+ // proc->frame_rx,
+ // subframe,
+ // UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx);
+ //#endif
+
+ if (ulsch->harq_processes[harq_pid]->round > 0) // NACK detected on phich
+ {
+ // ulsch->harq_processes[harq_pid]->round++; already done on phich_rx
+ ulsch->harq_processes[harq_pid] = ulsch->harq_processes[8];
+ // LOG_I(PHY," Adaptative retransmission - copy temporary harq Process to current harq process. [harqId %d round %d] \n",harq_pid, ulsch->harq_processes[8]->round);
+
+ if (ulsch->harq_processes[harq_pid]->round >= UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx)
+ {
+ ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+ ulsch->harq_processes[harq_pid]->round = 0;
+ ulsch->harq_processes[harq_pid]->status = IDLE;
+ //LOG_I(PHY," PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid);
+ //LOG_I(PHY," [HARQ-UL harqId: %d] Adaptative retransmission NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
+ }
+ else
+ {
+ // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+ uint8_t rv_table[4] = {0, 2, 3, 1};
+ ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3];
+ ulsch->O_RI = 0;
+ ulsch->O = 0;
+ ulsch->uci_format = HLC_subband_cqi_nopmi;
+ //LOG_I(PHY," [HARQ-UL harqId: %d] Adaptative retransmission NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round);
+ }
+ }
+
}
}
@@ -6476,7 +6519,16 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
if (cqi_req == 1) {
- ulsch->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table
+
+ if( (AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) )
+ {
+ ulsch->O_RI = 1;
+ }
+ else
+ {
+ ulsch->O_RI = 0;
+ }
+ //ulsch->O_RI = 0; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table
switch(transmission_mode) {
// The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling
@@ -7036,15 +7088,19 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
// ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
-#ifdef DEBUG_DCI
+ #ifdef DEBUG_DCI
+ printf("Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx,subframe);
printf("Format 0 DCI : ulsch (ue): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
printf("Format 0 DCI :ulsch (ue): first_rb %d\n",ulsch->harq_processes[harq_pid]->first_rb);
+ printf("Format 0 DCI :ulsch (ue): rballoc %d\n",rballoc);
printf("Format 0 DCI :ulsch (ue): harq_pid %d\n",harq_pid);
+ printf("Format 0 DCI :ulsch (ue): first_tx %d\n",ulsch->harq_processes[harq_pid]->first_tx);
+ printf("Format 0 DCI :ulsch (ue): DCINdi %d\n",ulsch->harq_processes[harq_pid]->DCINdi);
printf("Format 0 DCI :ulsch (ue): round %d\n",ulsch->harq_processes[harq_pid]->round);
printf("Format 0 DCI :ulsch (ue): TBS %d\n",ulsch->harq_processes[harq_pid]->TBS);
printf("Format 0 DCI :ulsch (ue): mcs %d\n",ulsch->harq_processes[harq_pid]->mcs);
printf("Format 0 DCI :ulsch (ue): O %d\n",ulsch->O);
-
+ printf("Format 0 DCI :ulsch (ue): cqiReq %d\n",cqi_req);
if (frame_parms->frame_type == TDD)
printf("Format 0 DCI :ulsch (ue): O_ACK/DAI %d/%d\n",ulsch->harq_processes[harq_pid]->O_ACK,dai);
else
@@ -7052,6 +7108,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
printf("Format 0 DCI :ulsch (ue): Nsymb_pusch %d\n",ulsch->Nsymb_pusch);
printf("Format 0 DCI :ulsch (ue): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
+ printf("Format 0 DCI :ulsch (ue): phich status %d\n",ulsch->harq_processes[harq_pid]->status);
#else
UNUSED_VARIABLE(dai);
#endif
@@ -7240,7 +7297,17 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
if (cqi_req == 1) {
- ulsch->harq_processes[harq_pid]->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table
+ /* 36.213 7.2.1 (release 10) says:
+ * "RI is only reported for transmission modes 3 and 4,
+ * as well as transmission modes 8 and 9 with PMI/RI reporting"
+ * This is for aperiodic reporting.
+ * TODO: deal with TM 8&9 correctly when they are implemented.
+ * TODO: deal with periodic reporting if we implement it.
+ */
+ if (transmission_mode == 3 || transmission_mode == 4)
+ ulsch->harq_processes[harq_pid]->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table
+ else
+ ulsch->harq_processes[harq_pid]->O_RI = 0;
switch(transmission_mode) {
// The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index deb1110a55..f8d36d3bd4 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -227,6 +227,11 @@ typedef struct {
uint8_t control_only;
/// Flag to indicate that this is a calibration ULSCH (i.e. no MAC SDU and filled with TDD calibration information)
// int calibration_flag;
+ /// Number of soft channel bits
+ uint32_t G;
+
+ // decode phich
+ uint8_t decode_phich;
} LTE_UL_UE_HARQ_t;
typedef struct {
@@ -278,7 +283,7 @@ typedef struct {
/// SRS active flag
uint8_t srs_active;
/// Pointers to 8 HARQ processes for the ULSCH
- LTE_UL_UE_HARQ_t *harq_processes[8];
+ LTE_UL_UE_HARQ_t *harq_processes[9];
/// Pointer to CQI data
uint8_t o[MAX_CQI_BYTES];
/// Length of CQI data (bits)
@@ -362,12 +367,18 @@ typedef struct {
uint8_t TPC;
/// First Allocated RB
uint16_t first_rb;
+ /// First Allocated RB - previous scheduling
+ /// This is needed for PHICH generation which
+ /// is done after a new scheduling
+ uint16_t previous_first_rb;
/// Current Number of RBs
uint16_t nb_rb;
/// Transport block size
uint32_t TBS;
/// The payload + CRC size in bits
uint32_t B;
+ /// Number of soft channel bits
+ uint32_t G;
/// CQI CRC status
uint8_t cqi_crc_status;
/// Pointer to CQI data
@@ -444,6 +455,10 @@ typedef struct {
uint8_t Nsymb_initial;
/// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2)
uint8_t n_DMRS;
+ /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) - previous scheduling
+ /// This is needed for PHICH generation which
+ /// is done after a new scheduling
+ uint8_t previous_n_DMRS;
/// n_DMRS 2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1)
uint8_t n_DMRS2;
/// Flag to indicate that this ULSCH is for calibration information sent from UE (i.e. no MAC SDU to pass up)
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
index c7cd5ab52f..4a80110b22 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
@@ -619,7 +619,11 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
harq_process->errors[harq_process->round]++;
harq_process->round++;
- // LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
+
+ if(is_crnti)
+ {
+ LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS);
+ }
// printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
if (harq_process->round >= dlsch->Mdlharq) {
harq_process->status = SCH_IDLE;
@@ -632,7 +636,10 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
dlsch->harq_ack[subframe].ack = 1;
dlsch->harq_ack[subframe].harq_id = harq_pid;
dlsch->harq_ack[subframe].send_harq_status = 1;
- LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
+ if(is_crnti)
+ {
+ LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round,harq_process->TBS);
+ }
}
diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
index 91374078c0..663978e92c 100644
--- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c
+++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
@@ -463,7 +463,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
}
/* Consider this is a false detection if the offset is > 1000 Hz */
- if( (abs(ue->common_vars.freq_offset) > 1000) && (ret == 0) )
+ if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) )
{
ret=-1;
LOG_E(HW,"Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index 1727ec5324..2d07ba948a 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -34,6 +34,10 @@
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "defs.h"
+
+#include "LAYER2/MAC/extern.h"
+#include "LAYER2/MAC/defs.h"
+
#ifndef USER_MODE
#include "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h"
#endif
@@ -1375,15 +1379,39 @@ void rx_phich(PHY_VARS_UE *ue,
subframe,
HI16,
nseq_PHICH,
- ngroup_PHICH);
+ ngroup_PHICH,
+ UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx);
//#endif
- ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+
// ulsch->harq_processes[harq_pid]->Ndi = 0;
ulsch->harq_processes[harq_pid]->round++;
- ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3];
- ulsch->O_RI = 0;
- ulsch->O = 0;
- ulsch->uci_format = HLC_subband_cqi_nopmi;
+
+ if ( ulsch->harq_processes[harq_pid]->round >= (UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx - 1) )
+ {
+ // this is last push re transmission
+ ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3];
+ ulsch->O_RI = 0;
+ ulsch->O = 0;
+ ulsch->uci_format = HLC_subband_cqi_nopmi;
+
+ // disable phich decoding since it is the last retransmission
+ ulsch->harq_processes[harq_pid]->status = IDLE;
+
+ //ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+ //ulsch->harq_processes[harq_pid]->round = 0;
+
+ //LOG_I(PHY,"PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid);
+ //LOG_I(PHY,"[HARQ-UL harqId: %d] PHICH NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
+ }
+ else
+ {
+ // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+ ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3];
+ ulsch->O_RI = 0;
+ ulsch->O = 0;
+ ulsch->uci_format = HLC_subband_cqi_nopmi;
+ //LOG_I(PHY,"[HARQ-UL harqId: %d] PHICH NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round);
+ }
}
@@ -1405,11 +1433,22 @@ void rx_phich(PHY_VARS_UE *ue,
//#endif
}
+ // LOG_I(PHY,"[HARQ-UL harqId: %d] subframe_scheduling_flag = %d \n",harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag);
+
+ // Incase of adaptive retransmission, PHICH is always decoded as ACK (at least with OAI-eNB)
+ // Workaround:
+ // rely only on DCI0 decoding and check if NDI has toggled
+ // save current harq_processes content in temporary struct
+ // harqId-8 corresponds to the temporary struct. In total we have 8 harq process(0 ..7) + 1 temporary harq process()
+ ulsch->harq_processes[8] = ulsch->harq_processes[harq_pid];
+
ulsch->harq_processes[harq_pid]->subframe_scheduling_flag =0;
ulsch->harq_processes[harq_pid]->status = IDLE;
ulsch->harq_processes[harq_pid]->round = 0;
// inform MAC?
ue->ulsch_Msg3_active[eNB_id] = 0;
+
+ //LOG_I(PHY,"[HARQ-UL harqId: %d] PHICH ACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
}
}
@@ -1453,8 +1492,12 @@ void generate_phich_top(PHY_VARS_eNB *eNB,
LOG_D(PHY,"[eNB][PUSCH %d/%x] Frame %d subframe %d (pusch_subframe %d,pusch_frame %d) phich active %d\n",
harq_pid,ulsch[UE_id]->rnti,proc->frame_tx,subframe,pusch_subframe,pusch_frame,ulsch[UE_id]->harq_processes[harq_pid]->phich_active);
- ngroup_PHICH = (ulsch[UE_id]->harq_processes[harq_pid]->first_rb +
- ulsch[UE_id]->harq_processes[harq_pid]->n_DMRS)%Ngroup_PHICH;
+ /* the HARQ process may have been reused by a new scheduling, so we use
+ * previous values of first_rb and n_DMRS to compute ngroup_PHICH and nseq_PHICH
+ */
+
+ ngroup_PHICH = (ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb +
+ ulsch[UE_id]->harq_processes[harq_pid]->previous_n_DMRS)%Ngroup_PHICH;
if ((frame_parms->tdd_config == 0) && (frame_parms->frame_type == TDD) ) {
@@ -1462,20 +1505,28 @@ void generate_phich_top(PHY_VARS_eNB *eNB,
ngroup_PHICH += Ngroup_PHICH;
}
- nseq_PHICH = ((ulsch[UE_id]->harq_processes[harq_pid]->first_rb/Ngroup_PHICH) +
- ulsch[UE_id]->harq_processes[harq_pid]->n_DMRS)%(2*NSF_PHICH);
+ nseq_PHICH = ((ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb/Ngroup_PHICH) +
+ ulsch[UE_id]->harq_processes[harq_pid]->previous_n_DMRS)%(2*NSF_PHICH);
LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Generating PHICH, ngroup_PHICH %d/%d, nseq_PHICH %d : HI %d, first_rb %d dci_alloc %d)\n",
eNB->Mod_id,harq_pid,proc->frame_tx,
subframe,ngroup_PHICH,Ngroup_PHICH,nseq_PHICH,
ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK,
- ulsch[UE_id]->harq_processes[harq_pid]->first_rb,
+ ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb,
ulsch[UE_id]->harq_processes[harq_pid]->dci_alloc);
+ T(T_ENB_PHY_PHICH, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(subframe),
+ T_INT(UE_id), T_INT(ulsch[UE_id]->rnti), T_INT(harq_pid),
+ T_INT(Ngroup_PHICH), T_INT(NSF_PHICH),
+ T_INT(ngroup_PHICH), T_INT(nseq_PHICH),
+ T_INT(ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK),
+ T_INT(ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb),
+ T_INT(ulsch[UE_id]->harq_processes[harq_pid]->previous_n_DMRS));
+
if (ulsch[UE_id]->Msg3_active == 1) {
LOG_D(PHY,"[eNB %d][PUSCH %d][RAPROC] Frame %d, subframe %d: Generating Msg3 PHICH for UE %d, ngroup_PHICH %d/%d, nseq_PHICH %d : HI %d, first_rb %d\n",
eNB->Mod_id,harq_pid,proc->frame_tx,subframe,
UE_id,ngroup_PHICH,Ngroup_PHICH,nseq_PHICH,ulsch[UE_id]->harq_processes[harq_pid]->phich_ACK,
- ulsch[UE_id]->harq_processes[harq_pid]->first_rb);
+ ulsch[UE_id]->harq_processes[harq_pid]->previous_first_rb);
}
if (eNB->abstraction_flag == 0) {
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
index 53eaa849fd..6d2d6232cb 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
@@ -498,6 +498,21 @@ uint32_t ulsch_encoding(uint8_t *a,
G = G - Q_RI - Q_CQI;
+ ulsch->harq_processes[harq_pid]->G = G;
+
+/*
+ LOG_I(PHY,"ULSCH Encoding G %d, Q_RI %d (O_RI%d, Msc_initial %d, Nsymb_initial%d, beta_offset_ri_times8 %d), Q_CQI %d \n",G,Q_RI,ulsch->O_RI,ulsch->harq_processes[harq_pid]->Msc_initial,ulsch->harq_processes[harq_pid]->Nsymb_initial,ulsch->beta_offset_ri_times8,Q_CQI);
+
+ LOG_I(PHY,"ULSCH Encoding (Nid_cell %d, rnti %x): harq_pid %d round %d, RV %d, mcs %d, O_RI %d, O_ACK %d, G %d\n",
+ frame_parms->Nid_cell,ulsch->rnti,
+ harq_pid,
+ ulsch->harq_processes[harq_pid]->round,
+ ulsch->harq_processes[harq_pid]->rvidx,
+ ulsch->harq_processes[harq_pid]->mcs,
+ ulsch->O_RI,
+ ulsch->harq_processes[harq_pid]->O_ACK,
+ G);
+*/
if ((int)G < 0) {
LOG_E(PHY,"FATAL: ulsch_coding.c G < 0 (%d) : Q_RI %d, Q_CQI %d, O %d, betaCQI_times8 %d)\n",G,Q_RI,Q_CQI,ulsch->O,ulsch->beta_offset_cqi_times8);
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 9081455f00..80dfb69877 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -228,7 +228,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
int Q_m = get_Qm_ul(ulsch_harq->mcs);
- int G = ulsch_harq->nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
+ int G = ulsch_harq->G;
uint32_t E;
uint32_t Gp,GpmodC,Nl=1;
uint32_t C = ulsch_harq->C;
@@ -450,7 +450,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
int Q_m = get_Qm_ul(ulsch_harq->mcs);
- int G = ulsch_harq->nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
+ int G = ulsch_harq->G;
unsigned int E;
int Cby2;
@@ -658,7 +658,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
LTE_eNB_ULSCH_t *ulsch = eNB->ulsch[UE_id];
LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
int Q_m = get_Qm_ul(ulsch_harq->mcs);
- int G = ulsch_harq->nb_rb * (12 * Q_m) * ulsch_harq->Nsymb_pusch;
+ int G = ulsch_harq->G;
unsigned int E;
uint8_t (*tc)(int16_t *y,
@@ -1036,6 +1036,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
#endif
G = G - Q_RI - Q_CQI;
+ ulsch_harq->G = G;
if ((int)G < 0) {
LOG_E(PHY,"FATAL: ulsch_decoding.c G < 0 (%d) : Q_RI %d, Q_CQI %d\n",G,Q_RI,Q_CQI);
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c
index 80168dd3c5..ee9bfc53cd 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_modulation.c
@@ -426,13 +426,14 @@ void ulsch_modulation(int32_t **txdataF,
G = (int)ulsch->harq_processes[harq_pid]->nb_rb * (12 * Q_m) * (ulsch->Nsymb_pusch);
+
// Mapping
nsymb = (frame_parms->Ncp==0) ? 14:12;
Msc_PUSCH = ulsch->harq_processes[harq_pid]->nb_rb*12;
#ifdef DEBUG_ULSCH_MODULATION
- printf("ulsch_modulation.c: Doing modulation (rnti %x,x2 %x) for G=%d bits, harq_pid %d , nb_rb %d, Q_m %d, Nsymb_pusch %d (nsymb %d), subframe %d\n",
- ulsch->rnti,x2,G,harq_pid,ulsch->harq_processes[harq_pid]->nb_rb,Q_m, ulsch->Nsymb_pusch,nsymb,subframe);
+ LOG_D(PHY,"ulsch_modulation.c: Doing modulation (rnti %x,x2 %x) for G=%d bits, harq_pid %d , nb_rb %d, Q_m %d, Nsymb_pusch %d (nsymb %d), subframe %d\n",
+ ulsch->rnti,x2,G,harq_pid,ulsch->harq_processes[harq_pid]->nb_rb,Q_m, ulsch->Nsymb_pusch,nsymb,subframe);
#endif
// scrambling (Note the placeholding bits are handled in ulsch_coding.c directly!)
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 4163b8340c..7ac6e2bf1f 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -1206,6 +1206,38 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
eNB->dlsch[i][0]->subframe_tx[subframe] = 0;
}
+ /* save old HARQ information needed for PHICH generation */
+ for (i=0; iulsch[i]) {
+ /* Store first_rb and n_DMRS for correct PHICH generation below.
+ * For PHICH generation we need "old" values of last scheduling
+ * for this HARQ process. 'generate_eNB_dlsch_params' below will
+ * overwrite first_rb and n_DMRS and 'generate_phich_top', done
+ * after 'generate_eNB_dlsch_params', would use the "new" values
+ * instead of the "old" ones.
+ *
+ * This has been tested for FDD only, may be wrong for TDD.
+ *
+ * TODO: maybe we should restructure the code to be sure it
+ * is done correctly. The main concern is if the code
+ * changes and first_rb and n_DMRS are modified before
+ * we reach here, then the PHICH processing will be wrong,
+ * using wrong first_rb and n_DMRS values to compute
+ * ngroup_PHICH and nseq_PHICH.
+ *
+ * TODO: check if that works with TDD.
+ */
+ if ((subframe_select(fp,ul_subframe)==SF_UL) ||
+ (fp->frame_type == FDD)) {
+ harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe);
+ eNB->ulsch[i]->harq_processes[harq_pid]->previous_first_rb =
+ eNB->ulsch[i]->harq_processes[harq_pid]->first_rb;
+ eNB->ulsch[i]->harq_processes[harq_pid]->previous_n_DMRS =
+ eNB->ulsch[i]->harq_processes[harq_pid]->n_DMRS;
+ }
+ }
+ }
+
num_pdcch_symbols = DCI_pdu->num_pdcch_symbols;
LOG_D(PHY,"num_pdcch_symbols %"PRIu8",(dci common %"PRIu8", dci uespec %"PRIu8"\n",num_pdcch_symbols,
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 55e7686462..6e7354f883 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -944,9 +944,18 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc) {
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case
ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti-
- ue->hw_timing_advance-
- ue->timing_advance-
- ue->N_TA_offset+5)%(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
+ ue->hw_timing_advance-
+ ue->timing_advance-
+ ue->N_TA_offset+5);
+ //LOG_E(PHY,"ul-signal [subframe: %d, ulsch_start %d]\n",subframe_tx, ulsch_start);
+
+ if(ulsch_start < 0)
+ ulsch_start = ulsch_start + (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
+
+ if (ulsch_start > (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti))
+ ulsch_start = ulsch_start % (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
+
+ //LOG_E(PHY,"ul-signal [subframe: %d, ulsch_start %d]\n",subframe_tx, ulsch_start);
#else //this is the normal case
ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance;
#endif //else EXMIMO
@@ -1213,7 +1222,14 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
ue->generate_ul_signal[eNB_id] = 1;
// deactivate service request
- ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+ // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+ LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx);
+ if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx - 1))
+ {
+ LOG_D(PHY,"PUSCH MAX Retransmission acheived ==> send last pusch (%d) \n");
+ ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+ ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
+ }
ack_status = get_ack(&ue->frame_parms,
ue->dlsch[eNB_id][0]->harq_ack,
@@ -3089,22 +3105,27 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
if (ret == (1+dlsch0->max_turbo_iterations)) {
*dlsch_errors=*dlsch_errors+1;
-
+ if(dlsch0->rnti != 0xffff)
+ {
LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH in error (rv %d,mcs %d,TBS %d)\n",
ue->Mod_id,dlsch0->rnti,
harq_pid,frame_rx,subframe_rx,
dlsch0->harq_processes[harq_pid]->rvidx,
dlsch0->harq_processes[harq_pid]->mcs,
dlsch0->harq_processes[harq_pid]->TBS);
+ }
} else {
+ if(dlsch0->rnti != 0xffff)
+ {
LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH (rv %d,mcs %d,TBS %d)\n",
ue->Mod_id,dlsch0->rnti,
harq_pid,frame_rx,subframe_rx,
dlsch0->harq_processes[harq_pid]->rvidx,
dlsch0->harq_processes[harq_pid]->mcs,
dlsch0->harq_processes[harq_pid]->TBS);
+ }
#ifdef DEBUG_DLSCH
int j;
@@ -3293,6 +3314,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
// do procedures for C-RNTI
if (ue->dlsch[eNB_id][0]->active == 1) {
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
ue_pdsch_procedures(ue,
proc,
eNB_id,
@@ -3302,9 +3324,11 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
ue->frame_parms.symbols_per_tti>>1,
abstraction_flag);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
}
// do procedures for SI-RNTI
if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
ue_pdsch_procedures(ue,
proc,
eNB_id,
@@ -3314,10 +3338,12 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
ue->frame_parms.symbols_per_tti>>1,
abstraction_flag);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
}
// do procedures for SI-RNTI
if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
ue_pdsch_procedures(ue,
proc,
eNB_id,
@@ -3327,10 +3353,12 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
ue->frame_parms.symbols_per_tti>>1,
abstraction_flag);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
}
// do procedures for RA-RNTI
if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
ue_pdsch_procedures(ue,
proc,
eNB_id,
@@ -3340,6 +3368,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
ue->frame_parms.symbols_per_tti>>1,
abstraction_flag);
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
}
if (subframe_select(&ue->frame_parms,subframe_rx) != SF_S) { // do front-end processing for second slot, and first symbol of next subframe
@@ -3375,6 +3404,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
// do procedures for C-RNTI
if (ue->dlsch[eNB_id][0]->active == 1) {
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
ue_pdsch_procedures(ue,
proc,
eNB_id,
@@ -3393,7 +3423,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
&ue->dlsch_errors[eNB_id],
mode,
abstraction_flag);
-
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
}
else {
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 617acff8b4..8ac2094efc 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -828,9 +828,6 @@ void schedule_ulsch_rnti(module_id_t module_idP,
UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power;
UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul;
mcs = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
- if ((cqi_req==1) && (mcs>19)) {
- mcs=19;
- }
if (UE_template->pre_allocated_rb_table_index_ul >=0) {
rb_table_index=UE_template->pre_allocated_rb_table_index_ul;
} else {
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.c b/openair2/UTIL/LOG/vcd_signal_dumper.c
index 226f8f0754..d367ec7766 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.c
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.c
@@ -240,6 +240,10 @@ const char* eurecomFunctionsNames[] = {
"rx_pdcch",
"dci_decoding",
"rx_phich",
+ "pdsch_procedures",
+ "pdsch_procedures_si",
+ "pdsch_procedures_p",
+ "pdsch_procedures_ra",
"phy_ue_config_sib2",
"macxface_phy_config_sib1_eNB",
"macxface_phy_config_sib2_eNB",
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h
index 81a5fb083d..1e03e95002 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.h
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.h
@@ -214,6 +214,10 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH,
VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING,
VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P,
+ VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_CONFIG_SIB1_ENB,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_CONFIG_SIB2_ENB,
diff --git a/targets/DOCS/E-UTRAN_User_Guide.docx b/targets/DOCS/E-UTRAN_User_Guide.docx
old mode 100644
new mode 100755
index 824aa46e9a..12a9d17da5
Binary files a/targets/DOCS/E-UTRAN_User_Guide.docx and b/targets/DOCS/E-UTRAN_User_Guide.docx differ
diff --git a/targets/DOCS/E-UTRAN_User_Guide.pdf b/targets/DOCS/E-UTRAN_User_Guide.pdf
old mode 100644
new mode 100755
index 5005692944..3de31b24f2
Binary files a/targets/DOCS/E-UTRAN_User_Guide.pdf and b/targets/DOCS/E-UTRAN_User_Guide.pdf differ
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.usrpb210.conf
index 191071d18c..868e499de6 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if5.usrpb210.conf
@@ -38,6 +38,7 @@ eNBs =
Nid_cell_mbsfn = 0;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
+ nb_antenna_ports = 1;
tx_gain = 90;
rx_gain = 125;
prach_root = 0;
@@ -100,6 +101,7 @@ eNBs =
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
+ ue_TransmissionMode = 1;
}
);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.usrpb210.conf
index 8e1e1441bf..805bb1aba8 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.band7.tm1.if5.usrpb210.conf
@@ -38,6 +38,7 @@ eNBs =
Nid_cell_mbsfn = 0;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
+ nb_antenna_ports = 1;
tx_gain = 90;
rx_gain = 125;
prach_root = 0;
@@ -100,6 +101,7 @@ eNBs =
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
+ ue_TransmissionMode = 1;
}
);
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index d070b91083..0741d88c42 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -1305,7 +1305,7 @@ extern void init_te_thread(PHY_VARS_eNB *, pthread_attr_t *);
void init_eNB_proc(int inst) {
- int i;
+ int i=0;
int CC_id;
PHY_VARS_eNB *eNB;
eNB_proc_t *proc;
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 117beb68d7..9f98aaada1 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -1608,6 +1608,11 @@ int main( int argc, char **argv )
PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,abstraction_flag);
PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;
+ PHY_vars_eNB_g[0][CC_id]->ue_dl_rb_alloc=0x1fff;
+ PHY_vars_eNB_g[0][CC_id]->target_ue_dl_mcs=target_dl_mcs;
+ PHY_vars_eNB_g[0][CC_id]->ue_ul_nb_rb=6;
+ PHY_vars_eNB_g[0][CC_id]->target_ue_ul_mcs=target_ul_mcs;
+
if (phy_test==1) PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0;
else PHY_vars_eNB_g[0][CC_id]->mac_enabled = 1;
@@ -1802,11 +1807,19 @@ int main( int argc, char **argv )
// start the main thread
- if (UE_flag == 1) init_UE(1);
+ if (UE_flag == 1) {
+ init_UE(1);
+ number_of_cards = 1;
+
+ for(CC_id=0; CC_idrf_map.card=0;
+ PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
+ }
+ }
else {
init_eNB(node_function,node_timing,1,eth_params,single_thread_flag);
- // Sleep to allow all threads to setup
-
+ // Sleep to allow all threads to setup
+
number_of_cards = 1;
for(CC_id=0; CC_idCC_id;
int ind;
int found;
int freq_offset=0;
@@ -312,9 +312,8 @@ static void *UE_thread_synch(void *arg)
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 <= downlink_frequency[0][0]) && (eutra_bands[ind].dl_max >= downlink_frequency[0][0])) {
- for (card=0; cardrf_map.card].rx_num_channels;i++) {
+ 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].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;
else //FDD
- openair0_cfg[0].duplex_mode = duplex_mode_TDD;
+ openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD;
}
sync_mode = pbch;
@@ -350,18 +349,14 @@ static void *UE_thread_synch(void *arg)
} else if (UE->UE_scan == 1) {
current_band=0;
- for (card=0; cardrx_total_gain_dB;
- printf( "UE synch: setting RX gain (%d,%d) to %f\n", card, i, openair0_cfg[card].rx_gain[i] );
- }
+ 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;
+
+ 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;
}
-
}
@@ -417,28 +412,19 @@ static void *UE_thread_synch(void *arg)
oai_exit=1;
}
- for (card=0; cardrx_total_gain_dB;
- printf("UE synch: setting RX gain (%d,%d) to %f\n",card,i,openair0_cfg[card].rx_gain[i]);
- }
+ 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;
+ if (UE->UE_scan_carrier) {
+ openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
+ }
+
}
- if (UE->UE_scan_carrier) {
-
- for (i=0;iUE_scan_carrier = 0;
// rerun with new cell parameters and frequency-offset
- for (i=0;irx_total_gain_dB;//-USRP_GAIN_OFFSET;
- openair0_cfg[0].rx_freq[i] -= UE->common_vars.freq_offset;
- openair0_cfg[0].tx_freq[i] = openair0_cfg[0].rx_freq[i]+uplink_frequency_offset[0][i];
- downlink_frequency[0][i] = openair0_cfg[0].rx_freq[i];
+ 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;
+ openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= UE->common_vars.freq_offset;
+ openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
+ downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
freq_offset=0;
}
// reconfigure for potentially different bandwidth
switch(UE->frame_parms.N_RB_DL) {
case 6:
- openair0_cfg[0].sample_rate =1.92e6;
- openair0_cfg[0].rx_bw =.96e6;
- openair0_cfg[0].tx_bw =.96e6;
+ 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[0].sample_rate =7.68e6;
- openair0_cfg[0].rx_bw =2.5e6;
- openair0_cfg[0].tx_bw =2.5e6;
+ 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[0].sample_rate =15.36e6;
- openair0_cfg[0].rx_bw =5.0e6;
- openair0_cfg[0].tx_bw =5.0e6;
+ 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[0].sample_rate=30.72e6;
- openair0_cfg[0].rx_bw=10.0e6;
- openair0_cfg[0].tx_bw=10.0e6;
+ openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
+ openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
+ openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
// openair0_cfg[0].rx_gain[0] -= 0;
break;
}
-
+
UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
//UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
UE->rfdevice.trx_stop_func(&UE->rfdevice);
@@ -559,25 +545,19 @@ static void *UE_thread_synch(void *arg)
downlink_frequency[0][0]+freq_offset,
downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
- for (card=0; cardrx_total_gain_dB;//-USRP_GAIN_OFFSET;
- UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
-
- }
- }
-
- if (UE->UE_scan_carrier==1) {
- 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;