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 4d9b1055fa..7cde2811c8 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -253,13 +253,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_defs.h b/common/utils/T/T_defs.h index 9285a68d56..eb327bb261 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -29,15 +29,15 @@ typedef struct { #define T_SHM_FILENAME "/T_shm_segment" /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS 146 +#define VCD_NUM_FUNCTIONS 142 /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_VARIABLES 99 +#define VCD_NUM_VARIABLES 107 /* first VCD function (to be kept up to date! see in T_messages.txt) */ #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) /* first VCD variable (to be kept up to date! see in T_messages.txt) */ -#define VCD_FIRST_VARIABLE ((uintptr_t)T_VCD_VARIABLE_FRAME_NUMBER_TX_ENB) +#define VCD_FIRST_VARIABLE ((uintptr_t)T_VCD_VARIABLE_FRAME_NUMBER_TX0_ENB) #endif /* _T_defs_H_ */ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 050c48d0a9..321225a597 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -806,12 +806,36 @@ ID = buf_test #variables -ID = VCD_VARIABLE_FRAME_NUMBER_TX_ENB - DESC = VCD variable FRAME_NUMBER_TX_ENB +ID = VCD_VARIABLE_FRAME_NUMBER_TX0_ENB + DESC = VCD variable FRAME_NUMBER_TX0_ENB GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value -ID = VCD_VARIABLE_FRAME_NUMBER_RX_ENB - DESC = VCD variable FRAME_NUMBER_RX_ENB +ID = VCD_VARIABLE_FRAME_NUMBER_TX1_ENB + DESC = VCD variable FRAME_NUMBER_TX1_ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value +ID = VCD_VARIABLE_FRAME_NUMBER_RX0_ENB + DESC = VCD variable FRAME_NUMBER_RX0_ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value +ID = VCD_VARIABLE_FRAME_NUMBER_RX1_ENB + DESC = VCD variable FRAME_NUMBER_RX1_ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value +ID = VCD_VARIABLE_SUBFRAME_NUMBER_TX0_ENB + DESC = VCD variable SUBFRAME_NUMBER_TX0_ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value +ID = VCD_VARIABLE_SUBFRAME_NUMBER_TX1_ENB + DESC = VCD variable SUBFRAME_NUMBER_TX1_ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value +ID = VCD_VARIABLE_SUBFRAME_NUMBER_RX0_ENB + DESC = VCD variable SUBFRAME_NUMBER_RX0_ENB + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value +ID = VCD_VARIABLE_SUBFRAME_NUMBER_RX1_ENB + DESC = VCD variable SUBFRAME_NUMBER_RX1_ENB GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_RUNTIME_TX_ENB @@ -822,28 +846,36 @@ ID = VCD_VARIABLE_RUNTIME_RX_ENB DESC = VCD variable RUNTIME_RX_ENB GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value -ID = VCD_VARIABLE_FRAME_NUMBER_TX_UE - DESC = VCD variable FRAME_NUMBER_TX_UE +ID = VCD_VARIABLE_FRAME_NUMBER_TX0_UE + DESC = VCD variable FRAME_NUMBER_TX0_UE GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value -ID = VCD_VARIABLE_FRAME_NUMBER_RX_UE - DESC = VCD variable FRAME_NUMBER_RX_UE +ID = VCD_VARIABLE_FRAME_NUMBER_TX1_UE + DESC = VCD variable FRAME_NUMBER_TX1_UE GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value -ID = VCD_VARIABLE_SLOT_NUMBER_TX_UE - DESC = VCD variable SLOT_NUMBER_TX_UE +ID = VCD_VARIABLE_FRAME_NUMBER_RX0_UE + DESC = VCD variable FRAME_NUMBER_RX0_UE GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value -ID = VCD_VARIABLE_SLOT_NUMBER_RX_UE - DESC = VCD variable SLOT_NUMBER_RX_UE +ID = VCD_VARIABLE_FRAME_NUMBER_RX1_UE + DESC = VCD variable FRAME_NUMBER_RX1_UE GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value -ID = VCD_VARIABLE_SUBFRAME_NUMBER_TX_UE - DESC = VCD variable SUBFRAME_NUMBER_TX_UE +ID = VCD_VARIABLE_SUBFRAME_NUMBER_TX0_UE + DESC = VCD variable SUBFRAME_NUMBER_TX0_UE GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value -ID = VCD_VARIABLE_SUBFRAME_NUMBER_RX_UE - DESC = VCD variable SUBFRAME_NUMBER_RX_UE +ID = VCD_VARIABLE_SUBFRAME_NUMBER_TX1_UE + DESC = VCD variable SUBFRAME_NUMBER_TX1_UE + GROUP = ALL:VCD:UE:VCD_VARIABLE + FORMAT = ulong,value +ID = VCD_VARIABLE_SUBFRAME_NUMBER_RX0_UE + DESC = VCD variable SUBFRAME_NUMBER_RX0_UE + GROUP = ALL:VCD:UE:VCD_VARIABLE + FORMAT = ulong,value +ID = VCD_VARIABLE_SUBFRAME_NUMBER_RX1_UE + DESC = VCD variable SUBFRAME_NUMBER_RX1_UE GROUP = ALL:VCD:UE:VCD_VARIABLE FORMAT = ulong,value ID = VCD_VARIABLE_MISSED_SLOTS_ENB @@ -1217,92 +1249,32 @@ ID = VCD_FUNCTION_TRX_WRITE DESC = VCD function TRX_WRITE GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_TX0 - DESC = VCD function eNB_PROC_TX0 +ID = VCD_FUNCTION_TRX_READ_IF + DESC = VCD function TRX_READ_IF GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_RX0 - DESC = VCD function eNB_PROC_RX0 +ID = VCD_FUNCTION_TRX_WRITE_IF + DESC = VCD function TRX_WRITE_IF GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_TX1 - DESC = VCD function eNB_PROC_TX1 +ID = VCD_FUNCTION_eNB_PROC_RXTX0 + DESC = VCD function eNB_PROC_RXTX0 GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_RX1 - DESC = VCD function eNB_PROC_RX1 +ID = VCD_FUNCTION_eNB_PROC_RXTX1 + DESC = VCD function eNB_PROC_RXTX1 GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_TX2 - DESC = VCD function eNB_PROC_TX2 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_RX2 - DESC = VCD function eNB_PROC_RX2 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_TX3 - DESC = VCD function eNB_PROC_TX3 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_RX3 - DESC = VCD function eNB_PROC_RX3 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_TX4 - DESC = VCD function eNB_PROC_TX4 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_RX4 - DESC = VCD function eNB_PROC_RX4 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_TX5 - DESC = VCD function eNB_PROC_TX5 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_RX5 - DESC = VCD function eNB_PROC_RX5 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_TX6 - DESC = VCD function eNB_PROC_TX6 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_RX6 - DESC = VCD function eNB_PROC_RX6 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_TX7 - DESC = VCD function eNB_PROC_TX7 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_RX7 - DESC = VCD function eNB_PROC_RX7 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_TX8 - DESC = VCD function eNB_PROC_TX8 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_RX8 - DESC = VCD function eNB_PROC_RX8 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_TX9 - DESC = VCD function eNB_PROC_TX9 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_eNB_PROC_RX9 - DESC = VCD function eNB_PROC_RX9 - GROUP = ALL:VCD:ENB:VCD_FUNCTION - FORMAT = int,value -ID = VCD_FUNCTION_UE_THREAD_TX - DESC = VCD function UE_THREAD_TX +ID = VCD_FUNCTION_UE_THREAD_SYNCH + DESC = VCD function UE_THREAD_SYNCH GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value -ID = VCD_FUNCTION_UE_THREAD_RX - DESC = VCD function UE_THREAD_RX +ID = VCD_FUNCTION_UE_THREAD_RXTX0 + DESC = VCD function UE_THREAD_RXTX0 + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_UE_THREAD_RXTX1 + DESC = VCD function UE_THREAD_RXTX1 GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_eNB_TX @@ -1377,8 +1349,28 @@ ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_TX DESC = VCD function PHY_PROCEDURES_ENB_TX GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value -ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_RX - DESC = VCD function PHY_PROCEDURES_ENB_RX +ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_TX1 + DESC = VCD function PHY_PROCEDURES_ENB_TX1 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_RX_COMMON + DESC = VCD function PHY_PROCEDURES_ENB_RX_COMMON + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_RX_COMMON1 + DESC = VCD function PHY_PROCEDURES_ENB_RX_COMMON1 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_RX_UESPEC + DESC = VCD function PHY_PROCEDURES_ENB_RX_UESPEC + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_RX_UESPEC1 + DESC = VCD function PHY_PROCEDURES_ENB_RX_UESPEC1 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_PHY_PROCEDURES_ENB_SLOT_FEP + DESC = VCD function PHY_PROCEDURES_ENB_SLOT_FEP GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value ID = VCD_FUNCTION_PHY_PROCEDURES_UE_TX @@ -1573,6 +1565,10 @@ ID = VCD_FUNCTION_ENB_DLSCH_ENCODING DESC = VCD function ENB_DLSCH_ENCODING GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value +ID = VCD_FUNCTION_ENB_DLSCH_ENCODING_W + DESC = VCD function ENB_DLSCH_ENCODING_W + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value ID = VCD_FUNCTION_ENB_DLSCH_SCRAMBLING DESC = VCD function ENB_DLSCH_SCRAMBLING GROUP = ALL:VCD:ENB:VCD_FUNCTION @@ -1645,6 +1641,10 @@ ID = VCD_FUNCTION_UE_DECODE_SI DESC = VCD function UE_DECODE_SI GROUP = ALL:VCD:UE:VCD_FUNCTION FORMAT = int,value +ID = VCD_FUNCTION_UE_DECODE_PCCH + DESC = VCD function UE_DECODE_PCCH + GROUP = ALL:VCD:UE:VCD_FUNCTION + FORMAT = int,value ID = VCD_FUNCTION_UE_DECODE_CCCH DESC = VCD function UE_DECODE_CCCH GROUP = ALL:VCD:UE:VCD_FUNCTION @@ -1789,3 +1789,19 @@ ID = VCD_FUNCTION_TEST DESC = VCD function TEST GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value +ID = VCD_FUNCTION_SEND_IF4 + DESC = VCD function SEND_IF4 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_RECV_IF4 + DESC = VCD function RECV_IF4 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_SEND_IF5 + DESC = VCD function SEND_IF5 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value +ID = VCD_FUNCTION_RECV_IF5 + DESC = VCD function RECV_IF5 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value diff --git a/common/utils/T/tracer/hacks/Makefile b/common/utils/T/tracer/hacks/Makefile index ab10305c0b..f49e437bf5 100644 --- a/common/utils/T/tracer/hacks/Makefile +++ b/common/utils/T/tracer/hacks/Makefile @@ -3,16 +3,23 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I. -I.. LIBS=-lX11 -lm -lpng -lXft -all: dump_nack_signal +all: dump_nack_signal time_meas timeplot dump_nack_signal: ../utils.o ../database.o ../config.o ../event.o \ dump_nack_signal.o $(CC) $(CFLAGS) -o dump_nack_signal $^ $(LIBS) +time_meas: ../utils.o ../database.o ../config.o ../event.o \ + time_meas.o + $(CC) $(CFLAGS) -o time_meas $^ $(LIBS) + +timplot: timeplot.o + $(CC) $(CFLAGS) -o timeplot $^ $(LIBS) + .PHONY: all %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< clean: - rm -f *.o core dump_nack_signal + rm -f *.o core dump_nack_signal time_meas timeplot diff --git a/common/utils/T/tracer/hacks/time_meas.c b/common/utils/T/tracer/hacks/time_meas.c new file mode 100644 index 0000000000..04d4fa5acf --- /dev/null +++ b/common/utils/T/tracer/hacks/time_meas.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include "utils.h" +#include "event.h" +#include "database.h" +#include "config.h" +#include "../T_defs.h" + +void usage(void) +{ + printf( +"options:\n" +" -d this option is mandatory\n" +" -ip connect to given IP address (default %s)\n" +" -p connect to given port (default %d)\n", + DEFAULT_REMOTE_IP, + DEFAULT_REMOTE_PORT + ); + exit(1); +} + +struct timespec time_sub(struct timespec a, struct timespec b) +{ + struct timespec ret; + if (a.tv_nsec < b.tv_nsec) { + ret.tv_nsec = (int64_t)a.tv_nsec - (int64_t)b.tv_nsec + 1000000000; + ret.tv_sec = a.tv_sec - b.tv_sec - 1; + } else { + ret.tv_nsec = a.tv_nsec - b.tv_nsec; + ret.tv_sec = a.tv_sec - b.tv_sec; + } + return ret; +} + +int main(int n, char **v) +{ + char *database_filename = NULL; + void *database; + char *ip = DEFAULT_REMOTE_IP; + int port = DEFAULT_REMOTE_PORT; + int i; + char t; + int number_of_events; + int socket; + int *is_on; + int ev_fun; + int start_valid = 0; + struct timespec start_time, stop_time, delta_time; + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); + if (!strcmp(v[i], "-d")) + { if (i > n-2) usage(); database_filename = v[++i]; continue; } + if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } + if (!strcmp(v[i], "-p")) + { if (i > n-2) usage(); port = atoi(v[++i]); continue; } + usage(); + } + + if (database_filename == NULL) { + printf("ERROR: provide a database file (-d)\n"); + exit(1); + } + + database = parse_database(database_filename); + + load_config_file(database_filename); + + number_of_events = number_of_ids(database); + is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) abort(); + + on_off(database, "VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER", is_on, 1); + + ev_fun = event_id_from_name(database, + "VCD_FUNCTION_ENB_DLSCH_ULSCH_SCHEDULER"); + + socket = connect_to(ip, port); + + t = 1; + if (socket_send(socket, &t, 1) == -1 || + socket_send(socket, &number_of_events, sizeof(int)) == -1 || + socket_send(socket, is_on, number_of_events * sizeof(int)) == -1) + abort(); + + while (1) { + char v[T_BUFFER_MAX]; + event e; + int on_off; + e = get_event(socket, v, database); + if (e.type == -1) break; + if (e.type != ev_fun) + { printf("unhandled event %d\n", e.type); continue; } + on_off = e.e[0].i; +printf("yo %d\n", on_off); + if (on_off == 1) { + start_time = e.sending_time; + start_valid = 1; + continue; + } + if (on_off != 0) { printf("fatal!\n"); abort(); } + if (!start_valid) continue; + stop_time = e.sending_time; + delta_time = time_sub(stop_time, start_time); + fprintf(stderr, "%ld\n", + delta_time.tv_sec * 1000000000UL + delta_time.tv_nsec); + fflush(stderr); + } + + return 0; +} diff --git a/common/utils/T/tracer/hacks/timeplot.c b/common/utils/T/tracer/hacks/timeplot.c new file mode 100644 index 0000000000..79905d16f9 --- /dev/null +++ b/common/utils/T/tracer/hacks/timeplot.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include + +void RESET(void) +{ printf("\x1b""c"); fflush(stdout); } + +void GOTO(int x, int y) +{ char s[64];sprintf(s,"\x1b[%d;%dH",y,x);printf("%s",s);fflush(stdout); } + +void HIDE_CURSOR(void) +{ printf("\x1b[?25l"); fflush(stdout); } + +void sig(int x) +{ + RESET(); + exit(0); +} + +/* 0: [0-2[ + * ... + * 48: [96-98[ + * 49: [98-infinity] + */ +int bins[50]; + +#define N 1000 +int data[N]; + +void plot(void) +{ + int i; + int max = 0; + int vmin = data[0]; + int vmax = 0; + long vavg; + memset(bins, 0, sizeof(bins)); + int binsize_ns = 500; + + vavg = 0; + + for (i = 0; i < N; i++) { + if (data[i] < vmin) vmin = data[i]; + if (data[i] > vmax) vmax = data[i]; + vavg += data[i]; + int ms2 = data[i]/binsize_ns; + if (ms2 > 49) ms2 = 49; + bins[ms2]++; + if (bins[ms2] > max) max = bins[ms2]; + } + + vavg /= N; + + GOTO(1,1); + for (i = 0; i < 50; i++) { + double binend = (i+1) * binsize_ns / 1000.; + int k; + int width = bins[i] * 70 / max; + /* force at least width of 1 if some point is there */ + if (bins[i] && width == 0) width = 1; + printf("%#5.1f ", binend); + for (k = 0; k < width; k++) putchar('#'); + for (; k < 70; k++) putchar(' '); + putchar('\n'); + } + printf("min %d ns max %d ns avg %ld ns\n", vmin, vmax, vavg); +} + +int main(void) +{ + int i; + int pos = 0; + signal(SIGINT, sig); + RESET(); + HIDE_CURSOR(); + while (!feof(stdin)) { + for (i=0; i<100; i++) { scanf("%d", &data[pos]); pos++; pos%=N; } + plot(); + } + RESET(); + return 0; +} diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index aa2daf8ebb..f66ec5fe4b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -7205,7 +7205,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 1f3179a969..83b34971da 100644 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -366,6 +366,8 @@ typedef struct { 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 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/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index a5c1e90147..da06e60d25 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1006,7 +1006,7 @@ void dump_CCE_table(int *CCE_table,const int nCCE,const unsigned short rnti,cons for (i=0;ieNB_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/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.conf index 10bee7627a..9d9d5b4535 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.conf @@ -23,6 +23,9 @@ eNBs = component_carriers = ( { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; frame_type = "FDD"; tdd_config = 3; tdd_config_s = 0; @@ -97,7 +100,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/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 6da474c4a0..40b9255936 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1795,11 +1795,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;